April 26, 2012

Can not prevent form submit when I add one line

Question by tosin

I am stacked. My code can not prevent defaut action of submit. This was working fine until I add this.doSomething();.

Why this happens? Do I have to use preventDefault?

working code: http://jsfiddle.net/WwW5R/

HTML:

<div id="container">
    <form action="" method="post" id="input">
            <input type="submit">
    </form>
</div>

JavaScript:

$(function() {
    var ReserveUI = function($el) {
        this.$form = {
            input: $el.find('#input')
        };
        this._eventify();
    };

    ReserveUI.prototype.doSomething = function() {
        return false;
    }

    ReserveUI.prototype._eventify = function() {
        this.$form.input.submit(function() {
            this.doSomething(); //if comment out this line, it works
            return false;
        });
    };
    var UI = new ReserveUI($("#container"));
});

thanks for reading:)

Answer by Alnitak

In your submit callback function, this no longer refers to your object, but to the element itself.

It’s therefore causing an exception because the element has no doSomething property, and your return false is skipped.

Instead, write this:

ReserveUI.prototype._eventify = function() {
    var self = this;
    this.$form.input.submit(function(e) {
        e.preventDefault(); // cancels event even if subsequent lines fail
        self.doSomething();
    });
};

See http://jsfiddle.net/xgGGx/1/ for a working example showing that it’s just the scope issue causing the bug.

This is what script debugging tools are for – the reported error should have made the fault reasonably obvious…

Answer by Starx

This is a scope mismatch.

this.$form.input.submit(function() { //here "this" is ReserveUI
    this.doSomething(); //here "this" is input button
    return false;
});

And since there is no doSomething() on input button, the script breaks thus no longer executing the portion to return false.

Here is a way you can get around this

ReserveUI.prototype._eventify = function() {
    var $this = this; //create a reference to the object
    this.$form.input.submit(function() {
        $this.doSomething(); //Now call the object method
        return false;
    });
};

Demo

Author: Nabin Nepal (Starx)

Hello, I am Nabin Nepal and you can call me Starx. This is my blog where write about my life and my involvements. I am a Software Developer, A Cyclist and a Realist. I hope you will find my blog interesting. Follow me on Google+

...

Please fill the form - I will response as fast as I can!