Dynamically delete each row while append row index - javascript

I'm kind of confused on how to dynamically delete each row while also updating all row index accordingly, instead of row 1,2,3, while deleting 2, the rows should be append into 1,2, not remained 1,3..
jQuery(function(){
jQuery('a.add-author').click(function(event){
var number=document.getElementById("noofinputs").value;
event.preventDefault();
number++;
var newRow = jQuery(
'<tr>'+
'<td><textarea class="txtsize" name="item' +number + '" id="item' +number + '" rows="5" cols="32"></textarea></td>'+
'<td><select name="category' +number + '" id="category' +number + '" style="width:202px;" >'+
<?php
$q3=mysqli_query($con,"select * from categories ORDER BY category ASC");
while ($row3 = mysqli_fetch_assoc($q3)){
?>
'<option value="<?php echo $row3['no']; ?>"><?php echo $row3['category']; ?></option>'+
<?php
}
?>
+'</select></td>'+
'<td>$<input type="text" size="10" name="amount' +number + '" id="amount' +number + '" /></td>'+
'<td><img style="cursor: pointer;" height="24px" width="24px;" src="http://../images/Cancel.png" /> </td>'+
'</tr>');
jQuery('table.authors-list').append(newRow);
$('#noofinputs').val(number);
});
});
$(document).ready(function () {
$(".remove-author").click(function () {
removeRow(this);
});
});
function removeRow(elem){
var i = 0;
var ii = 0;
var iii = 0;
$(elem).closest('tr').remove();
$("table.authors-list tr").not(':first').each(function (){
$('td', this).not(':last').each(function() {
$(this).find('textarea').each(function(){
$(this).attr('name', 'item' + ( i+1 ));
i++;
});
$(this).find('select').each(function(){
$(this).attr('name', 'category' + ( ii+1 ));
ii++;
});
$(this).find('input').each(function(){
$(this).attr('name', 'amount' + ( iii+1 ));
iii++;
});
});
});
var a=document.getElementById("noofinputs").value;
var b = (a - 1);
$('#noofinputs').val(b);
}
I edited the code yet I can't even delete a single row...
I tried to follow this renumber appended table row in javascript after deleting
but it's not working at all...
EDITED: FINALLY it can be deleted and renumber its "number" name attribute after some changes!

Edit: Looks like you need to remove the number from <a href="#" title="" class="remove-author'+number+'">. Just leave it as <a href="#" title="" class="remove-author">.
You also you want to remove the $('.remove-author').each(function(){
jQuery doesn't act on elements that are created dynamically. So you'll want to create a new function and inject it into the <a> element (not the best solution, but it will work without heavily modifying your code)
So your code should be
$(document).ready(function () {
$(".remove-author").click(function () {
removeRow(this);
});
});
function removeRow(elem){
$(elem).closest('tr').remove();
$("table.authors-list tr").each(function (i){
var txt = $(this).find('textarea').attr('name');
$(this).find('textarea').attr('name', txt.replace(/\d+/, i+1));
var sel = $(this).find('select').attr('name');
$(this).find('select').attr('name', sel.replace(/\d+/, i+1));
var amt = $(this).find('input').attr('name');
$(this).find('input').attr('name', amt.replace(/\d+/, i+1));
});
}
now you will want to add this to the <a> element
<a href="#" title="" class="remove-author" click="removeRow(this);">

Related

adding row and then deleting causes duplicate rows

So when I add new rows each row is given an id that increments according the number of rows already added. if I add three rows and then delete the second row, then add another row, now the new row has an id the same as the old third row.
is there an easier way to do this or a loop that i can perform to check for an existing number.
$('body').delegate('.remove', 'click', function() {
$(this).parent().parent().remove();
});
function addnewrow() {
var n = ($('.detail tr').length - 0) + 1;
var tr = '<tr>' +
'<td>' + n + '</td>' +
'<td><select id="drop' + n + '" class="select-service" name="prodService[]"> <
option value = "" > -Choose Service - < /option></select > < /td>'+
'<td id="desc' + n + '"></td>' +
'<td>Delete</td>' +
'</tr>';
Try this way...Put counter outside of the function.
$('body').on("click", '.remove', function() {
$(this).closest("tr").remove();
});
var n = 1;
$('body').on('click', '.add-new-row', function() {
var $tr = $("<tr />");
var $td1 = $("<td />").text(n).appendTo($tr);
var $td2 = $("<td />").append("<select id='drop" + n + "' class='select-service' name='prodService[]' />").appendTo($tr);
var $td3 = $("<td id='desc" + n + "' />").appendTo($tr);
var $td4 = $("<td />").append("<a href='#' class='remove'>Delete</a>").appendTo($tr);
$("table").append($tr);
n++;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="add-new-row">Add New Row</button>
<table></table>
Using jQuery is nice because you can avoid writing these giant element strings, so I've gone ahead and rewritten your addnewrow() function to (hopefully) make it slightly cleaner.
As far as determining the IDs, while I believe what talg123 suggested in the comments would be fine - storing a global variable that just increases by 1 each time you add a new row - I personally try to avoid polluting the global scope where I can.
You can use this line to find the last drop id, and remove the "drop" text from it so you're just left with a number.
$("tr select").last().attr("id").replace("drop", "");
Unfortunately, this will break if there are no rows becuase it won't be able to find any select elements. So, first we have to check if they exist:
+$("tr select").length ? (exists) : (does not exist)
If it doesn't exist, we'll just use 1.
Put that all together, and you've got:
//If select exists Get last ID and remove "drop" from it, and add 1 Else, 1
$("tr select").length ? 1 + +$("tr select").last().attr("id").replace("drop", "") : 1;
$('body').on("click", '.remove', function() {
$(this).closest("tr").remove();
});
$('body').on('click', '.add-new-row', function() {
var nextId = $("tr select").length ? 1 + +$("tr select").last().attr("id").replace("drop", "") : 1;
//Create a new select list
var $selectList = $("<select id='drop" + nextId + "' class='select-service' name='prodService[]' />");
$selectList.append("<option> -Select Service- </option"); //Append option 1
$selectList.append("<option> Another example </option"); //Append option 2
var $tr = $("<tr />"); //Create a new table row
var $td1 = $("<td />").text(nextId).appendTo($tr); //Create first cell. Set text to nextId. Add it to the row.
var $td2 = $("<td />").append($selectList).appendTo($tr); //Create second cell. Add our select list to it. Add it to the row.
var $td3 = $("<td id='desc" + nextId + "' />").appendTo($tr); //Create third cell. Set its id to 'desc{nextId}'. Add it to the row.
var $td4 = $("<td />").append("<a href='#' class='remove'>Delete</a>").appendTo($tr); //Create fourth cell. Add link to it. Add it to the row.
$("table").append($tr); //Add the row to the table
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="add-new-row">Add New Row</button>
<table></table>

external java script "mtree script" not working when element added by jquery dynamically

Here I attach the images where you can see the list of data which show after page load but in all rows but when i add the row using jquery it is not show the data. please check image 2
image first
image 2
This is the link of mtree demo and this is the codepen link
and below is the code that i use to generate row and display mtree.
$(document).ready(function() {
var ite = <?php echo $projectCount; ?>;
$('.btn-row-add').click(function() {
var leaveDays = checkLeaveDays();
console.log(leaveDays);
var ite2 = 1
style = '';
readOnly = '';
if(jQuery.inArray(ite2, leaveDays) !== -1){
style = "style = 'background:#00FF00;'";
readOnly = "readonly='readonly'";
}
var el2 = '<td><input '+style+' '+readOnly+' id="text_'+ite2+'" class="short-textbox" type="text" name="day_'+ite+'[]" value="" onkeyup="sumNewRows(), colsValues(), colsVertical()"></td>';
for(var i=2; i<<?php echo $noOfDays+1; ?>; i++) {
styleInner = '';
readOnlyInner = '';
if(jQuery.inArray(i, leaveDays) !== -1){
styleInner = "style = 'background:#00FF00;'";
readOnlyInner = "readonly='readonly'";
}
el2 = el2 + '<td><input '+styleInner+' '+readOnlyInner+' id="text_'+i+'" class="short-textbox" type="text" name="day_'+ite+'[]" value="" onkeyup="sumNewRows(), colsValues(), colsVertical()"></td>';
}
console.log($('whc-table tbody').html());
var el = '<tr id="data_'+ite+'">\n' +
'<th scope="row">\n' +
'<select class="dropdownlist" data-text-field="name" name="project_name[]" style="width: 300px;">\n' +
'<option value=""></option>\n' +
'</select>\n' +
'\n' +
'</th>\n' +
'<td id="mm-transit">\n' +
'\n' +
'<div class="fake-input">\n' +
'<input value="" name="task_no[]" class="task_list" id="task_list_" type="text" title="Show category list here leter"><img class="show_task" id="show_task" src="<?=base_url()?>images/down.png">\n' +
'\t<div id="cat-list-" class="cat-list"><?php echo $categories_list ?></div>\n' +
'</div>\n' +
'</td>\n' +
el2 +
'\n' +
'<td style="text-align: center;">\n' +
'<input style="width: 35px;" id="text_total_'+ite+'" readonly=\'readonly\' class="short-textbox" type="text" name="total_'+ite+'" value="">\n' +
'</td>\n' +
'</tr>';
ite++;
$(el).appendTo($('#whc-table tbody'));
projectDropdown();
taskDropdown();
initializeMtree();
});
});
Note - same way i used to show mtree in normal rows means rows those are not generated by javascript that is
Try using
$('.btn-row-add').on('click', function() {
instead of
$('.btn-row-add').click(function() {

How to remove a dynamically added div?

This is my HTML
<div class="form-group">
<label>Categories</label>
<button type="button" onclick="createContainer(availableCategories,'','.categoriesWrapper','Categories')" class="btn btn-default">+</button>
<div class="categoriesWrapper">
</div>
</div>
Inside I'm adding more divs with 'child' class with this function:
function createContainer(datasource, selectedItem, wrapper, name) {
var maxFields = 10;
var $container = $('<div style="margin-top:5px;" class="child" />');
var $select = $("<select class='form-control littleSpace' name='" + name + "'/>");
var $button = $("<button type='button' class='delete btn btn-default ' '>-</button>");
if ($(wrapper).children().length < maxFields) {
for (var itemId in datasource) {
//check to see if the option is the selected one
var isItemSelected = selectedItem && selectedItem === itemId;
var $option = null;
//create each option
if (isItemSelected == true) {
$option = $('<option value="' + itemId + '" selected>' + datasource[itemId] + '</option>');
}
else {
$option = $("<option value='" + itemId + "'>" + datasource[itemId] + "</option>");
}
//append option to select
$select.append($option);
}
$container.append($select);
$container.append($button);
$(wrapper).append($container);
}
};
Everything works great until now, but when I try to delete one o those divs and div content...it won't work. This is what I've tried:
$('.categoriesWrapper').on('click', 'delete', function () {
$(this).parent.remove();
});
Please help me
Pass class with . to make it work .delete inside click function as well as per #Rayon noticed change parent to parent()
$('.categoriesWrapper').on('click', '.delete', function () {
$(this).parent().remove();
});

How to implement a simple error with counter jquery

I have some code which adds fields but currently it adds an infinite abouts of boxes. How can I constrain it to only be a max of 10. I ideally want it to alert when I try to add more after 10.
http://jsfiddle.net/spadez/9sX6X/13/
var container = $('.copies'),
value_src = $('#current');
$('.copy_form')
.on('click', '.add', function(){
var value = value_src.val();
var html = '<div class="line">' +
'<input class="accepted" type="text" value="' + value + '" />' +
'<input type="button" value="X" class="remove" />' +
'</div>';
$(html).appendTo(container);
value_src.val('');
})
.on('click', '.remove', function(){
$(this).parents('.line').remove();
});
The code I know:
alert("Only 10 allowed");
The code I had a go at:
var i = 0 // Set counter
i++ // Increment counter
if(i > 10) {
alert("Only 10 allowed");
}
else {
// code to be executed
}
This is one of my first scripts and I wondered if I could get help on the right way to implement this because the code I tried above broke my current working code.
Within your click handler, check if the number of elements with the class line is less than 10.
if ($('.line').length < 10) {
//execute code
}else{
alert('Only 10 allowed');
return false;
}
Fiddle
Rather than embedding 'magic numbers' in your code (see: What is a magic number, and why is it bad?), define a maxFields variable and maintain a count throughout, checking against that value each time another one tries to be added.
This allows your code to be more portable and reusable by someone else, or by you for another use case, when say you want 20 fields.
It also reads more like English (current field is less than max fields) which leads to self documentation.
http://jsfiddle.net/9sX6X/21/
var container = $('.copies'),
value_src = $('#current'),
maxFields = 10,
currentFields = 1;
$('.copy_form').on('click', '.add', function () {
if (currentFields < maxFields) {
var value = value_src.val();
var html = '<div class="line">' +
'<input class="accepted" type="text" value="' + value + '" />' +
'<input type="button" value="X" class="remove" />' +
'</div>';
$(html).appendTo(container);
value_src.val('');
currentFields++;
} else {
alert("You tried to add a field when there are already " + maxFields);
}
})
.on('click', '.remove', function () {
$(this).parents('.line').remove();
currentFields--;
});
From Wikipedia:
The term magic number also refers to the bad programming practice of
using numbers directly in source code without explanation. In most
cases this makes programs harder to read, understand, and maintain.
Although most guides make an exception for the numbers zero and one,
it is a good idea to define all other numbers in code as named
constants.
Here I used the .length method from jQuery.
var container = $('.copies'),
value_src = $('#current');
$('.copy_form')
.on('click', '.add', function(){
if ($('.accepted').length < 10)
{
var value = value_src.val();
var html = '<div class="line">' +
'<input class="accepted" type="text" value="' + value + '" />' +
'<input type="button" value="X" class="remove" />' +
'</div>';
$(html).appendTo(container);
value_src.val('');
}
else
{
alert("Only 10 allowed");
}
})
.on('click', '.remove', function(){
$(this).parents('.line').remove();
});
Fiddle

Counting number of field and limiting to 10

I have some code which uses this to allow to keep the same function code but apply it to different form elements which can be seen on a jsFiddle demo
//latest
var maxFields = 10,
currentFields = 1;
$('.form').on('click', '.add', function () {
var value_src = $(this).prev();
var container = $(this).parent().prev();
if ($.trim(value_src.val()) != '') {
if (currentFields < maxFields) {
var value = value_src.val();
var html = '<div class="line">' +
'<input id="accepted" type="text" value="' + value + '" />' +
'<input type="button" value="X" class="remove" />' +
'</div>';
$(html).appendTo(container);
value_src.val('');
currentFields++;
} else {
alert("You tried to add a field when there are already " + maxFields);
}
} else {
alert("You didn't enter anything");
}
})
.on('click', '.remove', function () {
$(this).parents('.line').remove();
currentFields--;
});
My issue is that I still want to be able to limit each section to only have 10 <inputs>, but at the moment each section shares the counter, so 5 in requirements and 5 in qualifications would trigger the 10 limit.
Is there a nice clean way of keeping the input field counter separate for each section?
What you need to do is store the current number of children for each list in a context sensitive way. There are a couple ways you could structure this (it would be easy using MVC libraries or the likes), but the simplest solution for your code will be to just use the DOM. So instead of using your global currentFields variable, instead use container.children().length to get the number of notes in the list you are currently operating on.
http://jsfiddle.net/9sX6X/70/
//latest
var maxFields = 10;
$('.form').on('click', '.add', function () {
var value_src = $(this).prev();
var container = $(this).parent().prev();
if ($.trim(value_src.val()) != '') {
if (container.children().length < maxFields) {
var value = value_src.val();
var html = '<div class="line">' +
'<input id="accepted" type="text" value="' + value + '" />' +
'<input type="button" value="X" class="remove" />' +
'</div>';
$(html).appendTo(container);
value_src.val('');
} else {
alert("You tried to add a field when there are already " + maxFields);
}
} else {
alert("You didn't enter anything");
}
})
.on('click', '.remove', function () {
$(this).parents('.line').remove();
});
You can add a class to each row like form-row
var html = '<div class="line form-row">' +
'<input id="accepted" type="text" value="' + value + '" />' +
'<input type="button" value="X" class="remove" />' +
'</div>';
and count the length by using
console.log($(container).find('.form-row').length);
// Use +1 because initially it is 0
Fiddle http://jsfiddle.net/9sX6X/69/
You can make use of the placeholder property to identify which button triggered the function.
value_src.attr('placeholder');
This string can then be used to access three different counters in an associative array.
Code
var maxFields = 10;
var currentFields = new Object;
$('.form').on('click', '.add', function () {
var value_src = $(this).prev();
var container = $(this).parent().prev();
if ($.trim(value_src.val()) != '') {
var identity = value_src.attr('placeholder');
if(currentFields[identity] == undefined)
currentFields[identity] = 0;
if (currentFields[identity] < maxFields) {
var value = value_src.val();
var html = '<div class="line">' +
'<input id="accepted" type="text" value="' + value + '" />' +
'<input type="button" value="X" class="remove" />' +
'</div>';
$(html).appendTo(container);
value_src.val('');
currentFields[identity]++;
} else {
alert("You tried to add a field when there are already " + maxFields);
}
} else {
alert("You didn't enter anything");
}
})
.on('click', '.remove', function () {
$(this).parents('.line').remove();
currentFields--;
});
JSFiddle: http://jsfiddle.net/9sX6X/73/

Categories