ToreyHeinz
ToreyHeinz

Reputation: 595

How can I have jquery attach behavior to an element after inserting it

I have a form that I submit through ajax, and returns an updated chunk of html that includes an updated form that I want to submit through jquery.

The problem I am having is that the first time I click submit the event is captured by jquery and works great. When I make another change to the form without refreshing, the event is not captured by jquery, but makes a standard post request.

How can I have jquery attach behavior to an element after inserting it.

Here is my jquery code.

$('.edit_clothing_product').submit(function(){
  var productDiv = $(this).parent();
  var action = $(this).attr('action');
  var formData = $(this).serialize();

  $.post(action, formData, function(data){
  productDiv.replaceWith(data);
  });
  return false;
 });

Here is the (trimmed down) HTML that I return.

<div class="product">
    <form action="..." class="edit_clothing_product">
      <div class="color_combos">
        ...{form fields}
      </div>
      <a href=".../add_color_combo" class="add_color_combo">Add Color Combo</a>
    <input name="commit" type="submit" value="Save" />
  </form>
</div>

Upvotes: 2

Views: 2290

Answers (2)

ToreyHeinz
ToreyHeinz

Reputation: 595

Meder pointed me in the right direction, thanks!

One thing I forgot to mention was that I had multiple product divs on a page, which meant I had to invoke the function for each.

Also, I was not able to re-attach the submit event directly to the form I just inserted, but I was able to re-attach to all the product forms. It works, but seems a little clumsy, let me know if I should not do it this way.

Here's the final jquery

function handleForm( el ) {
$(el).submit(function(){
  var productDiv = $(el).parent();
  var action = $(el).attr('action');
  var formData = $(el).serialize();

  $.post(action, formData, function(data){
      productDiv.replaceWith(data)
      $('.edit_clothing_product').each(function(){
        handleForm(this);
    });
  });
  return false;
 });
}

$('.edit_clothing_product').each(function(){
    handleForm(this);
});

Upvotes: 0

meder omuraliev
meder omuraliev

Reputation: 186552

You'll need to re-attach the submit event handler you defined because you are replacing the form. You can make this entire thing a callable function so you can invoke it multiple times.

As far as I know, live doesn't work for submit - you might be able to attach a click event handler with live but it's not the exact same thing as .submit. I would just define a function like so:

function handleForm( el ) {
$(el).submit(function(){
  var productDiv = $(el).parent();
  var action = $(el).attr('action');
  var formData = $(el).serialize();

  $.post(action, formData, function(data){
      productDiv.replaceWith(data);
      var form = data.find('form');
      handleForm( form );
  });
  return false;
 });
}

handleForm('.edit_clothing_product')

If you feel lazy, attach .live('click', function() {} ); to your submit button but if it gets submitted without a click it wont work so it has its drawbacks.

$('.edit_clothing_product #submitButton').live('click', function(){
  var form = $(this).closest('form');
  var productDiv = form.parent();
  var action = $(form).attr('action');
  var formData = $(form).serialize();

  $.post(action, formData, function(data){
      productDiv.replaceWith(data);
  });
  return false;
 });

You might also be able to use liveQuery but I never really used that.

Upvotes: 3

Related Questions