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.
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.
.prev()
and .prevAll()
select siblings. Even though the checkboxes are on the same level of the DOM tree, they are not siblings. Siblings must share the same immediate parent. Those checkboxes are more like cousins.
Try something like this inside your click event:
if(this.checked) {
$(this).parent().prevAll().children(':checkbox').attr('checked', 'checked');
}
Here's a demo: http://jsfiddle.net/dTK6n/
精彩评论