Thread: Clone table row

    #1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Posts
    391
    Rep Power
    19

    Clone table row


    I've been struggling with this all day...

    I have a form that is layed out in a table. The first row of the table has fields for a new entry.
    The next row has a button that is meant for creating clones of the first row.
    The following fields are filled with values from a db.

    I want to clone the first row and place the clone right before the row with the button.

    I'm not sure if I am doing this right, could someone let me know?
    Code:
    var counter = 0;
    function moreFields()
    {
    	var table = document.getElementById("imagetable");
    	var tbody = table.getElementsByTagName("tbody")[0];
    	var rows = tbody.getElementsByTagName("tr");
    	
    	for ( var i=0; i<rows.length; i++ )
    	{
    		if ( rows[i].id == 'readtr' )
    		{
    			var newRow = rows[i].cloneNode(true);
    			var newFields = newRow.childNodes;
    			for ( var j=0; j<newFields.length; j++ )
    			{
    				var theName = newFields[j].name;
    
    				if ( theName )
    				{
    					newFields[j].name = theName.replace(/^(img|url)\[\d{1,2}\](\[\[a-z]+\])?/,"$1["+counter+"]$2");
    					newFields[j].value = '';
    				}
    				// I'm trying to see what is being cloned
    				// returns undefined
    				alert(theName);
    			}
    		}
    	}
    	counter++
    }
    Last edited by aconway; July 7th, 2006 at 04:30 PM.
  2. #2
  3. CSS & JS/DOM Adept
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jul 2004
    Location
    USA (verifiably)
    Posts
    20,127
    Rep Power
    4304
    You don't seem to be calling appendChild() or insertBefore()? A call to insertBefore() seems to be what you need to add.

    If you want help adding that call, then we'll need to see the X/HTML code for the table.
    Spreading knowledge, one newbie at a time.

    Check out my blog. | Learn CSS. | PHP includes | X/HTML Validator | CSS validator | Common CSS Mistakes | Common JS Mistakes

    Remember people spend most of their time on other people's sites (so don't violate web design conventions).
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Posts
    391
    Rep Power
    19
    this is what the table looks like
    Code:
    <table id='imagetable'>
      <tr id='readtr'>
        <td colspan='2'>
                <input type='file' name='url[0]' /><br />
                 Change File Name to:<br />
                <input type='text' name='img[0][filename]' size='30' />
        </td>
        <td>
                 Public Comment<br />
                <input type='text' name='img[0][comment]' size='30' />
        </td>
      </tr>
      <tr id='writetr'>
         <td colspan='3'>
                <input name='button' type='button' onClick='moreFields();' value='Add Additional Image'><br /><br />
                <input type='submit' value='submit' />
        </td>
      </tr>
      /*
      //a bunch of other rows
      <tr>
        <td> ... </td>
      </tr>
      */
    </table>
    Last edited by aconway; July 7th, 2006 at 05:45 PM.
  6. #4
  7. CSS & JS/DOM Adept
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jul 2004
    Location
    USA (verifiably)
    Posts
    20,127
    Rep Power
    4304
    Hmm... so, why are you using a for() loop?
    Spreading knowledge, one newbie at a time.

    Check out my blog. | Learn CSS. | PHP includes | X/HTML Validator | CSS validator | Common CSS Mistakes | Common JS Mistakes

    Remember people spend most of their time on other people's sites (so don't violate web design conventions).
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Posts
    391
    Rep Power
    19
    The first for() loop is because I initially tried to get the childNodes from "readtr" with getElementById(), but nothing was returned. I searched around on the web and found a script that was similar to what I am trying to achieve and they were copying multiple rows from tbody. I figure why not do it there way and loop until the script finds the row I want to copy.

    The second for() loop is, of course to alter all the childNodes of the selected row.

    If I could get a more direct approach to gathering the childNodes from "readtr" that would be great... that's one of the reasons for posting. I know I'm not a javascript guru. If anyone see's any housekeeping that can be done on anything I post I would greatly appreciate it. I don't think I'll take any offense to anyones suggestions. I'm here to learn.

    so, please don't hesitate to tear apart what ever script I post
    Last edited by aconway; July 9th, 2006 at 10:23 AM.
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Posts
    391
    Rep Power
    19
    For some reason getElementById() is working now, so I changed my script.
    Code:
    var row = document.getElementById("readtr");
    	
    	var newRow = row.cloneNode(true);
    	var newFields = newRow.childNodes;
    	for ( var i=0; i<newFields.length; i++ )
    	{
    		var theName = newFields[i].name;
    		if ( theName )
    		{
    			newFields[i].name = theName.replace(/^(img|url)\[\d{1,2}\](\[\[a-z]+\])?/,"$1["+counter+"]$2");
    			newFields[i].value = '';
    		}
    		alert(newFields[i].tagName);
    	}
    All this does now is alert me to the tagNames, I just want to see what is being cloned and returned.

    All of the TD's are being returned but everything else is undefined.

    Am I missing something?
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Posts
    391
    Rep Power
    19
    This is now working for all those interested
    Code:
    var tbody = document.getElementById("imagetable").tBodies[0];
    	var row = document.getElementById("readtr");
    	
    	var newRow = row.cloneNode(true);
    	newRow.id = '';
    	var newCell = newRow.childNodes;
    	for ( var i=0; i<newCell.length; i++ )
    	{
    		if ( newCell[i].tagName == 'TD' )
    		{
    			var newFields = newCell[i].childNodes;
    			for ( var j=0; j<newFields.length; j++ )
    			{
    				var theName = newFields[j].name;
    				if ( theName )
    				{
    					newFields[j].name = theName.replace(/(img|url)\[[0-9]{1,2}\](\[[a-z]+\])?/,"$1["+counter+"]$2");
    					newFields[j].value = '';
    				}
    			}
    		}
    	}
    	var insertHere = document.getElementById('writetr');
    	tbody.insertBefore(newRow,insertHere);
    	counter++;
  14. #8
  15. CSS & JS/DOM Adept
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jul 2004
    Location
    USA (verifiably)
    Posts
    20,127
    Rep Power
    4304
    Congratulations on figuring it out.

    There's one thing that you may want to do differently:
    For XHTML compatibility and because childNodes[] can include nodes that aren't element nodes, I would change
    Code:
    if ( newCell[i].tagName == 'TD' )
    to
    Code:
    if ( newCell[i].nodeName.toLowerCase() == 'td' )
    Spreading knowledge, one newbie at a time.

    Check out my blog. | Learn CSS. | PHP includes | X/HTML Validator | CSS validator | Common CSS Mistakes | Common JS Mistakes

    Remember people spend most of their time on other people's sites (so don't violate web design conventions).
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Posts
    391
    Rep Power
    19
    thanks for the heads-up Kravvitz

    works great!

IMN logo majestic logo threadwatch logo seochat tools logo