5

I want to add/remove rows in a table dynamically. I have javascript function to add and remove the rows. But, I want the delete button beside every single row so that I can delete a particular row.

ANd I want to add a row only if the first row is completely filled.

function to remove row

 function removeRowFromTable()
{
  var tbl = document.getElementById('tblSample');
  var lastRow = tbl.rows.length;
  if (lastRow > 2) tbl.deleteRow(lastRow - 1);
}

function to add rows:

function addRow(tableID) {

            var table = document.getElementById(tableID);

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

            var cell1 = row.insertCell(0);
            var element1 = document.createElement("input");
            element1.type = "text";
            cell1.appendChild(element1);

            var cell2 = row.insertCell(1);
            var element2 = document.createElement("input");
            element2.type = "text";
            cell2.appendChild(element2);
        }

my table:

<table id="tableId">
<tr><td>Host Name</td><td>Directory</td></tr>
<tr><td><input type="text"/></td><td><input type="text"/></td></tr>
<tr><td><input type="button" value="+" onclick="addRow(tableId)"/></td>
<td><input type="button" value="-" onclick="removeRowFromTable()"/></td></tr>
</table>

Any help is appreciated! Thanks in Advance!!!

4 Answers 4

7

If you put a delete button on each row, then:

<tr>
  <td><input type="button" value="Delete row" onclick="deleteRow(this)">
  <td><input type="text">
  <td><input type="text">
</tr>

And the deleteRow function can be:

function deleteRow(el) {

  // while there are parents, keep going until reach TR 
  while (el.parentNode && el.tagName.toLowerCase() != 'tr') {
    el = el.parentNode;
  }

  // If el has a parentNode it must be a TR, so delete it
  // Don't delte if only 3 rows left in table
  if (el.parentNode && el.parentNode.rows.length > 3) {
    el.parentNode.removeChild(el);
  }
}

BTW, if all your rows have the same content, it will be much faster to add a row by cloning an existing row:

function addRow(tableID) {
  var table = document.getElementById(tableID);

  if (!table) return;

  var newRow = table.rows[1].cloneNode(true);

  // Now get the inputs and modify their names 
  var inputs = newRow.getElementsByTagName('input');

  for (var i=0, iLen=inputs.length; i<iLen; i++) {
    // Update inputs[i]
  }

  // Add the new row to the tBody (required for IE)
  var tBody = table.tBodies[0];
  tBody.insertBefore(newRow, tBody.lastChild);
}
Sign up to request clarification or add additional context in comments.

1 Comment

content will be different..BTW, I will be saving the data to DB and pulling from it to show the content..so,I think cloning might be a risk in long run..will be considering your suggestion of cloning for time being for sure..
4

You can avoid a lot of cross browser headaches by using jquery. Here is a sample.

http://jsfiddle.net/piyushjain7/gKJEs/

Comments

2

Javascript has this really useful function called deleteRow where if you know the index you are deleting from, you can simply input that number, and then it'll delete that specific row (index's starting at 0 - tbl.rows.length).

I also found a nice example that uses it in action. You can adjust it to fit your needs though (although his uses checkboxes which might be a lot cleaner than just making a button next to every single row). I don't encourage you to blatantly copy the code so if there is anything that confuses you, please let us know. Hope this helps.

EDIT: I didn't see you wanted to add rows after you found out the last row was completely filled. I'll update my answer when I figure that out. However, the basic idea of that is to check if the <td> tag has text in it (perhaps check if the text inside the tag isn't a blank or if there is a <td> tag at all and then if it isn't empty, make a new <tr> element else don't.

1 Comment

I really do like the checkbox style..but, unfortunately I have to go without checkboxes..probably, i need to check for the value of last textbox to null and further go from there...
2

See http://jsfiddle.net/9gnAx/

HTML & JavaScript (body):

<table id="tableId">
    <tr>
        <th>Host Name</th>
        <th>Directory</th>
        <td><input class="add" type="button" value="+" /></td>
    </tr>
    <tr>
        <td></td><td></td>
        <td><input class="add" type="button" value="+" /></td>
    </tr>
</table>
<script type="text/javascript">
    (function(){
    var els=getElementsByClassName("add","tableId");
    for(var i=0;i<els.length;i++){
        els[i].onclick=addRow;
    }
    els[0].onclick();
    })();
</script>

CSS (head):

.add,.del{
    width:25px;
}

JavaScript (head):

function getElementsByClassName(c,el){
    if(typeof el=='string'){el=document.getElementById(el);}
    if(!el){el=document;}
    if(el.getElementsByClassName){return el.getElementsByClassName(c);}
    var arr=[],
        allEls=el.getElementsByTagName('*');
    for(var i=0;i<allEls.length;i++){
        if(allEls[i].className.split(' ').indexOf(c)>-1){arr.push(allEls[i])}
    }
    return arr;
}
function killMe(el){
    return el.parentNode.removeChild(el);
}
function getParentByTagName(el,tag){
    tag=tag.toLowerCase();
    while(el.nodeName.toLowerCase()!=tag){
        el=el.parentNode;
    }
    return el;
}
function delRow(){
    killMe(getParentByTagName(this,'tr'));
}
function addRow() {
    var table = getParentByTagName(this,'table')
    var lastInputs=table.rows.length>2?
        table.rows[table.rows.length-2].getElementsByTagName('input'):[];
    for(var i=0;i<lastInputs.length-1;i++){
        if(lastInputs[i].value==''){return false;}
    }
    var rowCount = table.rows.length;
    var row = table.insertRow(rowCount-1);

    var cell1 = row.insertCell(0);
    var element1 = document.createElement("input");
    element1.type = "text";
    cell1.appendChild(element1);

    var cell2 = row.insertCell(1);
    var element2 = document.createElement("input");
    element2.type = "text";
    cell2.appendChild(element2);

    var cell3 = row.insertCell(2);
    var element3 = document.createElement("input");
    element3.type = "button";
    element3.className="del";
    element3.value='-';
    element3.onclick=delRow;
    cell3.appendChild(element3);
}

Update:

RobG has made me realize that getParentByTagName throws an error if there isn't any parent with the nodeName passed.

If you want a more general getParentByTagName, which doesn't throw errors, you can use

function getParentByTagName(el,tag){
    tag=tag.toLowerCase();
    while(el&&el.nodeName.toLowerCase()!=tag){
        el=el.parentNode;
    }
    return el||null;
}

And when you call the function you should check if the result is null.

Updated jsfiddle: http://jsfiddle.net/9gnAx/1/

1 Comment

The getParentByTagName function should check that the current node has a parent node, otherwise it will throw an error if a parent with the required tag isn't found, e.g. while (el.parentNode && el.nodeName.toLowerCase() != tag), then at the end you have to check that you have a node with the right tag name.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.