5

I have a live -on click- event for a Header which has an arrow flipping up/down upon opening & closing it's contents.

The strangest thing is happening with ! followed by a variable -- which is supposed to flip it from true -> false, and vice versa. Basically it's not working at all, and it flips to false and stays there... Check out the fiddle to see what I mean.

I've deleted lots of code for the sake of brevity.

Demo Code

$(document).on('click', '.regimenHeader', function () {
    var _state = $(this).attr('data-state');

    if (_state === 'true') {
        // do stuff
    }

    else { 
        // do stuff
    }

    // This is where the issue is happening, it isn't flipping the Boolean value
    // !"true" = false, !true = false, it works with strings or booleans
    $(this).attr('data-state', !_state);
});​

I can get it working perfectly fine if I do the following:

    if (_state === 'true') {
        // Manually flip the data-state boolean
        $(this).attr('data-state', false);
    }

Is there something I'm missing why this isn't working the way it should ?? Just wondering why it's doing this!

4 Answers 4

10

I think you are trying to do this:

http://jsfiddle.net/JKUJb/2/

if so, the problem was that you are using .attr() which returns a string, so if you convert:

!"true" //false

!"false" //false

.data() on the other hand returns the value already "casted

EDIT:

Just to be more clear, in javascript the only falsy values are:

false;
null;
undefined;
'';
0;
NaN;

So if you really wanted to use .attr(), you could, but I recommend that first you do:

var _state = $(this).attr('data-state') === 'true'; //if 'true' then true, false otherwise

Good luck!

Sign up to request clarification or add additional context in comments.

2 Comments

Next time i'll stick to .data() haha. I simply wanted it to be visible in [data-state] so I could search for all of them as opposed to looping through all headers and then seeing if they have `.data('state') === true etc. Appreciate the help though!
Glad I helped, if you're having some information in an element, .data() it's probably what you're looking for :). Just in case you want to see some performance test: jsperf.com/jquery-data-vs-attr/22
2

Change your second line to:

var _state = $(this).attr('data-state') == 'true';

And in the if statement check for boolean:

if ( _state ) {
 // do stuff
 ...

1 Comment

Boom there it is... I just needed to turn it into a Boolean, thanks Vlad. Works like a charm: jsfiddle.net/JKUJb/4
1

_state is a String (typeof _state === String //true) you need to convert it to a boolean first (a String will alwase be true)

Comments

1

If you really want to use data- attributes for this, use jQuery's .data method to retrieve and set the value. It will automatically convert the string "true" into a Boolean, or the string "1" into a number:

$(document).on('click', '.regimenHeader', function () {
    var _state = $(this).data('state');
    if (_state) {
        // do something
    }
    $(this).data('state', !_state);
});​

http://jsfiddle.net/mblase75/JKUJb/6/

Or you could toggle a class -- you can use the .hasClass method to return a Boolean:

$(document).on('click', '.regimenHeader', function () {
    var _state = $(this).hasClass('data-state');
    if (_state) {
        // do something
    }
    $(this).toggleClass('data-state');
});​

http://jsfiddle.net/mblase75/JKUJb/3/

1 Comment

I thought about doing it, at this point just wanted to figure out why data- was acting so strange, but I see now, it keeps coming back as a string and i'm not testing it here: var _state = $(this).attr('data-state') === 'true'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.