Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery traversing elements get all previous elements that match selector

I have a collection of divs that contain either images or checkboxes. My end goal is to have the onclick event on the checkbox also check all previous checkboxes.

Here is my layout (dynamically created so id #'s can change based on page load data):

   <div id="Main1">
      <div id="Secondary1">
         <div id="div1">
            <img id="section1" src="image1" alt="" />
            <span>Div 1 text</span>
          </div>
         <div id="div2">
            <img id="section2" src="image2" alt="" />
            <span>Div 2 text</span>
          </div>
         <div id="div3">
            <input type="checkbox" id="section3">
             Div 3 text
             </input>
         </div>
         <div id="div4">
            <input type="checkbox" id="section4">
             Div 4 text
             </input>
         </div>
         <div id="div5">
            <input type="checkbox" id="section5">
             Div 5 text
             </input>
         </div>
         <div id="div6">
            <input type="checkbox" id="section6">
             Div 6 text
             </input>
         </div>
      </div>
   </div>

I want to be able to check the section5 and have it auto check the previous checkboxes.

The code I've been using, which is producing sporadic results is below:

$('input[id^=section]').click(function() {
   if($(this).attr('checked')) {
       var slide = $(this).attr('id').replace('section', '');
       $(this).replaceWith('<img src="images/ajax-loader.gif" id="loader" alt="" />'); //replace checkbox with loader animation
       $.ajax({
            type: 'POST',
            url: 'URL to AJAX page',
            data: '{ data for ajax call }',
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            success: function() {
               $('#loader').parents('div[id^=Secondary]').children('div[id^=section]').each(function() {
                    if($(this).children('input[id^=section]').attr('id') != undefined) {
                          if($(this).children('input[id^=section]').attr('id').replace('section', '') < slide) {
                             $(this).children('input[id^=section]').replaceWith('<img src="images/checkmark.gif" alt="" />');
                       }
                    }
              });
            },
            error: function() {
                   //handle errors
            }
        });
   }
});

Seems to me I'm going about this inefficiently, I had tried .prev() and .prevAll() but without success. However I could have been using them incorrectly as well. Any assistance is appreciated.

like image 869
jon3laze Avatar asked Feb 02 '26 14:02

jon3laze


1 Answers

Try this: http://jsfiddle.net/kgc4M/

if(this.checked) {
    $(this).closest('div').prevAll('div:has(:checkbox)')
                         .find(':checkbox').attr('checked','checked');

}

EDIT: From your comment, you want to use .replaceWith() to replace the checkbox with an image, yet reuse the ID of the checkbox.

Try this:

if(this.checked) {
    $(this).closest('div').prevAll('div:has(:checkbox)')
                .find(':checkbox')
                .replaceWith(function() {
                      return "<img src='/some/path.jpg' id='" + this.id + "' />";
                }).remove();
}

Note that I'm also calling unbind() on the checkboxes being replaced, since I don't think replaceWith() will clean that up for you. I'll double check though.

EDIT: Appears as though .replaceWith() removes the events and data, but keeps an entry in jQuery.cache for the removed elements. To be thorough, I got rid of unbind() but added .remove() at the end, which completely removes them from the cache.

like image 84
user113716 Avatar answered Feb 05 '26 02:02

user113716



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!