JSF life cycle gets interrupted when disabling a button after a submit call.

J

jeffotn

I have a form that the users continue to click the save button
multiple times. I can sovled this simply by saying the following:

onclick="this.disabled=true"

However the button does not peform a submit.

My jsf button def

<x:panelGroup style="margin-right: 5px;">
<h:commandButton action="#{activeForm.save}" id="save"
value="#{messages['detail_button_save']}" immediate="false"
styleClass="defaultButton" disabled="#{activeForm.noAppliedAmount}"
onclick="return submitDisable();" />
</x:panelGroup>

I can do something like this

var submitted = false;

function submitDisable() {

if(submitted == true) { return; }

document.forms["summary"].elements["summary__save"].click();
submitted = true;
return true;
}

and this works, the form doesnt get resubmit and the jsf action for
that button occurs onces, however I want to really gray out that
button. This seems simple, am i missing something?
 
L

Lew

I have a form that the users continue to click the save button
multiple times. I can sovled this simply by saying the following:

onclick="this.disabled=true"

You don;t need Javascript to solve this, and disabling the submit is not the
best way.

Make the transaction idempotent - it only affects the result the first time
it's applied. (Think of multiplying by zero - repeating the action doesn't
change the outcome.)

One way to do that is to place a token in the session when the page is first
generated. On submit, on the server side, remove the token from the session.
If the token is already absent, ignore the submit and redisplay the page.

This is called the token pattern.
 
R

Real Gagnon

var submitted = false;
function submitDisable() {

if(submitted == true) { return; }

document.forms["summary"].elements["summary__save"].click();
submitted = true;
return true;
}

Pass the button to the JS function to be able to disable it.

Something like :

<x:panelGroup style="margin-right: 5px;">
<h:commandButton action="#{activeForm.save}" id="save"
value="#{messages['detail_button_save']}" immediate="false"
styleClass="defaultButton" disabled="#{activeForm.noAppliedAmount}"
onclick="return submitDisable(this);" />
</x:panelGroup>

and then from Javascript :

var submitted = false

function submitDisable(button) {
if (!submitted ) {
submitted = true;
button.value = 'Please Wait';
button.disabled = true;
document.forms["summary"].submit();
}
else {
alert ("Already submitted, please wait!");
}
return true;
}

Bye.
 
J

jeffotn

I have already tried both these suggestions. The first one causes the
page to be reposted and the request response to be disconnected from
the original save action. After the save is clicked the system will
dynamically forward to any number of pages based on the disposition
return from the request. I understand that this can be taken care of
if I was using Struts, i have seen this article before
http://www.javaworld.com/javaworld/javatips/jw-javatip136.html?page=2
and I am sure that there is a way to accomplish this with JSF. I
really do not like the idea of having a middle page as part of the
solution.

The second approach of disabling the button will not work because the
jsf binded action (action="#{activeForm.save}") will not get called
after I submit the application. The screen simply refreshes after the
call to submit because it doesnt know what to do on submit. There are
numerouse buttons on the page binding to several backen bean methods;
i.e. save, delete, copy, etc.

I want to have both a client solution and a backend solution so the
token pattern works, I may just result in submiting a form calling a
method and the javascript setting a hidden form element that
represents the method call of the button. This is outside the jsf
life cycle and seems wrong, but the customer doesnt want a screen in
the middle and I cant control the speed of the external calls I make
from this page.

If anyone has a more robust solution please let me know and as an FYI
there is no AJAX involved just the simple JSF with POJOs and
Hibernate.

Thanks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top