Reputation: 407
I am trying to make a set of greyed out images switch with color images when a checkbox is checked within a table row. This operation will be reversed when the checkbox is unchecked again. The changes must only apply to img elements in that particular tablerow. The table rows will be dynamically generated but will follow this DOM structure. I have looked into .parent() .parentAll() but these do not seem to provide the matches. I am happy to apply non jQuery javascript if it is not possible in jQuery but I would prefer to use jQuery if possible
<html>
<head>
<meta charset="utf-8">
<title> Total Tutor </title>
<link type="text/css" rel="stylesheet" href="course.css">
<script src="../jquery.js"></script>
<style>
.color{display:none;}
.grey{display:block;}
</style>
</head>
<body>
<div>
<form>
<table id="units" >
<thead>
<tr>
<th>Units</th>
<th>Add Video</th>
<th>Add Worksheet</th>
<th>Add Quiz</th>
<th>Add Exam</th>
<th>Add Revision</th>
</tr>
</thead>
<tbody>
<!-- table rows will be dynamically generated based on a SQL query -->
<tr>
<td class="unit_table"><input type="checkbox" class="design_units" name="units[]" value="Bike"> Unit 2.1.1.1</td>
<td class="unit_table"><img class="color" src="../images/video-selector-small.png"><img class="grey" disabled src="../images/video-selector-small-grey.png"></td>
<td class="unit_table"><img class="color" src="../images/worksheet-selector-small.png"><img class="grey" disabled src="../images/worksheet-selector-small-grey.png"></td>
</tr>
<tr>
<td class="unit_table"><input type="checkbox" class="design_units" name="units[]" value="Bike"> Unit 3.1.1.1</td>
<td class="unit_table"><img class="color" src="../images/video-selector-small.png"><img class="grey" disabled src="../images/video-selector-small-grey.png"></td>
<td class="unit_table"><img class="color" src="../images/worksheet-selector-small.png"><img class="grey" disabled src="../images/worksheet-selector-small-grey.png"></td>
</tr>
</tbody>
</table>
<button type="submit" id="save_design_course" name="sent" value="save_design_course"><img src="../images/save.png"></button>
</form>
</div>
</body>
</html>
<script>
$(document).ready(function()
{
$(".design_units").click(function ()
{
if ($(this).is(':checked'))
{
/*change all of the img elements of class grey to display: none
and change all img elements of class color to display:block*/
}
if (!$(this).is(':checked'))
{
/*change all of the img elements of class grey to display:block
and change all img elements of class color to display:none*/
}
});
</script>
Upvotes: 0
Views: 179
Reputation: 2063
another simple way to show and hide your image, is using toggle()
rather than checking its checked
property
toggle()
is used to switch the visibility of elements from hide
to show
, vice versa.
$(".design_units").click(function ()
{
$(this).parents('tr').find('img.grey').toggle();
$(this).parents('tr').find('img.color').toggle();
});
demo : https://jsfiddle.net/81sLL212/
Upvotes: 1
Reputation: 29
try this,
<html>
<hrad></head>
<body>
<div>
<form>
<table id="units" >
<thead>
<tr>
<th>Units</th>
<th>Add Video</th>
<th>Add Worksheet</th>
<th>Add Quiz</th>
<th>Add Exam</th>
<th>Add Revision</th>
</tr>
</thead>
<tbody>
<!-- table rows will be dynamically generated based on a SQL query -->
<tr>
<td class="unit_table"><input type="checkbox" class="design_units" name="units[]" value="Bike"> Unit 2.1.1.1</td>
<td class="unit_table"><img alt="color" class="color" src="../images/video-selector-small.png"><img alt="grey" class="grey" disabled src="../images/video-selector-small-grey.png"></td>
<td class="unit_table"><img class="color" src="../images/worksheet-selector-small.png"><img class="grey" disabled src="../images/worksheet-selector-small-grey.png"></td>
</tr>
<tr>
<td class="unit_table"><input type="checkbox" class="design_units" name="units[]" value="Bike"> Unit 3.1.1.1</td>
<td class="unit_table"><img class="color" src="../images/video-selector-small.png"><img class="grey" disabled src="../images/video-selector-small-grey.png"></td>
<td class="unit_table"><img class="color" src="../images/worksheet-selector-small.png"><img class="grey" disabled src="../images/worksheet-selector-small-grey.png"></td>
</tr>
</tbody>
</table>
<button type="submit" id="save_design_course" name="sent" value="save_design_course"><img src="../images/save.png"></button>
</form>
</div>
<script>
$(function(){
$('#units').on('click','.design_units',function ()
{
if ($(this).is(':checked'))
{
$($(this).closest('tr').find('.grey')).hide();
$($(this).closest('tr').find('.color')).show();
/*change all of the img elements of class grey to display: none
and change all img elements of class color to display:block*/
}
if (!$(this).is(':checked'))
{
$($(this).closest('tr').find('.grey')).show();
$($(this).closest('tr').find('.color')).hide();
/*change all of the img elements of class grey to display:block
and change all img elements of class color to display:none*/
}
});
});
</script>
</body>
</html>
Upvotes: 0
Reputation: 150010
Within the click
handler (or you could use a change
handler, but either is OK for checkboxes) you can find the clicked element's associated images by using .closest("tr")
to navigate up to the containing row, then .find("img")
to navigate back down to the images in that row.
Then you can call .toggle()
on those images, passing a boolean argument to indicate whether to show or hide each one.
This means you don't need an if/else
structure and the event handler can be reduced to three lines:
$(document).ready(function() {
$(".design_units").click(function() { // When a CB is clicked
var imgs = $(this).closest("tr").find("img"); // find its associated imgs
imgs.filter(".color").toggle(this.checked); // Show color if CB checked
imgs.filter(".grey").toggle(!this.checked); // Show grey if CB not checked
});
});
.color { display: none; }
.grey { display: block; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="units">
<tbody>
<tr>
<td class="unit_table"><input type="checkbox" class="design_units" name="units[]" value="Bike"> Unit 2.1.1.1</td>
<td class="unit_table"><img class="color" alt="color" src="../images/video-selector-small.png"><img class="grey" alt="grey" disabled src="../images/video-selector-small-grey.png"></td>
<td class="unit_table"><img class="color" alt="color" src="../images/worksheet-selector-small.png"><img class="grey" alt="grey" disabled src="../images/worksheet-selector-small-grey.png"></td>
</tr>
<tr>
<td class="unit_table"><input type="checkbox" class="design_units" name="units[]" value="Bike"> Unit 3.1.1.1</td>
<td class="unit_table"><img class="color" alt="color" src="../images/video-selector-small.png"><img class="grey" alt="grey" disabled src="../images/video-selector-small-grey.png"></td>
<td class="unit_table"><img class="color" alt="color" src="../images/worksheet-selector-small.png"><img class="grey" alt="grey" disabled src="../images/worksheet-selector-small-grey.png"></td>
</tr>
</tbody>
</table>
Note that when dealing with a single checkbox this.checked
gives you the same boolean value as $(this).is(':checked')
, except it is easier to read, faster to type, and faster to execute.
(Note: in the demo above I've given the images an alt
attribute so that you can tell whether they're the .color
or .grey
ones without needing valid src
paths.)
EDIT: If the table is dynamically generated in the sense of being loaded via Ajax after the initial page load then replace the following line:
$(".design_units").click(function() {
...with:
$(document).on("click", ".design_units", function() {
Where ideally document
would be replaced by the nearest parent element that is static.
Upvotes: 1
Reputation: 299
$("body").on("change", ".design_units", function(){
//Your code
});
You can use other selector instead of "body", if that is present on page while event binding.
Use find and closest to find the exact elements in your case. for eg. -
$(this).closest('tr').find('.grey').hide();
Upvotes: 1
Reputation: 2474
You need to iterate through each img
as
$(document).ready(function()
{
$(".design_units").click(function ()
{
if ($(this).is(':checked'))
{
$(this).parent().nextAll('td').find('img').each(function(){
if($(this).attr('class') == 'color')
{
$(this).css('display','block');
}else if($(this).attr('class') == 'grey')
{
$(this).css('display','none');
}
})
/*change all of the img elements of class grey to display: none
and change all img elements of class color to display:block*/
}
if (!$(this).is(':checked'))
{
$(this).parent().nextAll('td').find('img').each(function(){
if($(this).attr('class') == 'grey')
{
$(this).css('display','block');
}else if($(this).attr('class') == 'color')
{
$(this).css('display','none');
}
})
/*change all of the img elements of class grey to display:block
and change all img elements of class color to display:none*/
}
});
});
Working fiddle : https://jsfiddle.net/gaq23jbL/3/
Upvotes: 0
Reputation: 191
You might use the .parents()
selector to get the appropriate table row, then search for the image you want within that row. Here's an example solution to your problem following that pattern:
$('.design-units').on('change', (e)=>{
const $row = $(e.target).parents('tr');
const $grays = $row.find('.grey');
const $colors = $row.find('.color');
const isChecked = $(e.target).is(':checked');
if(isChecked){
$grays.attr('disabled', false);
$colors.attr('disabled', true);
} else {
$grays.attr('disabled', true);
$colors.attr('disabled', false);
}
})
Upvotes: 0
Reputation: 548
You can use closest()
to get the nearest ancestor with a particular tag, then find()
to get all children matching a jQuery selector under that ancestor.
I switched the images for buttons because we don't have access to the actual images, and closed the document.ready()
function:
$(document).ready(function()
{
$(".design_units").click(function ()
{
if ($(this).is(':checked'))
{
$(this).closest('tr').find('.grey').hide();
$(this).closest('tr').find('.color').show();
}
if (!$(this).is(':checked'))
{
$(this).closest('tr').find('.grey').show();
$(this).closest('tr').find('.color').hide();
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<head>
<meta charset="utf-8">
<title> Total Tutor </title>
<link type="text/css" rel="stylesheet" href="course.css">
<script src="../jquery.js"></script>
<style>
.color{display:none;}
.grey{display:block;}
</style>
</head>
<body>
<div>
<form>
<table id="units" >
<thead>
<tr>
<th>Units</th>
<th>Add Video</th>
<th>Add Worksheet</th>
<th>Add Quiz</th>
<th>Add Exam</th>
<th>Add Revision</th>
</tr>
</thead>
<tbody>
<!-- table rows will be dynamically generated based on a SQL query -->
<tr>
<td class="unit_table"><input type="checkbox" class="design_units" name="units[]" value="Bike"> Unit 2.1.1.1</td>
<td class="unit_table"><button class="color" src="../images/video-selector-small.png"><button class="grey" disabled src="../images/video-selector-small-grey.png"></td>
<td class="unit_table"><button class="color" src="../images/worksheet-selector-small.png"><button class="grey" disabled src="../images/worksheet-selector-small-grey.png"></td>
</tr>
<tr>
<td class="unit_table"><input type="checkbox" class="design_units" name="units[]" value="Bike"> Unit 3.1.1.1</td>
<td class="unit_table"><button class="color" src="../images/video-selector-small.png"><button class="grey" disabled src="../images/video-selector-small-grey.png"></td>
<td class="unit_table"><button class="color" src="../images/worksheet-selector-small.png"><button class="grey" disabled src="../images/worksheet-selector-small-grey.png"></td>
</tr>
</tbody>
</table>
<button type="submit" id="save_design_course" name="sent" value="save_design_course"><img src="../images/save.png"></button>
</form>
</div>
</body>
</html>
Upvotes: 0
Reputation: 12176
You have lot of syntax errors in the script block.
You can use closest() and find tr and access the color and grey classes
$(document).ready(function(){
$(".design_units").on('click',function(){
if ($(this).is(':checked')) {
/*change all of the img elements of class grey to display: none
and change all img elements of class color to display:block*/
$(this).closest('tr').find('.color').show();
$(this).closest('tr').find('.grey').hide();
}
if (!$(this).is(':checked')){
/*change all of the img elements of class grey to display:block
and change all img elements of class color to display:none*/
$(this).closest('tr').find('.color').hide();
$(this).closest('tr').find('.grey').show();
}
});
});
Upvotes: 3