I want to change the color of the table row when the button is clicked. but I have a problem with the code. when I click the button, the color of the table row does not change.
CSS :
tr.highlighted td {
background: red;
}
HTML :
<table id="data" border="1" cellspacing="1" width="500">
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
</table>
<button type="button" id="change">
Change
</button>
JQuery :
$('#data tr').click(function(e) {
$('#change').click(function() {
$('#data tr').removeClass('highlighted');
$(this).addClass('highlighted');
})
});
Demo 2 and Demo 3 added. One of the demos behaves as the OP commented hopefully.
Demo 2: The <tr>
are selected by click then highlighted by clicking the button.
Demo 3: Same as Demo 2 except only one row can be highlighted at a time.
Delegate the click event on document object. Any click to the document (which is basically the whole page) will be detected -- this of course is not desirable.
`$(document).on("click',...`
Delegating what actually reacts to the click and what doesn't is the goal of the programming pattern called Event Delegation. jQuery provides an optional second parameter referred to as a data
object in any event method signature. This parameter is basically a selector string that specifies the scope of $(this)
:
`$(document).on("click', '#data td, #change', ...
So the example above delegates the click event exclusively to any <td>
within #data
OR #change
. Clicks anywhere other than to the delegated elements is ignored (unless there's another click event handler down the line). The last parameter is the callback function that will be invoked when triggered by a click event on any <td>
of #data
or #change
. The callback function uses $(this)
and flow controls to delegate the click event and determine behavior (or outcome). In the demo it is basically .toggleClass()
method that .addClass()
to target <tr>(s)
without the .highlighted
class and inversely .removeClass()
to target <tr>(s)
that already has the .highlighted
class.
Further details commented in demo.
Click any <td>
directly and its parent <tr>
class .highlighted
is toggled.
Click the button and all .highlighted
classes on all <tr>
are toggled.
Click either the <tr>
or button to highlight <tr>
/* Delegate click event on document -- Consider clicks only on #data td or #change */ /* if the clicked tag is a <td>... get the .closest <tr> from that <td> and add .highlighted class if it doesn't have it otherwise remove .highlighted */ /* ...otherwise get all <tr> and toggle the .highlighted class */ $(document).on('click', '#data td, #change', function(e) { if ($(this).is('td')) { $(this).closest('tr').toggleClass('highlighted'); } else { $('#data tr').toggleClass('highlighted'); } });
tr.highlighted td { background: red; }
<table id="data" border="1" cellspacing="1" width="500"> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> </table> <button type="button" id="change"> Change </button> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Click <tr>
to select/deselect then click button to highlight all selected <tr>
.
$(document).on('click', '#data td, #change', function(e) { if ($(this).is('td')) { $(this).closest('tr').toggleClass('selected'); } else { $('#data tr:not(.selected)').removeClass('highlighted'); $('#data tr.selected').addClass('highlighted'); } });
tr.highlighted td { background: red; }
<table id="data" border="1" cellspacing="1" width="500"> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> </table> <button type="button" id="change"> Change </button> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
The last <tr>
clicked is selected and then highlighted when button is clicked
$(document).on('click', '#data td, #change', function(e) { if ($(this).is('td')) { $('#data tr').removeClass('selected'); $(this).closest('tr').addClass('selected'); } else { $('#data tr').removeClass('highlighted'); $('.selected').addClass('highlighted'); } });
tr.highlighted td { background: red; }
<table id="data" border="1" cellspacing="1" width="500"> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> </table> <button type="button" id="change"> Change </button> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
The nested click
handler have no sense here. Instead you can add a particular class, lets call it active
to the last clicked row
to keep track of it. After that, when you click the change
button, you can first remove the highlighted
class from every row
and then add it to the row
that hold the active
class:
$('#data tr').click(function(e) { $('#data tr').removeClass('active'); $(this).addClass('active'); }); $('#change').click(function() { $('#data tr').removeClass('highlighted'); $("tr.active").addClass('highlighted'); });
tr.highlighted td { background: red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <table id="data" border="1" cellspacing="1" width="500"> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> </table> <button type="button" id="change">Change</button>
You can do:
const $dataTr = $('#data tr'); const $change = $('#change'); let $toBeChanged = null; $dataTr.click(function() { $toBeChanged = $(this); $change.prop('disabled', false); }); $change.click(function() { $dataTr.removeClass('highlighted'); $toBeChanged.addClass('highlighted'); })
tr.highlighted td { background: red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"> </script> <table id="data" border="1" cellspacing="1" width="500"> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> </table> <button type="button" id="change" disabled> Change </button>
The this
in $(this).addClass('highlighted');
refers to the button, not the table row, since this
will be set to whatever raised to event to trigger the callback function to execute, in this case, the element with the id change
. One of the easiest ways to fix this would be to assign this
to another variable before you do $('#change').click(function() {...})
.
Otherwise, if you want to make sure that only one table row is being changed at a time, you should separate the ('#data tr').click(function(e) {...})
and $('#change').click(function() {...})
so that they are not nested, have a variable outside both that keeps track of which row was last clicked, and read that variable whenever $('#change').click()
is raised (instead of capturing which table row was clicked when you register the callback).
You can use index
and eq
method of jquery. Remove the nested click
. First on click of the table row
get the index of the row in the table using index . The value start from 0
. Set this value to a variable. Then use on click of the button use eq to get the table row and add class to it
let getRowIndex; let elem = $('#data tr'); elem.click(function(e) { getRowIndex = $(this).index() }); $('#change').click(function() { if (getRowIndex !== undefined) { elem.removeClass('highlighted'); elem.eq(getRowIndex).addClass('highlighted'); } })
tr.highlighted td { background: red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <table id="data" border="1" cellspacing="1" width="500"> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> </table> <button type="button" id="change"> Change </button>
$(document).ready(function(){ $('#data tr').click(function(e) { if($(this).attr("class") == 'highlighted'){ $(this).removeClass('highlighted'); }else{ $(this).addClass('highlighted'); } }); })
tr.highlighted td { background: red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script> <table id="data" border="1" cellspacing="1" width="500"> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> </table> <button type="button" id="change"> Change </button>
You are attaching click
event to table tr's and then inside the callback function you are attaching a click event to your button
. Within the button click
callback your $(this)
will refer to your button and not clicked tr. Instead add the classes to clicked tr
itself.
$('#data tr').click(function(e) { $('#data tr').removeClass('highlighted'); $(this).addClass('highlighted'); });
.highlighted { background: red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <table id="data" border="1" cellspacing="1" width="500"> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> </table> <button type="button" id="change">Change</button>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.