2

I have a page containing:

<div class="my_div">
  <table>
    <tr>
      <th>Title 1</th><th>Title 2</th><th>Title 3</th>
    </tr>
    <tr>
      <td><input type="input" name="set[1][arg1]" value="X"></td>
      <td><input type="input" name="set[1][arg2]" value="Y"></td>
      <td><input type="input" name="set[1][arg3]" value="Z"></td>
    </tr>
    <tr>
      <td><input type="input" name="set[2][arg1]" value="X"></td>
      <td><input type="input" name="set[2][arg2]" value="Y"></td>
      <td><input type="input" name="set[2][arg3]" value="Z"></td>
    </tr>
    <tr>
      <td><input type="input" name="set[3][arg1]" value="X"></td>
      <td><input type="input" name="set[3][arg2]" value="Y"></td>
      <td><input type="input" name="set[3][arg3]" value="Z"></td>
    </tr>
  </table>
  <a href="#" id="addSet">Add another Set</a>
</div>    
<div class="my_div">
  <table>
    <tr>
      <th>Title 1</th><th>Title 2</th><th>Title 3</th>
    </tr>
    <tr>
      <td><input type="input" name="set[4][arg1]" value="X"></td>
      <td><input type="input" name="set[4][arg2]" value="Y"></td>
      <td><input type="input" name="set[4][arg3]" value="Z"></td>
    </tr>
    <tr>
      <td><input type="input" name="set[5][arg1]" value="X"></td>
      <td><input type="input" name="set[5][arg2]" value="Y"></td>
      <td><input type="input" name="set[5][arg3]" value="Z"></td>
    </tr>
    <tr>
      <td><input type="input" name="set[6][arg1]" value="X"></td>
      <td><input type="input" name="set[6][arg2]" value="Y"></td>
      <td><input type="input" name="set[6][arg3]" value="Z"></td>
    </tr>
  </table>
  <a href="#" id="addSet">Add another Set</a>
</div>    

Two (or more) divs, containing a table each, plus n rows, each containing inputs. The inputs you already see are dynamically created from data in the db.

I would like to be able to just add a new <tr> when the link below any table is clicked. The catch being that the table which will recieve the new row is the one immediately above the link clicked.

I did think about giving each table a unique id which matches the id of the link but am unsure how in the jQuery to then recognise that a link with a random id has been clicked.

Then i thought maybe I could use the closest functionality and traverse backwards from the link to the table above it but I don't think that works. (maybe it does?)

Also, when I add the new row, it needs to be blank, which I think I could figure out, once I manage to clone the last (or any for that matter) row and append it to the end of the relevant table. E.g. new row:

<tr>
  <td><input type="input" name="newSet[][arg1]" value=""></td>
  <td><input type="input" name="newSet[][arg2]" value=""></td>
  <td><input type="input" name="newSet[][arg3]" value=""></td>
</tr>

Hope it makes sense what I am asking.

Thanks in advance.

Jon

2
  • a fiddle with content will be better. Commented Aug 12, 2014 at 12:02
  • ID's have to be unique ... so you may have to change id="addSet" to class="addSet". And what do you mean by type="input"? Commented Aug 12, 2014 at 12:06

4 Answers 4

1

First, add a class addSet to your links and remove the id or make it unique. Repeated ids is not a valid markup. After doing this, I'd say this should work

$('.addSet').click(function(e) {
    e.preventDefault();
    var $table = $(this).prev();
    var $row = $table.find('tr:last');
    var $clonedRow = $row.clone();
    $clonedRow.find('input').each(function(index) {
        var $this = $(this);
        $this.val('');
        $this.prop('name','set[][arg' + (index + 1) + ']' );
    })
    $table.append($clonedRow);
});

DEMO

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for this, its nice and simple, but missing the fact that the set[n][argm] needs to be cleared to newSet[][argm].
@j0nr: indeed I missd it, just fixed it.
1

DEMO

As pointed out in the comments, please change id="addSet" to class="addSet" to get rid of duplicate ID's. Make a clone of the last row .... there should be at least one row in the table, otherwise this part will fail. Then fix the name and value of each input element in the clone. You can either change the current value with .val() or the default/initial value with .attr() or removeAttr('value').

Here is the code you need:

$(function() {
    $(document).on('click', 'a.addSet', function(e) {
        e.preventDefault();
        var tr = $(this).closest('div.my_div').find('tr').last().clone();
        tr.find('input').attr('name', function() {
            return $(this).attr('name').replace(/set\[\d{1,}\]/g,'newSet[]');
        })
        .each(function() {
            $(this).val('');
        });
        $(this).closest('div.my_div').find('table tbody').append( tr );
    });
});

2 Comments

Thanks for this, out of interest, on this and other solutions, when you set val(''), is it correct that the HTML still shows the cloned set value: <input value="3" name="set[][order]"></input>? The rendered box is clear though.
Yes that is correct; value="3" is the default value which does not change. The current and effective value is what shows in the textbox. If you want to change the default value you can replace the .each() part with .attr('value', function() { return ""; }) which will render <input ..... value>
0

you can do it by adding a class to the link as id must be unique:

HTML:

<div class="my_div">
    <table>
        <tr>
            <th>Title 1</th>
            <th>Title 2</th>
            <th>Title 3</th>
        </tr>
        <tr>
            <td>
                <input type="input" name="set[1][arg1]" value="X" />
            </td>
            <td>
                <input type="input" name="set[1][arg2]" value="Y" />
            </td>
            <td>
                <input type="input" name="set[1][arg3]" value="Z" />
            </td>
        </tr>
        <tr>
            <td>
                <input type="input" name="set[2][arg1]" value="X" />
            </td>
            <td>
                <input type="input" name="set[2][arg2]" value="Y" />
            </td>
            <td>
                <input type="input" name="set[2][arg3]" value="Z" />
            </td>
        </tr>
        <tr>
            <td>
                <input type="input" name="set[3][arg1]" value="X" />
            </td>
            <td>
                <input type="input" name="set[3][arg2]" value="Y" />
            </td>
            <td>
                <input type="input" name="set[3][arg3]" value="Z" />
            </td>
        </tr>
    </table> <a href="#" class="addSet">Add another Set</a>

</div>
<div class="my_div">
    <table>
        <tr>
            <th>Title 1</th>
            <th>Title 2</th>
            <th>Title 3</th>
        </tr>
        <tr>
            <td>
                <input type="input" name="set[4][arg1]" value="X" />
            </td>
            <td>
                <input type="input" name="set[4][arg2]" value="Y" />
            </td>
            <td>
                <input type="input" name="set[4][arg3]" value="Z" />
            </td>
        </tr>
        <tr>
            <td>
                <input type="input" name="set[5][arg1]" value="X" />
            </td>
            <td>
                <input type="input" name="set[5][arg2]" value="Y" />
            </td>
            <td>
                <input type="input" name="set[5][arg3]" value="Z" />
            </td>
        </tr>
        <tr>
            <td>
                <input type="input" name="set[6][arg1]" value="X" />
            </td>
            <td>
                <input type="input" name="set[6][arg2]" value="Y" />
            </td>
            <td>
                <input type="input" name="set[6][arg3]" value="Z" />
            </td>
        </tr>
    </table> <a href="#" class="addSet">Add another Set</a>

</div>

JQUERY:

$(".addSet").click(function () {

    $(this).prev("table").append('<tr><td><input type="input" name="newSet[][arg1]" value=""></td><td><input type="input" name="newSet[][arg2]" value=""></td><td><input type="input" name="newSet[][arg3]" value=""></td></tr>');

})

FIDDLE:

http://jsfiddle.net/kbxekrjc/

Comments

0

I am answering my own question because I used a combination of two of the other provided answers (@ClaudioRedi & @user3558931)

$('.addSet').click(function(e) {
  e.preventDefault();
  var $table = $(this).prev();
  var $row = $table.find('tr:last');
  var $clonedRow = $row.clone();
  $clonedRow.find('input').attr('name', function() {
    return $(this).attr('name').replace(/set\[\d{1,}\]/g,'newSet[]');
  })
  .each(function() {
    $(this).val('');
  });
  $clonedRow.hide();
  $table.append($clonedRow);
  $clonedRow.show('slow');    
});

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.