views:

28

answers:

2

I am dynamically appending form elements. The newly appended elements need to have distinct name attributes. I am doing this by starting with a base form, grabbing a hidden set of form elements, cloning them and appending them. My problem is that when I go to set the name attribute of the new elements all of the form elements get changed to the new name attribute.

So in the below example the freshly appended cloned bit has the correct name attribute but not the existing elements, in this example they are like name="notabletitle1" but after the cloning they all have the same name attribute (name="notabletitle2"). Why? I thought this would only change the elements I am adding, not the existing ones.

My form is like:

<form>
<fieldset id="meh">
          <legend>Notable</legend>
          <p class="title">
              <input  name="notabletitle1" type="text" />
              <label for="notabletitle1">Title</label>
          </p>
          <p class="text">
              <textarea class="thin markItUp" name="notabletext1"></textarea>
          </p>
          <p class="link">
              <input  name="notablelink1" type="text" />
              <label for="notablelink1">Link</label>
          </p>
          <a class="new" href="#">[ + ]</a>
</fieldset>
</form>

and my js is like:

  $(".new").click(function() {
    c = ($(this).parent().children("p").length)/3+1;
      nam = $(this).parent().children("legend").text().toLowerCase();
      n = $("#cloneset1").children();
      n.each(function(){
            $('input').attr("name", nam+"title"+c);
            $('textarea').attr("name", nam+"text"+c);
            $('label').attr("for", nam+"link"+c);
      })
      n.clone().appendTo('#meh');

      return false;
    });

the area being used for cloning is like:

  <!-- Title, Text, Link set for cloning -->
  <div style="display:none" id="cloneset1">
      <p class="title">
            <input  name="" type="text" />
            <label for="">Title</label>
        </p>
        <p class="text">
            <textarea class="thin markItUp" name=""></textarea>
        </p>
        <p class="link">
            <input  name="" type="text" />
            <label for="">Link</label>
        </p>
  </div>
  <!-- end clone set -->
+5  A: 

This piece of code will change all input,textarea and label elements, not just the ones you want:

n.each(function(){
        $('input').attr("name", nam+"title"+c);
        $('textarea').attr("name", nam+"text"+c);
        $('label').attr("for", nam+"link"+c);
  })

I haven't analyzed your code thoroughly, but I think you want something like this:

n.each(function(){
        $('input',this).attr("name", nam+"title"+c);
        $('textarea',this).attr("name", nam+"text"+c);
        $('label',this).attr("for", nam+"link"+c);
  })

This will change only the elements which are children of the collection "n".

Philippe Leybaert
Aha! That does it. I actually tried $(this,'input') and it failed... I had it backwards! Thanks so much.
gaoshan88
A: 

You should clone your cloneset before doing modifications on it :

n = $("#cloneset1").clone().children();
      n.each(function(){
            $('input').attr("name", nam+"title"+c);
            $('textarea').attr("name", nam+"text"+c);
            $('label').attr("for", nam+"link"+c);
      })
      n.appendTo('#meh');
Arnaud F.
This actually doesn't work, Arnaud. It will affect each input/textarea/label in the whole form, not just the children. It also gets the numbering wrong with the cloned area getting number 1 regardless of how many elements there are.
gaoshan88
Caution, when cloning elements you must keep in mind that the ID attribute will be cloned too, so if you have ID to clone, change it later. Vote up for Philippe's solution else :)
Arnaud F.