user132638
user132638

Reputation: 69

Javascript table child not showing as undefined?

We have a script below where it add rows dynamically. In the addRow function we have this code alert(newcell.childNodes[0].type); to capture the childnode type. It only show the first column as checkbox but all the rest is shown as undefined. In addition for the 4th column we have more then one child node that one button and also a table in it? So how to know their types?

<html>
<head>
    <script language="javascript">
        function addRow(tableID) {

            var table = document.getElementById(tableID);

            var rowCount = table.rows.length;
            var row = table.insertRow(rowCount);

            var colCount = table.rows[0].cells.length;

            for(var i=0; i<colCount; i++) {

                var newcell = row.insertCell(i);

                newcell.innerHTML = table.rows[1].cells[i].innerHTML;
                newcell.innerHTML = newcell.innerHTML;
                alert(newcell.childNodes[0].type);

        }
     }

        function addSubRow2(subtbl){
            var table = document.getElementById(subtbl);
            var rowCount = table.rows.length;
      var a=document.getElementById(subtbl).insertRow(rowCount); 
          var b=a.insertCell(0); 
          var c=a.insertCell(1); 
          b.innerHTML="TEST"; 
          c.innerHTML="<p class=error id='slaveIDError'>"; 


      /* var dropdown="<SELECT class=\"select\" name=\"country\">\n" +
                "<OPTION value=\"1\">Serial 1<\/OPTION>\n" +
                "<OPTION value=\"2\">Serial 2<\/OPTION>\n" +
                "<OPTION value=\"3\">Serial 3<\/OPTION>\n" + 
                "<OPTION value=\"4\">Serial 4<\/OPTION>" +
                "<OPTION value=\"5\">Serial 5<\/OPTION>" + 
                "<\/SELECT>";
       */


        //cell.innerHTML += "<br\/ >" + dropdown;
    }


        function deleteRow(tableID) {
            try {
            var table = document.getElementById(tableID);
            var rowCount = table.rows.length;

            for(var i=0; i<rowCount; i++) {
                var row = table.rows[i];
                var chkbox = row.cells[0].childNodes[0];
                if(null != chkbox && true == chkbox.checked) {
                    if(rowCount <= 1) {
                        alert("Cannot delete all the rows.");
                        break;
                    }
                    table.deleteRow(i);
                    rowCount--;
                    i--;
                }


            }
            var table = document.getElementById(tableID);
            for (var i = 0, row; row = table.rows[i]; i++) {
                  row.id="row"+i;
               //iterate through rows
               //rows would be accessed using the "row" variable assigned in the for loop
               for (var j = 0, col; col = row.cells[j]; j++) {
                 //iterate through columns
                 //columns would be accessed using the "col" variable assigned in the for loop
                 //alert("J : "+j);
                 col.id="col"+i;
                 if(j==0)
                 {

                 }
                 else if(j==1)
                 {

                }
               }  
            }

            }catch(e) {
                alert(e);
            }
        }

    </script>
</head>
<body>
  Begin Location : <select class='select' id="beginLocation" name="beginLocation">
                    <option value="1">Loc 1</option>
                    <option value="2">Loc 2</option>
                    <option value="3">Loc 3</option>
                    <option value="4">Loc 4</option>
                    <option value="5">Loc 5</option>
                </select>
                <p type="text" class=error id='beginLocation_Error'>
    <br\>
    <input type="button" value="Add Row" onclick="addRow('dataTable')" />

    <input type="button" value="Delete Row" onclick="deleteRow('dataTable')" />

    <table id="dataTable" width="350px" border="1">
        <tr>
            <th></th>
            <th>Client</th>
          <th>Location</th>
          <th>Serial</th>
        </tr>

        <tr>
            <td id="col_0_0"><input type="checkbox" name="chk"/></td>
            <td id="col_0_1">
                <select class='select' id="client1" name="client1">
                    <option value="1">Client 1</option>
                    <option value="2">Client 2</option>
                    <option value="3">Client 3</option>
                    <option value="4">Client 4</option>
                    <option value="5">Client 5</option>
                </select><p type="text" class=error id='client_0_Error'>                
            </td>

            <td id="col_0_1">
                <select class='select' id="location1" name="location1">
                  <option value="1">Loc 1</option>
                    <option value="2">Loc 2</option>
                    <option value="3">Loc 3</option>
                    <option value="4">Loc 4</option>
                    <option value="5">Loc 5</option>
                </select>
                <p type="text" class=error id='beginLocation_Error'>                
            </td>

            <td id="col_0_3">
                <input type="button" value="Add Serial" onclick="addSubRow2('sub0');" />
                <br\>
                <table id="sub0">
                    <tr>
                        <td>
                            <select class='select' id="serial_0_1" name="serial_0_1">
                                <option value="1">Serial 1</option>
                                <option value="2">Serial 2</option>
                                <option value="3">Serial 3</option>
                                <option value="4">Serial 4</option>
                                <option value="5">Serial 5</option>
                            </select>
                       </td>
                       <td>
                         <input type="text" id="txt_0_1" name="txt_0_1">                        
                       </td>
                       <td>
                         <input type="button" value="Remove" onclick="removeSubRow2(this.parentNode);" />                       
                       </td>
                  </tr>
                  <tr>
                     <td>
                     <p  class=error id="selecterror_0_1">
                    </td>
                     <td>
                     <p class=error id="inputerror_0_1">
                    </td>   
                    <td>

                    </td>
                  </tr>
                </table>

            </td>
        </tr>
    </table>

</body>
</html>

Code to update row and column id

var rows = table.querySelectorAll('[id^=row]');
          for (var i = 0, row; row = table.rows[i]; i++) {
                  row.id="row"+i;
                  row.name="row"+i;
                  var rowName = "row"+i;
                  for (var j = 0, col; col = row.cells[j]; j++) {
                     col.id="col_"+i+"_"+j;
                     col.name="col_"+i+"_"+j;

                     if(j==3)
                     {
                        alert(col.childNodes[0].getElementsByTagName('button')[0]);

                     }
              }

Upvotes: 0

Views: 4709

Answers (2)

RobG
RobG

Reputation: 147453

Note that the language attribute for script elements was deprecated in HTML 4 and is removed in HTML5. The type attribute is required.

In your code:

    function addRow(tableID) {

        var table = document.getElementById(tableID);

        var rowCount = table.rows.length;
        var row = table.insertRow(rowCount);

There is no need to add an argument, no argument will add the row to the end of the table. Such operations are usually faster if the node is appended to the DOM after all modification is complete.

        var colCount = table.rows[0].cells.length;

        for(var i=0; i<colCount; i++) {

            var newcell = row.insertCell(i);

            newcell.innerHTML = table.rows[1].cells[i].innerHTML;
            newcell.innerHTML = newcell.innerHTML;
            alert(newcell.childNodes[0].type);

    }
 }

If you are just creating a clone of an existing row, then all of the above can be replaced with something like:

// Get the first tbody
var tbody = table.tbodies[0];

// Clone the second row
var newRow = tbody.rows[1].cloneNode(true);

/*
   Do whatever with newRow, like change element names and IDs to 
   suitble values
*/

tbody.appendChild(newRow);

Note that if you put your header rows in a table head section, you can clone the first row of the tbody (i.e. table.tbody[0].rows[0]), but always add rows to the tBody because older versions of IE will barf if you append to the table. insertRow avoids that but it's slow.

When deleting rows, you can do something like:

        var i = table.rows.length;
        var chkbox;

        while (i--) { 
            chkbox = table.rows[i].getElementsByTagName('input')[0];

            if (chkbox && chkbox.checked) {
                if (table.rows.length < 1) { 

                    /* error */

                } else {
                    table.deleteRow(i);
                }
            }
        }

Upvotes: 1

timidboy
timidboy

Reputation: 1722

childNodes property includes text nodes, so by doing newcell.childNodes[0] you are referring to the white space before the select element.

Instead, you should do like this:

newcell.childNodes[0].getElementsByTagName('select')[0]

or

newcell.childNodes[0].getElementsByTagName('input')[0]

Upvotes: 2

Related Questions