Mark
Mark

Reputation: 367

JSF form does not get submitted when form is disabled by JavaScript

This is the submit button:

<h:commandButton 
    actionListener="#{regBean.findReg}" 
    action="#{regBean.navigate}" value="Search" />

This is the form:

<h:form onsubmit="this.disabled=true;busyProcess();return true;">

If the submit button is pressed, the page shows a "busy" icon until request is processed. The problem is, the form is never submitted and the request never reaches the backend. However, if I instead take out the "disabled" call like so:

<h:form onsubmit="busyProcess();return true;">

Then everything works. Any ideas?

Upvotes: 3

Views: 5035

Answers (6)

Mark
Mark

Reputation: 367

BalusC, your very creative timeout option works well. I actually came to the same conclusion when I tried the "disabled" attribute in other browsers. It didn't disable the form at all in Opera and Firefox. I just chalk it up to those browsers being more versatile than IE.

Sean K, disabling the button only without setting a timeout produces the same issue as the form disable, as info is passed to the server.

Thanks for all your help guys!

Upvotes: 0

BalusC
BalusC

Reputation: 1109715

JSF relies on the presence of the name-value pair of the submit button to invoke a specific action in the server side. If you disable the form (at least, the button) before submitting the form, then no information will be available in the request parameter map and JSF will not invoke any action.

Your best bet is to introduce a timeout wherein you disable the button about 50ms after submitting. E.g.

onsubmit="setTimeout(function(){document.getElementById('formId:buttonId').disabled=true;},50);busyProcess();"

The explicit return true; at end is by the way superflous. Also, disabling the the HTML form element directly ain't going to work since it doesn't have a disabled attribute, you want to disable the button (and if necessary the other input elements as well).

Here's some improvement:

<h:form onsubmit="busyProcess(this);">

with

function busyProcess(form) {
    setTimeout(function() {
        for (var i = 0; i < form.elements.length; i++) {
            form.elements[i].disabled = true;
        }
    }, 50);

    // Remnant of your code here.
}

Update: since I wondered that you told that it "works", I tested the form's disabled attribute in various browsers, it only works in MSIE (surprising..), but not in the other (real) browsers. You don't want to be browserdependent, so forget it and go ahead with disabling the form's individual elements.

Upvotes: 6

Sean Patrick Floyd
Sean Patrick Floyd

Reputation: 299218

if you want the user not to submit anything, let a layer appear above the form and remove the focus from the active component.

Another way would be to make sure the AJAX requests use a common channel that has a queue in which only one request is processed at a time (easy using frameworks like prototype etc)

Upvotes: 0

Scott
Scott

Reputation: 9488

You've disabled the entire form, you need to disable just the button instead.

Also you will want to ensure that your busyProcess() returns a truthy value or the submission could be disabled as well.

Upvotes: 0

Pointy
Pointy

Reputation: 414016

I'm pretty sure that disabling the whole form will mean to the browser that you don't want it to be submittable. When you disable individual input elements, those aren't included in the parameters sent to the server when the form is posted.

Upvotes: 0

Sean Kinsey
Sean Kinsey

Reputation: 38046

Change this.disabled = true into [buttonref].disabled = true

Upvotes: 1

Related Questions