简体   繁体   中英

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]);

                     }
              }

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]

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 (ie 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);
                }
            }
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM