Reputation: 2240
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
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
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
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
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
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
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 :
Upvotes: 2
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