adding/deleting dynamic table row, rowIndex

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • AdamG

    adding/deleting dynamic table row, rowIndex

    I am trying hard for days now to add and delete rows to a table. I
    could really use some help...

    Each row contains two buttons (images) - 'add row' and 'delete row'.
    When the user clicks add row within a specific cell/row, the index of
    that row should be passed to a function that creates a new row using
    that index (the new row should be added directly below the row where
    the user clicked. The new row should contain all of the cells and html
    in the cells from the row above, including the buttons/images. If a
    user clicks delete row, the index of the row with the delete button
    should pass to the function that deletes the row.

    I would greatly appreciate any help - I'm new to this. The more
    thorough the explanation, the better. I've seen the other postings in
    this group and I can't seem to apply the logic to my situation.

    THANKS

  • RobG

    #2
    Re: adding/deleting dynamic table row, rowIndex

    AdamG wrote:[color=blue]
    > I am trying hard for days now to add and delete rows to a table. I
    > could really use some help...
    >[/color]

    You probably want to use cloneNode, some code follows. Be aware that
    you will also clone any element ids or names too. Post again if you
    need further help.


    <html><head><ti tle>Add & Delete Table Rows...</title>

    <script type="text/javascript">

    /* cloneRow
    * Clones a row when a cell has been clicked on
    * Given a reference to the cell, clones the row and inserts it
    * before nextSibling.
    * If the nextSibling doesn't exist, it doesn't matter, the
    * newElement is put immediately after the the row theThing is
    * in anyway.
    */
    function cloneRow(theCel l) {
    if( document.create Element && document.childN odes ) {
    var thisRow = theCell.parentN ode;
    var newElement = thisRow.cloneNo de(true);
    thisRow.parentN ode.insertBefor e(newElement,th isRow.nextSibli ng);
    }}

    /* deleteRow
    * Deletes a row when a cell is clicked on.
    * Gets a reference to the row that the cell is in, then deltes the
    * entire row from the table.
    */
    function deleteRow(theCe ll) {
    if( document.create Element && document.childN odes ) {
    var thisRow = theCell.parentN ode;
    thisRow.parentN ode.removeChild (thisRow);
    }}

    </script>
    </head>
    <body>

    <table border="1">
    <tr>
    <td onclick="cloneR ow(this);">Clic k here to clone the row</td>
    <td>here is another cell</td>
    <td onclick="delete Row(this);">Cli ck here to delete the row</td>
    </tr>
    </table>

    </body></html>

    --
    Rob

    Comment

    • Michael Winter

      #3
      Re: adding/deleting dynamic table row, rowIndex

      On 8 Dec 2004 12:17:09 -0800, AdamG <agarlan78@yaho o.com> wrote:

      [snip]
      [color=blue]
      > When the user clicks add row within a specific cell/row, the index of
      > that row should be passed to a function that creates a new row using
      > that index (the new row should be added directly below the row where the
      > user clicked.[/color]

      Table rows contain, amongst other properties, two named rowIndex and
      sectionRowIndex . The former specifies the position within the table as a
      whole. The latter specifies the position within the containing table
      section: an implicit or explicit TBODY, THEAD or TFOOT element.

      To get those values when a button within the row in question is activated,
      use:

      var button, cell, row;
      if((cell = button.parentNo de) && (row = cell.parentNode )) {
      return row.rowIndex; // or row.sectionRowI ndex
      }

      The easiest way to obtain a reference to the button is to use the this
      operator inside the click event. I'll show that later.

      It's probably obvious, but the number obtained from the rowIndex property
      should be used with the table's insertRow and deleteRow methods, whilst
      rowSectionIndex should be used with a table section's insertRow and
      deleteRow methods.
      [color=blue]
      > The new row should contain all of the cells and html in the cells from
      > the row above, including the buttons/images.[/color]

      That's simple enough. Calling

      row.cloneNode(t rue)

      will return a new row which contains everything the original did. However,
      you'll have to add event listeners again as they're not copied.
      [color=blue]
      > If a user clicks delete row, the index of the row with the delete button
      > should pass to the function that deletes the row.[/color]

      This will follow on from the insertion code.

      [snip]

      In all, you're probably looking at:

      function remove(btn) {var cell, row, sect;
      if((cell = button.parentNo de) && (row = cell.parentNode )
      && (sect = row.parentNode) && sect.deleteRow)
      {
      sect.deleteRow( row.sectionRowI ndex);
      }
      }

      function insert(btn) {var cell, newRow, row, sect;
      if((cell = button.parentNo de) && (row = cell.parentNode )
      && row.cloneNode && (sect = row.parentNode)
      && sect.insertBefo re)
      {
      newRow = row.cloneNode(t rue);
      /* If you need to alter the new row
      * or its contents, do it here.
      */
      sect.insertBefo re(newRow, row.nextSibling );
      }
      }

      You'd call these with:

      <input type="button" ... onclick="insert (this);">

      and

      <input type="button" ... onclick="remove (this);">

      If you need more help, you'll have to show the relevant HTML you're using.

      Good luck,
      Mike

      --
      Michael Winter
      Replace ".invalid" with ".uk" to reply by e-mail.

      Comment

      • Michael Winter

        #4
        Re: adding/deleting dynamic table row, rowIndex

        On Thu, 09 Dec 2004 07:56:24 +1000, RobG <rgqld@iinet.ne t.auau> wrote:

        [snip]
        [color=blue]
        > if( document.create Element && document.childN odes ) {[/color]

        Umm, what relevance does document.create Element and document.childN odes
        have to the methods and properties you're using?
        [color=blue]
        > var thisRow = theCell.parentN ode;
        > var newElement = thisRow.cloneNo de(true);
        > thisRow.parentN ode.insertBefor e(newElement,th isRow.nextSibli ng);[/color]

        Test what you're actually using: don't infer. Even complete feature testing

        function cloneRow(cell) {var row, section;
        if((row = cell.parentNode ) && row.cloneNode
        && (section = row.parentNode) && section.insertB efore)
        {
        section.insertB efore(row.clone Node(true), row.nextSibling );
        }
        }

        won't adversely affect the speed of execution to any noticable level.
        However, it is probably (fairly) safe to assume that is a property that
        exists on one node will exist on another.

        [snip]

        Mike

        --
        Michael Winter
        Replace ".invalid" with ".uk" to reply by e-mail.

        Comment

        • RobG

          #5
          Re: adding/deleting dynamic table row, rowIndex

          A few more hints, I have a tad more time at the moment.

          A useful enhancement is to prevent the last row of the table from being
          deleted. Get the parent of the row (which should be a tbody) and count
          the rows:

          var numRows = theRow.parentNo de.rows.length;

          if numRows <= 1, don't allow the user to delete the row. To make
          sure it all works, it is probably best to put tbody elements in your
          HTML. That's a belt and braces approach I guess, but removes any doubt
          as to what the row parent is (read: simpler maintenance).

          And a few thoughts on cloneNode:

          A common use for cloneNode is when you have a form set out in a
          table, like a purchase order with many inputs in each row. cloneNode
          allows you to simply create another line in the form and includes any
          user input too, potentially saving user input keystrokes.

          It may be useful to create a function that goes through the cloned node
          and selectively removes some (or all) user input that has been cloned.

          A downside of using cloneNode is that you now have identical element
          ids/names. If you are allowing users to add and delete new elements
          in no particular order this can be a real issue.

          When submitting the form, you will get multiple name/value pairs with
          the same name - which can be handled OK at the server as all the
          parameters are passed in sequence (though I'm not sure you can
          guarantee the sequence, so don't depend on it). The real grief is when
          you try to validate the form, as you can't uniquely identify elements
          with identical names other than by their order in the form.

          And if you clone an entire form, how do you identify one from another?

          And of course there is the syntactical correctness issue of creating
          invalid markup by having identical ids.

          So you need to develop a scheme for creating unique ids and names and
          attaching them to the elements - it can be labourious and kinda defeats
          the beautiful simplicity of cloneNode, but may still be better than
          creating it all from scratch.

          Mike Winter shows where to do it in his post.

          Provided you can overcome these issues, cloneNode is a great invention.

          --
          Rob

          Comment

          • RobG

            #6
            Re: adding/deleting dynamic table row, rowIndex

            Michael Winter wrote:
            [...][color=blue]
            > Umm, what relevance does document.create Element and document.childN odes
            > have to the methods and properties you're using?[/color]
            [...]

            Err, excellent point. This was from some old code that I didn't clean
            up properly - rushing between assignments at the moment.

            My apologies to the OP and thanks to Mike. :-p

            --
            Rob

            Comment

            • AdamG

              #7
              Re: adding/deleting dynamic table row, rowIndex

              You guys have given me some fantastic advice. Thanks! I'm trying it
              all right now.

              I am concerned about not having unique element IDs when I use
              cloneNode.

              Thanks!!

              Comment

              • AdamG

                #8
                Re: adding/deleting dynamic table row, rowIndex

                What about using insertRow and innerHTML for each cell, instead of
                using cloneNode? Would this create unique IDs for the elements?

                Comment

                • Michael Winter

                  #9
                  Re: adding/deleting dynamic table row, rowIndex

                  On 9 Dec 2004 07:37:04 -0800, AdamG <agarlan78@yaho o.com> wrote:
                  [color=blue]
                  > What about using insertRow and innerHTML for each cell, instead of using
                  > cloneNode? Would this create unique IDs for the elements?[/color]

                  No. If you can show *exactly* what a row will contain and how you'd like
                  to change its contents, we can give you an answer.

                  Mike

                  --
                  Michael Winter
                  Replace ".invalid" with ".uk" to reply by e-mail.

                  Comment

                  • AdamG

                    #10
                    Re: adding/deleting dynamic table row, rowIndex

                    Hi - I tried you code above. I was able to get it working - I had to
                    change one thing :

                    if((cell=btn.pa rentNode)..... I changed "button" to "btn", to
                    correspond to the parameter passed to the function (btn).

                    I'm now thinking about ways to make each row element unique for the
                    purposes of submitting the form. Any ideas on how I could submit the
                    results (I'm sure you have ideas). Again THANK YOU !!!!!!!!!!!!!!! !!!!

                    Comment

                    • AdamG

                      #11
                      Re: adding/deleting dynamic table row, rowIndex

                      Hi Mike - I'll try to give you some more info, because it sounds like
                      you can actually help me.

                      Here's the code for my table:
                      <form name="form2" method="post" action="">
                      <table border="1" align="left" cellpadding="1" id="Table">
                      <tr>
                      <td height="74" colspan="4" bgcolor="#F4F4F 4"><strong><fon t
                      color="#000000" size="4">Please
                      enter a name for the ROI Survey:</font>
                      <input name="Survey Name" type="text" id="Survey Name5"
                      value="Fiorano ESB" size="30">
                      </strong></td>
                      <td height="74"><di v align="center"> <a href="#"
                      onMouseOut="MM_ swapImgRestore( )"
                      onMouseOver="MM _swapImage('Ima ge5','','click% 20to%20save2.gi f',1)"><img
                      src="click%20to %20save.gif" alt="click to save" name="Image5"
                      width="120" height="75" border="0"></a></div></td>
                      </tr>
                      <tr valign="bottom" bgcolor="#F5F5F 5">
                      <td width="34">&nbs p;</td>
                      <td width="156" height="26"><di v align="left">
                      <p align="center"> <font size="3"><stron g>Enter Touch
                      Points</strong></font></p>
                      </div></td>
                      <td width="185"><di v align="center"> <font
                      size="3"><stron g>Enter Survey
                      Questions</strong></font></div></td>
                      <td width="91"><div align="center"> <font
                      size="3"><stron g>Answer Type</strong></font></div></td>
                      <td width="260"><p align="center"> <font
                      size="3"><stron g><strong>Conta ct
                      Info </strong></strong></font></p></td>
                      </tr>
                      <tr valign="top">
                      <td valign="top"><o l>
                      <li></li>
                      </ol></td>

                      /*The following is the row I'd like to copy when I hit add new row -
                      the new row should contain a number identifier (a unique identifier) in
                      cell 1, blank text in cell 2, a text box and two buttons (add and
                      delete) in cell 3, and 4 text boxes in cell 4.

                      <td height="98" valign="top"> <div align="left">
                      <textarea name="TouchPoin t_txt" cols="20" rows="3"
                      id="TouchPoint_ txt"></textarea>
                      <br>
                      </div></td>
                      <td><textarea name="question_ txt" cols="25" rows="4"
                      id="question_tx t"></textarea><br>
                      <input name="add" type="button" onclick="insert (this);"
                      id="button" value="+"> <font size="1">-
                      add new Touch Point<br>
                      <input name="delete" type="button" onclick="remove (this);"
                      id="button" value="-"><font size="1">-
                      delete this Touch Point</font></font></td>
                      <td><select name="answer type" id="answer type">
                      <option selected>Number </option>
                      <option>List</option>
                      <option>Percent age</option>
                      <option>Text</option>
                      <option>Yes/No</option>
                      </select></td>
                      <td align="left" valign="top"><p > <font
                      size="2"><stron g>Name</strong></font>
                      <input type="text" name="textfield 5">
                      <font color="#000000"
                      size="2"><stron g>Email</strong></font><strong><f ont color="#0000FF" >
                      </font></strong><font color="#0000FF" >
                      <input type="text" name="textfield 6">
                      <br>
                      <font color="#000000" size="2"><stron g>Name
                      2</strong></font>
                      <input name="textfield 8" type="text" size="18">
                      <br>
                      <font color="#000000" size="2"><stron g>Email
                      2</strong></font>
                      <input name="textfield 7" type="text" size="18">
                      </font> </p>
                      </td>
                      </tr>
                      </table>
                      </form>

                      I have not had success using your code to delete a row - I am getting
                      no error message or action when I click it (the delete button does call
                      the remove(btn) function, but it's not working).

                      My goal is to allow the user to add rows as he/she pleases. Then they
                      should be able to click a button to submit the entire form - ideally
                      the contents of the form could be output to a server to text file, with
                      unique identifiers on each row.

                      I know this may be a poorly constructed question - sorry I'm totally
                      new to javascript and relatively inexperienced in programming. Your
                      suggestions have been great!

                      Comment

                      Working...