Table Edit enhancement for Javascript

Summary

Support dynamic list management, can put an 'Add Row' or 'Delete Row' button on a table to manage lists of fields. The buttons must be created in the page render.

Example

id value action
252
277

On noscript, the 'delete' button will submit the form with an appropriate command, so the action can be handled normally. Noscript 'new' should be handled in the traditional manner, by adding an empty row in the code.

Code


/////////////////////////////////////////////////////////////////

/**
 * Add a new row to a table by duplicating the last row.
 * This allows users to keep adding new info to a table that includes
 * editable text fields as the last row.
 * Should be triggered from a button of your own that calls this function.
 * Table must have an 'id' set
 */
function add_row_to_edit_table(event_src) {
  if (document.getElementById) {

    var parentN = event_src.parentNode;
    while(parentN && (parentN != parentN.parentNode) && (parentN.nodeName.toLowerCase() != "table") ){
      parentN = parentN.parentNode;
    }
    var t;
    if(parentN.nodeName.toLowerCase() == "table"){
      t = parentN;
    }

    if(t){
      // find last row,
      var rows = t.getElementsByTagName("tr");
      var lastrow = rows[rows.length-1];
      var copyrow = lastrow.cloneNode(true);

      // Cannot allow duplicate IDs
      // By changing the old row, hopefully scripts will still work on the new row
      _set_unique_ids(lastrow,rows.length)

      lastrow.parentNode.appendChild(copyrow);

      // need to do this to add the event to the button again
      if(typeof(init_combo_boxes)=='function'){init_combo_boxes()};
    } else {
      alert("container table not found, cannot add a row to it");
    }
    return false;
  }
  return true
}

/**
 * Recursively ensure that any item in this tree with an id gets suffix added to it
 */
function _set_unique_ids(node,suffix) {
  var child = node.firstChild;
  if(!child) return;
  while (child){
    if(child.id){
      //incidentally, delete the 'new' button
      if(child.id=="new_button"){
        child.parentNode.removeChild(child);
      } else {
        child.id = child.id + suffix ;
      }
    }
    _set_unique_ids(child,suffix);
    child = child.nextSibling;
  }
}


/**
 * Remove the target row from a table.
 * Called from a button with the parameter 'this', this func
 * will find the nearest tr and wipe it.
 */
function delete_row_from_edit_table(event_src) {
  if (document.getElementById) {
    var parentN = event_src['parentNode']; // 'parent' is a reserved word in IE!

    while(parentN && (parentN != parentN.parentNode) && (parentN.nodeName.toLowerCase() != "tr") ){
      parentN = parentN.parentNode;
    }
    if(parentN.nodeName.toLowerCase() == "tr"){
      // and remove it
      parentN.parentNode.removeChild(parentN);
    } else {
      alert("No row found above here - was this action launched from inside a table at all?");
    }
    return false;
  }
  return true;
}

/////////////////////////////////////////////////////////////////
DOM by
Self-documenting code idea from