Ignore validation on commandButton press - jsf

I have page in which I edit some entity. That page has two command buttons. One is "Back" and one is "Save" and also on that page I have form with input fields (idInputSubject). Some of them are required, some are not.
How can I ensure that we I press "Back" button (cancel editing and go back) validation will be ignored, which is not the case now. Now, when I press either "Back" or "Save" button validation's messages appear if I did't fill required filed with the correct values (idInputSubject).
Both "Back" and "Save" buttons are in the same form:
<h:form id="idFormMeasureDetail" styleClass="bodyForm" prependId="false">
...
<p:commandButton value="#{contentMB.msg.label_back.value}"
action="#{chooseMeasureControllerMB.aSearch}"
rendered="#{detailMeasureMB.navigation eq 0}" ajax="false"
icon="ui-icon-arrowreturnthick-1-w"/>
<p:commandButton value="#{contentMB.msg.button_save.value}" ajax="false"
icon="ui-icon-disk" actionListener="#{detailMeasureControllerMB.alApplyChanges}"
title="#{contentMB.msg.tip_Apply.value}" />
...
<p:inputTextarea id="idInputSubject" value="#{detailMeasureMB.measure.aufgabe}"
readonly="#{!userSessionMB.supervisor and !detailMeasureMB.isCreator}"
required="#{globalSessionMB.globalWebOptionsMap['MMRequiredSubject'].propvalue}"
title="#{contentMB.msg.tip_Betreff.value}"
autoResize="false" style="width:100%;" >
</p:inputTextarea>
<p:message id="inputSubjectMsg" for="idInputSubject" display="icon" />
...
</h:form>
ChooseMeasureControllerMB:
#ManagedBean(name = "chooseMeasureControllerMB")
#RequestScoped
public class ChooseMeasureControllerMB extends BaseMeasureControllerMB {
...
public String aSearch() {
...
// navigate to target-page
return "/pages/mm/showMeasuresList.xhtml?faces-redirect=true";
}
...
}

If you want prevent/skip validation on certain button click use
immediate="true" on that specific button
For a good explanation about the immediate="true" read the following BalusC answer
And here a nice diagram that shows how imemdiate="true works"

In short, when you're clicking the "back" button, you submit the form and the data is validated. To prevent this, place the button in another form or use Java-script for the navigation.
In general, when you want to cancel an operation you don't want to submit the data, since it is to be discarded. Use some client side action. I think you can also use a <p:commandButton> or a <p:button> for navigation. This way the form isn't submitted either.

Related

How to prevent/stop submit of commandbutton when having on going AJAX-call

I have a form with a few different text fields which the user needs to fill in to be able to go to the next step. The next step of the page is accessed by clicking a commandbutton "Next" and should only be enabled when all of the fields are valid (validated on the server).
The problem is that the user can click the "next step" button directly after changing a field with valid input to invalid input, without loosing focus on the field, causing the validation to not get triggered in time to prevent the user to go to the next step.
Here is an example of one of the fields, together with the commandbutton doing the submit.
<p:inputTextarea id="lineFreeText" value="#{line.freeText}" rows="1" disabled="#{facesContext.validationFailed and component.valid}"
maxlength="#{itemConstant.MAX_FREE_TEXT_LENGTH}" counter="freeTextCounter"
counterTemplate="{0}/#{itemConstant.MAX_FREE_TEXT_LENGTH}" rendered="#{showFreeText and !line.hasItemForm()}" validator="freeTextValidator" validatorMessage="#{messages.freeTextRequired}" requiredMessage="#{messages.freeTextRequired}">
<p:ajax event="change" process="#this" listener="#{cartController.saveLine(line)}" update="#form cartForm lineFreeText lineEditedSymbols lineFreeTextMessage #([id$=nextStepBtn])" />
</p:inputTextarea>
<h:commandButton value="#{messages['checkout.nextStep']}" id="nextStepBtn" rendered="#{cartController.size() gt 0 and !clientContext.OCIRequest}"
onclick="$('.jqRealNextStepButton').click();" style="border: 2px solid #008091; padding: 0.5em;"
styleClass="ju-button" disabled="#{clientContext.client.visitor or checkoutDeliveryDateController.disableNextButton() or totalMinAmountNotMet or facesContext.validationFailed or not facesContext.postback}"
title="#{clientContext.client.visitor ? messages.disabledForVisitor : tooltip}">
<f:ajax execute="#this" />
</h:commandButton>
I want the commandbutton to cancel the submit when there's an on going ajax happening, so that the validation can finish before the form is submitted, enabling me to prevent users from inputting invalid data and continuing. Is there an easy way to accomplish this?
Cheers
The solution was to change the commandbutton to the primefaces one, and remove the onclick pointing to another commandlink, which executed the backend-logic to traverse to the next page. When I put the action-method in the <p:commandbutton/> the ajax-events were properly queued.

p:commandButton click updates h:form unwantedly

<p:commandButton id="excelAccountLevelOneAccLvl1" ajax="false" icon = "fa fa-fw fa-download" >
<f:param name="accountLevelOneFormRequest" value="accountLevelOneFormRequest" />
<p:dataExporter type="xlsx" target="baselineOneTable"
fileName="#{exportToExcelPageBean.fileName}"
postProcessor="#{exportToExcelPageBean.postProcessXLS}" />
</p:commandButton>
On clicking this button, somehow the forms seems to update and it activates the Faces validation and asks me to fill enter the mandatory field values! I can't figure out why! There is not update parameter here at all!
update is for ajax requests only. You are using ajax="false" which means the commandButton activates a
full page request. That in turn means that the whole form in which the commandButton is included is
processed. If you want to avoid this put your commandButton in a separate form.

How to hide/show a panel conditionally in primefaces/jsf2 on commandButton click?

I want to hide/show <p:panel> on commandButton click with some condition ,I tried following
<h:form>
// some tag here
<p:commandButton value="EDIT" ajax="false"
onclick="if(#{bean.status == 'ACTIVE'}){editable.show();}"
actionListener="#{beanMgnt.edit}">
</h:form>
and editable is a panel as
<p:panel widgetVar="editable" closable="true"
toggleable="true" visible="false">
// some tags here
</p:panel
edit method is doing only sysout.
What I want when enduser clicks the button this panel will be visible with bean data populated with Editable text boxes.
I want to make visible this panel visible with button click.How to do that?
You also have to use update="<id>" in your button...
so,for example, you would need <p:commandButton...update="thepanelid".../> <p:panel id="thepanelid"...
I think you could use a boolean attribute in your backing bean. In the panel you put : visible="backingbean.yourAttribute" and you use a method in your bean to control it via onclick.
onclick="backingbean.theMethod"
In the method, if your condition is verified, you can set the attribute to "true".

PrimeFaces :: display p:Dialog to fill-in a form field, without reposting

I have a data-entry form that displays a number of fields (mostly p:inputText) for the user to provide. Some of these are LOVs so I display a p:dialog to allow the user to select the right value. The p:dialog is displayed by means of a p:commandLink next to the p:inputText. Main parts of code shown below:
<h:form id="parentForm">
(...)
<p:inputText value="#{CustomerCEVController.customer.municipality}" id="customerMncName"/>
<p:commandLink type="button" onclick="MunicipalityDlg.show()" styleClass="ui-icon ui-icon-search"/>
(...)
<p:commandButton value="Submit" id="save" actionListener="#{CustomerCEVController.saveButtonListener}" /> (...)
</h:form>
The problem is, whenever the user clicks on the p:commandLink to display the p:dialog (to allow him to select one of the values) the outer form goes through its lifecycle phases (restore view, apply request values, process validations, etc.) since the p:commandLink is placed inside an h:form. How can I implement this dialog-displaying functionality while avoiding posting the h:form with every dialog that the user opens?
Just add "return false" as the last statement to onclick event handler. It prevents commandLink's default function (posting the form).
Just add set the appendToBody attribute to true on <p:dialog>
<p:dialog header="Header Text" widgetVar="dlg" appendToBody="true">
//Content
</p:dialog>
This appends the dialog as a child of the document body outside the parent form.

Restrict f:validator on a specific submit button alone

I'm having a JSF form in which I have a textarea and multiple buttons.
For the text area I'm doing validation using f:validator
<f:validator validatorId="myValidator" />
<a4j:support event="onsubmit" ajaxSingle="true" process="textarea1" />
The validator is working as expected. Now i have multiple submit buttons on the page i want the validation to happen on specific button only and validator should be ignored on the remaining buttons.
Is there anyway to restrict the validator on a specific submit button alone. Thanks.
You can use the disabled attribute.
<f:validator validatorId="myValidator" disabled="#{empty param['formId:buttonId']}" />
Where formId is the ID of your <h:form> and the buttonId is the ID of the button which is supposed to be the only button to trigger validation.
I assume that you want to submit the textarea value to the server when clicking on other buttons too (so no point of playing with the process attribute)
How about adding immediate="true" to the other buttons ?
That way they will skip validation, while the submit button without immediate="true" will do the validation as expected
Or
There seems another workaround in this article JSF 2 - Conditionally Skip Validation
Something like
<h:commandButton action="#{bean.someMethod"} value="Submit2">
<f:param name="skipValidation" value="true"/>
</h:commandButton>
and inside the validate method of the validator check for the skipValidation attirbute (look for further explanation in the article...)

Resources