rg88
rg88

Reputation: 20977

Jquery - Why am I altering elements I do no expect to be altered?

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 -->

Upvotes: 1

Views: 64

Answers (2)

Arnaud F.
Arnaud F.

Reputation: 8452

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');

Upvotes: 0

Philippe Leybaert
Philippe Leybaert

Reputation: 171784

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".

Upvotes: 5

Related Questions