Search code examples
eventsmootools

Javascript Mootools event stop


well,i have this script that i have set up that on submit requests php file that is used to validate my input values...i have set up that when it is not validated the correct way to echo it is not validated,now i want in my request when i get response and it is the error response to stop the submit..here is the script,it does send the request and returns response but it doesnt stop the submit...

i have made it like this but now i need to pop a confirm message when it is all done,i want to stop the form from executing when message pops up and if the user clicks yes to continue with the form...i tried it like this with fireEvent but it wont work...help guys!

window.addEvent('domready', function(){

var form=document.adminForm;
form.addEvent('submit', function(e){
var success = false;    

var dataString="date=" + document.getElementById("date").value + "&start=" + document.getElementById("start").value + "&end=" + document.getElementById("end").value;


var requestData = new Request ({
        url: '/provjera.php',
        method:'POST',
        async:false,

        data:dataString,
        onComplete: function(responseText){
                var requestData2 = new Request({
                    url:'/posalji.php',
                    method:'POST',
                    data:dataString,
                    onComplete:function(responseText){

                    }

                });
                requestData2.send();


            success= responseText == 'NO ERROR';
            if(responseText == 'NO ERROR'){


            }else{
                alert("FAIL");
            }

        }
    });

    requestData.send();
    if(success){
        var result=confirm("Are you sure!?");
    e.stop();
    if(result){
    form.fireEvent("submit");  
    }

    }else{
            e.stop();
    }


});


});

Solution

  • This won't work, it breaks the asynchronous nature of XHR (it's *A*JAX, heh).

    The way it works is this:

    [form]
    [submit event]
    \->[function]->[xhr]->[onComplete function much later]->[e.stop() not applicable]
                \->[function continues and terminates]
    

    By the time the onComplete arrives and calls .stop(), the parent function execution has exited and failed to stop the event, it has already bubbled... XHR is non-blocking!

    you have 2 patterns you can do to work around that:

    1. always stop event, do something extra in onComplete

    essentially, whatever the XHR passes to your onComplete can let you determine the success/failure of your operation and you can call another function, fire an event or do what you need to do (eg, transition page or display validation errors on screen or whtever).

    2. use sync AJAX (anti-pattern)

    you can actually make your XHR blocking if you wanted to so that in this execution context you can set a variable or stop the event from the onComplete - do so by passing async: false to your Request constructor options.

    I would definitely not recommend 2 unless you are doing something like username availability checker onBlur/onChange that needs to block the thread before they submit. And even then, you can do it gracefully w/o this.

    edit as per request, here is an example: http://jsfiddle.net/dimitar/du5s4/

    var form = document.id('adminForm');
    
    form.addEvent('submit', function (e) {
        var success = false;
    
        // simulate a server response of two types.
        this.getElement('input[name=html]').set('value', ['success','error'].getRandom());
    
        var requestData = new Request({
            url: '/echo/html/',
            method: 'post',
            async: false,
            data: this,
            onComplete: function (responseText) {
                // if server returned success, don't stop the event.                                          
                success = this.response.text == 'success';
                console.log(success);
            }
        }).send();
    
        success || e.stop();
    });
    

    this has been tailored for the jsfiddle api for ajax testing but you get the idea. since you evalResponse, your response can also set variables - though I don't remember what the scope of evluation will be - it may be the global object and not the inner scope of the submit function.

    once again, this is totally wrong, use sparringly. you need to change over to a proper event based setup.

    http://jsfiddle.net/dimitar/du5s4/2/ - same thing but w/o the async hack.

    var form = document.id('adminForm');
    
    form.addEvent('submit', function (e) {
        e && e.stop && e.stop();
    
        var self = this;
    
        // simulate a server response of two types.
        this.getElement('input[name=html]').set('value', ['success','error'].getRandom());
    
        var requestData = new Request({
            url: '/echo/html/',
            method: 'post',
            data: this,
            onComplete: function (responseText) {
                // if server returned success, 
                // call something like form.submit();                                          
                this.response.text == 'success' && self.submit();
                console.log(this.response.text);
            }
        }).send();
    });