2

I have data attributes I'm using for options on a table, for example:

<table data-do-something-neat>
...
</table>

I'm using HAML to define them:

%table{ data: { do_something_neat: true } }
  ...

In HAML it's an HTML5 formatted page, so it's behavior is to drop the value if it's a boolean and true. If it were set to false, it would be gone, like so:

<table>
...
</table>

All this seems fine, but accessing whether that flag is true or false in jQuery is a bit of a pain, and I can't find any definitive reference on how to do it.

For the first table, the following is true:

table.is('[data-do-something-neat]') # true
table.attr('data-do-something-neat') # '' (empty string)
table.data('do-something-neat')      # '' (empty string)

And for the second table:

table.is('[data-do-something-neat]') # false
table.attr('data-do-something-neat') # undefined
table.data('do-something-neat')      # undefined

So attr and data return something falsy for a true HTML5 data attribute. Is this expected? Is there another data method that could be used? Or am I stuck using is in this way? It's unfortunate to have to use a special method for boolean attributes, instead of just using data for all data attributes.

2
  • Is there a reason other than cleanliness to not always output the attribute? <table data-do-something-neat="true/false"> Commented Apr 23, 2014 at 19:42
  • I'm using HAML for templating, and it handles boolean attributes in this way. Commented Apr 23, 2014 at 20:33

3 Answers 3

1

It kind of makes sense that you're stuck using .is(). Some data attributes should be treated as Booleans, and some should be treated as strings.

Imagine if attr() returned true for an empty string; it would be difficult to test for, and in order to have it properly appear as 'null', your server code would need to write:

<table
<?php if $accountId != null {?>
  data-accountId="<?php echo $accountId; ?>"
<?php } ?> >

(The emphasis being on the outside null-checking condition). But, since it returns an empty string, you can simply use javascript and use any standard "is empty string" method you prefer, or just check "if length == 0" if you know the attribute should always be printed from the server.

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

2 Comments

Fair enough. The argument that it would be more difficult to test for does make a lot of sense. I guess my beef is with Javascript treating an empty string as falsy.
@NickVeys In fact, I have to admit - I was halfway through a reply in which I explained that the inverse was true ("" evaluates true). Then, just to be sure, I did a test in another browser and was surprised to find it wasn't the case.
1

The difference is that if the attribute is not there, $.attr and $.data return undefined, if it's there without a value, it returns an empty string, which is the expected behavior, as far as I know.

What is the problem with checking?

if (typeof table.attr('data-do-something-neat') !== 'undefined') {
    // attribute exists, but it could be the empty string
}

If you want a more straight forward way to test it, you can use Element.hasAttribute

if (table[0].hasAttribute('data-do-something-neat')) {
     // attribute exists, but it could be the empty string
}

1 Comment

Nothing wrong with checking that way of course, but when things are inconsistent I figure I must not know everything I need to. I guess it's not jQuery's fault that "" is falsy. hasAttribute may come in handy. Thanks!
1

I would just use a selector and check for the existance of a correctly selected element:

$('table[data-do-something-neat]').length !== 0

or

$('#A').attr('myattr') !== undefined // If attribute exists

That's what's noted in this SO question: Select elements by attribute

Or if you can go without jQuery there are native DOM methods that will suffice:

Element.hasAttribute('data-do-something-neat');

1 Comment

That's what $.is does

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.