views:

170

answers:

6

Here is my html:

<form>
    <dl>
        <dt>&nbsp;</dt>
        <dd><input type="hidden"></dd>

        <dt>Dont hide this one</dt>
        <dd><input type="text"></dd>
    </dl>
</form>

I'm using jQuery to hide the dt/dd elements where the input type is hidden with this code:

$("input[type=hidden]").each(function() {
    $(this).parent().hide().prev().hide();
});

But I also only want to apply this to dts where the text is &nbsp;. How can I do this sort of select?

Update: Maybe I need to clarify: A few people have posted answers where it hides the dd before checking if the content of the dt is also &nbsp;. Both conditions must be true before hiding both the dt and dd.

Final Solution: Here's what I ended up with:

$('input[type=hidden]').filter(function() {
    return $(this).closest('dd').prev('dt').html() === '&nbsp;';
}).each(function() {
    $(this).closest('dd').hide()
           .prev('dt').hide();
});
+1  A: 

Use the contains selector:

$("dt:contains('&nbsp;')").hide();

Scharrels
+1  A: 
$("input[type=hidden]").each(function() {
    $(this).closest('dd').hide()
           .prev('dt').hide();
});

This code finds the closest parent of the input with tag dd, hides it, then looks for a dt sibling and hides it as well.

Emil Ivanov
+1 for cleaning up my code and making it more readable. =]
Andrew
+3  A: 
$("input[type=hidden]").filter(function() {
    return $(this).parent().prev('dt').html() === "&nbsp;";
}).each(function() {
    $(this).parent().hide().prev().hide();
});

This will not select <dt>foo&nbsp;bar</dt>

which contains('&nbsp;') would.

More concisely (with credit to Emil's answer)

$("input[type=hidden]").filter(function() {
    return $(this).closest('dd').prev('dt').html() === "&nbsp;";
}).closest('dd').hide().prev('dt').hide();
cobbal
Sorry, misunderstood what you were trying to do. Updated now
cobbal
perfect! thank you!
Andrew
A: 

As people have already reposted answers... and I can't comment yet cobbal's code is missing this:

$("input[type=hidden]").each(function() {
$(this).parent().hide().prev().filter(function() {
    return $(this).html() === "&nbsp;";
}).hide();

});

return
Skawful
this doesn't work. it hides the dd before checking if the content of the dt is also  . Both conditions must be true before hiding both the dt and dd.
Andrew
A: 

The contains selector doesn't match the whole content, so it might work for you, but is not an ideal solution. The correct way to do this is to use the filter function:

$('input[type=hidden]').filter(function() {
   return $(this).prev().html() == '&nbsp;'
})
.each(function() {
   $(this).hide();
   $(this).prev().hide();
});
eWolf
this doesn't work. it end up hiding the entire dl. I am only trying to hide the dt and dd where the dt contains   and the dd contains a hidden form element.
Andrew
Oh, I didn't unterstand the question correct, I'm sorry. I changed the code now.
eWolf
A: 

This also does the trick (adapted from an earlier version of cobbal's answer):

$("input[type=hidden]").each(function() {
    if ($(this).parent().prev().filter(function() {
        return $(this).html() === "&nbsp;";
    }).hide().length > 0) {
        $(this).hide();
    }
});
Jeff Sternal
I don't think an empty jQuery set evaluates to false, wouldn't the if statement always execute?
cobbal
D'oh, thank you. Fixed now.
Jeff Sternal