Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Need help with appendChild 1

Status
Not open for further replies.

TheCandyman

Technical User
Sep 9, 2002
761
US
I'm trying to have JavaScript create some html inputs when i click a button and just can't seem to find what i need when searching. I have the basics working but can't figure out some of the appendChild that i think i need. This does correctly add a row to my table with one <input> for each column. I feel as if i'm making no progress and I, sadly, am not sure how to even have it create a <select>, <label>, or <p> options. Here is what i have.


Button to create new <input>
Code:
<input type="button" class="btn" name="Add" value="Add Another Person" onClick="addRowToTable();">


What i'm trying to create in HTML:
Code:
<p>
      <select name="Profession1" id="Profession1" tabindex="7" class="Profession">
            <option value="0">-- Select Category--</option>
            <option value="1">I am</option>
            <option value="2">I am not</option>
      </select>
      </p>
      <p>
            <label for="FName1" class="Fname">First Name</label><br />
            <input type="text" name="FName1" id="FName1" value="" class="Fname" <%=EnterKey%>>
       </p>
       <p>
            <label for="LName" class="Lname">Last Name</label><br />
            <input type="text" name="LName1" id="LName1" value="" class="Fname" <%=EnterKey%>>
       </p>


What i have for the JS so far:
Code:
function addRowToTable()
            {
              var tbl = document.getElementById('tblAddress');
              var lastRow = tbl.rows.length;
              var iteration = lastRow;
              var row = tbl.insertRow(lastRow);
              var rowcount = rowcounter();
			  
              //  cell 0	  
		var cell0 = row.insertCell(0);
              var el = document.createElement('input');
              el.type = 'text';
              el.name = 'FName' + rowcount;
		el.id = 'FName' + rowcount;
		el.className = "aClassName";
              cell0.appendChild(el);
             	 

            }
			
	function rowcounter()
        {
          temp=cln(document.form1.rowcounter.value);
          document.form1.rowcounter.value = temp+1 ;
          return temp
        }
 
have you considered an alternative approach? something like this to add a row
NB not tested. and note that this just adds increments the number of the last row. it does not use the row index as, if you deleted a row other than the last, you would end up with identically named form elements.
Code:
var tbl = getElementById("tblAddress");
var numRows = tbl.rows.length;
var rw= tbl.lastChild.cloneNode(true);
//get previous index
var iH = rw.innerHTML;
var arr = /Professional(.*?)\"/i.exec(iH);
var newIndex = parseInt(arr[1]) + 1;
iH = iH.replace(arr[1] + '"', newIndex +'"');
rw.innerHTML = iH;
tbl.appendChild(rw);
 
ps. this is even easier if you have jQuery loaded.
 
Actually, i do have jQuery that i'm using another part on this page. I searched but guess i didn't use the right terms as i didn't see anything.
 
I finally found the 'clone' option; yet another reason why jQuery rocks. I tried it and i'm getting closer. It seems to clone the row but then submits the form which isn't needed. Can this change the names for the <input> fields so the new row will be address2, city2, state2, etc?

Take a look here:
 
have you looked at the native javascript code I posted above? did it nor work for you? if so, if you can explain the defect I can try to help.
 
To be honest, i heard the jQuery option and jumped straight to that. Did you look at that link i posted?
 
You could try this JQuery method...
Code:
<script type="text/javascript">
function addRowToTable() {
    
    $("#tblAddress").append($("#tblAddress tr:last").clone());

    $("#tblAddress tr:last input").each(function(){
        var num = parseInt($(this).attr('name').replace(/[^0-9]/g,''))+1;
        var name = $(this).attr('name').replace(/[0-9]/gi,'');
        $(this).attr('name',name+num);
        });
}
</script>

"In complete darkness we are all the same, it is only our knowledge and wisdom that separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!"

Free Dance Music Downloads
 
Thanks 1DMF,

That's what i ended up doing; using jQuery. I have it so it increments label, input, and select fields.

in form:
Code:
<button id="add_row" class="btn">Add Another Person +</button>

jquery:
Code:
$("#add_row").click(function () {
	var row = $("#Mytable tbody > tr:last"),
	newRow = row.clone(true);
					
newRow.find("label").each(function () {
	var num = +(this.id.match(/\d+$/) || [0])[0] + 1;
	this.id = this.id.replace(/\d+$/, "") + num;
	this.name = this.id;
	this.value = "";
});
newRow.find("input").each(function () {
	var num = +(this.id.match(/\d+$/) || [0])[0] + 1;
	this.id = this.id.replace(/\d+$/, "") + num;
	this.name = this.id;
	this.value = "";
});
	newRow.find("select").each(function () {
	var num = +(this.id.match(/\d+$/) || [0])[0] + 1;
	this.id = this.id.replace(/\d+$/, "") + num;
	this.name = this.id;
});
newRow.insertAfter(row);
 
good to hear you have it working.
i couldn't get jsFiddle to work at all. for some reason I kept getting weird errors with xsrf warnings.

i got this code working ok though

Code:
<table id="tblAddress">
	<tr>
<td><p>
    <select name="Profession1" id="Profession1" tabindex="7" class="Profession">
        <option value="0">-- Select Category--</option>
        <option value="1">I am</option>
        <option value="2">I am not</option>
    </select>
</p>
</td>
<td>
<p>
    <label for="FName1" class="Fname">
        First Name
    </label>
    <br/>
    <input type="text" name="FName1" id="FName1" value="" class="Fname">
</p>
</td>
<td>
<p>
    <label for="LName1" class="Lname">
        Last Name
    </label>
    <br/>
    <input type="text" name="LName1" id="LName1" value="" class="Fname">
</p>
</td>
</tr>
</table>
<input type="button" value="Add Row" onclick="addRow(); return false;"/>
<div>
	
<textarea id="log" rows="20" cols="100">
	
</textarea>
</div>
<script type="text/javascript">
	
function addRow(){
	var tbl = document.getElementById("tblAddress");
	var numRows = tbl.rows.length;
	var rw = tbl.lastChild.cloneNode(true);
	//get previous index
	var iH = rw.innerHTML;
	var arr = /Profession(.*?)\"/i.exec(iH);
	var newIndex = parseInt(arr[1]) + 1;
	var obj = ['input', 'select', 'label'];
	var log = document.getElementById('log');
	for(var i = 0; i < obj.length; i++){
		var elems = rw.getElementsByTagName(obj[i]);
		for (var j = 0; j < elems.length; j++){
			try{
				if (i == 2) { //label
					elems[j].setAttribute('for', elems[j].getAttribute('for').replace(arr[1], newIndex));
				}
				else {
					elems[j].name = elems[j].name.replace(arr[1], newIndex);
					elems[j].setAttribute('id', elems[j].getAttribute('id').replace(arr[1], newIndex));
				}
			} catch(err){
				log.innerHTML = log.innerHTML + "\n" + err;
			}
		}
	}
	
	tbl.appendChild(rw);
	log.innerHTML = log.innerHTML + "\n" + tbl.innerHTML;
	
}
</script>

you could use the dual loop in a similar way to reduce the jQuery selectors too. although in that case you need only one loop as all the tags can get picked up in a single selector.

also, the num variable will be the same for each element in the new row. so there is no point in doing the (expensive) match for each item.

something like this might work in jQuery

Code:
$("#add_row").click(function () {
		var row = $("#Mytable tbody > tr:last"),
		newRow = row.clone(true);
		var num = 0;
		var newIndex = 0;
	
		newRow.find("input").add("select, label").each(function () {	//need to do this to _ensure_ that the first item has a name
			if (num == 0 && $(this).prop('tagName') != 'LABEL') {
				var nums = ($(this).attr('id').match(/\d+$/));
				num = parseInt(nums[0]);
				newIndex = num + 1;
			}
			if($(this).prop('tagName') == 'LABEL'){
				$(this).attr('for', $(this).attr('for').replace( num, newIndex ));
			} else {
			var t = ['id','name'];
			for(var i = 0; i<t.length;i++){
				$(this).attr(t[i], $(this).attr(t[i]).replace( num, newIndex ));
			}
			$(this).value("");
		}
		});
		num = newIndex = 0; //reset number
	});
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top