I have a table that has plus or minus glyph-icons at the top that allow the user to add or subtract rows. The code I have works but if the user clicks the minus button too many times it will eat the whole table.
What I have tried is to add an unique ID tag to the rows I add and only delete the TRs with the ID but if 2 rows are added and the minus is pressed both rows will be deleted at once, I only want to delete one row at a time. Note: the code below does not reflect this attempt.
Glyphicons:
<div class="well" style="margin-bottom:0px;" id="addrow">
<span class="glyphicon glyphicon-plus" id="add"></span>
<span class="glyphicon glyphicon-minus" id="minus"></span>
Table:
<table class="table table-bordered table-striped" style="margin-bottom:0px;" id="myTable">
<tr>
<td>Customer Master #</td>
</tr>
<tr>
<td><input type="text" class="form-control" ></td>
</tr>
</table>
JS:
$(document).ready(function(){
$("#addrow").on("click", "span#add", function(){
var tablerow = '<tr><td><input type="text" class="form-control" ></td></tr>'
$("#myTable tr:last").after(tablerow);
})
$("#addrow").on("click", "span#minus", function(){
$('#myTable tr:last').remove();
} )
});
Not sure 100% you want changed with your code, but here is a fiddle which adds or removes - but will not remove the first row (won't eat the whole table).
http://jsfiddle.net/HR5se/
$('#myTable tr .form-control').size()
Will give you how many data (input) rows there are. In this fiddle, I check to see if there's greater than one data row, and if not, the remove doesn't happen.
Note: I turned your glyphs into "+" and "-" text so I could see them here.
See if changing the onclick event to mouseup has any effect. I had a similar problem a while back.
I added an if statement to only allow a row to be taken out if the table has 3 or more rows. This preserves the last two rows that I always want to be on the page.
if ($('#myTable tr').length > 2)
This seemed to solve the problem.
Full code:
$("#addrow").on("click", "span#minus", function(){
if ($('#myTable tr').length > 2) {
$('#myTable tr:last').remove();
};
} )
Related
Please consider the following code:
CODE:
$(document).on("click", "#add_new_item_ingredient", function() {
$(this).siblings("#ingredients_table").append('<tr><td style="width:20%"> <input type="text" id="option_item_costs_2" class="form-control" placeholder="£2.50"> </td><td style="width:50%"> <input type="text" id="option_item_desc_2" class="form-control" placeholder="Ex. Extra tomato"> <input type="hidden" id="option_item_id_2" value="-1"> </td></tr>');
});
$(document).on("click", "#remove_new_item_ingredient", function() {
$(this).siblings("#ingredients_table tr").each(function(index) {
alert("!");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-striped notifications" id="ingredients_table">
<tbody>
<tr>..</tr>
<tr>..</tr>
<tr>..</tr>
</tbody>
</table>
<button class="btn_1" id="add_new_item_ingredient">+ Ingredient</button>
<button class="btn_1" style="background:#C70000;" id="remove_new_item_ingredient">- Ingredient</button>
Adding new rows with the first button works great, however when I attempt to remove the last tr element from the same table, it does nothing. I am now attempting to alert, for each tr element found, but I get no alerts. I have tried getting the table row count which always returns 0, and also attempted trying to get the element with #ingredients_table >tbody >tr
I can confirm that both of the click events are firing correctly, and I can correctly select the table element, just none of the rows within.
Any advise would be greatly appreciated.
It's because the button #remove_new_item_ingredienthas no tr siblings.
You either select the table first and then use find to get the tr's:
$(this).siblings("#ingredients_table").find("tr").each(function(index) {
or use the:
$("#ingredients_table tr").each(function(index) {
which is better in redability.
And as #T.J.Crowder mentioned:
You have two tbody elements in your table (neither of them closed, probably a typo)
You're appending the rows to the table, not the tbody
Remove's handler $.siblings looks for tr elements on the same level as button, which is not the case. trs are in table, that is 2 levels down. So just modify your call to $(this).siblings("#ingredients_table").find('tr')
I have a table & in each TR if I click the icon a new TR is appended to the end.
TR also has a row_seperator class. I want this row_seperator to be removed from previous all newly appended rows but remain in the last appended row TR.
$(this).closest('tr').removeClass("row_seperator") ;
$('.new_row').removeClass('row_seperator').removeClass('new_row');
$('<tr class="row_seperator new_row"><td colspan="8">new td</td></tr>').insertAfter($(this).closest('tr'));
As shown below in the image. I want these two crossed lines to disappear & the last line to remain. So that each section has a line to separate it from other sections.
I suppose this refers to the icon clicked. In which case $(this).closest('tr') will be always the TR with "Section-A" (or -B, -C, depending on which icon was clicked). And this means that each new TR will be inserted above the previous TRs, so it will be always the first new TR that must have the row_separator class.
If all what I supposed is correct, I would simply check if $(this).closest('tr').hasClass('row_separator'), and if so, I would call removeClass on it and addClass on the new element (or include the class in the string as you did). If not, I would do neither.
If - on the other hand - you would like to insert new TRs after the previous new TRs, you can add some distinctive class to the TRs having the icon and call $(this).closest('tr').nextUntil('distinctive_class').last().after(newTr);
Also be aware that if you have added some new TRs after Section-A, B and C and call $('.new_row').removeClass('new_row'); it will remove class from every .new_row not only from the ones after the TR of the icon clicked.
<table class="authors-list">
<tr class="row_seperator">
<td>Column 1</td>
<td>Column 2</td>
</tr>
<tr class="row_seperator">
<td><input type="text" name="first_name" /></td>
<td><input type="text" name="last_name" /></td>
</tr>
</table>
Add
// Jquery Code
var counter = 1;
$('a.add-author').click(function(event){
event.preventDefault();
counter++;
$(".authors-list tr").addClass("row_seperator");
var newRow = jQuery('<tr><td><input type="text" name="first_name' +
counter + '"/></td><td><input type="text" name="last_name' +
counter + '"/></td></tr>');
$('table.authors-list').append(newRow);
});
Working Fiddle http://jsfiddle.net/yUfhL/1097/
JSFiddle: https://jsfiddle.net/dxhen3ve/4/
Hey guys,
I've been trying to figure out the issue here for some time.
Essentially, I have a table with rows. You can add new rows (works fine). However, on the deletion of rows, I would like to re-number all of the rows below it (including all of their input names/ids within).
This works fine as I have it on the first time you click "remove" for any row.. say, if you have rows 0-4 and delete row 1, you will now have rows 0-3 and they will be numbered correctly--however, after that if you click remove again on another row, the numbers do not update
The indexes are getting mixed up some how and it almost seems like it's not recognizing that I've removed an element from the DOM.. when I console.log the indexes everything looks fine.
As an example:
- Add 5 rows (0-4)
- Remove row #1 (the rows below get updated as they should).
- Remove the new row #1, and you will see that row #2 takes its place instead of changing to row #1.
- In the function 'renumber_budget_rows', the if statement seems to get skipped for that row #2, even though I feel like it should meet the conditions (and is present if I console.log(item)
What am I missing? https://jsfiddle.net/dxhen3ve/4/
** Update: Just wanted to update that I have a true resolution that works, which is great! However, I am more interested in knowing WHY my solution is failing. At the moment, the best I have, from the correct answer, was that my indexes were misaligned. I'm going to take a new look at them.
HTML
<script type="text/template" id="budget_row-template">
<tr id="budget_row-{{index}}" class="budget-row" data-budget-index="{{index}}">
<td class="budget-line">{{index}}</td>
<td><input type="text" name="budget_description-{{index}}" id="budget_description-{{index}}" class="budget-description" /></td>
<td><input type="text" name="budget_amount-{{index}}" id="budget_amount-{{index}}" class="budget-amount" /></td>
<td>
<select name="budget_costcode-{{index}}" id="budget_costcode-{{index}}" class="budget-costcode">
<option>-- Select Cost Code</option>
</select>
</td>
<td><i class="fa fa-share"></i></td>
<td>remove</td>
</tr>
</script>
<div class="table-scroll-container">
<table class="table table-striped table-bordered table-hover tablesorter" id="budget-display">
<thead>
<tr>
<th>Line #</th>
<th>Description</th>
<th>Amount</th>
<th>Cost Code</th>
<th data-sorter="false"></th>
<th data-sorter="false"></th>
</tr>
</thead>
<tbody id="test">
<tr id="budget_row-0" class="budget-row" data-budget-index="0">
<td class="budget-line">0</td>
<td><input type="text" name="budget_description-0" id="budget_description-0" class="budget-description" /></td>
<td><input type="text" name="budget_amount-0" id="budget_amount-0" class="budget-amount" /></td>
<td>
<select name="budget_costcode-0" id="budget_costcode-0" class="budget-costcode">
<option>-- Select Cost Code</option>
</select>
</td>
<td><i class="fa fa-share"></i></td>
<td></td>
</tr>
</tbody>
</table>
</div>
<div class="text-align-center">
<i class="icon icon-plus icon-white"></i> Add Line Item<br />
</div>
JS
function renumber_budget_rows(removed) {
$('#budget-display tbody .budget-row').each(function(indite, item) {
var ti = $(item).data('budget-index');
if( ti > removed ) {
ti--;
//console.log(item);
$(item).attr('id', 'budget_row-'+ti);
$(item).attr('data-budget-index', ti);
$(item).find('.budget-line').html(ti);
$(item).find('.budget-description').attr({ 'name': 'budget-description-'+ti, 'id': 'budget-description-'+ti });
$(item).find('.budget-amount').attr({ 'name': 'budget-amount-'+ti, 'id': 'budget-amount-'+ti });
$(item).find('.budget-costcode').attr({ 'name': 'budget-costcode-'+ti, 'id': 'budget-costcode-'+ti });
$(item).find('.add-budget-child').attr({ 'id': 'budget_row-addparent-'+ti, 'data-budget-index': ti });
$(item).find('.trash-budget-row').attr({ 'id': 'budget_row-'+ti+'-trash' });
$(item).find('.trash-budget-row').attr('data-budget-index', ti);
}
});
}
var budget_index = 0;
$('.add-budget-row').click(function(e) {
budget_index++;
e.preventDefault();
var budget_html = $('#budget_row-template').html();
budget_html = budget_html.replace(/{{index}}/g, budget_index);
$('#budget-display tbody').append(budget_html);
});
$('#budget-display').on('click', '.trash-budget-row', function(e) {
var removed = $(this).data('budget-index');
$(this).closest('tr').remove();
console.log(removed);
renumber_budget_rows(removed);
budget_index--;
});
While you are deleting the row, after a row deletion, you can iterate through every tr using .each() function and change the attributes based on the index i value.
$('#budget-display').on('click', '.trash-budget-row', function(e) {
var removed = $(this).data('budget-index');
$(this).closest('tr').remove();
$('tbody tr').each(function(i){
$(this).find('td').eq(0).text(i);
$(this).attr("data-budget-index",i);
$(this).attr("id","budget-row-" + i);
});
budget_index--;
});
Working example : https://jsfiddle.net/DinoMyte/dxhen3ve/5/
<table id="linkedin_match">
<tr>
<th>Name</th>
<th>Location</th>
<th>Industry</th>
<th>Company</th>
<th>Position</th>
<th> </th>
<th> </th>
</tr>
<tr>
<td>Moses Gonzales</td>
<td>Greater Seattle Area</td>
<td>Chemicals</td>
<td>Superior Grocers</td>
<td>WC Claim Manager</td>
<td>Invite</td>
<td><input type="checkbox" id="match"/></td>
</tr>
<tr>
<td>Moses Gonzales</td>
<td>Greater Seattle Area</td>
<td>Chemicals</td>
<td>Superior Grocers</td>
<td>WC Claim Manager</td>
<td>Invite</td>
<td><input type="checkbox" id="match"/></td>
</tr>
</table>
With the table above, how would I perform the logic, such that if the checkbox is selected, the other rows will hide? The rows are not limited to just two. It could be five, it could be ten, it can be just one. Currently my code is :
$('document').ready(function() {
var tr = $('#linkedin_match tr');
});
Now I don't know what to do with the tr. I'm kinda new to JS too. Thanks.
You can do this way. ids must be unique so change match as class name.
$(document).ready(function() {
$('#linkedin_match .match').change(function(){ //bind change event to the checkboxes
var $this = $(this);
$('#linkedin_match').find('tr:gt(0)').not($this.closest('tr')).toggle();
//since all trs are visible you can use toggle to toggle all the trs but not the one that is a parent of this.
//And un checking will bring all of them back to visible state.
});
});
Fiddle
if you have no control over changing the id to class or add a class, then you can target the checkbox
$('#linkedin_match :checkbox').change(function(){...});
gt(0) - To select the rows with index greater than 0. i.e to avoid the first one.
closest('tr') - To get the parent tr of the checked element.
not($this.closest('tr')) - To add a filter. i.e to exclude the current row.
toggle() - To toggle the element's state.
Add a checkbox
<input type="checkbox" class="check"> Check me
then invoke jquery toggle
$('.check').click(function(){
$('td.hide').toggle();
});
Fiddle: http://jsfiddle.net/webbymatt/DLxjR/
P.s. in my example I have put a class on the cell I want to hide, this could also be applied to entire rows. In this case:
<td class="hide">WC Claim Manager</td>
First off you shouldn't have two elements with the same id. change those to classes and you could do the following:
$(document).on('click', '.match', function(){
if ($(this).is(':checked')) {
$('.match').closest('tr').hide();
$(this).closest('tr').show();
} else { $('.match').closest('tr').show(); }
});
This solution will show all rows with a checkbox when a box is unchecked, and only show the relevant row when the checkbox is checked.
Scenario:
I'm using datatable library to display alot of information. That table have the following rows:
Id Type Name Case
What I'm looking for is that when I click the second row Type, that value will be taking and pasted in a textbox
Example
Id Type Name Case
1 text Juan 20001
3 List Pedro 20005
If I click the row that has the id # 1, I need to take the Type innerHTML. Does not matter what apart of the row I click just take the second td's html.
I tried with this code:
$("tr td").click(function () {
alert($(this).html());
})
It worked great, But the problem is that the user have to click exactly the row Name, but would be better if user can click over any of the row and just take the second rows html.
Suggesstions?
myRow.getElementsByClassName('td')[1].innerHTML
should get you the innerHTML of the second table cell of myRow as long as the first table cell does not contain a nested table.
You might try adding the click handler to the rows instead of to the cells too.
Try using eq()
but would be better if user can click over any of the row and just
take the second rows html.
$("tr td").click(function () {
secondrow = $(this).closest('tr').siblings().eq(1);
});
If i click the row that has the id # 1, i need to take the Type
innerHTML. Does not matter what apart of the row i click just take the
second td's html.
$("tr td").click(function () {
secondTd = $(this).siblings().eq(1);
alert(secondTd.html());
});
Try this
$(function () {
$("#thetable tr").click(function () {
if ($(this).index() == 0) return;
$('#tbox').val($('td:nth-child(2)', $(this)).html())
})
});
HTML
<table border="1" cellpadding="4" id="thetable">
<tr>
<td>Id</td>
<td>Type</td>
<td>Three</td>
<td>Four</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
</tr>
</table><br />
<input type="text" name="tbox" id="tbox" />
It method takes into account the first row that contains only labels and doesn't set the textbox value to a label if top row is clicked.