jon
jon

Reputation: 407

How do I use jQuery to change the CSS of direct img sibling elements matching a class conditional

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

Answers (8)

Mark
Mark

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

vikash kumar tiwari
vikash kumar tiwari

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>

js-fiddle

Upvotes: 0

nnnnnn
nnnnnn

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

Rohit Verma
Rohit Verma

Reputation: 299

  1. If it is gonna generate dynamically use on as

$("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.

  1. Use find and closest to find the exact elements in your case. for eg. -

    $(this).closest('tr').find('.grey').hide();

Upvotes: 1

Rahul
Rahul

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

JWayne
JWayne

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

Cuagau
Cuagau

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

karthick
karthick

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

Related Questions