trentrichardson / jQuery-Impromptu

An extention to help provide a more pleasant way to spontaneously prompt a user for input.
http://trentrichardson.com/Impromptu/
MIT License
327 stars 144 forks source link

Valid form by Enter key with ajax call inside, call 2 times the submit callback ! #55

Open deguich opened 9 years ago

deguich commented 9 years ago

When I use the enter key to valid a form and doing an ajax call in the submit callback. It call a second time the submit callback.

I build this small test with these files : https://filesender.renater.fr/?vid=61d10bb3-1df0-37c9-2bef-000036df7ed9 I put the ajax async = false properties to reproduce easily this strange behaviour. When I click directly on "Work" button, it works fine. I used console.log function to trace calls.

trentrichardson commented 9 years ago

Be sure when you use the enter key to validate you stop the even from bubbling up the dom. Then when it is valid send it. Impromptu uses a standard form, but includes some of its own events to process the form.

deguich commented 9 years ago

Hi, sorry, I don't understand, do you propose I stop the propagation of enter key event on my input textField ? As you can see on my test, I call the same submit function with the event.preventDefault(). But If enter key pressed and withAjaxCall is true, submit callback is called a second time with a false v parameter. The prompt close but it would not.

html: '<label>Acronyme <input type="text" name="acro"></label>',
buttons: { Close: false, Work: true },
focus: 1,
submit:function(event,v,m,f){
    console.log("=> Submit callback start");
    if(v){
        event.preventDefault();
        if (withAjaxCall)
            ajax();
        console.log("End of Work bloc (don't close the prompt)");
        return false;
    }
    else
    {
        console.log("Ask for a prompt close");
        $.prompt.close();
    }
}

Is it a bug or just a coding error ...

trentrichardson commented 9 years ago

Typically when I do asyncronous work, such as ajax I will create another state that may have a spinner gif for "Waiting". I will also include one called errors sometimes where I inject any custom errors. Of course you can always update the main state and go back to it.

var states = [
        {
            name: 'state0',
            title: 'Create Project',
            html: '... html string ...',
            buttons: { Create: true, Cancel: false },
            submit: function(e,v,m,f){
                if(v){
                    e.preventDefault();
                    var err = [];

                    // do validation
                    if(f.name === ''){
                        err.push('Please enter a name');
                    }

                    if(err.length > 0){
                        $.prompt.getState('error').find('.errors').html(err.join('<br />')));
                        $.prompt.goToState('error');
                    }
                    else{

                        $.prompt.goToState('wait');

                        // do ajax save
                        $.post('file.html', f, function(res){
                            if(res && res.errors && res.errors.length > 0){ // error was returned
                                $.prompt.getState('error').find('.errors').html(res.errors.join('<br />')));
                                $.prompt.goToState('error');
                            }
                            else{ // ajax was successful
                                $.prompt.close();
                            }
                        },'json');
                    }// end err.length
                }// end if(v)
            }
        },
        {
            name: 'wait',
            title: 'Saving Project',
            html: 'Please wait as the project is saved&hellip;',
            buttons: {}
        },
        {
            name: 'error',
            title: 'An Error Occured',
            html: '<p class="errors">A error may have prevented this from being saved.</p>',
            buttons: { Close: true }
        }
    ];
$.prompt(states);

I have no clue if that works, I just whipped it up to demonstrate. This way you don't try to conditionally allow the form to submit, you will always go to another state or close. Ajax validation and saving would work the same way. I hope that makes sense, sorry if not...