Show Submit Button Only When All Mandatory Fields Completed

Home » Show Submit Button Only When All Mandatory Fields Completed

Today I had this query about refreshing multiple areas of the page on a blog post about partial execution:

I have several input text fields with onChange events that do a partial updates on panels (a panel for each field) that contain the images that display whether the required field is completed. But I also have a submit button at the top of the xPage, that only becomes usable when all required fields are completed. So, I’d like to be able to refresh that button also, from each required field (rather than a full update). That means refreshing two different objects in different places on the xPage (hence they can’t be in a single panel).

Chaining partial refreshes is one option, but I recalled being asked a similar question some time ago (two years now) by a customer of our XPages mentoring package.

One option is to have your validation running client-side.

If you prefer server-side validation, the challenge with a traditional partial refresh is not running SSJS or Java to show a Submit button once all mandatory fields have been filled in. That’s fine, because at that time the validation phase will succeed and the subsequent business logic will run to now show the button. The challenge is running SSJS or Java to hide the button if a mandatory field is cleared.

That’s because if you use SSJS or Java in an onblur or onchange event, it will only run if validation is successful. If a mandatory field is cleared, the validation will fail and the business logic will not run. That’s why it is easier to run the code from the rendered or styleClass / style property of the Submit button. The example I’m going to give uses rendered property.

The key step is something I’ve blogged before and Tim Tripcony added an improvement to, using facesContext.getMessages().hasNext(). When the partial refresh occurs and validation runs, this basically returns true if there is at least one error message for the page.

But there will not be an error when the page first loads, so we also need to check that one of the mandatory fields – it doesn’t matter which – has been completed.

If we’re using the rendered property, that code runs multiple times during the XPages lifecycle, which is bad for performance. So we want to prevent that. Fortunately, view.isRenderingPhase() can be used to ensure it only runs during the Render Response phase.

So the whole code is as follows:

<xp:button value="Submit" id="button1">
<xp:this.rendered><![CDATA[#{javascript:if (view.isRenderingPhase()) {
if (document1.getItemValueString("Name")=="") {
return false;
}
if (facesContext.getMessages().hasNext()) {
return false;
}
return true;
}}]]></xp:this.rendered>
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:document1.save()}]]></xp:this.action>
</xp:eventHandler>
</xp:button>

This way the code only runs during the Render Response phase, returns false if my first mandatory field “Name” is empty, returns false if there are error messages, otherwise returns true.

One caveat here is if you have a field or button that has “Process data without validation” (disableValidators=”true”) or “Do not validate or update data” (immediate=”true”). In this case, if the Name field is completed, that will return true; validation will not trigger, so will return true; so the Submit button will show.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top