views:

68

answers:

4

I currently have code similar to this for a form:

$('#some-form')
    .submit(function()
    {
        // Make sure we are not already busy
        if($(this).data('busy'))
            return false;
        $(this).data('busy', true);

        // Do post
        $.post("some/url", $(this).serialize(), function(data)
        {
            if(data.success) // Success is a boolean I set in the result on the server
            {
                // Deal with data
            }
            else
            {
                // Display error
            }

            $('#some-form')
                .removeData('busy');
        });
        return false;
    });

My issue is that I would like to somehow remove the need for knowing the form id in the post callback. In the end where I remove the busy data from the form, I'd like to somehow not have that hard coded. Is there any way I can do this? Is there a way I can hand whatever is in this to the post callback function? Since I know the id right now, I can get around it by doing what I have done, but I'd like to know how to not be dependent on knowing the id, since often I don't have an id. (For example if I have a link in each row in a table and all the rows have the same click handler.

+2  A: 

Set a variable with the value "this" before creating the callback. Then use that variable name in the callback function.

var form = this;
$.post("some/url", $(this).serialize(), function(data) {
      $(form).removeData('busy');
}

That way, the variable with the form will be available inside the callback. When you declare a function, that function will have access to all the variables in that same scope, even if it's called after the function it was declared in has returned.

You can read about closures in detail at: http://www.jibbering.com/faq/notes/closures/

baloo
Seems to work nicely!
Svish
Glad to hear! :)
baloo
A: 

Keep a reference to the form.

var form = $("form").submit(function ()
{
    // do ajax call here, referencencing the "form" variable

    return false; // return false to prevent default behavior
});

In general you will only have one form element to deal with. So there's no need to create the reference inside the submit function, wrapping this in the jQuery object.

Here's your modified code:

var form = $("#some-form").submit(function ()
{
    if(form.data("busy")) return false;

    form.data("busy", true);

    $.post("some/url", form.serialize(), function (data)
    {
        if (data.success)
        {
        }
        else
        {
        }

        form.removeData("busy");
    });

    return false;
});
roosteronacid
In genereal I need this for other things than forms though. So I don't want to keep references to whatever it is since it will be quite many and they will be deleted and added and such.
Svish
A: 

I guess you want to prevent an user to double post data by exicident?

Is setting attribute

 disabled 

To

disabled 

an option for you?

Like

$("#submitbtn").attr("disabled", "disabled");
jAndy
This is just a different way of disabling the form. The issue with re-enabling it in the callback remains the same :)
Svish
not exactly, when disabling a submit button for instance, you can just requery that button within the callback and remove the disabled attribute
jAndy
A: 

Use the bind

$('#some-form')
.submit(function()
{
    // Make sure we are not already busy
    if($(this).data('busy'))
        return false;
    $(this).data('busy', true);

    // Do post
    $.post("some/url", $(this).serialize(), function(data)
    {
        if(data.success) // Success is a boolean I set in the result on the server
        {
            // Deal with data
        }
        else
        {
            // Display error
        }


        $(this).removeData('busy');

    }.bind(this)); //Here
    return false;
});

You can find intresting article about javascript scope: http://www.digital-web.com/articles/scope_in_javascript/ Just google it

mathk
Interesting. When I try this I get an error saying that bind is not a function though...
Svish
@mathk : I think you are confusing with MooTools' bind() function. The bind() function exists in jQuery, but it does not have the same meaning : it is used to attach events.
mexique1
actually I am confusing with the bind() in Prototype library. Sorry
mathk