Skip to content
This repository

Cannot override data in ajax:beforeSend Event #168

Closed
regis-leray opened this Issue May 27, 2011 · 10 comments

3 participants

Regis leray Steve Schwartz Ramon Tayag
Regis leray

I try to send some data with a post ajax request like this and in the server side i dont receive the data (but i do see the value in firebug)

$('a[data-with], a[data-submit]').live('ajax:beforeSend', function(event, xhr, settings) {
      settings.data = "name=John&time=2pm";
});

but if im doing like this it s working

$('a[data-with], a[data-submit]').live('ajax:beforeSend', function(event, xhr, settings) {
      settings.url += "?name=John&time=2pm";
});

My route is configured as a POST method

resources :categories do
      collection do 
        post :addcategory
      end
    end

What im doing wrong ?

Steve Schwartz
Collaborator

Try binding to ajax:before event hook instead of the ajax:beforeSend. From the wiki, "The ajax:beforeSend event is also useful for adding custom request headers."

Alternatively (and probably preferably), as of this commit, you can now add a data-params attribute to your remote links which will be appended to the POST parameters for data-method => :post links, and appended to the URL for GET remote links.

Regis leray

Thanks.

So i try with the ajax:before, "event.data" but it doesnt seem to work (the ajax request is not send anymore).

Obviously, i try the other solution with the "data-params", but i seems to have an issue with the cleaning of the variable in the ajax request. When i try to submit many times, the values of the request parameters are not changing (these values values come from input text)

here my code

 function hasAttr (element, name) {
            return element.attr(name) !== undefined;
    }

  function retreiveData (element) {
        var data = '';

        if(element.attr('data-with')){
            data = eval(element.attr('data-with'));
        }
        else if(element.attr('data-submit')){
            data = $('#'+element.attr('data-submit')+' :input').serialize();
        }

        return data;
 }

  //add the dynamic parameters in the form
   $('a[data-with], a[data-submit]').live('ajax:before', function(event) {
      var el = $(this);
      el.attr('data-params', retreiveData(el));
    });

    //clean the attribute, dont need anymore
    $('a[data-with], a[data-submit]').live('ajax:complete', function(event, xhr, status) {
      var el = $(this);
      el.removeAttr('data-params');
    });

The value serialize come from a input text and when i debug with a breakpoint in the ajax:before the values are changing, but in the ajax request, the parameters dont change.

thanks

Regis leray

Oki i get it, there is an issue with this line in jquery-ujs.js(line 115)

data = element.data('params') || null; data

after the request is send we need to clear the values with "element.removeData('params')" (we dont need to store them, it is dynamic values). I had these function in my code and its working.

Steve Schwartz
Collaborator

Awesome, glad you got it working.

In your previous comment, when you said using the ajax:before hook caused the ajax request to not be made, it sounds like the function you bound to the hook may have been returning false, which will cause the ajax submission to be canceled.

From your code, it looks like your ajax:before handler was returning the result of retrieveData(el), which in turn was returning the evaluated script from the element's data-with attribute. I would make sure that the script in data-with was not returning false at the end.

Concerning removing the data-params attribute after submission, that sounds like it works well for your scenario since you're dynamically creating the value before each submission. Though it probably isn't a good default since I imagine most people will be using this for static params and would probably wonder why their remote links only work once and then break.

Steve Schwartz
Collaborator

Also, in your original post, I think the reason that settings.data = "name=John&time=2pm" wouldn't work is because, by the time beforeSend is fired, the settings have already been used to create the jqXHR object which is used for the body of ajax request. From the jquery docs, the beforeSend callback "can be used to modify the jqXHR (in jQuery 1.4.x, XMLHTTPRequest) object before it is sent."

In other words, the xhr object must be modified directly to alter the request. You can see an example of how we do this to add the default request content-type header. Unless I'm mistaken, the settings object is mainly passed for readonly purposes.

Regis leray

Oki im pretty satisfied with the solution to use the ajax:before like i did.

But i m still convinced there is an issue with this line in jquery-ujs.js(line 115)

data = element.data('params') || null; data

and we need at on point to clean the data store in the current element by doing

element.removeData('params')

if not if you change the data after the first submission, it will continue to send the same value.

to get working this is what i was doing

//clean the attribute, dont need anymore
    $('a[data-with], a[data-submit]').live('ajax:complete', function(event, xhr, status) {
      var el = $(this);
      el.removeData('params');
    });
Steve Schwartz
Collaborator

I'm not sure I understand the problem being described.

if not if you change the data after the first submission, it will continue to send the same value.

Correct. In the normal use-case, this is exactly the expected and desired behavior. If I have:

link_to "Post data", some_path, :remote => true, :method => :post, :'data-params' => 'name=John'

Then :name => 'John' should be posted every time the link is clicked.

Regis leray

oki. I thought the "data-params" where only for dynamic values.
Thanks a lot. It really help me

Regis leray regis-leray closed this May 30, 2011
Steve Schwartz
Collaborator

Hey Regis, no prob. Yeah, it's a really new feature so we haven't had a chance to document it yet or anything.

Ramon Tayag

Hey @JangoSteve, I tried to do this with forms, but after reading the code a little bit more closely, it seems that data-params was only for rails.inputChangeSelector and non-forms. Did I read it right?

How would you go about appending data to a form before sending it out? I have one already in a long serialized string that I get from another plugin, and would simply like to append it to the data of the form.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.