views:

269

answers:

3

I'm unsure of the best practice for modifying the DOM based on an ajax response. I'll try to let the code do the talking because it's hard to explain.

// page has multiple checkboxes
$("input[type='checkbox']").live('click', function {
  var cb = $(this); // for the sake of discussion i need this variable to be in scope
  $("form").ajaxSubmit({ dataType: "script" });
}

The server sends a response back, and the js gets eval'd and that means "cb" is out of scope.

What I've done so far is create a couple of helper functions:

var target = undefined;

function setTarget(val) {
  target = val;
}

function getTarget() {
  return target;
}

And that turns the first snippet of code into this:

// page has multiple checkboxes
$("input[type='checkbox']").live('click', function {
  setTarget($(this));
  $("form").ajaxSubmit({ dataType: "script" });
}

Then on the server's response I call getTarget where I need to. This seems hackish... Any suggestions?

+1  A: 

It's unclear what you're actually trying to do, but I feel like you want to be looking at the success parameter for that AJAX call. The success callback function should execute in parent scope and do what you're looking for.

See 'success' on this page in the jQuery docs.

Gabriel Hurley
If the dataType option is script, then the response gets eval'd globally (globalEval function in jQuery) - there's no need for a success handler.
what does your returned script do? it's always good to avoid sending scripts to be eval'd if it can be avoided... Otherwise, you could possibly give your storage variable a global scope, though then you risk concurrency issues.
Gabriel Hurley
so the server should return an html fragment even if the request is for javascript?
A commons setup would be that you'd send your form data, request either html or json back from the server, and your success handler function would know what to do with that return data. With json, for example, you might get back a few values, and have your success function insert those values in known places.
Gabriel Hurley
A: 

So what you are trying to do is get the form to submit the content via ajax whenever the user checks/unchecks a checkbox? And because there are several checkboxes, you need to find out which one triggered the submit, so you can change its value to whatever is stored on the server?

If you submit the entire form everytime, why don't you reply with all the checkboxes values, and then change each and every one of them? If not, get the server to reply with the id and the value of the checkbox, then use jquery to find the checkbox with that ID and then change it's value.

Marius
A: 

How about:

jQuery(function($) {

    // give it scope here so that the callback can modify it
    var cb,
        cbs = $('input[type="checkbox"]');

    cbs.live('click', function {
        // taking away var uses the most recent scope
        cb = $(this);

        // disable checkboxes until response comes back so other ones can't be made
        cbs.attr('disabled', 'true'); // 'true' (html5) or 'disabled' (xhtml)

        // unless you are using 'script' for something else, it's best to use
        // a callback instead
        $('form').ajaxSubmit({
            success : function(response) {
                // now you can modify cb here
                cb.remove(); // or whatever you want

                // and re-enable the checkboxes
                cbs.removeAttr('disabled');
            }
        });
    }

});
Tres
Might run into concurrency problems if not constructed carefully. Otherwise not a bad thought.
Gabriel Hurley
Yeah, you're right, but using the setTarget and getTarget you would also, so I was assuming he didn't care. I'll see if I can find time to edit it to solve the concurrency issue.
Tres
Very true about the same problem existing with his functions.
Gabriel Hurley
Concurrency can be solved by disabling the checkboxes until the response comes back.
Tres