1

I have a liferay portlet with a simple form for entering two numbers and submitting them to be added:

<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>

<portlet:defineObjects />

<portlet:actionURL var="calculateURL">
    <portlet:param name="mvcPath" value="/html/calculator/edit.jsp" />
</portlet:actionURL>

<aui:form action="<%= calculateURL %>" method="post">
    <aui:input label="x" name="x" type="text" value="${x}"/>
    <aui:input label="y" name="y" type="text" value="${y}"/>
    <aui:button type="submit" value="add"/>
</aui:form>

This works fine. I would now like to add a button that allowed me to subtract the numbers instead. But when I add the new button, I don't know how to differentiate between which button was pressed, when I am in my processAction method. How can I do this?

Alternatively: I have found this answer on how to do it, but I wasn't able to get it to work. Does it point me in the right direction, and should I keep experimenting with the answer given there?

Boris
  • 5,094
  • 4
  • 45
  • 71
  • Based on Button clicked , you can change action attribute of form in order to have different functions. This you can do using some javascript functions. – Pankaj Kathiriya Jun 13 '13 at 13:11
  • or else you can pass some parameter based on basis of button clicked which will decide what operation is to perform. – Pankaj Kathiriya Jun 13 '13 at 13:17

3 Answers3

2

You can have two different action method in your controller class and in jsp based on which button clicked, call the action url accordingly. Find below code which changes form action based on the button clicked. This helps you keep your business on logic seperate in your controller class. Else you can have only action and then pass parameter to action to identify what to perfrom (add or subtract)

<portlet:actionURL var="subtractNumberURL">
</portlet:actionURL>

<portlet:actionURL var="addNumberURL">
    <portlet:param name="mvcPath" value="/html/calculator/edit.jsp" />
</portlet:actionURL>

<script type="text/javascript" charset="utf-8">
function submitForm(action){
  if(action==0){
     A.one('<portlet:namespace/>form').set('action',"<%=addNumberURL%>");
  }else{
     A.one('<portlet:namespace/>form').set('action',"<%=subtractNumberURL%>");
  }
}
</script>

<aui:form action="<%= addNumberURL%>" name="form" method="post">
    <aui:input label="x" name="x" type="text" value="${x}"/>
    <aui:input label="y" name="y" type="text" value="${y}"/>
    <aui:button type="submit" value="add" onClick="submitForm(0)"/>
    <aui:button type="submit" value="subtract" onClick="submitForm(1)"/>
</aui:form>
Pritesh Shah
  • 857
  • 1
  • 7
  • 8
  • 1
    Thanks for the answer. I have two questions. First, I am not very experienced with javascript, so I don't understand the `A.one` part. I understand that it is supposed to reference the form by calling out its name, but in my javascript console I get the error `Uncaught ReferenceError: A is not defined`. Am I missing something? Second, how can I distinguish between the two actions in my portlet code? Does the call go to `processAction`, or should I make two distinct methods, one for subtracting, and one for adding? – Boris Jun 14 '13 at 09:28
  • for distinguish between calls you can pass parameter along with " " using "" – Laxman Rana Jun 15 '13 at 04:37
  • A.one is aui script. At the top of the script you should do var A=AUI(); then you will not get uncaught referenceerror. Second, you should create should different method in your controller class one for addition and another for substraction and call them accordingly on button click – Pritesh Shah Jun 17 '13 at 05:15
1

I've successfully implemented this way (tested on liferay 6.1.2 and FF). I've found this article very useful! Keep into account function name: must NOT be "submitForm"!

<aui:script use="aui-base">
Liferay.provide(window, 'mysubmitForm', function(action) {
   if(action=='add'){
     A.one('#<portlet:namespace/>form').set('action','<%=addNumberURL.toString()%>');
  }else{
     A.one('#<portlet:namespace/>form').set('action','<%=subtractNumberURL.toString()%>');
  }
});
</aui:script>
Community
  • 1
  • 1
Vincenzo Cerbone
  • 404
  • 5
  • 12
1

Personally I prefer a clean and simple solution into javascript with just one input hidden on the HTML code and then in the action with a switch select the correct code to be executed. I use Jquery but the code can be implemented on plain javascript as well:

Inside the form, we put a hidden variable like this:

<aui:input name="botonClicked" id="botonClicked" type="hidden"></aui:input>

We define then our buttons but with "type='button'", not with "type='submit'", for example:

<aui:button icon="icon-save" iconAlign="left" value="Save" type="button" cssClass="btn-primary buttonListener" name="Save"></aui:button>
<aui:button icon="icon-save" iconAlign="left" value="Send" type="button" cssClass="btn-primary buttonListener" name="Send"></aui:button>

And then with a simple jquery we put the button clicked on our hidden input and submit the form:

$(".buttonListener").click(function(){
var nombre = $(this).attr("name");
nombre = nombre.replace(namespace,'');
$("#botonClicked").val(nombre);
$("#OurForm").submit();
}); 

In your Java code, in the Action code, just we use a switch to know wich button was pressed and call our different functions:

String botonClicked= ParamUtil.getString(actionRequest, "botonClicked");

    switch (botonClicked) {
    case "Save":
        Guardar(actionRequest, actionResponse);
        break;
    case "Send":
        Enviar(actionRequest, actionResponse);
        break;
    default:
        break;
    }

For me at least this solution is cleaner and it works perfectly.

Santiago
  • 371
  • 2
  • 7