I want to sum a selected column inside a table. 2nd and 3rd column in my case. I managed to get the sum but I really want to add the value of a row in case a checkbox in column #1 is checked.
I can get the innerHTML value of a cell abut I do not know how to search or find out if the checkbox inside is checked or not.
console.log(cell.innerHTML);
returns for example
"Extend (2x)<input type=\"checkbox\" id=\"Extend2x\" name=\"Extend2x\" class=\"beru\" <=\"\" td=\"\">
so I can see that the checkbox is there but that is where I ended up
I tried
console.log(cell.innerHTML.getElementsByTagName("checkbox"));
console.log(cell.innerHTML.html());
console.log(cell.html());
console.log($(cell).find(':checkbox').checked) returns undefined
but nothing worked.
Could somoone help me to find out? The working fiddle is here You just click the checkbox and summing of the columns will be done.
The code you are looking for is this
$(':checked')
you can add stuff like input:checked, or something to make it more specific.
EDIT--
just saw the comments - and Taplar already answered this. Well this can be considered as alternative answer, and does not need to use cells / iterate through cells of the table.
I think this is what you wanted. This is using jQuery for every reference to elements in the the dom (html).
$(".beru").on('change', function() {
updateTotals();
});
function updateTotals() {
// loop cells with class 'celkem'
$('.celkem').each(function(){
// for each celkem, get the column
const column = $(this).index();
let total = 0;
// loop trough all table rows, except the header and the row of totals
$(this).closest('table').find('tr:not(:first, :last)').each(function(){
if($(this).find('input').is(':checked')) {
// if the input is checked, add the numeric part to the total
const str = $(this).find(`td:eq(${column})`).text().replace(/\D/g, "");
if(str) {
total += Number(str);
}
}
});
if(!total) {
// if the total is zero, clear the cell
$(this).text("");
} else {
// otherwise, print the total for this column in the cell
$(this).text(total + " EUR");
}
});
}
td {
width: 25%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="Zinzino" style="border-collapse: collapse; width: 100%;" border="1">
<tbody>
<tr>
<th><strong>Název</strong></th>
<th class="sum"><strong>První balíček</strong></th>
<th class="sum"><strong>Měsíčně</strong></th>
<th> </th>
</tr>
<tr>
<td>BalanceOil <input type="checkbox" id="BalanceOil" name="BalanceOil" class="beru"></td>
<td>149 EUR</td>
<td>30 EUR</td>
<td> </td>
</tr>
<tr>
<td>Extend (2x)<input type="checkbox" id="Extend2x" name="Extend2x" class="beru"</td>
<td>44 EUR</td>
<td>22 EUR</td>
<td> </td>
</tr>
<tr>
<td>Zinobiotic (3x)<input type="checkbox" id="Zinobiotic" name="Zinobiotic" class="beru"</td>
<td>64 EUR</td>
<td>23 EUR</td>
<td> </td>
</tr>
<tr>
<td><strong>Celkem</strong></td>
<td class="celkem"> </td>
<td class="celkem"> </td>
<td> </td>
</tr>
</tbody>
</table>
If you already have a reference to the DOM element then just select all the checkboxes using a selector.
var cbList = cell.querySelectorAll("[type='checkbox']");
for(var i = 0; i < cbList.length; i++){
//do something with each checkbox
//cbList[i];
}
Remember a node list is not an array, so you can't use forEach ;)
Related
I'm trying to do the following: I have a table populated with data from the DB. Apart from that, I have an input where you can write something and a button that will filter, only showing the lines that have that string. This is working now!
The thing is, the input should only allow you to filter by foo.name/foo.code (two propertys of my entity).
I'm adding the code I have in case anyone can guide me out, I've tried several things but this are my first experiences with JQuery while I have a strict story-delivery time. Thanks everyone!
<tbody>
<c:forEach var="foo" items="${foo}">
<tr id = "fooInformation" class="mtrow">
<th id="fooName" scope="row">${foo.name}</th>
<td id="fooCode" class="left-align-text">${foo.code}</td>
<td class="left-align-text">${foo.country}</td>
<td class="left-align-text">${foo.region}</td>
<td class="left-align-text">${foo.subregion}</td>
</tr>
</c:forEach>
</tbody>
$("#search").click(function () { -> button id
var value = $("#fooRegionSearch").val(); -> value of the input
var rows = $("#fooRegionTable").find("tr"); -> table id
rows.hide();
rows.filter(":contains('" + value + "')").show();
});
To start with, your HTML is invalid - there cannot be elemenets with duplicate IDs in HTML. Use classes instead of IDs.
Then, you need to identify which TRs pass the test. .filter can accept a callback, so pass it a function which, given a TR, selects its fooName and fooCode children which contain the value using the :contains jQuery selector:
$("#search").click(function() {
var value = $("#fooRegionSearch").val();
var rows = $("#fooRegionTable").find("tr");
rows.hide();
rows.filter(
(_, row) => $(row).find('.fooName, .fooCode').filter(`:contains('${value}')`).length
).show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="fooRegionTable">
<tr id="fooInformation" class="mtrow">
<th class="fooName" scope="row">name1</th>
<td class="fooCode" class="left-align-text">code1</td>
<td class="left-align-text">${foo.country}</td>
<td class="left-align-text">${foo.region}</td>
<td class="left-align-text">${foo.subregion}</td>
</tr>
<tr id="fooInformation" class="mtrow">
<th class="fooName" scope="row">name2</th>
<td class="fooCode" class="left-align-text">code2</td>
<td class="left-align-text">${foo.country}</td>
<td class="left-align-text">${foo.region}</td>
<td class="left-align-text">${foo.subregion}</td>
</tr>
</table>
<button id="search">click</button><input id="fooRegionSearch" />
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/
I am trying to check multiple checkboxes using one with jQuery. I know how to do this to check all checkboxes or to check multiple if they have ids. I want to be able to do this without that though.
All of my checkboxes are in a similar grouping. I have them grouped in a consistant way.
I have my work on a fiddle here.
Here is my code
window.onCheck = function () {
var totals = [0, 0, 0];
$('tr.checkRow').each(function () {
var $row = $(this);
if ($row.children('td:first').find('input:checkbox').prop('checked')) {
$(this).find('td.imageBox').each(function (index) {
var $imageBox = $(this);
if ($imageBox.children('img:first').attr('src').indexOf('yes') >= 0) {
++(totals[index]);
}
});
}
});
$('#total1').text(totals[0]);
$('#total2').text(totals[1]);
$('#total3').text(totals[2]);
};
window.onCheckForm = function (cb) {
var $cb = $(cb);
var $table = $cb.parents("table");
$('input.subFieldCheck').find($table).prop('checked', function () { return cb.prop('checked')});
}
My problem is with the onCheckForm function.
Thank you.
Note: I started writing this answer for a duplicate of this question and realized I couldn't post this, so I posted it here instead. The table structure is different and a lot simplified in this answer.
Lets start off with a very simple table with a checkbox column:
<table>
<thead>
<tr>
<th scope='col' id='toggler'>
<input type='checkbox' id='toggleAll'>
<label for='toggleAll'>Select all</label>
</th>
<th scope='col'>A column</th>
</tr>
</thead>
<tbody>
<tr>
<td headers='toggler'>
<input type='checkbox'>
</td>
<td>some cell data</td>
</tr>
<tr>
<td headers='toggler'>
<input type='checkbox'>
</td>
<td>some cell data</td>
</tr>
<tr>
<td headers='toggler'>
<input type='checkbox'>
</td>
<td>some cell data</td>
</tr>
<tr>
<td headers='toggler'>
<input type='checkbox'>
</td>
<td>some cell data</td>
</tr>
<tr>
<td headers='toggler'>
<input type='checkbox'>
</td>
<td>some cell data</td>
</tr>
</tbody>
</table>
Here, I have a checkbox in the header along with a label for accessibility purposes (you may hide the label if you wish).
I've also given the header cell an ID and used the headers attribute for the td elements. This isn't absolutely necessary for what we're doing, however it seems like an appropriate case to use the headers attribute. If you ever want to move the checkbox to another column for certain rows, you can just add the headers attribute to that cell.
Here is some JavaScript code:
$('#toggleAll').change(function () {
$('td[headers~="toggler"] > input[type="checkbox"]').prop('checked', $(this).prop('checked'));
});
We are binding a function to the change event to the checkbox in the header.
The selector will look for all checkboxes that are children of td elements that contain the ID toggler in a space-separated list of tokens in the headers attribute.
The .prop() method sets the checked property of the checkboxes to match the value of the checked property of the one in the header ("this").
Our basic functionality is done here.
We can make improvements though, by changing the state of the checkbox at the top to match the state of the checkboxes in the rows.
The state of the header checkbox should be:
Unchecked if 0 are checked
Interdetermine if (0, n) are checked
Checked if n are checked
Where n indicates all the checkboxes.
To do this, we bind a function to the change event of each of the boxes in the table rows:
$('td[headers~="toggler"] > input[type="checkbox"]').change(function() {
var allChecked = true, noneChecked = true;
var headerCheckbox = $('#toggleAll');
$('td[headers~="toggler"] > input[type="checkbox"]').each(function(i, domElement) {
if(domElement.checked) {
// at least one is checked
noneChecked = false;
} else {
// at least one is unchecked
allChecked = false;
}
});
if(allChecked) {
headerCheckbox.prop('checked', true);
headerCheckbox.prop('indeterminate', false);
} else if (noneChecked) {
headerCheckbox.prop('checked', false);
headerCheckbox.prop('indeterminate', false);
} else {
headerCheckbox.prop('indeterminate', true);
}
});
I'm using .each() here to loop through all of the appropriate checkboxes to determine whether all, none, or some are checked.
See the jsFiddle demo.
Hope this helps, I sure learned quite a bit while answering the question!
See this fiddle for a cleaner way:
http://jsfiddle.net/W75dy/19/
<td class="field">
<form class="fieldCheck">
<input type="checkbox" id="Row1Chk" name="Row1" value="Row1" />
</form> Programs
</td>
$('#Row1Chk').on('change', function(event) {
$('table.checkTable input[type=checkbox]').prop('checked', $(this).prop('checked'));
});
I have a pretty basic table at the moment:
I need to be able to only hightlight one row in each column, and deselect whatever was selected before it..
I understand I'm going to need a CSS class, e.g.
.hightlighted {
background: #f00;
color: #fff;
}
The HTML in the view is pretty basic also:
<tbody>
<tr>
<td> </td>
<td>Differdange</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td>Dippach</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td>Dudelange</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td>Echternach</td>
<td></td>
</tr>
<tr>
<td> </td>
<td>Erpelscheid</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td>Esch-sur-Alzette</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td>Esch-sur-Sûre</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td>Ettelbruck</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td>Feulen</td>
<td> </td>
</tr>
</tbody
But I don't know whether it's appropriate to highlight/unhighlight rows in CSS if I am going to be needing to 'grab' the selected data from the rows when the table is completed by the user?
Can anyone suggest what I should use (JQuery, Javascript, CSS) to highlight a row in a column so that I can get the data later?
EDIT
Now I've got the highlighting sorted, the only problem I'm having is differentiating between columns so that instead of this (which I'm getting atm)
I want each columns to be able to have it's own unique row highlighted (e.g. Differdange could be highlighted, as well as dddd on Localities)
Any way to edit the
$("tr").click(function() {
$("tr").removeClass("highlighted");
$(this).addClass("highlighted");
});
code to do this? Thanks
You can use the .removeClass() and .addClass() jQuery methods to achieve this. Here's a little demo: little link. The code is pretty self-explaining, but here's a commented version of the JavaScript part:
var chosen = []; //an array to save the chosen row for each column
$("td").click(function() { //when a td is clicked
var idx = $(this).index() + 1; //get column of current cell
$("td:nth-child(" + idx + ")").removeClass("highlighted"); //unhighlight all cells in column
$(this).addClass("highlighted"); //highlight this one
chosen[idx] = $(this).parent("tr").index(); //and save it as chosen in its column
});
............................
Demo
Hi now you can do this jquery as like this
Css
.hightlighted{
background: #f00;
color: #fff;
}
jquery
$("tr").click(function(){
$("tr").removeClass('hightlighted')
$(this).addClass('hightlighted');
});
Could you be more precise on when and how the selection should be made? I'm guessing you want the user to click on a row, which then gets highlighted. In that case you'd want to create a highlight class in css, add it to the row the user clicked on and later you can get the row cia its class:
tr.highlighted td {
background: #f0;
color: #fff;
}
And in the javascript:
// catch click event
$('tr').click(function (e) {
// remove prvious selection
$('tr.highlighted').removeClass('highlighted');
// make this row selected
$(e.currentTarget).addClass('highlighted');
});
// get current selection
function getSelected () {
return $('tr.highlighted');
}
I have been working on this and cannot get this iterator to work. I have the following HTML and am trying to iterate through all rows (except the first row) and extract the values in cells (td) 2 and 3 :
<div id="statsId">
<table width="220" cellspacing="0" cellpadding="0" border="0">
<tbody>
<tr>
<td width="65"/>
<td width="90"/>
<td width="65"/>
</tr>
<tr style="font-weight: bold;">
<td align="left">$1.00</td>
<td>
UserID1
</td>
<td>Single</td>
</tr>
<tr>
<td align="left">$6.99</td>
<td>
UserID2
</td>
<td>Multiple</td>
</tr>
<tr>...
.....(snip)
I tried the following iterator to iterate through all except the first row of the table that is a child of "div#statsID" and get the values of the 2nd and 3rd cells (in the example, the first extracted cells would have values of "UserID1" and "Single"), but it doesn't work.
$('div#statsId > table tr:not(:nth-child(1))').each(function(i, ele) {
var secondCol = $('td:nth-child(2)', ele).innerHTML
var thirdCol= $('td:nth-child(3)', ele).text()
.....
});
Any suggestions on how to specify and iterate through the rows (except the first) of a table that is a child of a div would be appreciated.
$("#statsId > table tbody tr:not(:first)").each ( function() {
var secondCol = $(this).find('td:nth-child(2)').html();
var thirdCol= $(this).find('td:nth-child(3)').text();
});
Note
You can use the id selector independently. No need to use the tag name.
There is no innerHTML for a jQuery object. Use html() instead