views:

78

answers:

1

I have a table that looks like this:

<table name="exercises" id="workout-table">
<tr>
<th>Name</th>
<th>Reps/Intervals</th>
<th>Sets</th>
<th>Weight/Distance/Time</th>
</tr>


[%- i=0 %]
[% WHILE i<=10 %]
<tr class="workout-rows">
<td><input type="text" name="workout[exercise][[% i %]][name]" /></td>
<td><input type="text" name="workout[exercise][[% i %]][repetitions]" size="3"/></td>
<td><input type="text" name="workout[exercise][[% i %]][sets]" size="3"/></td>
<td><input type="text" name="workout[exercise][[% i %]][weight]" size="4"/></td>
</tr>
[% i = i + 1 %]
[% END %]

</table>

That template code is Template::Toolkit code that basically just generates an index so I can keep track of elements in what will become an HoAoH from Catalyst::Plugin::Params::Nested. This is the javascript that actually adds the row to the table on button click:

$("#add-row").click(function(){
       var size = $(".workout-rows").length;
       //size += 1;
       var row ='<tr class="workout-rows">' +
        '<td><input type="text" name="workout[exercise][' + size + '][name]" /></td>' +
        '<td><input type="text" name="workout[exercise][' + size + '][repetitions]" size="3"/></td>' +
        '<td><input type="text" name="workout[exercise][' + size + '][sets]" size="3"/></td>' +
        '<td><input type="text" name="workout[exercise][' + size + '][weight]" size="4"/></td>' +
        '</tr>';

       $("#workout-table >tbody tr:last").after(row)
    });

I really really don't like the idea of copy-pasting the table row markup into the script itself, as it's repetitive and non-intuitive. I've tried .clone stuff, which works great for copying the row verbatim, but it doesn't keep track of the number of rows dynamically like I need it to.

So basically I've pared it down to needing to find out how to mess with the name of each input so that it can reflect the loop index appropriately, so Catalyst::Plugin::Params::Nested will build the correct structure.

Thoughts?

+4  A: 

You should make a function that returns a table clone. I use this for templating all the time:

<div id="tableTemplate" style="display: none;">
    <table>
      <tr class="workout-rows">
        <td> <input type="text" name="" /> </td>
        <td> <input type="text" name="" size="3" /> </td>
        <td> <input type="text" name="" size="3" /> </td>
        <td> <input type="text" name="" size="4" /> </td>
      </tr>
    </table>
</div>

Then, you clone that template.

function createTableRow(size)
{
    var template = $('#tableTemplate').clone(true);
    template = template.find('tr'); // Dont need to clone the table tag
    template.find('td:nth-child(1)').find('input').attr('name', 'workout[exercise][' + size + '][name]');

    // Similar logic for the other names

    return template;
}
Tejs