I'm designing a dynamic input form that essentially acts as a user GUI for creating tables in a mysql database.
The Javascript
var counter = 0;
function moreFields() {
counter++;
var newFields = document.getElementById('poptemplate').cloneNode(true);
newFields.id = '';
newFields.style.display = 'block';
var newField = newFields.childNodes;
for (var i=0;i<newField.length;i++) {
var fieldname = newField[i].name;
if (fieldname){
newField[i].name = fieldname + counter;
}
}
var insertHere = document.getElementById('catidtable');
insertHere.parentNode.appendChild(newFields);
}
window.onload = moreFields;
The HTML
<div id="poptemplate" style="display: none" >
<table border="3">
<tr>
<td>Field Name:</td>
<td><input class="renameme" form="catform" type="text" name="fieldname_input" /></td>
</tr>
<tr>
<td>Data Type:</td>
<td><?php $typedown->displayList(); ?></td>
</tr>
<tr>
<td colspan='2'><input type="button" value="Remove Field" onclick="this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode.parentNode);" /></td>
</tr>
</table>
</div>
The Problem
The problem is that when new fields are added to the form, they retain the same name designators from the original clone. (Clone structure is 'poptemplate' div in code above.)
Having taught myself most of my web developing skills from research, I have located this script, now modified, (original source: http://www.quirksmode.org/dom/domform.html) in order to clone the template and insert it into the page (with an unshown jquery function that merely calls the JS function when the Add Field button is clicked).
The problem is, the JS, while it clones the DIV successfully and places it, the loop involved does not delve deep enough into the node structure of my template to find the input fields and change their names.
One input field is a drop-down list that is populated through a mysql query with php, however its location in the node structure should be at the same level as the text input.
(i.e. <Table><tr><td><input(or/)select>
)
The Attempt At Fixing Part 1
function moreFields() {
counter++;
var newFields = document.getElementById('poptemplate').cloneNode(true);
newFields.id = '';
newFields.style.display = 'block';
var newField = newFields.childNodes; //Table level of poptemplate
if (newField.hasChildNodes()){//If the table has children, and it does, loop through them
for (var i=0;i<newField.length;i++) {
var x = newField.rows[i].cells.length; //how many cells you got in your row
if (x>0;){ //if its more than 0, look at the cells
for (var r = 0;r<x;r++) {
var td = newField.rows[0].cell[r]; //td is equal to the td level time to check to see if it has input or select
var k = td.getElementsByTagName("select");
if (k.hasChildren()){
k.firstChild.setAttribute(name, name + counter);
}
var p = td.getElementsByTagName("input");
if (p.hasChildren()){
p.firstChild.setAttribute(name, name + counter);
}
}
}
}
}
var insertHere = document.getElementById('catidtable');
insertHere.parentNode.appendChild(newFields);
}
window.onload = moreFields;
Attempt At The Fix Part 2
After following through with a suggestion from briansol
, I have the following modified java script that still does not follow through with what it is supposed to do on execution. I have left the unnecessary, however useful, line of code inputs[index].value = inputs[index].name + counter;
for troubleshooting purposes.
var counter = 0;
function moreFields() {
counter++;
var index, inputs;
var newFields = document.getElementById('poptemplate').cloneNode(true);
newFields.id = newFields.id+counter;
newFields.style.display = 'block';
var newField = newFields.childNodes;
var insertHere = document.getElementById('catidtable');
insertHere.parentNode.appendChild(newFields);
// now update it
container = document.getElementById(newFields.id+counter);
// Find its child `input` elements
inputs = container.getElementsByTagName('input');
selects = container.getElementByTagName('select');
for (index = 0; index < inputs.length; ++index) {
// deal with inputs[index] element.
inputs[index].name = inputs[index].name + counter;
inputs[index].value = inputs[index].name + counter;
}
for (index = 0; index < selects.length; ++index) {
// deal with select element
selects[index].name = selects[index].name + counter;
}
}
window.onload = moreFields;
The Need UPDATED:
Currently, Attempt 2 seems promising but there is something missing. It successfully clones the template, but the procedures to capture the select and input elements is not succeeding.
ORIGINAL:
I'm looking for a solution to patch the already provided for loop to delve deeper, or alternative code that doesn't break the cloning process, but additionally changes the name attributes. All of my attempts to modify this code to traverse deeper have resulted in the code breaking on execution.
This is my first post here, I have found stackoverflow to be incredibly helpful, I hope my problem and its solution can help others learn and understand better. Thanks for assistance in advanced.
I'm indebted to briansol
for helping with the structural example. This code is a functioning solution to my problem. Edits from briansol's original code example includes removal of + counter
from the container
assignment. Firefox's developer console allowed me to see that the variable was coming up null. Once the counter had been added to the ID, there was no need to append it again.
The Solution
var counter = 0;
function moreFields() {
counter++;
var newFields = document.getElementById('poptemplate').cloneNode(true);
newFields.id = newFields.id+counter;
newFields.style.display = 'block';
var insertHere = document.getElementById('catidtable');
insertHere.parentNode.appendChild(newFields);
// now update it
var index, inputs, selects, container;
container = document.getElementById(newFields.id);
// Find its child `input` elements
inputs = container.getElementsByTagName('input');
selects = container.getElementsByTagName('select');
for (index = 0; index < inputs.length; ++index) {
// deal with inputs[index] element.
inputs[index].name = inputs[index].name + counter;
}
for (index = 0; index < selects.length; ++index) {
// deal with select element
selects[index].name = selects[index].name + counter;
}
}
window.onload = moreFields;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With