kate_hudson kate_hudson - 6 months ago 12
Javascript Question

Duplicating table rows with clone

I am having an issue I am struggling to resolve. I have two tables

<div class="form-group">
<div class="row">
<div class="col-md-12">
<div class="col-md-12 noPadding">
<table class="table table-bordered table-hover additionalMargin alignment" id="table1">
<thead>
<tr>
<th>Campaign Type</th>
<th>Deployment Date</th>
<th>Additional Information</th>
</tr>
</thead>
<tbody>
<tr class='template'>
<td>
<select class="selectType" name='typeInput[0][campType]' id="campInput">
<option value=""></option>
<option value="Main">Main</option>
<option value="Other">Standalone</option>
</select>
</td>
<td>
<input type="text" name='typeInput[0][deliveryDate]' id="dateInput" placeholder='Deployment Date' class="form-control dateControl"/>
</td>
<td>
<textarea name='typeInput[0][addInfo]' id="additionalInput" placeholder='Additional Information' class="form-control noresize"></textarea>
</td>
</tr>
</tbody>
</table>
<a id='add' class="pull-right btn btn-default">Add Row</a>
<a id='delete' class="pull-right btn btn-default">Delete Row</a>
</div>
</div>
</div>
</div>


<div class="form-group">
<div class="row">
<div class="col-md-12">
<div class="col-md-12 noPadding">
<table class="table table-bordered table-hover additionalMargin alignment" id="table4">
<thead>
<tr>
<th>Additional Information</th>
<th>Deployment Date</th>
</tr>
</thead>
<tbody>
<tr class='template4'>
<td>
<textarea name='amendsInput[0][addInfo]' id="additionalInput" placeholder='Additional Information' class="form-control noresize"></textarea>
</td>
<td>
<input type="text" name='amendsInput[0][deliveryDate]' id="dateInput" placeholder='Deployment Date' class="form-control dateControl"/>
</td>
</tr>
</tbody>
</table>
<a id='add4' class="pull-right btn btn-default">Add Row</a>
<a id='delete4' class="pull-right btn btn-default">Delete Row</a>
</div>
</div>
</div>
</div>


One table has 3 inputs, the other has 2. When the add button is pushed on either table, I am cloning the table row, which includes cloning a datepicker.

Things have been going fine but now I have a problem. The second table I end everything with 4 e.g. table4, template4, add4 and delete4. I then duplicated the Javascript from the preious table but added 4 to everything (I duplicated it because this table has different inputs). This resulted in the following code.

$(function() {
initJQueryPlugins();

$('#add').on('click', function() {
$last_row = $('#table1 > tbody > tr').last();
if(!hasValues($last_row)){
alert('You need to insert at least one value in last row before adding');
} else {
add_row($('#table1'));
}
});

$('#delete').on('click', function() { delete_row($('#table1')); });


$('#add4').on('click', function() {
$last_row = $('#table4 > tbody > tr').last();
if(!hasValues4($last_row)){
alert('You need to insert at least one value in last row before adding');
} else {
add_row4($('#table4'));
}
});

$('#delete4').on('click', function() { delete_row4($('#table4')); });
});


function add_row($table) {
var tr_id = $table.find('tr').length - 1;
var $template = $table.find('tr.template');

var $tr = $template.clone().removeClass('template').prop('id', tr_id);

$tr.find(':input').each(function() {
if($(this).hasClass('hasDatepicker')) {
$(this).removeClass('hasDatepicker').removeData('datepicker');
}

var input_id = $(this).prop('id');
input_id = input_id + tr_id;
$(this).prop('id', input_id);

var new_name = $(this).prop('name');
new_name = new_name.replace('[0]', '['+ tr_id +']');
$(this).prop('name', new_name);

$(this).prop('value', '');
});
$table.find('tbody').append($tr);

$(".dateControl", $tr).datepicker({
dateFormat: "dd-mm-yy"
});

$(".selectType", $tr).select2({
tags: true
});
}

function hasValues($row){
$optVal = $row.find('td option:selected').text();
$inputVal = $row.find('td input').val();
$textVal = $row.find('td textarea').val();
if($optVal != "" || $inputVal != "" || $textVal != ""){
return true;
} else {
return false;
}
}

function delete_row($table) {
var curRowIdx = $table.find('tr').length - 1;
if (curRowIdx > 2) {
$("#" + (curRowIdx - 1)).remove();
curRowIdx--;
}
}

function add_row4($table4) {
var tr_id = $table4.find('tr').length - 1;
var $template = $table4.find('tr.template4');

var $tr = $template.clone().removeClass('template4').prop('id', tr_id);

$tr.find(':input').each(function() {
if($(this).hasClass('hasDatepicker')) {
$(this).removeClass('hasDatepicker').removeData('datepicker');
}

var input_id = $(this).prop('id');
input_id = input_id + tr_id;
$(this).prop('id', input_id);

var new_name = $(this).prop('name');
new_name = new_name.replace('[0]', '['+ tr_id +']');
$(this).prop('name', new_name);

$(this).prop('value', '');
});
$table4.find('tbody').append($tr);

$(".dateControl", $tr).datepicker({
dateFormat: "dd-mm-yy"
});
}

function hasValues4($row4){
$inputVal = $row4.find('td input').val();
$textVal = $row4.find('td textarea').val();
if($inputVal != "" || $textVal != ""){
return true;
} else {
return false;
}
}

function delete_row4($table4) {
var curRowIdx = $table4.find('tr').length - 1;
if (curRowIdx > 2) {
$("#" + (curRowIdx - 1)).remove();
curRowIdx--;
}
}

function initJQueryPlugins() {
add_row($('#table1'));
add_row4($('#table4'));
}


I have set up a working FIDDLE
The problem is this. If you start adding a few rows in the first table, this all works fine. After this, add a few rows in the second table. This seems to work fine. However, now start deleting rows in the second table. For some reason it seems to also delete rows in the first table.

So my main question is why does this happen? Additionally, is there any way I can do this without duplicating the code? The second table does not use select2.

Thanks

Answer

You are deleting this:

 $("#" + (curRowIdx - 1)).remove();

This id is also available in the first table, you have to choose a more specified selector

like:

$table4.find("#" + (curRowIdx - 1)).remove();

or better: (comment from K. Bastian above)

$table4.find('tr').last().remove()

I edited your sample here:

https://jsfiddle.net/cLssk6bv/

Here I also deleted the dublicated code, only the different insert method still exist:

https://jsfiddle.net/cLssk6bv/1/

Comments