I have a form which allows the user to add a new table row via a button in the bottom row which all is working well. I now need to also add the functionality to have an additional button to allow them to delete a table row.
I gather the simplest method would be to use:
$(this).closest('tr').remove();
but I'm having trouble integrating this into the existing functionality. I also only need the "delete" button to appear on all rows except the first row (i.e. users can delete all rows except the first one). I've setup a jsfiddle here that demonstrates my current functionality:
http://jsfiddle.net/fmdataweb/daayf/1/
So in my example when the user clicks the "Add another activity" button it should create the new table row as it currently does but also add the "delete" button which deletes that row. I've currently hard-coded the "delete" button to the first row as I'm now sure how to make it appear only for new rows created via the "add new activity" button.
Few changes
In the starting markup, add the classes addbtn and delbtn also hide the delete button
<td>
<input type="button" class="button mt5 addbtn" value="Add another activity" id="button1" name="button2" />
</td>
<td>
<input type="button" class="button mt5 delbtn" value="Delete" id="deleteRowButton" name="deleteRowButton" style="display: none"/>
</td>
Then
$('#lastYear').on('click', '.delbtn', function () {
$(this).closest('tr').remove()
});
var newIDSuffix = 2;
$('#lastYear').on('click', '.addbtn', function () {
var thisRow = $(this).closest('tr')[0];
$(thisRow).find('.delbtn').show();
var cloned = $(thisRow).clone();
cloned.find('input, select').each(function () {
var id = $(this).attr('id');
id = id.substring(0, id.length - 1) + newIDSuffix;
$(this).attr('id', id);
});
cloned.insertAfter(thisRow).find('input:text').val('');
cloned.find('.delbtn').hide();
cloned.find("[id^=lastYearSelect]")
.autocomplete({
source: availableTags,
select: function (e, ui) {
$(e.target).val(ui.item.value);
setDropDown.call($(e.target));
}
}).change(setDropDown);
$(this).remove();
newIDSuffix++;
});
Demo: Fiddle
Check out this one!
if($("table tr").length > 1) {
$(this).parent().parent("tr").remove();
}
Try this
On your Delete Button
$('#lastYear').on('click', '#deleteRowButton', function(e){
$(this).closest('tr').remove()
})
First of all I renamed your Button1 for your Adding a Row to addRowButton and then I change the delegate method to be more specific to addRowButton that is from
$('#lastYear').delegate('input[type="button"]'
To like this:
$('#lastYear')delegate('input[type="button"][id^="addRow"]'
Then inside the delegate method specifically after
$(this).attr('id', id);
I add after that the one below:
var checkid = $(this).attr('id').substring(0,id.length-1);
if (checkid == 'deleteRowButto') // the 'deleteRowButto' is not a mistake
{
$(this).click(function() {
$(this).closest("tr").remove(); // I assign an onclick for the delete button in order to remove a specific row
});
}
Edit:
I made some improvements that once the row is deleted the previous add button is shown so I add the code below:
var showmenow = $(this).closest("tr").prev().find("td:eq(5)").find("input[type='button']");
$(showmenow).show();
$(this).closest("tr").remove();
});
And instead of removing the button in your original code:
$(this).remove();
newIDSuffix++;
I use hide instead:
$(this).hide();
newIDSuffix++;
See the new jsfiddle that I created.
Since you want to use the first row as template for all other row but do not want to have a delete on the all the other rows we should insert the delete only during first insertion in java script.Check this demo out i modified your fiddle for this to work.
if(cloned.find('input.mt5[value="Delete"]').length==0){
cloned.find('.mt5').each(function(){
cloned.append($('<td><input type="button" class="button mt5" value="Delete" id="deleteRow'+newIDSuffix+'" name="deleteRowButton" /></td>'));
})
}
now for handling the delete events
$('#lastYear').delegate('input.button[value="Delete"]', 'click', function () {
var thisrow=$(this).parent().parent();
var button=thisrow.find("input.button[value='Add another activity']");
if(button.length>0){
var buttoncell=button.parent().detach();
var prevrow=thisrow.prev();
var prevDelete=prevrow.find('input.button[value="Delete"]');
var previd=(prevDelete.length>0)?prevDelete[0].id:'deleteRow1';
buttoncell.children()[0].id=previd.replace('deleteRow','button');
prevrow.find('input:text:last').parent().after(buttoncell);
}
thisrow.remove();
});
Demo: http://jsfiddle.net/vwdXD/2/
You have got it right for the most part except for the small oversight here and there. I have fixed your code for you and you can find it here: http://jsfiddle.net/ManojRK/86Nec/ .
Please try to understand the changes by comparing your version and my version using a Code Diff Tool (like http://www.quickdiff.com). It will teach you a lot.
Changes Made:
I have used styles to show and hide your buttons. This is not the only way to do it. But since you are cloning rows to add, using styles will make your JavaScript simple. This is a lot less buggy and less susceptible to changes.
I have introduced css classes to differentiate Add Another Activity and Delete buttons for the click event.
Hope it helps you understand.
I used the jsfiddle that you provided in hopes of being more direct in terms of answering your question. The method I took was to:
Check if the add or delete button was pressed
If the delete button was pressed, check if its the delete button contained within the first row (actually the third row, but it's the first row with user input). If the delete button is in the first row, do nothing
If the delete button was not in the first row, create an 'add activity' button in the previous row and remove the clicked button's parent row.
Step 1:
// let's check whether they clicked the add or delete button
if ( $(this).val() == 'Add another activity' ) { // if the add button was clicked
Step 2-3:
if ( $(thisRow).index() == 2 ) { // if it's the first row, don't let them delete
return false;
} else { // if it is not the first row remove this row and create an 'add' button in first row
$(thisRow).prev().find('td:last').prev().append('<input type="button" class="button mt5" value="Add another activity" id="button2" name="button2">');
$(thisRow).remove();
}
Here's a fiddle for ya: http://jsfiddle.net/daayf/22/
I placed a couple comments in the code to help out a bit. My edits were at:
Line 275-276
Line 300-307
Hope this helps out!
I recommend adding an id attribute dynamically for each row that way you can just refer to that id with jQuery.
You can set a specific class for the buttons like this
<input type="button" class="button mt5 deleteButton" value="Delete" id="deleteRowButton" name="deleteRowButton" />
and add this code to jquery
$('.deleteButton').on('click',function(){
$(this).parent().parent().remove();
});
this jquery deletes the grandparent of the input with deleteButton Class(the delete button), which is the row it is located in.
how about do this?
$(this).find('tr').length > 0 ? $(this).closest('tr').remove() : ;
Why is your "add new activity" and "delete" having the same class "button mt5"? not sure if space is allowed for the name of a class.
You may want to refer to my table here http://jsfiddle.net/yvonnezoe/nbrSR/1/ :D I have a fixed row on top and dynamic rows following that can be deleted.
My new row is created as below:
var str = '<tr id="' + rowID + '">' + '<td>' + index + '</td><td>' + rowID + '</td><td class="type_row_' + textInput + '">' + type + '</td><td class="feedback number">' + textInput + '</td>' + '<td id="status_'+rowID+'"></td>' + '<td><input type="checkbox" name="CB" id="monitor_' + rowID + '" class="custom" data-mini="true" /><label for="CB"> </label></td><td class="outputRemove">x</td>' + '</tr>';
$('#status_table tr:last').after(str);
The remove buttons are having a same class. So the rows can deleted when clicked.
$('#status_table').on('click', '.outputRemove', function () {
$(this).closest('tr').remove();
$('#status_table tbody tr').find('td:first').text(function (index) {
return ++index;
});
});
Hope it inspires you somehow :)
very simple way
function remove_point_item(th) {
var tr = $(th).closest("tr");
var _counter=0;
$(tr.siblings('tr')).each(function(){
_counter++;
});
if(_counter!=1){
tr.remove();
}
}
Related
On my HTML I have buttons list and text input field. Input field is to add extra buttons to my buttons list.
On jQuery I have eventListener when one of these buttons with .choices is clicked console log its value.
It works fine without any errors. But when I add extra button to my list with same class (.choices) new button appears but it doesn't respond to my click.
Any suggestions?
<div class="buttons">
<button id="button0" class="choices">Running</button>
<button id="button1" class="choices">Yoga</button>
<button id="button2" class="choices">Karate</button>
</div>
JS
$("#add-button").click(function(){
var inputValue = $("#add-input").val();
var generatedId = "button" + healthyChoices.length;
healthyChoices.push(inputValue);
$("<button>").attr("id", generatedId).appendTo(".buttons");
$("#" + generatedId).attr("value", inputValue);
$("#" + generatedId).attr("class", "choices");
$("#" + generatedId).text(inputValue);
$("#add-input").val("");
});
$(".choices").click(function(){
var selectedGroup = $(this).val();
console.log(selectedGroup);
});
The .click method does not handle elements dynamically added to the DOM. You should be using the .on method (as indicated by dfsq's comment).
See this SO post: Difference between .on('click') vs .click()
I'm working on making a dynamic HTML table using jQuery. In a table, my user has two interactions:
Append a row
Remove a specific row
The problem with numbering the rows is that if a user removes a specific row, all of the rows following that row need to be renumbered. I would have to select all rows following the removed row and subtract their number by 1.
Is there a better way to go about this?
EDIT: Here's a JSFiddle demonstrating the problem: http://jsfiddle.net/LNXae/2/
I'm aware that an ordered-list would automatically renumber my rows, but I'd rather use a table since the example I'm giving now is pretty boiled-down.
http://jsfiddle.net/mblase75/LNXae/1/
First, wrap the counter number in a <span> with a class for easy finding later:
$new_row.children('td').prepend('Row #<span class="num">' + ($new_row.index() + 1) + "</span>");
Then update all these spans with an .each loop after you remove the desired row. The first argument passed into .each's callback function is a zero-based index number, and the second is the HTML element:
var $row = $(this).closest('tr'),
$table = $row.closest('table');
$row.remove();
$table.find('tr').each(function(i, v) {
$(v).find('span.num').text(i + 1);
});
After the user has appended a row, or deleted one, you just need to iterate over the "number" cells. If we assume that you have a <td> element, we:
1) give them a nice ID, e.g. row_0, row_1, etc...
2) write a function to iterate over them:
function updateRows(){
$('[id*="row_"]').each(function(index){
$(this).html(index + 1); // add +1 to prevent 0 index.
};
};
I have written a jquery plugin which does exactly this, and you shouldnt need to "number" the rows per-se. All you need to do when deleting a row is to pass the index of the row being deleted.
eg, if you have a delete button in a row:
<table>
<tr>
<td> <input type="button" class="delete" value="delete this row" /></td>
</tr>
</table>
The jQuery might look like
$('.delete').click(function(){
var index = $(this).parents('tr').index();
// tell your plugin to delete row "index"
});
The method from my plugin which does this looks something like:
removeRow: function (index) {
return this.each(function () {
var $this = $(this);
var $tbody = $('tbody', $this);
var $tr = $('tr', $tbody).eq(index);
$this.trigger('rowRemoved', [$tr]);
$tr.remove();
});
}
I'm new to jquery scripts. I managed to clone one section of the form dynamically but my button to display the ckeditor's div in the cloned section is not working. It still listening to the button from the original section and will only show the ckeditor's div(but unable to edit all of them except the original) when the original button was clicked. Here is my code:-
for(i=num; i<value; i++){
var newSlot = $('#slot' + i).clone().attr('id','slot' + (i+1));
newSlot.find('.heading-slot').attr('id', 'ID' + (i+1) + '_slot').html('Slot ' + (i+1)); //add new slot name
newSlot.find('.other_message').hide();
newSlot.find('.select_instruction').on('change', function () {
$(this).next('.other_message').toggle((this.value) == "Other")
});
newSlot.find('.extra_instruction').hide();
//the button here is not working as I wanted
newSlot.find('.btnAdditional').on('click', function(){
$(this).next('.extra_instruction').show();
});
$('#slot' + i).after(newSlot);
}
html code
<div class="col-sm-6">
<button type="button" id="btn_Additional" name="btn_Additional" class="btnAdditional btn btn-info">Additional Instruction</button>
<div class="extra_instruction">
<textarea id="input_add_instruction" name="add_instruction[]" class="form-control"></textarea>
<script>CKEDITOR.replace( 'input_add_instruction' );</script>
</div>
</div>
Can anyone guide me on this?? Please I'm very new to this. Thanks in advances..
The clone function not only clones the html but also the event listeners, instead of cloning try creating your element and adding the event listeners properly.
I have a table with Column title. There is also a edit button. If I click the button, Table title should be a Input field with title name as a value in it. Edit button will turn into Save Button.
I can rename the title and Save the new names. I not good in jquery and what I made creating bunch of input fields and I can't save new names. FIDDLE
Any help will save my day. Thanks in advance.
jQuery:
var textInfo = $('.table th').text();
$("html").on('click', '.btn-danger', function() {
$('.table th').append('<input id="attribute" type="text" class="form-control" value="' + textInfo + '" >');
$('.btn-danger').text('Save');
}) ;
Here is a fiddle that solves your problem.
http://jsfiddle.net/has9L9Lh/54/
It uses a common approach of toggling an element's class (or some other attribute), to determine the state of your program. In this case, it determines whether or not the columns are in edit-mode, and changes the button text and th html accordingly.
$("html").on('click', '.btn-danger', function() {
var editMode = $(this).hasClass('edit-mode'),
columns = $('.table th');
if (!editMode){
$(this).html('Save').addClass('edit-mode');
columns.each(function(){
var txt = $(this).text();
var input = $('<input type="text">');
input.val(txt);
$(this).html(input);
});
} else {
$(this).html('Edit').removeClass('edit-mode');
columns.each(function(){
var newName = $(this).find('input').eq(0).val();
$(this).html(newName);
});
}
}) ;
• you should not use id in the append this will create multiple id of the same name.
• use $(".form-control").length to check if it exist. this will solve multiple input when button is clicked multiple times.
• create a new button to submit your change.
• create another click event for the new button.
• than use it $.val() to get input value than pass that value to the new table title. and you are done.
I hope this will point you to the right direction. :D
To be as simple as I can:
I have condition where I do not know where I'm going to have 3 or more input elements (type of "text") and I'm looking for solution which will generate 4th input type text when I start to fill 3th input field with characters, and so on.
Something similar Adminer have for adding new columns when creating/altering database:
here you click on + to add new input and x to remove it. This would also be good to me.
How to achieve that/what library should I use?
You can clone full row, and append it to parent table. Have a look at jQuery clone() and append().
Sample code:
$('#yourtableid').on('click', '.add', function() {
// clone first row
var row = $('#yourtableid tbody tr:first').clone();
// reset inputs
row.find('input[type!=button]').val('');
// append cloned row
$('#yourtableid tbody').append(row);
});
Live DEMO.
EDIT: To add row automatically when filled some text in last row, you can go with:
$('#tbl').on('change', 'input', function() {
// check that some input was entered and that it is in the last tr
if($(this).val() != '' &&
$(this).closest('tr').is(':last-child')) {
addRow();
}
});
It's difficult to tell what you're trying to get without a code sample, but do you want something like this?
HTML:
<input type='text' />
JS:
$('input').on( 'change', function() {
$(this).after( '<input type="text" />' );
$('input').off( 'change' );
});
jsFiddle is down and jsBin can't handle the extra load, but here's a demo.