using jquery to highlight either tr's or td's - javascript

I have two tables:
<table class="highlight_row" id="table1">
<tr id="first_row">
<td><input type="checkbox" id="first">first thing</td>
<td><input type="checkbox" id="second">second thing</td>
<td><input type="checkbox" id="third">third thing</td>
</tr>
</table>
<table class="highlight_td" id="table2">
<tr id="second_row">
<td><input type="checkbox" id="fourth">fourth thing</td>
<td><input type="checkbox" id="fifth">fifth thing</td>
<td><input type="checkbox" id="sixth">sixth thing</td>
</tr>
</table>
and I am trying to differenciate them -- when I check any box in the first table, I want that whole row to be highlighted, and when I check a box in the second table, I want just that td to be highlighted.
I am able to get rows highlighted (using addClass() to a 'selected' color), but when I specify the table class, I still get the whole row for the second table, when I just want the td (I figure identifying by class instead of id will be better in the long run as I add more tables).
jquery code:
$(".highlight_row").click(function(){
$(":checkbox").change(function() {
$(this).closest("tr").toggleClass("selected", this.checked)
})
});

Something like this fiddle, perhaps?
Your HTML.
CSS:
.highlight { background: #ff0; }
JS:
$("#table1 input[type=checkbox]").on('click', function ()
{
$(this).parent().parent().toggleClass('highlight');
});
$("#table2 input[type=checkbox]").on('click', function ()
{
$(this).parent().toggleClass('highlight');
});

For the first table, you'll want to eval all of the checkboxes so it doesn't get un-highlighted. The second table is much easier.
Fiddle: http://jsfiddle.net/24vm61dk/
$(function () {
// Highlight Row
$('#table1 input[type="checkbox"]').on('change', function () {
var anyChecked = false;
$(this).closest('tr').find('input[type="checkbox"]').each(function () {
if ($(this).prop('checked')) {
anyChecked = true;
}
});
if (anyChecked) {
$(this).closest('tr').addClass('highlight');
} else {
$(this).closest('tr').removeClass('highlight');
}
});
// Highlight Cell
$('#table2 input[type="checkbox"]').on('change', function () {
var checked = $(this).prop('checked');
if (checked) {
$(this).closest('td').addClass('highlight');
} else {
$(this).closest('td').removeClass('highlight');
}
});
});

Code shown is adding change handler within a click handler on the whole table.
This will lead to compounding events and can lead to serious browser performance problems if user clicks a lot in table.
Simply put, click on table 4 times and every time a checkbox gets changed it will trigger 4 change handlers
A simple way for the row highlighting would be to use the count of checked checkboxes in the row to determine the class state
$('table.highlight_row input:checkbox').change(function(){
var $row = $(this).closest('tr'),
hasChecked = $row.find(':checkbox:checked').length;
$row.toggleClass('selected', hasChecked);
});
The cell highlighting is even easier...just toggle the class on the parent cell based on the checked state
$('table.highlight_td input:checkbox').change(function(){
$(this).parent().toggleClass('selected', this.checked);
});

For rows use:
.highlight_row .selected {
background: yellow;
}
for the cell use:
.highlight_td .selected td:nth-child(1) {
background: yellow;
}

Related

jquery select entire row except last column

I have a table like this :
When I click on a row, entire row are selected. For example in the image above the second row is selected. After selecting the row the name and family are displayed in the bottom of table.
If you look at the jquery code, the ajax commands are used. The problem is that when i click the Details button on each row , the Ajax scripts will run. How do i click a button without executing Ajax code?
$("#tablelist tr").click(function () {
$(this).addClass('selected').siblings().removeClass('selected');
$("#selectedUser").html("Selected User : " + $(this).find('td').eq(1).html() + ' ' + $(this).find('td').eq(2).html());
$.ajax({
//some code
});
});
.selected {
background-color: blue;
color: white;
color: #FFF;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<td>rows</td>
<td>name</td>
<td>family</td>
<td>username</td>
<td>Jobs</td>
</tr>
</thead>
<tbody id="tablelist">
#foreach (var item in TableList)
{
<tr style="font-size:13px;">
<td>#counter</td>
<td>#item.FirstName</td>
<td>#item.Family</td>
<td>#item.UserName</td>
<td>
Details
</td>
</tr>
}
</tbody>
Use stopPropagation on click of the details button:
$("#tablelist tr").click(function () {...})
$("#tablelist tr a").click(function (e) { e.stopPropagation() })
You are binding your listener to the whole row, so you can't exclude part of it.
Instead, try binding to the cells you need. Instead of:
$("#tablelist tr")
Try
$("#tablelist td:not(:last-child)")
Just be aware that if you have space in your row that is not a cell, it won't fire the event. You can likely adjust padding and margins to resolve this.

How to not allow deleting all rows in table?

I have a simple table with 3 columns with classes = "code","description","delete" the column has class "delete" is a checkbox type, and one button with class="savebtn".
I need the following :
When user click save :
the Jquery must verify the code column that it has data.
If any cell in delete column is checked, Delete that row.
If the user checked all cells in delete column alert message that the table must has at least one row , and don't delete the rows.
this is a Demo but it not working with me.
that what i tried :
$(document).ready(function (){
$(".savebtn").bind("click", function(e){
$('.savebtn').attr('disabled',true);
$('.table tbody tr').each(function () {
$(this).find('.code input').each(function () {
if ($(this).closest("tr").find(".delete input").is(":checked") && $('.cf-table-block tbody tr').length >=1){
$('.delete input :checkbox:checked').closest('tr').remove();
$('.savebtn').removeAttr('disabled');
}else if($(this).closest("tr").find(".delete input").is(":checked") && $('.cf-table-block tbody tr').length <2){
e.preventDefault();
}else if($('.delete input').prop('checked')==false && ( $(this).val().length>0)){
$('.savebtn').removeAttr('disabled');
}else if ($('.delete input').prop('checked')==false && ( $(this).val().length==0)){
$(this).attr("placeholder", "Please fill this field");
}
});
});
});
});
First, you should look at wrapping your table header in <thead> and body in <tbody>. This will allow you to determine how many rows are relevant to our needs.
It'd be good to then create an array of rows that are checked to be deleted, this can then be compared (via length) to the original amount of rows.
Here's an example - I've removed a lot of the logic as the use of an array to store checked rows will help remove the need for a lot of those conditionals.
Here's a fiddle.
Edit: Here's a new fiddle in which i've added a button for you to clear/populate the last rows value so you can test.
This is updated fiddle of what you are trying to do.
https://jsfiddle.net/ko55Lbt3/6/
$(document).ready(function (){
$(".savebtn").bind("click", function(e){
$('.savebtn').attr('disabled',true);
if($(".table tr [type='checkbox']:checked").length >= $('.table tr').length -1)
{
alert("all rows can not be deleted");
return false;
}
$('.table tr').each(function () {
$(this).find('.code input').each(function () {
if ($(this).closest("tr").find(".delete input").is(":checked")){
if($(this).val().length > 0)
{
$(this).closest("tr").remove();
$('.savebtn').removeAttr('disabled');
}
else
{
$(this).attr("placeholder", "Please fill this field");
}
}
});
});
});
});
There are few problem with selectors in your current code which i have corrected.For example "tbody" element is no where, the td should not have the type attribute.
I've done it with a simple count on each click:
See in Fiddle
$(document).ready(function (){
// on click "Save"
$(".savebtn").bind("click", function(e){
$('.savebtn').attr('disabled',true);
// Delete rows
$("input:checkbox").each(function () {
if($(this).prop("checked")){
$(this).closest("tr").remove();
}
});
});
// on click a checkbox
$("input:checkbox").on("click", function(){
checkboxCount=0;
$("input:checkbox").each(function(){
checkboxCount++;
});
$("input:checkbox").each(function(){
if($(this).prop("checked")){
checkboxCount--;
}
});
// this is just to see the value in jsFiddle
$("#console").html(checkboxCount);
// If there is no checkbox unchecked, disables the Save button and alert.
if(checkboxCount<1){
alert("Table must have at least one row!");
$('.savebtn').attr('disabled',true);
}else{
$('.savebtn').attr('disabled',false);
}
});
});
Try this one:
https://jsfiddle.net/ersamrow/f7ce7dpj/
HTML:
<table class="table" style="width:100%" border="1">
<thead>
<tr>
<th class="code">Code</th>
<th class="description">Description</th>
<th class="delete">Delete</th>
</tr>
</thead>
<tbody>
<tr>
<td class="code" type="text">1</td>
<td type="text">aa</td>
<td class="delete">
<input type="checkbox">
</td>
</tr>
<tr>
<td class="code" type="text">2</td>
<td type="text">bb</td>
<td class="delete">
<input type="checkbox">
</td>
</tr>
<tr>
<td class="code" type="text">3</td>
<td type="text">cc</td>
<td class="delete">
<input type="checkbox">
</td>
</tr>
</tbody>
</table>
<br>
<input class="savebtn" style="width: 65px; font-size: 16px;" type="button" value="Save">
Script:
$(document).ready(function() {
// on click "Save"
$(".savebtn").bind("click", function(e) {
$('.savebtn').attr('disabled', true);
var table_rows = $('table tbody').find('tr').length;
var checked = $('input:checkbox:checked').length;
if (checked < table_rows) {
// Delete rows
$("input:checkbox").each(function() {
if ($(this).prop("checked")) {
$(this).closest("tr").remove();
}
});
} else {
alert("Table must have at least one row!");
}
$('.savebtn').attr('disabled', false);
});
});

How to change color of my div if check-box is checked?

I have table that is created based on records from data base. Inside of tbody I have tr that creates each table row. Table row has multiple time slots for same date. I want to change background color of my time block if check box is checked. I got my check box to work, I did test with alert and some text inside. Now I'm trying to change the background color but nothing works in this case that I tried so far. Here is my code:
<cfoutput query="qryTest" group="DateMeeting">
<tbody>
<tr>
<td>#DateMeeting#</td>
</tr>
<cfoutput>
<tr class="blockRow">
<td>#StartTime#</td>
<td>#EndTime#</td>
<td><input type="checkbox" name="block" id="block"></td>
</tr>
</cfoutput>
</tbody>
</cfoutput>
Java script:
$('input[type=checkbox]').on('change', function() {
var div = $(this).closest('.blockRow');
$(this).is(":checked") ? div.addClass("red") : div.removeClass("red");
});
and my css:
.red{
background-color:red;
}
This is working code that I updated. Problem number one was in html structure of my code. Second If I used document.getElementById('') I was getting only first row chnaged background-color, no matter which row I click on. So I have had to use getElementByClassName. Anyway I decided to use JQuery addClass/removeClass. Thanks everyone for help with this problem.
Try this:
$('input[type=checkbox]').on('change', function() {
var div = $(this).closest('.blockRow');
$(this).is(":checked") ? div.addClass("red") : div.removeClass("red");
});
.red{
background-color:red;
}
<cfoutput query="qryTest" group="DateMeeting">
<tbody>
<tr>
<td>#DateMeeting#</td>
<cfoutput>
<div class="blockRow">
<td>#StartTime#</td>
<td>#EndTime#</td>
<td><input type="checkbox" name="block" id="block"></td>
</div>
</cfoutput>
</tr>
</tbody>
</cfoutput>
jsfiddle:
https://jsfiddle.net/3s83gj70/2/
This gets the closest blockrow to the current checkbox so should work with more than one instance. Since you can't have 2 elements with the same id I have change blockrow to the class.
If you want to do other things based on the same condition then you can do this:
$('input[type=checkbox]').on('change', function() {
var div = $(this).closest('.blockRow');
if($(this).is(":checked")){
div.addClass("red");
//checkbox is checked, do something
}
else
{
div.removeClass("red");
//checkbox is not checked, do something else
}
});
Easy:
$('#blockRow').css("background-color","red")
------------------------------^
EDIT
Then you don't include jQuery library. To make pure js make this:
http://jsfiddle.net/bfss81sa/
document.getElementById("box").style.backgroundColor = "red";
Here you are the complete snippet:
var cbs = document.querySelectorAll('input[type=checkbox]');
for(var i = 0; i < cbs.length; i++) {
cbs[i].addEventListener('change', function() {
if(this.checked) {
document.getElementById("box").style.backgroundColor = "red";
} else {
document.getElementById("box").style.backgroundColor = "transparent";
}
});
}
<input type="checkbox" name="block" id="block">
<div id="box">
The box
</div>
Your html code is a mess. Anyway, generally :
$('input[type=checkbox]').click(function() {
if($(this).is(':checked') {
$(this).parents('tr').find('td:first').css('background', 'red');
} else {
$(this).parents('tr').find('td:first').css('background', 'white');
}
});
Of course, you can narrow the scope of input:checkbox selector.
If it is not the FIRST <td> in your <tr> then you better assign it a class and get it with it.
NOTE : DOM must be correct <cfoutput> cannot be child of <tr>; <div> cannot have <td> as direct child; Incorrect DOM impact javascript traversing.

Multiple JQuery effects from a single event

I'm new to JQuery but have some experience with HTML and CSS.
I'm trying to make a list of checkboxes on a form more interactive, I though I could put them inside a table, clicking anywhere inside each row would check the corresponding checkbox and change the row color so the user would know the selection had been made. For some of the rows I would need a toggle effect to reveal a new row where more information could be entered. I have had some success in doing these things on their own but cannot get them to work together. Please Help!
My toggle effect was simple enough
$(document).ready(function(){
$("#top1").click(function(){$("#bottom1").toggle();});
$("#top2").click(function(){$("#bottom2").toggle();});
});
For the click selection I used
$(document).ready(function() {
$('#row5 tr').click(function(event) {
$(this).toggleClass('selected');
if (event.target.type !== 'checkbox') {
$(':checkbox', this).trigger('click');
}
});
});
Each click would add/remove the 'selected' class which I would use to change the row color. However I'm finding that the selected class only take effect if I use an anonymous function for the click event and adding the code for the extra row, breaks the function.
What am I missing, or am I doing this all wrong? Would love some guidance.
This is the HTML structure I am using
<table class="rowclick" id="rowclick5">
<tbody>
<tr>
<td class="cb"><input type="checkbox" value="yes" /></td>
<td>row 1</td>
</tr>
<tr>
<td class="cb" id="bottom2"><input type="checkbox" value="yes" /></td>
<td>row 2</td>
</tr>
<tr>
<td class="cb"><input type="checkbox" value="yes" /></td>
<td>row 3</td>
</tr>
</tbody>
</table>
Here is what I would do:
$(function() {
$(document).on('click', '#row5 tr', function (event) {
var newState = !$(this).is('.selected');
$(this)
.toggleClass('selected', newState)
.find(':checkbox').prop('checked', newState);
});
});
This uses event delegation (via $(document).on()) and prevents that the state of the checkbox (checked/not checked) and the state of the row (selected/not selected) ever become inconsistent.
Note that I would probably use tr.selectable instead of #row5 tr, as the latter is a bit too specific and therefore hinders re-usability.
You could simply check /uncheck it using:
$(document).ready(function() {
$('#row5 tr').click(function(event) {
$(this).toggleClass('selected');
if ($(event.target).is(':not(:checkbox)')) {
$(':checkbox', this).prop('checked', $(this).hasClass('selected'));
// if you want to trigger click handler bound to checkbox
// without making it bubbles, use:
/*$(':checkbox', this).triggerHandler('click');*/
}
});
});
-jsFiddle-

Need to delete row if checkbox is checked

I've got a jQuery/AJAX solution set up to update and delete items that are displayed in a table. The AJAX part works fine but once an item is deleted I need to be able to remove it from view and I can't figure out how to identify the selected item(s) based on their value after the submit button is clicked.
Here's my jQuery:
$('#button').click(function(event){
var order = $("#sortable tbody").sortable("serialize");
order += "&" + $("form[name=favorites]").serialize().replace(/%5B%5D/g, '[]');
order += "&crudtype=update_favorites";
$('#savemessage').html('<p>Saving changes...</p>');
$.post("/crud",order,function(theResponse){
$('#savemessage').html(theResponse);
});
});
});
My HTML is generated from PHP so the quantities and IDs are variable but the format is as follows:
<tr class="odd" id="field_37">
<td class="handle">Item #1 Name</td>
<td><input type="checkbox" name="fid[]" id="fid" value="37" class="box check-child"></td>
</tr>
<tr class="even" id="field_29">
<td class="handle">Item #2 Name</td>
<td><input type="checkbox" name="fid[]" id="fid" value="29" class="box check-child"></td>
</tr>
So effectively what (I think) I need is to add to my .click function something like "foreach checked fid, remove the corresponding row ID" if that makes any sense.
A basic selector to get a checked checkbox is
'input[type="checkbox"]:checked'
or
'input:checkbox:checked'
Now you can either use has() or loop through and use closest to get the trs
$('input[type="checkbox"]:checked').closest("tr").remove();
or
$('tr:has(input[type="checkbox"]:checked)').remove();
You can do it like this: http://jsfiddle.net/dSANw/
When user clicks on checked box add class to the parent tr
$(".box").click(function() {
if($(this).is(':checked')) {
$(this).parents('tr').addClass('checkedtd');
} else {
$(this).parents('tr').removeClass('checkedtd');
}
});
When clicked on delete, get all tables tr's classed 'checkedtd' and delete
$("#delt").click(function() {
alert($('.checkedtd').length);
$('.checkedtd').remove();
});

Categories