tags:

views:

244

answers:

2

I have been trying to make something work with JQuery. I have the following function:

<script type="text/javascript">
$(function(){
    // start a counter for new row IDs
    // by setting it to the number
    // of existing rows
    var newRowNum = 2;

    // bind a click event to the "Add" link
    $('#addnew').click(function(){
        // increment the counter
        newRowNum += 1;

        // get the entire "Add" row --
        // "this" refers to the clicked element
        // and "parent" moves the selection up
        // to the parent node in the DOM
        var addRow = $(this).parent().parent();

        // copy the entire row from the DOM
        // with "clone"
        var newRow = addRow.clone();

        // set the values of the inputs
        // in the "Add" row to empty strings
        //$('input', addRow).val('');
        //$('name', addRow).val('os' + newRowNum);

        // replace the HTML for the "Add" link 
        // with the new row number
        $('td:first-child', newRow).html('<input type="hidden" name="on' + newRowNum + '" value="Email Address ' + (newRowNum - 1) + '">Recipient');

        // insert a remove link in the last cell
        $('td:last-child', newRow).html('<a href="" class="remove">Remove<\/a>');

        // loop through the inputs in the new row
        // and update the ID and name attributes
        $('td:first-child.next-child.input', newRow).each(function(i){
            var newID = newRowNum;
            $(this).attr('id','os' + newID).attr('name','os' + newID);
        });

        //$('td:first-child.next', newRow).html('<input type="text" id="os' + newRowNum + '" name="os' + newRowNum + '" value="">');

        // insert the new row into the table
        // "before" the Add row
        addRow.before(newRow);

        // add the remove function to the new row
        $('a.remove', newRow).click(function(){
            $(this).parent().parent().remove();
            return false;      
        });

        // prevent the default click
        return false;
    });
});
</script>

In the html, I have this (part of a larger code block):

<tr>
  <td><input type="hidden" name="on2" value="Email Address 1"><a id="addnew" href="">Add</a></td><td><input name="os2" type="text" id="os2" value="" size="24" maxlength="60" /></td>
  <td>&nbsp;</td>
</tr>

What is supposed to be happening here is that when the Add link is clicked, the Add is changed to the word Recipient with a hidden form element with name="on + newRowNum" (incremented by one for each new row added) and the same for id. This works just fine. However, the second part of this in the next , I need to update the name and id of the text input to match the newRowNum, in this case name="os + newRowNum" etc. I am not able to make this happen. I am most likely not using the proper form to access this. I have tried all of the following:

$('td:first-child.next-child.input', newRow).each(function(i){
    var newID = newRowNum;
    $(this).attr('id','os' + newID).attr('name','os' + newID);
});

$('td:firstChild.nextSibling.input', newRow).each(function(i){
    var newID = newRowNum;
    $(this).attr('id','os' + newID).attr('name','os' + newID);
});

plus many other versions of the above. Can anyone help me out with this? Hope this is not too vague.

A: 

what about this:

$(newRow:input:last).each(function(i){
    var newID = newRowNum;
    var newOID = 'os' + newID;
    $(this).attr('id',newOID ).attr('name',newOID);
});

NOTE: I have not tested the callback on the attr so you might need:

$(this).attr('id',newOID);
$(this).attr('name',newOID);

instead of

$(this).attr('id',newOID ).attr('name',newOID);
Mark Schultheiss
Well, this stops the whole Add new row function. I am using jquery-1.3.2.js Not sure if this makes a difference.
Dave
+1  A: 

This selector $('td:first-child.next-child.input', newRow) is a little bit wrong. If all we need to do is get the inputs in the row we could do

$('input:hidden', newRow).attr('id','on' + newRowNum ).attr('name','on' + newRowNum );
$('input:text', newRow).attr('id','os' + newRowNum ).attr('name','os' + newRowNum );

Here's a Working Demo. if you want to see the code, add /edit to the URL.

BTW - I thought that you meant something like this originally until I re-read your question :)

Russ Cam
Right but I have two input elements in this row so wouldn't this make them all have the same name and id? I need the first on (a hidden element) to have a name and id of on + newRowNum and the second one to have name and id of os + newRowNum.Dave
Dave
my bad, will amend now :)
Russ Cam
have amended the code and the demo too. Take a look at the `name` and `id` attributes using Firebug or other DOM inspector
Russ Cam
Yeah this did it. A lot easier that I was making it out to be. Thanks for clearing this up.
Dave