Link to home
Start Free TrialLog in
Avatar of Mark
Mark

asked on

how to prevent accidental double clicking when submitting forms

I'm having a big problem preventing double submission of an html form when either the user accidentally double clicks the submit button, or if an extra touchy mouse accidentally causes this. I've tried 2 things:

thing 1: the submit button runs a javascript function that disables the button. The button does disable, but not fast enough to prevent the 2nd click.

thing 2: in my jsp program I created a session variable to hold the time of the last update. I check this time on each update. If it has been less than 5 seconds since the previous update, I abort the update. However, same problem here. The 2nd click submits the form before the 1st submission has time to update the session variable. So, it doesn't see the timestamp of the 1st update.

This is a serious problem because I am inserting duplicate records into my database all the time.
ASKER CERTIFIED SOLUTION
Avatar of evedder
evedder
Flag of Mexico image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ioanton
ioanton

basic option is by restricting using javascript only.

<input type='button' value='submit' onclick='submit(this)'>

function submit(obj)
{
obj.disabled=true;
document.forms[0].action="../actionservlet";
document.forms[0].submit();

}




Avatar of Mark

ASKER

ioanton: That's basically what I tried with setting the session variable.
evedder's (and chaituu's) solution did the trick. My button was:

<button name=updateBtn type=submit onclick="doSubmit()">Update</button>

function doSubmit() { document.myForm.updateBtn.disabled = true; ...

Of course, type=submit appears to submits the form anyway, regardless of the whether the function executes. I knew that before from related issues, but I forgot. Changing this to type=button makes it NOT submit the form and leaves that up the the doSubmit() javascript function.

It appears that evedder beat chaituu to the punch on this one so, unless I'm missing something in cahituu's solution, evedder gets the points. I'll leave this open today in case there are more comments.
Avatar of rrz
> The button does disable, but not fast enough to prevent the 2nd click.  
If that it the case, then maybe add a flag to chaituu's solution.
<script language="JavaScript">
                         var sent = false;
                         function submit(obj){
                              if(!sent){
                                        sent = true;
                                        obj.disabled=true;
                                        document.forms[0].action="../actionservlet";
                                        document.forms[0].submit();
                                       }
                                 
                         }    
</script>

Open in new window

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Mark

ASKER

rrz@871311, yes you are right in 36938806. If I have a type=submit, then the correct place for running the edit function is from the onsubmit property of the form. If I had done that, I'm sure it would have worked too. The main functional difference is that a type=submit button will trigger if the user hits the enter key whereas the type=button will not. In this particular case, I want the user to click the button, not hit enter (which they might mindlessly do attempting to go to the next field). So, using a type=button versus form onsubmit gives me more of what I want in this case.

my onSubmit() function does return true/false ... and re-enables the button before returning false. Otherwise, we're back on the form, but with a disabled submit button!
I think you'd be better off recognizing the second submit on the server side and either ignoring it or acting appropriately in some other way.

You can recognize a submit in the server jsp (or servlet) page, and set a session variable.  If that variable is set, then this is the second submit and should be ignored.

Javascript disable functions are good, too, so that most of the time your server  code doesn't have to kick in.
Avatar of Mark

ASKER

mrcoffee365: I did do exactly that as my "thing 2" attempted solution in my initial post. It still didn't catch it in time. I think the 2nd click already launced a 2nd server app before the session variable got set. Or, perhaps my code is bad. I've put the session variable setting in the code snippet below.

Properly disabling the button, either in the javascript for type=button, or in the form/onsubmit for type=submit, seems to be working just fine.
'update' is a form parameter indicating a database update request.

if (programStep.equals("update"))   // user clicked "UPDATE" button
{
    if (((String) session.getAttribute("prevUpdate")) != null)
    {
        int prevUpdate = Integer.parseInt((String) session.getAttribute("prevUpdate"));  // get previous session variable
        SimpleDateFormat debounce = new SimpleDateFormat("s");
        int thisUpdate = Integer.parseInt(debounce.format((new Date()),new StringBuffer(),new FieldPosition(0)).toString());  // get current seconds

        // If less than 5 seconds, clear "update" indicator

        if (Math.abs(thisUpdate - prevUpdate) < 5)
            programStep = "";
        else
            session.setAttribute("prevUpdate","" + thisUpdate);
    }
}

if (programStep.equals("update"))
{
// update database
:
:

Open in new window

It's not possible for the second submit to be processed after you set a session attribute from the first submit.  Unless you have odd programs which execute outside the normal servlet engine.

Your code above does not set a session attribute except in specific cases.  It's not the way to do it.  You have to set a session attribute as soon as you get the submit, so that all your subsequent processing will change depending on whether or not this is the first submit.

If disabling the button with Javascript works for you, then great.  With luck, all of your users have Javascript enabled, so you won't hit the alternative case.
Avatar of Mark

ASKER

mrcoffee365: at this point, it's probably not worth going through that code to see why it's not doing what I want, but yes, It does set the session variable in certain circumstances: only if it has been more than 5 seconds do I want to set a new "time" value, otherwise, I want to keep the existing value. However, with a cursory look at the code just now, perhaps the problem is that the initial session variable is never getting set. I think I probably need: session.setAttribute("prevUpdate","" + thisUpdate); as an else to the original 'if'.

Anyway, I think I've solved it via html which is simpler than having to set session variables in my program all the time.
Avatar of Mark

ASKER

evedder's solution is best when you want the button to act as a button (i.e. not submit the form on <enter>), but rrz@871311's solution is best if you want the button to act as a submit (submit the form on <enter>)

Thanks all for help and insight.