Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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
}

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');
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top