Adam Rackis
Adam Rackis

Reputation: 83356

jQuery closest with attribute filter

Does jQuery 1.5.1 support attribute selectors in the closest method?

Given the structure below, el represents the checkbox with the value 513, and I'm trying to reach up and check the ancestor checkbox with the value of 0 with

$(el).closest("input[value='0']")[0].checked = true;

but the selector is returning nothing.

Am I missing something silly?

enter image description here


EDIT

Sigh, so the checkbox with value 0 isn't an ancestor to el, just a sibling of the ul ancestor. I got it to work with

$(el).closest("ul").siblings("input[value='0']")[0].checked = true;

But us there a cleaner way to grab it?

Upvotes: 5

Views: 36071

Answers (5)

Pluckerpluck
Pluckerpluck

Reputation: 731

I believe that you shouldn't need the [0] as .closest only returns the first element found unlike parents() which returns multiple.

$(el).closest("input[value='0']").prop("checked") = true;

is the way I would prefer to do it.

This is assuming you are trying to check the "value 0" checkbox when you check the check the 513 box.

Edit: Sorry, misread this. In reality you need to try and get the <\li> tag and then get the underlying checkbox. Where you are actually looking for the checkbox which is not a direct parent.

Edit 2: You realize your edit doesn't work right? Wait... it would... you used siblings not children my mistake.

Edit 3: How about using:

$(el).parents().get(':eq(2)').children(':first-child');

or are we not assuming the layout is fixed?

Upvotes: 2

nnnnnn
nnnnnn

Reputation: 150050

The .closest() method does support attribute selectors the same as any other jQuery method (although I don't know about the specific version of jQuery you mentioned), but the problem here is that .closest() doesn't just look in the general vicinity, it goes up through the ancestors. You are trying to select an input element that is not an ancestor of the element you are starting with. (Given that inputs can't contain other elements they will never be the ancestors of anything...)

You should be able to do it by selecting the target checkbox's parent li element first:

$(el).closest('li:has(input[value="0"])')
     .find('input[value="0"]').prop("checked",true);

Demo: http://jsfiddle.net/Vpzyj/

Of course if you were able to add a class to the top level menu items you wouldn't need to mess around with ":has", you could just say:

$(el).closest('li.topMenu').find('input[value="0"]').prop("checked",true);

Upvotes: 25

Bruno Silva
Bruno Silva

Reputation: 3097

Regarding your question: yes, it does (http://api.jquery.com/closest/)

Your code does not work because closest() goes up through the DOM tree and in your case it would have to go up and and down because your checkbox 0 is not an ancestor of checkbox 513.

Upvotes: 1

PeeHaa
PeeHaa

Reputation: 72672

Closest checks up the DOM tree and not on the same level.

Upvotes: 1

DraganS
DraganS

Reputation: 2699

Check for: http://api.jquery.com/closest/

.closest( selector ) // version added: 1.3

Upvotes: 2

Related Questions