Liferay AUI Form Submission

  

Liferay AUI Form with Multiple Actions 

How to submit AUI Form to different actions using different submit buttons

Overview


Forms in Liferay are usually implemented using <aui:form tag. As default HTML form, it has the action attribute that defines the action URL to submit the form data to. Then you can use a submit button to submit data to the defined action.
In most cases a single action is enough to submit the form, but sometimes you might need more complex scenario, where you need multiple actions to process data in a different way.
Imagine a multi-step form with possibility to move to the next step, save draft form, or submit a form to review (on the last step):

Each of the buttons should submit the form data, but the logic is different for each of actions: save data and move to the next step, save data and redirect to homepage, or submit data for review process.
This articles explains how to handle cases like this.


Solution


To make it possible to submit forms to different actions, you need to define them first (usually as MVCActionCommand classes), and define the appropriate action URLs on the JSP with a form. For our example it could be like this:

<portlet:actionURL name="/form/next" var="nextStepURL" />
<portlet:actionURL name="/form/save" var="saveFormURL" />
<portlet:actionURL name="/form/submit" var="submitFormURL" />

Define the form using one of the URLs (default one) as form action:

<aui:form action="${nextStepURL}" method="post" name="fm">

Also, define the submit buttons in the bottom on the form:

<clay:button type="submit" label="btn.next" cssClass="btn btn-success btn-next" />
<clay:button type="submit" label="btn.save" cssClass="btn btn-primary btn-save" />
<clay:button type="submit" label="btn.submit" cssClass="btn btn-success btn-submit" />

Note: Next/Submit buttons rendered conditionally (Submit button only on the last step), custom CSS classes (btn-next/btn-save/btn-submit) will be required for JS.

Then define a JS function that submits the form to a different actions based on the submit button clicked:

<script type="text/javascript">
Liferay.on('allPortletsReady', function () {

Liferay.provide(window, '${namespace}submitForm', function(event, target) {

event.preventDefault();

let submitter = event._event.submitter;
let form = target.form;

if (submitter.classList.contains('btn-next')) {
form.action = '${nextStepURL}';
form.submit();
} else if (submitter.classList.contains('btn-save')) {
form.action = '${saveFormURL}';
form.submit();
} else if (submitter.classList.contains('btn-submit')) {
form.action = '${submitFormURL}';
form.submit();
}

return false;
});

});
</script>

The function accepts the event object (form submission event) and the target.
Using the event object you can find the "submitter" - the submit button that was clicked to initiate the submit event.
Using target you can get the form - to define it's action dynamically and submit the form data.
Using defined CSS class names on the submit buttons you can detect which button was clicked, set the form action accordingly, and submit the form.
event.preventDefault() is called to prevent default form submission.

Finally, add the JS function call in the onSubmit form handler:

<aui:form action="${nextStepURL}" method="post" name="fm"
onSubmit="${namespace}submitForm(event,this);">
Now your form should be able to submit data to different actions dynamically.


Enjoy 😏 

Comments

Popular posts from this blog

Liferay Search Container Example

Liferay DXP - max upload file size

Liferay Keycloak integration