HPWD
HPWD

Reputation: 2240

name attribute missing when adding new element to dom (dynamically) using jQuery

I have this JavaScript function (below) that will dynamically add a new element to the DOM (no problem) except there is no name attribute added or ID value.

The ultimate goal I'm looking to achieve is to be able to dynamically add elements to a process and then be able to save it (submit via jQuery serialize) without a page refresh (in simple terms, think of adding/removing tasks to a project). Dynamically "adding" is what I'm struggling with.

Here is the stripped down code I have so far:

<div id="itemList">
    <div><input class="textInput" name="input_1"  id="input_1" type="text" /></div>
    <div><input class="textInput" name="input_2"  id="input_2" type="text" /></div>
    <div><input class="textInput" name="input_3"  id="input_3" type="text" /></div>
</div>
<div><a href="javascript:void('');" id="addNewInputField" onClick="addNewInputField();">Add New Task</a></div>

<script type="text/javascript">
function addNewInputField(){
    elParentContainer = document.getElementById('itemList');
    newElement = document.createElement('div');
    newInput = document.createElement('input');
    newInput.setAttribute('class', 'textInput');
    newInput.setAttribute('type', 'text');      
    newElement.appendChild(newInput);
    elParentContainer.appendChild(newElement);
}
</script>

and here is the outputted source I'm currently getting when clicking the "Add New Task" twice:

Here is the what I'm currently getting when you view source:

<div id="itemList">
    <div><input class="textInput" name="input_1" id="input_1" type="text"></div>
    <div><input class="textInput" name="input_2" id="input_2" type="text"></div>
    <div><input class="textInput" name="input_3" id="input_3" type="text"></div>
    <div><input class="textInput" type="text"></div>
    <div><input class="textInput" type="text"></div>
</div>

Here is the desired output when you view source:

<div id="itemList">
    <div><input class="textInput" name="input_1" id="input_1" type="text"></div>
    <div><input class="textInput" name="input_2" id="input_2" type="text"></div>
    <div><input class="textInput" name="input_3" id="input_3" type="text"></div>
    <div><input class="textInput" name="input_4" id="input_4" type="text"></div>
    <div><input class="textInput" name="input_5" id="input_5" type="text"></div>
</div>

Can someone help me modify my function to increment the newly added DOM elements?

Upvotes: 0

Views: 950

Answers (7)

Th0rndike
Th0rndike

Reputation: 3436

One way to achieve this is to retrieve the last child of the collection, then use one of it's attributes to know the current index. Once this has been retrieved, it's easy to add attributes with the right contents to the newly created element:

function addNewInputField(){
    var elParentContainer = document.getElementById('itemList');

    //Get last child of list
    var inputList = elParentContainer.getElementsByTagName('input');
    var lastChild = inputList[inputList.length-1];

    //Get last index from the name attribute of last child
    var lastIndex = lastChild.getAttribute('name').split('_')[1];

    var newElement = document.createElement('div');
    var newInput = document.createElement('input');
    newInput.setAttribute('class', 'textInput');
    newInput.setAttribute('type', 'text');
    //Add new attributes to the newly created element
    newInput.setAttribute('name', 'input_'+(lastIndex++));
    newInput.setAttribute('id', 'input_'+(lastIndex++));   
    newElement.appendChild(newInput);
    elParentContainer.appendChild(newElement);
}

Upvotes: 0

Delanyo Aborchie
Delanyo Aborchie

Reputation: 309

You could keep track of the current number of inputs you have.That way it becomes easier to set the desired attributes of new inputs as you create them.

     <script type="text/javascript">
        var inputCounter =  3;
     function addNewInputField(){
        var name = "input_";
        inputCounter= inputCounter+1;
        name = name.concat(inputCounter);
        elParentContainer = document.getElementById('itemList');
        newElement = document.createElement('div');
        newInput = document.createElement('input');
        newInput.setAttribute('class', 'textInput');
        newInput.setAttribute('type', 'text');
        newInput.setAttribute('name', name);
        newInput.setAttribute('id', name);      
        newElement.appendChild(newInput);
        elParentContainer.appendChild(newElement);
    }

   </script>

Upvotes: 1

George Pant
George Pant

Reputation: 2117

You can just count how many children your container has and then create dynamically the id and name of the next element.

function addNewInputField(){
elParentContainer = document.getElementById('itemList');
var next_input = elParentContainer.children.length+1
newElement = document.createElement('div');
newInput = document.createElement('input');
newInput.setAttribute('class', 'textInput');
newInput.setAttribute('type', 'text');      
newInput.setAttribute('name', 'input_'+next_input);      
newInput.setAttribute('id', 'input_'+next_input);   
newElement.appendChild(newInput);
elParentContainer.appendChild(newElement);

}

Upvotes: 1

Delanyo Aborchie
Delanyo Aborchie

Reputation: 309

Based on your stripped down version, you could keep track of how many inputs you have and update them with each new addition. Here is a solution based on the code you submitted.

   <div id="itemList">
<div><input class="textInput" name="input_1"  id="input_1" type="text" /></div>
<div><input class="textInput" name="input_2"  id="input_2" type="text" /></div>
<div><input class="textInput" name="input_3"  id="input_3" type="text" /></div>

    <div><a href="javascript:void('');" id="addNewInputField" onClick="addNewInputField();">Add New Task</a></div>

    <script type="text/javascript">
     var inputCounter =  3;
     function addNewInputField(){
        var name = "input_";
        inputCounter= inputCounter+1;
        name = name.concat(inputCounter);
        elParentContainer = document.getElementById('itemList');
        newElement = document.createElement('div');
        newInput = document.createElement('input');
        newInput.setAttribute('class', 'textInput');
        newInput.setAttribute('type', 'text');
        newInput.setAttribute('name', name);
        newInput.setAttribute('id', name);      
        newElement.appendChild(newInput);
        elParentContainer.appendChild(newElement);
}
</script>

Upvotes: 2

Nils
Nils

Reputation: 969

If you want to use jQuery please consider using code like this:

  var inputCount = $('.textInput').size();
  inputCount += 1;
  $('#itemList').append('<div><input class="textInput" name="input_'+inputCount+'" id="input_'+inputCount+'" type="text" /></div>');

Additionally it may be more appropiate to use the data attribute, you might consider it.

Upvotes: 1

Rion Williams
Rion Williams

Reputation: 76547

You could consider updating your function to see how many current elements there are (via the getElementsByClassName() function) and use that to set your id and name properties respectively when creating your new element :

<script type="text/javascript">
  function addNewInputField(){
      // Set how many elements you have with that class (to determine which
      // value to append to 'input_{x}'
      var currentInput = document.getElementsByClassName('textInput').length + 1;
      elParentContainer = document.getElementById('itemList');
      newElement = document.createElement('div');
      newInput = document.createElement('input');
      newInput.setAttribute('class', 'textInput');
      // Set your new ID attribute
      newInput.setAttribute('id', 'input_' + currentInput);
      // Set your new name attribute
      newInput.setAttribute('name', 'input_' + currentInput); 
      newInput.setAttribute('type', 'text');      
      newElement.appendChild(newInput);
      elParentContainer.appendChild(newElement);
  }
</script>

You can see a working example here and an example of what the output markup would look like below :

enter image description here

Upvotes: 2

BHUVANESH MOHANKUMAR
BHUVANESH MOHANKUMAR

Reputation: 2777

Have you tried Jquery.append() functionality.

Hope this will solve your problem, where you can use to create dynamic elements and also append any text in the page.

Please see the sample and try this link , you will get better idea.

http://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_html_append_ref

Let me know, if any more support needed.

Thanks, Bhuvan

Upvotes: 0

Related Questions