Handler
Handler

Reputation: 57

jquery toggleclass with different classes only the first function works

In an unordered list the li tag can either have a class of open (green) or closed (red).

<li class="open">
    <div class="field">U8</div>
    <input type="hidden" name="status" id="status" value=1>
    <div class="status">OPEN</div>
</li>
<li class="closed">
    <div class="field">U10</div>
    <input type="hidden" name="status" id="status" value=0>
    <div class="status">CLOSED</div>
</li>

At the bottom of the document before the closing body tag I have

$(document).ready(function () {
    $("li.open").click(function () {
        $(this).toggleClass("closed");
    });

    $("li.closed").click(function () {
        $(this).toggleClass("open");
    });
});

The first function li.open works fine! The second li.closed does not do anything. =| I'm just getting my feet wet with javascript and jquery. So explain to me like I'm an idiot (which is partly true) what I did or am doing wrong!

In the end I wish to not only change the color but the value of the hidden input and change the OPEN to a CLOSED and vice versa.

I'm just boggled as why this doesn't work. I even made classes open0, open1, closed0 and closed1 and used the 0's for the first function and 1's for the second. Same results.

Appreciate the help/guidance/chiding =)

Upvotes: 0

Views: 1125

Answers (2)

isherwood
isherwood

Reputation: 61083

TrueBlueAussie is right, but a simpler solution may be to target the list items in a more general fashion, then update other elements based on the current class. I assume here that you have a class of open or closed on all list items initially.

$(document).on('click', 'ul#myList li', function () {
    $(this).toggleClass('open closed');

    if ($(this).hasClass('open')) {
        $(this).find('.myHiddenInputClass').val('OPEN');
        $(this).find('.myTextDivClass').text('OPEN');
    } else {
        $(this).find('.myHiddenInputClass').val('CLOSED');
        $(this).find('.myTextDivClass').text('CLOSED');
    }
});

Demo

Notice that I target the inputs and text divs by DOM traversal and class, not by ID.

Upvotes: 0

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93601

You are trying to bind events to classes that do not exist at the time of binding. You are binding a single event handler to the first LI and a single event handler to the second LI.

The following uses delegated event handlers, attached to a non-changing ancestor element (in this case document).

It works by listening for the click event to bubble up to the ancestor, then applies the selector, then applies the function to each matching element that caused the event.

$(document).ready(function () {

    $(document).on("click", "li.open", function () {
        $(this).toggleClass("closed");
    });

    $(document).on("click", "li.closed", function () {
        $(this).toggleClass("open");
    });

});

The advantage is you can listen for events on elements (or classes) that do not exist yet.

Assuming you do not want any other code to execute it can be shortened to a single handler to toggle both classes (as isherwood describes).

Note: Your original code does something quite odd, in that it can wind up with both open and closed set on an item. That is probably not what you intended, but I could not make any assumptions :)

I would expect you actually wanted something like this: http://jsfiddle.net/L4t6h8sa/1/

$(function () {

    $(document).on("click", "li.open,li.closed", function () {
        $(this).toggleClass("closed open");
    });
});

Upvotes: 1

Related Questions