1

I have a Primefaces dialog with a form where a user enters some data. After hitting Save, I need the data validated (in the standard JSF way) and if it passes, then some Javascript needs to be called to be able to show an indeterminate progress bar and to hide the form buttons - this is because the action method can take several seconds to complete due to some heavy backend processing.

I know there is args.validationFailed which can be used in an oncomplete but this would only work once the action method has finished which is too late.

At the moment the javascript obviously gets executed when the button is clicked, but i'm unsure how to proceed. Is there any way of kicking off the referPressed function only once validation is passed but before the action method is called?

JSF snippet

<p:commandButton value="Refer" actionListener="#{manageTrickleData.setLogToReferred}" 
onclick="referPressed();" update="subview1:mainForm:tabs:tablePanel2 
subview1:mainForm:tabs:tablePanel commentMessage" styleClass="dialogButtons">
</p:commandButton>

Javascript

function referPressed() {
    $('.dialogButtons').hide(); 
    $('.ui-progressbar-indeterminate').show();  
}
Selaron
  • 5,617
  • 4
  • 26
  • 38
Steve W
  • 87
  • 6
  • Does this answer your question? [Real time updates from database using JSF/Java EE](https://stackoverflow.com/questions/25947790/real-time-updates-from-database-using-jsf-java-ee) – Jasper de Vries Jan 30 '20 at 12:56
  • 1
    Also possilby relevant: https://stackoverflow.com/questions/4691132/how-to-run-a-background-task-in-a-servlet-based-web-application – Selaron Jan 30 '20 at 13:12
  • I think the answer is no. Validation happens on the server side of JSF. So once the action is called its off to your server unless you decide to validate using JavaScript on the client side using your referPressed() method. So all you can do is "onclick" to open the progressBar like you have an use "oncomplete" which is when the server returns with an answer to stop showing the progress bar and display your validation results. – Melloware Jan 30 '20 at 13:32

2 Answers2

2

You can use <p:remoteCommand> for that. Just let the <p:commandButton> invoke it on complete without validation errors and then let the <p:remoteCommand> invoke the desired action.

<p:commandButton value="Refer" styleClass="dialogButtons"
    update="commentMessage"
    oncomplete="if (!args.validationFailed) { referPressed(); setLogToReferred(); }">
</p:commandButton>
<p:remoteCommand name="setLogToReferred"
    action="#{manageTrickleData.setLogToReferred}"
    update="subview1:mainForm:tabs:tablePanel2 subview1:mainForm:tabs:tablePanel">
</p:remoteCommand>
BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • 1
    This worked great thank you very much! Just had to add update="commentMessage" to the commandButton to display the validation message. Cheers :) – Steve W Jan 30 '20 at 14:40
0

As stated in the comments this is not possible since validation happens server side.

You could also use ajax to enforce validation on change and disable the submit button if not valid.

<p:inputText value="#{bean.entity.comment}">
    <p:ajax event="change" update="btnSave"/>
</p:inputText>

<p:commandButton id="btnSave" disabled="#{bean.entity.comment ne null}" onStart="referPressed();" onComplete="hideProgressBar();"/>

To make this more flexible you can invoke bean validation programmatically or do custom validations like:

<p:commandButton id="btnSave" disabled="#{not bean.isValid(bean.entity)}" />

Those solutions show the problems of JSF validating server side. We programmers would need JSF to do two requests to the server and let us hook in after the validation phase adding a new ajax callback state like onEvent="if (data.status == 'validate') { }; or for primefaces onValidate to solve this.

djmj
  • 5,266
  • 4
  • 47
  • 89