how to highlight row on mouse click? - javascript

I have a table with rows of data. I am able to highlight the table when the checkbox is checked. I would like to enable the highlight and enable the checkbox on a mouse click over the table. the problem with my code now is that when I click on the check box its triggers the event for the mouse click to as the check box is part of the <tr> how can I fix this.
$('.form-check-input').on('click', function() {
if ($(this).is(':checked')) {
$(this).closest("tr").addClass("rowColor");
} else {
$(this).closest("tr").removeClass("rowColor");
}
});
$('#table1 tbody tr').on('click', function() {
//$(this).find(".form-check-input").checked = true;
var checkBox = $(this).find(".form-check-input");
if (checkBox.is(':checked')) {
checkBox.attr("checked", false);
$(this).removeClass("rowColor");
} else {
checkBox.attr("checked", true);
$(this).addClass("rowColor");
}
});
.rowColor {
background-color: #dfecf6;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table1" class="table table-striped">
//thead
<tbody>
<tr class="">
<td></td>
<td class="checkboxtd"><input class="form-check-input" type="checkbox" value="" id=""></td>
</tr>
</tbody>
<table>

Issue with above code is when checkbox clicked it also trigger parent element click event. you can stop that by calling stopPropagation() for event. here is updated code
$('.form-check-input').on('click', function(e) {
e.stopPropagation();
if ($(this).is(':checked')) {
$(this).closest("tr").addClass("rowColor");
} else {
$(this).closest("tr").removeClass("rowColor");
}
});
$('#table1 tbody tr').on('click', function() {
$('.form-check-input').trigger("click");
return;
});
.rowColor {
background-color: #dfecf6;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table1" class="table table-striped">
//thead
<tbody>
<tr class="">
<td>test</td>
<td class="checkboxtd"><input class="form-check-input" type="checkbox" value="" id=""></td>
</tr>
</tbody>
<table>

You had two events overlap each other because the checkbox click was bubbling to the tr click. I added e.stopPropagation(); to keep it from happening.
$('.form-check-input').on('click', function(e) {
e.stopPropagation();
if ($(this).is(':checked')) {
$(this).closest("tr").addClass("rowColor");
} else {
$(this).closest("tr").removeClass("rowColor");
}
});
$('#table1 tbody tr').on('click', function() {
//$(this).find(".form-check-input").checked = true;
var checkBox = $(this).find(".form-check-input");
if (checkBox.is(':checked')) {
checkBox.attr("checked", false);
$(this).removeClass("rowColor");
} else {
checkBox.attr("checked", true);
$(this).addClass("rowColor");
}
});
table {
width: 100%
}
.rowColor {
background-color: #dfecf6;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table1" class="table table-striped">
//thead
<tbody>
<tr>
<td>&nbsp</td>
<td class="checkboxtd">
<input class="form-check-input" type="checkbox" value="" id="">
</td>
</tr>
</tbody>
</table>

First of all some other this about your code:
you should use checkBox.prop("checked", false); and not .attr to set the current state of the checkbox.
you normally want to listen to the change (or input) event on an input element if you want to get notified about a change a click. A checkbox could also be checked/unchecked by using other input devices like a keyboard.
To your problem, there are different ways of targeting the problem.
My first and highly suggested solution would be to rewrite the logic of your code: I would go with only changing the checked state of the checkbox in the tr event handler and then trigger the change event on the checkbox.
$('.form-check-input').on('change', function(e) {
if ($(this).is(':checked')) {
$(this).closest("tr").addClass("rowColor");
} else {
$(this).closest("tr").removeClass("rowColor");
}
});
$('#table1 tbody tr').on('click', function(e) {
var checkBox = $(this).find(".form-check-input");
if (!$(e.target).is(checkBox)) {
// toggle the check state
checkBox.prop("checked", !checkBox.is(':checked'));
// trigger the change event
checkBox.trigger("change")
}
});
.rowColor {
background-color: #dfecf6;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table1" class="table table-striped">
//thead
<tbody>
<tr class="">
<td></td>
<td class="checkboxtd"><input class="form-check-input" type="checkbox" value="" id=""></td>
</tr>
</tbody>
<table>
If you really want to keep your code that way - which I won't suggest due to the above-mentioned reason - you could go with the way to prevent the propagation of the event in the click event handler of the input element, that way it won't reach the tr element.
$('.form-check-input').on('click', function(e) {
e.stopPropagation()
if ($(this).is(':checked')) {
$(this).closest("tr").addClass("rowColor");
} else {
$(this).closest("tr").removeClass("rowColor");
}
});
$('#table1 tbody tr').on('click', function(e) {
//$(this).find(".form-check-input").checked = true;
var checkBox = $(this).find(".form-check-input");
if (checkBox.is(':checked')) {
checkBox.prop("checked", false);
$(this).removeClass("rowColor");
} else {
checkBox.prop("checked", true);
$(this).addClass("rowColor");
}
});
.rowColor {
background-color: #dfecf6;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table1" class="table table-striped">
//thead
<tbody>
<tr class="">
<td></td>
<td class="checkboxtd"><input class="form-check-input" type="checkbox" value="" id=""></td>
</tr>
</tbody>
<table>
The other way would be to check in the event handler of the tr element if the click event originated from the input element, using $(e.target).is(checkBox). That way you could also change your event listener to listen for change instead of click for the checkbox. But I wouldn't recommend that either.
$('.form-check-input').on('change', function(e) {
if ($(this).is(':checked')) {
$(this).closest("tr").addClass("rowColor");
} else {
$(this).closest("tr").removeClass("rowColor");
}
});
$('#table1 tbody tr').on('click', function(e) {
//$(this).find(".form-check-input").checked = true;
var checkBox = $(this).find(".form-check-input");
if (!$(e.target).is(checkBox)) {
if (checkBox.is(':checked')) {
checkBox.prop("checked", false);
$(this).removeClass("rowColor");
} else {
checkBox.prop("checked", true);
$(this).addClass("rowColor");
}
}
});
.rowColor {
background-color: #dfecf6;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table1" class="table table-striped">
//thead
<tbody>
<tr class="">
<td></td>
<td class="checkboxtd"><input class="form-check-input" type="checkbox" value="" id=""></td>
</tr>
</tbody>
<table>

I think you can do a few changes feel free to visit my solution in CodePen: https://codepen.io/juanmaescudero/pen/PojQKzm
Anyway I share you the code:
HTML:
<table id="table1" class="table table-striped">
<tbody>
<tr class="">
<td>highlight row</td>
<td class="checkboxtd"><input class="form-check-input" type="checkbox" value="" id=""></td>
</tr>
</tbody>
<table>
CSS:
.rowColor {
background-color: #dfecf6;
}
JS:
$(".form-check-input").on("click", (e) => {
e = e.target;
if ($(e).is(":checked")) {
$(e.closest("tr")).addClass("rowColor");
} else {
$(e.closest("tr")).removeClass("rowColor");
}
});
Regards 😁

Related

Prevent Hyperlink to trigger Jquery?

I wrote this script so that if a user clicks on any <TR>, it gets highlighted - this is working fine and it highlights the TR fine.
<script>
$(document).ready(function () {
$(document).on('click', 'tbody tr', function (e) {
e.stopPropagation();
$(this).toggleClass('selected');
});
});
</script>
Now the issue is my <tr> has a hyperlink inside it and when user clicks on that hyper before the redirect the <tr> gets highlighted
<tr>
<td >
<div class="header">
TITLE HERE
</div>
</td>
</tr>
How to prevent that happening
Cheers
$(document).ready(function () {
$(document).on('click', 'tbody tr', function (e) {
e.stopPropagation();
$(this).toggleClass('selected');
});
});
.selected {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<table class="table table-hover">
<thead>
<tr>
Link
</tr>
</thead>
<tbody id="trow">
<tr>
<td style="Width:500px" >
<div class="header">
TITLE HERE
</div>
</td>
</tr>
</tbody>
First change 'tbody tr' to 'tbody tr a'
Second then to set the class on the tr use .closest() as in $(this).closest("tr").toggleClass('selected')
Demo
$(document).ready(function() {
$(document).on('click', 'tbody tr', function(e) {
if (e.target.nodeName == "A") {
e.stopPropagation();
} else {
$(this).closest("tr").toggleClass('selected');
}
});
});
.selected {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-hover">
<thead>
<tr>
Link
</tr>
</thead>
<tbody id="trow">
<tr>
<td style="Width:500px">
<div class="header">
TITLE HERE
</div>
</td>
</tr>
</tbody>
You need to listen to the click of a and stop the propagation in order to prevent highlighting of the row:
$(document).ready(function() {
$("table").on('click', 'tbody tr a', function(e) {
event.stopPropagation();
});
$(document).on('click', 'tbody tr', function(e) {
$(this).toggleClass('selected');
});
});
.selected {
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr style="height: 100px;">
<td>
<div class="header">
TITLE HERE
</div>
</td>
</tr>
</tbody>
</table>

HTML Row table selection

I have a table where the first column is a checkbox that selects the current row and the header has a SelectAll checkbox.
The table also gets selected when the user clicks on the row ( the checkbox becomes checked ).
My problem is that when I do the select all, all the checkboxes get selected but the rows are not being selected also.
My checkboxes have the change function so I assumed that when I hit the select all, the change method would execute as well, but this does not happen.
$(document).ready(function() {
$('#selectAll').click(function(event) {
if (this.checked) {
// Iterate each checkbox
$(':checkbox').each(function() {
this.checked = true;
});
} else {
$(':checkbox').each(function() {
this.checked = false;
});
}
});
$('.record_table tr').click(function(event) {
if (event.target.type !== 'checkbox') {
$(':checkbox', this).trigger('click');
}
});
$("input[type='checkbox']").change(function(e) {
if ($(this).is(":checked")) {
$(this).closest('tr').addClass("highlight_row");
} else {
$(this).closest('tr').removeClass("highlight_row");
}
});
});
.record_table {
width: 100%;
border-collapse: collapse;
}
.record_table tr:hover {
background: #eee;
}
.record_table td {
border: 1px solid #eee;
}
.highlight_row {
background: #eee;
}
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
<table class="record_table" id="table-patient-time">
<tr class="header">
<th>
<input type="checkbox" id="selectAll" />
</th>
<th>Hello</th>
<th>Hello</th>
</tr>
<tr class="selectable">
<td>
<input type="checkbox" />
</td>
<td>Hello</td>
<td>Hello</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>Hello</td>
<td>Hello</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>Hello</td>
<td>Hello</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>Hello</td>
<td>Hello</td>
</tr>
</table>
JS Fiddle here
You can fix this by triggering change event in click event:
$('#selectAll').click(function(event) {
if (this.checked) {
// Iterate each checkbox
$(':checkbox').each(function() {
this.checked = true;
}).change();
} else {
$(':checkbox').each(function() {
this.checked = false;
}).change();
}
});
$(document).ready(function() {
$('#selectAll').click(function(event) {
if (this.checked) {
// Iterate each checkbox
$(':checkbox').each(function() {
this.checked = true;
}).change();
} else {
$(':checkbox').each(function() {
this.checked = false;
}).change();
}
});
$('.record_table tr').click(function(event) {
if (event.target.type !== 'checkbox') {
$(':checkbox', this).trigger('click');
}
});
$("input[type='checkbox']").change(function(e) {
if ($(this).is(":checked")) {
$(this).closest('tr').addClass("highlight_row");
} else {
$(this).closest('tr').removeClass("highlight_row");
}
});
});
.record_table {
width: 100%;
border-collapse: collapse;
}
.record_table tr:hover {
background: #eee;
}
.record_table td {
border: 1px solid #eee;
}
.highlight_row {
background: #eee;
}
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
<table class="record_table" id="table-patient-time">
<tr class="header">
<th>
<input type="checkbox" id="selectAll" />
</th>
<th>Hello</th>
<th>Hello</th>
</tr>
<tr class="selectable">
<td>
<input type="checkbox" />
</td>
<td>Hello</td>
<td>Hello</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>Hello</td>
<td>Hello</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>Hello</td>
<td>Hello</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>Hello</td>
<td>Hello</td>
</tr>
</table>
Working fiddle
You could add class highlight_row and remove it in selectAll click event :
$('#selectAll').click(function(event) {
if(this.checked) {
// Iterate each checkbox
$(':checkbox').each(function() {
this.checked = true;
$(this).closest('tr').addClass('highlight_row');
});
}
else {
$(':checkbox').each(function() {
this.checked = false;
$(this).closest('tr').removeClass('highlight_row');
});
}
});
Hope this helps.
$(document).ready(function () {
$('#selectAll').click(function(event) {
if(this.checked) {
// Iterate each checkbox
$(':checkbox').each(function() {
this.checked = true;
$(this).closest('tr').addClass('highlight_row');
});
}
else {
$(':checkbox').each(function() {
this.checked = false;
$(this).closest('tr').removeClass('highlight_row');
});
}
});
$('.record_table tr').click(function (event) {
if (event.target.type !== 'checkbox') {
$(':checkbox', this).trigger('click');
}
});
$("input[type='checkbox']").change(function (e) {
if ($(this).is(":checked")) {
$(this).closest('tr').addClass("highlight_row");
} else {
$(this).closest('tr').removeClass("highlight_row");
}
});
});
.record_table {
width: 100%;
border-collapse: collapse;
}
.record_table tr:hover {
background: #eee;
}
.record_table td {
border: 1px solid #eee;
}
.highlight_row {
background: #eee;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="record_table" id="table-patient-time">
<tr class="header">
<th>
<input type="checkbox" id= "selectAll" />
</th>
<th>Hello</th>
<th>Hello</th>
</tr>
<tr class="selectable">
<td>
<input type="checkbox" />
</td>
<td>Hello</td>
<td>Hello</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>Hello</td>
<td>Hello</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>Hello</td>
<td>Hello</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>Hello</td>
<td>Hello</td>
</tr>
</table>
I would just trigger change and not have the logic in multiple places
$('#selectAll').click(function(event) {
$(':checkbox').prop("checked",this.checked).change();
});
$("input[type='checkbox']").change(function (e) {
$(this).closest('tr').toggleClass("highlight_row", this.checked);
});
Now what I would do for the html is you should use thead and tbody instead of using a class to say you have a head row.
JsFiddle
Made a small tweak to your working example that dispatches a click event to the checkboxes that need to be changed. This should properly trigger the onchange event for those boxes
The new section looks like this:
if(this.checked) {
// Iterate each checkbox
$(':checkbox').not(":checked").click()
}
else {
$(':checkbox:checked').click()
}

Unmark checkbox when there is no more TR and TABLE goes hide

I'm working on this function for remove any marked checkbox in a selector container element. The code works fine but has a small problem: I'm not able to uncheck the first checkbox (the one that toggle all the checkboxes in a selector2 container). Now this is the code for remove the checked checkboxes:
function eliminarMarcados(selector, toggleMsg, msgSelector) {
$(selector + " input[type='checkbox']:checked").closest("tr").not('.tableHead').remove();
if (toggleMsg) {
if ($(selector + " tbody tr").length == 0) {
$(msgSelector).show();
$(selector).hide();
// 1st test didn't work since it's not right
//$(selector + " tr").hasClass('tableHead').$(selector + " input[type='checkbox']").prop('checked', false);
}
}
}
And this is how I call it:
$("#btnEliminarNorma").on('click', function () {
eliminarMarcados("#tablaNorma", true, "#alertSinNorma");
});
This is the code I'm using for toggle all checkboxes checked:
function marcarTodosCheck(selChk, tableBody) {
$(selChk).on('click', function () {
var $toggle = $(this).is(':checked');
$(tableBody).find("input:checkbox").prop("checked", $toggle).trigger("change");
});
$(tableBody).find("input:checkbox").on('click', function () {
if (!$(this).is(':checked')) {
$(selChk).prop("checked", false).trigger("change");
} else if ($(tableBody).find("input:checkbox").length == $(tableBody).find("input:checkbox:checked").length) {
$(selChk).prop("checked", true).trigger("change");
}
});
}
And I call it as follow:
marcarTodosCheck("#toggleCheckNorma", "#tablaNorma");
And this is the HTML code behind this:
<table class="table table-condensed" id="tablaNorma">
<thead>
<tr class="tableHead">
<th><input type="checkbox" id="toggleCheckNorma" name="toggleCheckNorma"></th>
<th>Nro.</th>
<th>Norma COVENIN</th>
<th>Año de Publicación</th>
<th>Comité Técnico</th>
</tr>
</thead>
<tbody id="normaBody">
<tr class="">
<td><input type="checkbox" value="5"></td>
<td>382</td><td>Sit alias sit.</td>
<td>1970</td><td>Velit eum.</td>
</tr>
<tr class="">
<td><input type="checkbox" value="6"></td>
<td>38362</td>
<td>Et voluptatem.</td><td>1976</td>
<td>Et voluptatem.</td>
</tr>
</tbody>
</table>
How I can unmark the first checkbox?
I've just made a Fiddle with an additional <button id="btnEliminarNorma">Uncheck</button> to remove the checkmarks and the adjustment of your first approach in the function eliminarMarcados() :
$(selector).find(" input[type='checkbox']").prop('checked', false);

Select data attribute from row only for rows with checked checkboxes

I have table has 2 columns: checkbox and name.
<table id="data">
<tr class="header">
<th>
<input type="checkbox" class="download" />
</th>
<th>Name</th>
</tr>
<tr data-id="1">
<td>
<input type="checkbox" class="download" />
</td>
<td>One</td>
</tr>
<tr data-id="2">
<td>
<input type="checkbox" class="download" />
</td>
<td>Two</td>
</tr>
<tr data-id="3">
<td>
<input type="checkbox" class="download" />
</td>
<td>Something</td>
</tr>
</table>
I would like to select data attribute from those rows that have checkbox selected. Right now I'm doing it this way:
$(document).on('click', "#select", function (e) {
var mydata=[];
$.each($('#data tbody tr:not(.header)'), function(i, row) {
if($(row).find('input[type=checkbox]').is(":checked"))
mydata.push($(row).data('id'));
});
console.log(mydata);
});
This works fine, but can this be done better/faster?
Here is my working demo: http://jsfiddle.net/Misiu/yytR2/2/
Also how can I uncheck checkbox in header when one of more checkboxes in body are unchecked and check it when all will get checked?
EDIT: My final working code (thanks to #tymeJV):
$(document).on('change', "#data tr.header input.download", function (e) {
$('#data tbody tr:not(.header) input.download').prop('checked', $(this).is(":checked"));
});
$(document).on('change', "#data tr:not(.header) input.download", function (e) {
if ($(this).is(":checked") && $('#data tr:not(.header) input.download:not(:checked)').length == 0) {
$('#data tbody tr.header input.download').prop('checked', true);
} else {
$('#data tbody tr.header input.download').prop('checked', false);
}
});
$(document).on('click', "#select", function (e) {
var rows = $("#data tr:not(.header) td input:checked").map(function () {
return $(this).closest("tr").data("id");
}).get();
console.log(rows);
});
You can do:
var rows = $("#data tr:not(.header) td input:checked").map(function() {
return $(this).closest("tr").data("id");
}).get();
It iterates yet, but only checked rows.
You can use:
$(".download:checkbox").map(function() {
return $(this).parents('tr').data('id');
}).get()

Create Simple J Query todo list

I am trying to create a simple todo list in Javascript but for some reason when the check box is ticked, the styling text adjacent to it does not change rather the heading text style changes as per the fiddle
HTML:
<table border="1">
<tr>
<td>
<input type="checkbox" value="None" id="squaredTwo" name="check" />
</td>
<td>row 1, cell 2</td>
</tr>
<tr>
<td>
<input type="checkbox" value="None" id="squaredTwo" name="check" />
</td>
<td>row 2, cell 2</td>
</tr>
</table>
<h2> Heading 2</h2>
CSS:
.newclass {
text-decoration: line-through;
color: red;
}
JQuery:
$('input[type="checkbox"]').click(function () {
if ( this.checked ) {
//alert('Checked');
$("h2").addClass('newclass');
} else {
//alert('Unchecked');
$("h2").removeClass('newclass');
}
});
Please help
Change your Jquery like this
$('input[type="checkbox"]').click(function () {
if (this.checked) {
//alert('Checked');
$(this).closest("td").next().addClass('newclass');
} else {
//alert('Unchecked');
$(this).closest("td").next().removeClass('newclass');
}
});
Demo Fiddle
Even Simpler than that
$('input[type="checkbox"]').click(function () {
$(this).closest("td").next().toggleClass('newclass');
});
New Demo Fiddle
It is happening as you are targeting H2 element for styles on click of checkbox. Instead use the next TD element.
$('input[type="checkbox"]').click(function() {
if (this.checked) {
//alert('Checked');
$(this).parent().next().addClass('newclass');
} else {
//alert('Unchecked');
$(this).parent().next().removeClass('newclass');
}
});

Categories