views:

225

answers:

2

Hi,

With jquery, I'm dynamically adding rows. To do this, I'm copying the first of the table and then with some regex I'm changing the names and sometimes ids from thing like "column_name[0]" to "column_name[1]". This is the regex that I'm using:

  newRow = newRow.replace(new RegExp("\\[[0-9]+][\"\']", "gm"), "[" + $("#rowNum").val() + "]\"");

This is working fine.

I'm also adding a link to dynamically delete this line. This delete link has the following JQuery executed upon a click:

$(this).parents(\"tr.deletable\").remove();

This is also working fine.

Now, my problem is when a user adds 3 rows, and then deletes the first row. I want the second two rows to decrement their index number. For example column_name[2] would change to column_name[1]. How should I go about doing this? Here's what I've been trying so far:

$(this).parents("tr.deletable").nextAll().html().replace(new RegExp("\\[[0-9]+][\"\']", "gm"), "[" + i + "]\"");

I have i set to 50 just to see if it successfully puts that in as the new index but it does not. I haven't figured out smoothly get the decremented value. The above code does not work.

Does anyone have any suggestions on how I can accomplish this?

As for why I need to do this, it's because I'm using Java Struts and it requires all the form elements to have a name with a proper index at the end.

A: 

You could go up the DOM tree one more level and do it from there:

$(this).parents("tr.deletable").parent().find("tr.deletable").each();

You'll need to store the index of the row that was deleted.

var deletedIndex = parseInt($(this).attr("id").split("[")[1].split("]")[0]); // there's probably a better way to do this

Inside your each, process the rows you might need to decrement the index for using this function.

function() {
  var curIndex = parseInt($(this).attr("id").split("[")[1].split("]")[0]);
  if (curIndex  > deletedIndex) {
    $(this).attr("id", "column_name[" + (curIndex - 1) + "]");
  }
}

So, to summarize:

// get index of row deleted
var deletedIndex = parseInt($(this).attr("id").split("[")[1].split("]")[0]);

// loop through deleted items' siblings
$(this).parents("tr.deletable").parent().find("tr").each(function() {
  var curIndex = parseInt($(this).attr("id").split("[")[1].split("]")[0]);
  if (curIndex  > deletedIndex) {
    $(this).attr("id", "column_name[" + (curIndex - 1) + "]");
  }
});

Also, there might be a better way to loop through your deleted row's siblings. Like:

var curSib = $(this).next("tr.deletable");
while (curSib.length > 0) {
  var curIndex = parseInt(curSib.attr("id").split("[")[1].split("]")[0]);
  if (curIndex  > deletedIndex) {
    curSib.attr("id", "column_name[" + (curIndex - 1) + "]");
  }
  curSib = curSib.next("tr.deletable");
}

I didn't test this code, but I think you should get the idea.

Brandon Montgomery
A: 

I think the best way would be to make multiple inputs have the name of column_name, then append the [i] only when the form is submitted. Try this:

$("#Form").submit(function()
{
    $("input[name=column_name]",this).each(function(index)
    {
     var name = "column_name["+index+"]";
     $(this).attr("name",name);
    });
}
Eric
This would probably work but I need to use things like YUI's auto-complete that references a specific field by name. Changing all that would take too much time.
eli
Then call my function every time the rows need renumbering. Remove the `[]` s, and start the numbering again
Eric