Ian Vink
Ian Vink

Reputation: 68790

Adding a class to children with condition

$('tbody[role=rowgroup] tr').each(function() {
    if ($(this).has('SPAN.isclosed')) {
        $(this).find("td").addClass('isclosed');
    }
});

I am trying to add the class isclosed to all the TDs of the items that match the selector tbody[role=rowgroup] tr which has a child Span with a class isclosed.

This applies the isclosed to every td though?

Upvotes: 0

Views: 255

Answers (2)

Daerik
Daerik

Reputation: 4277

I know that this was already answered, but I wanted to present two more examples using jQuery's .toggleClass. One example uses a boolean as a state determining whether to add or remove a class name. The other example uses a function to determine which class name to add.

/* .toggleClass( className, state ) */
$('tbody[role="rowgroup1"] tr').each(function() {
    var condition = !!$(this).find('span.isclosed').length;
    $(this).find('td').toggleClass('isclosed', condition);
});

/* .toggleClass( function [, state ] ) */
$('tbody[role="rowgroup2"] tr td').toggleClass(function() {
    var condition = $(this).parents('tr').find('span.isclosed').length;
    if(condition) {
        return 'isclosed';
    }
});

/**
 * NOTE: $(this).length works with the IF statement only because
 * it returns either 0 or 1+, but you'll need a boolean for STATE.
 */
td.isclosed {
    background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<h1>Test Table 1</h1>
<table>
    <tbody role="rowgroup1">
        <tr>
            <td>
                <span>Demo</span>
            </td>
        </tr>
        <tr>
            <td>
                <span>Demo</span>
            </td>
        </tr>
        <tr>
            <td>
                <span class="isclosed">Demo</span>
            </td>
        </tr>
        <tr>
            <td>
                <span>Demo</span>
            </td>
        </tr>
    </tbody>
</table>

<h1>Test Table 2</h1>
<table>
    <tbody role="rowgroup2">
        <tr>
            <td>
                <span>Demo</span>
            </td>
        </tr>
        <tr>
            <td>
                <span>Demo</span>
            </td>
        </tr>
        <tr>
            <td>
                <span class="isclosed">Demo</span>
            </td>
        </tr>
        <tr>
            <td>
                <span>Demo</span>
            </td>
        </tr>
    </tbody>
</table>

Upvotes: 1

Barmar
Barmar

Reputation: 781761

.has() doesn't return a boolean, it returns all the elements of the collection that match the condition. Any jQuery collection is truthy.

You could write:

if ($(this).has("span.isclosed").length > 0)

but it's simpler to just just use .has() on the entire original collection, instead of using .each().

('tbody[role=rowgroup] tr').has("span.isclosed").find("td").addClass("isClosed");

Upvotes: 2

Related Questions