开发者

How to (re)bind to submit button/form on .load(ed) form

During early in learning how to implement unobtrusive js (using Rails & jQuery) I've run into an issue of how to (re)bind a submit button/form after .load(ing) new content that includes a form.

I've set up a 'create new item' form to show at the top of a lising of items (when the user clicks on a create button)

sale_case/show/开发者_Python百科_requirments_new.html.haml:

- form_for ([@sale_case, @sale_case_requirement]), :html => { :id => 'requirement_form', :class => "submit-with-ajax"} do |f|
...
%button{ :type => "submit" } Save Requirement

application.js:

jQuery(document).ready(function() {
  jQuery(".submit-with-ajax").submitWithAjax();
}
...
jQuery.ajaxSetup({
  'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
})

jQuery.fn.submitWithAjax = function() {
  this.submit(function() {
    jQuery.post(this.action, jQuery(this).serialize(), null, "script");
    return false;
  })
  return this;
};

requirements_controller.rb:

def create
  @sale_case_requirement = @sale_case.requirements.new(params[:requirement])
      if @sale_case_requirement.save
      @message = "Success..."
      @success = true
  #...
  respond_to do |format|
    format.js
  end
end

requirements/create.js.erb:

mesg("<%= @message %>");
<%- if @success %>
  jQuery("#requirement_form")[0].reset();
  jQuery('#requirements').load('<%= requirements_view_sale_case_requirements_path(@sale_case.id) %>' );
<% end %>

It's all working well the first time around unobtrusively. The problem comes when the user creates the second item (on the form loaded via ajax). The button is not getting bound to the submitWithAjax function. How do you do that when .load(ing) content?

I ended up having to do this in the partial (obtrusive) in order to get it to work, but it bugs me not to be able to figure this out. :

%button{ :type => "submit", :onclick => "jQuery.post('#{sale_case_requirements_path(@sale_case.id, @sale_case_requirement.id)}', jQuery('#requirement_form').serialize(), null, 'script'); return false;"} Save Requirement


Here's what I ended up changing in the code based on Ender's input. I got an error with finding 'submitWithAjax' with his version of the code, but he pointed me in the right direction and after reading the .live documentation I came up with this which works:

application.js

jQuery(document).ready(function() {

  # Just put it all in one place
  jQuery(".submit-with-ajax").live('submit', function() {
        jQuery.post(this.action, jQuery(this).serialize(), null, "script");
        return false;
      });
...
}

sale_case/show/_requirments_new.html.haml:

# Change the button back to unobtrusive
%button{ :type => "submit"} Save Requirement    

Thanks!


Change this original code:

jQuery(document).ready(function() {
  jQuery(".submit-with-ajax").submitWithAjax();
}

to this:

jQuery(document).ready(function() {
  jQuery(".submit-with-ajax").live('submit', submitWithAjax);
}

and this original code:

jQuery.fn.submitWithAjax = function() {
  this.submit(function() {
    jQuery.post(this.action, jQuery(this).serialize(), null, "script");
    return false;
  })
  return this;
};

to this:

jQuery.fn.submitWithAjax = function() {
    jQuery.post(this.action, jQuery(this).serialize(), null, "script");
    return false;
};

The jQuery .live() call binds the named handler to the named event on all current and future elements that match the given selector, including elements that are loaded in via ajax. Hopefully that does what you're looking for.

See the following for documentation on the .live() function: http://api.jquery.com/live/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜