223

Is there some way that I can run the following:

var data = $("#dataTable").data('timer');
var diffs = [];

for(var i = 0; i + 1 < data.length; i++) {
    diffs[i] = data[i + 1] - data[i];
}

alert(diffs.join(', '));

Only if there is an attribute called data-timer on the element with an id of #dataTable?

Huangism
  • 16,278
  • 7
  • 48
  • 74
Angela
  • 3,269
  • 3
  • 22
  • 24
  • One caveat to be aware of is that sometimes there won't be anything stored in a `data-` attribute but there will be data stored in jQuery and vice versa. – Alex W Jun 21 '16 at 19:33

15 Answers15

359
if ($("#dataTable").data('timer')) {
  ...
}

NOTE this only returns true if the data attribute is not empty string or a "falsey" value e.g. 0 or false.

If you want to check for the existence of the data attribute, even if empty, do this:

if (typeof $("#dataTable").data('timer') !== 'undefined') {
  ...
}
James McCormack
  • 9,217
  • 3
  • 47
  • 57
niiru
  • 4,982
  • 1
  • 17
  • 13
  • 37
    Another option for you: `if ($("#dataTable[data-timer]").length) { ... }`. – VisioN Aug 28 '12 at 14:15
  • 108
    Be careful! This only evaluates to true if data-timer has a value. If it's present, but empty it will return false. – Kong Jun 17 '13 at 02:43
  • 17
    Kong is right, if there is an empty value your code doesnt work. Use this instead : if (typeof $("#dataTable").attr('data-timer') !== "undefined") { ... } – PierrickM Aug 08 '13 at 15:45
  • 22
    Yet another version that gives you an actual boolean for your conditional: `if ( $("#dataTable").is("[data-timer]") ) { ... }`. It's also more useful if you already have a reference to the table in another jQuery object. – Noyo Dec 10 '13 at 11:01
  • 1
    niiru and @VisioN: important to note that your code won't work if the data attribute is added dynamically, whereas flem's code below will. – sterfry68 Sep 30 '14 at 04:33
  • 1
    @sterfry68 You shouldn't mix data *attribute* and data *property*: `$el.data('timer', 'value')` will never set an attribute to HTML element, while `$el.attr('data-timer', 'value')` will set. So it depends on which approach you decide to go for. – VisioN Sep 30 '14 at 07:09
  • 1
    @VisioN you're right. I meant, if the "data property" is set dynamically. – sterfry68 Sep 30 '14 at 15:34
  • 10
    It will return false if the value exists and is equal to 0. This is quirky. – Gherman Apr 07 '15 at 06:42
  • 1
    If the data attribute evaluates to false / zero, this method will imply that it doesn't exist – Sam Oct 24 '15 at 00:41
  • 4
    This is very WRONG answer - if attribbute exists but has no value it will be false. – Maciej Sikora Aug 02 '16 at 09:30
  • This is checking against the value of attribute, and that's unreliable. – Niki Romagnoli Mar 02 '17 at 07:47
  • Is there a way to check if this data attribute is set in css /less ? – Chaitanya Sep 25 '17 at 06:07
  • This updated answer indicates that jQuery needs some improvement. It's normal in HTML to indicate boolean states by the presence or absence of an attributed (e.g. 'checked' for checkboxes). It would be better if we had a way to access that with data attributes without having to compare to 'undefined' – Toby 1 Kenobi Nov 06 '18 at 06:42
  • 1
    I think you have a mistake here. The last option should be: `if (typeof $("#dataTable").data('timer') !== undefined) { ... }` – byzantine cucumber Jan 23 '19 at 18:36
  • The following gives you the HTML attributes that start with "data-": $('#someObject')[0].dataset while $.data() on the other hand is an internal method to jQuery for storing objects such as instances of widgets, see this answer: https://stackoverflow.com/questions/23596751/dataset-vs-data-difference – John Ernest Sep 26 '20 at 06:42
  • To elaborate further if you run the method .data('Test','somevalue') on an existing div it will add it to .data() method return but it will not add an attribute to the DOM. Looking at the inspector in Firefox right now I'm seeing it in an internal instance variable on the div in question's jQuery object $('#someDiv') called jQuery3410327181366300727142, just as an example, but it did not add a data--test attribute to the DOM. So be careful of this caveat when using the .data method. That means that it's read-only when it comes to attributes, you'll want to combine with the .attr() method too. – John Ernest Sep 26 '20 at 06:50
124
if (typeof $("#dataTable").data('timer') !== 'undefined')
{
    // your code here
}
Paul Fleming
  • 24,238
  • 8
  • 76
  • 113
  • @VisioN A fail-safe combination of your and [PierrickM](http://stackoverflow.com/users/775935/pierrickm)'s comment on [this](http://stackoverflow.com/a/12161190/192886) answer: `if (typeof $('#dataTable').data('timer') !== 'undefined') ...`. – WynandB Nov 20 '13 at 00:07
  • 3
    @Wynand. Updated to reflect yours and VisioN's comment. – Paul Fleming Nov 20 '13 at 14:43
  • 1
    @flem You also need to add in the `typeof` check – Brendan Bullen Nov 20 '13 at 14:46
  • 1
    @flem, @VisioN, your approaches fail in the case where there is no data attribute, but data has still been set with the .data() method, e.g. `$('#dataTable').data('timer', Date.now())`. It seems the OP wants to check that the actual data attribute is there. @niiru's solution (or the one you offer in a comment to that solution) is better, in this case. – Noyo Dec 10 '13 at 10:54
  • @Wynand There is no need in `typeof` here, as `.data()` will always return `undefined` even if the required property doesn't exist. jQuery is generally fail safe, no need to overcomplicate. – VisioN Sep 30 '14 at 07:13
  • 1
    @VisioN For me it's about checking for `undefined` in a consistent manner. We know why `typeof` is used to check for `undefined` in some cases, but I'd find it confusing to see it being checked _with_ `typeof` in one place and _without_ in another. Besides, it's not like using `typeof` adds a _lot_ more _complicated_ code. It may be more explicit, perhaps redundant at most but hardly overcomplicated. I see your point though, but I'd say that not using it would be oversimplification. ;] – WynandB Sep 30 '14 at 12:05
39

In the interest of providing a different answer from the ones above; you could check it with Object.hasOwnProperty(...) like this:

 if( $("#dataTable").data().hasOwnProperty("timer") ){
     // the data-time property exists, now do you business! .....
 }

alternatively, if you have multiple data elements you want to iterate over you can variablize the .data() object and iterate over it like this:

 var objData = $("#dataTable").data();
 for ( data in objData ){
      if( data == 'timer' ){
            //...do the do
      }
 }

Not saying this solution is better than any of the other ones in here, but at least it's another approach...

sadmicrowave
  • 39,964
  • 34
  • 108
  • 180
  • 9
    This is interesting, but it should be noted that if you have the attribute `data-foo-bar` then your check needs to be `.data().hasOwnProperty("fooBar")`, not `.data().hasOwnProperty("foo-bar")` – dgmstuart Sep 26 '15 at 01:03
  • Interesting in this instance with the javascript validator. The typeof returned undefined, but this worked! – Richard Housham Aug 15 '16 at 13:43
14

Or combine with some vanilla JS

if ($("#dataTable").get(0).hasAttribute("data-timer")) {
  ...
}
Max
  • 764
  • 7
  • 14
  • 1
    I like this one. However, you create the data using jQuery using `data()` instead of `attr()`, it will not find the attribute :( – Sam Jul 02 '20 at 11:55
13

If you want to distinguish between empty values and missing values you can use jQuery to check like this.

<div id="element" data-foo="bar" data-empty=""></div>

<script>
"foo" in $('#element').data(); // true
"empty" in $('#element').data(); // true
"other" in $('#element').data(); // false
</script>

So from the original question you'd do this.

if("timer" in $("#dataTable").data()) {
  // code
}
Ryan
  • 4,594
  • 1
  • 32
  • 35
13

All the answers here use the jQuery library.

But the vanilla javascript is very straightforward.

If you want to run a script only if the element with an id of #dataTable also has a data-timer attribute, then the steps are as follows:

// Locate the element
const myElement = document.getElementById('dataTable');

// Run conditional code
if (myElement.dataset.hasOwnProperty('timer')) {

  [... CODE HERE...]

}
Rounin
  • 27,134
  • 9
  • 83
  • 108
12

You can use jQuery's hasData method.

http://api.jquery.com/jQuery.hasData/

The primary advantage of jQuery.hasData(element) is that it does not create and associate a data object with the element if none currently exists. In contrast, jQuery.data(element) always returns a data object to the caller, creating one if no data object previously existed.

This will only check for the existence of any data objects (or events) on your element, it won't be able to confirm if it specifically has a "timer" object.

BZink
  • 7,687
  • 10
  • 37
  • 55
8

You can create an extremely simple jQuery-plugin to query an element for this:

$.fn.hasData = function(key) {
  return (typeof $(this).data(key) != 'undefined');
};

Then you can simply use $("#dataTable").hasData('timer')

Gotchas:

  • Will return false only if the value does not exist (is undefined); if it's set to false/null it hasData() will still return true.
  • It's different from the built-in $.hasData() which only checks if any data on the element is set.
Alex
  • 1,689
  • 18
  • 27
3

You can check by css attribute selection with

if ($('#dataTable').is('[data-timer]')) {
   // data-timer attribute exists
}
acme
  • 14,654
  • 7
  • 75
  • 109
  • 3
    Data values are not always stored as DOM attributes. When you modify data values with jQuery using $.data, it sets it as a element property. – qwerty Apr 15 '14 at 10:04
3

This is the easiest solution in my opinion is to select all the element which has certain data attribute:

var data = $("#dataTable[data-timer]");
var diffs = [];

for(var i = 0; i + 1 < data.length; i++) {
    diffs[i] = data[i + 1] - data[i];
}

alert(diffs.join(', '));

Here is the screenshot of how it works.

console log of the jquery selector

Animesh Singh
  • 8,382
  • 1
  • 17
  • 20
2

I've found this works better with dynamically set data elements:

if ($("#myelement").data('myfield')) {
  ...
}
JerSchneid
  • 5,817
  • 4
  • 34
  • 37
1

Wrong answer - see EDIT at the end

Let me build on Alex's answer.

To prevent the creation of a data object if it doesn't exists, I would better do:

$.fn.hasData = function(key) {
    var $this = $(this);
    return $.hasData($this) && typeof $this.data(key) !== 'undefined';
};

Then, where $this has no data object created, $.hasData returns false and it will not execute $this.data(key).

EDIT: function $.hasData(element) works only if the data was set using $.data(element, key, value), not element.data(key, value). Due to that, my answer is not correct.

1

I needed a simple boolean to work with. Because it's undefined of not present, and not false, I use the !! to convert to boolean:

var hasTimer = !!$("#dataTable").data('timer');
if( hasTimer ){ /* ....... */ }

An alternative solution would be using filter:

if( $("#dataTable").filter('[data-timer]').length!==0) { /* ....... */ }
Martijn
  • 15,791
  • 4
  • 36
  • 68
0
var data = $("#dataTable").data('timer');
var diffs = [];

if( data.length > 0 ) {
for(var i = 0; i + 1 < data.length; i++) {
    diffs[i] = data[i + 1] - data[i];
}

alert(diffs.join(', '));
}
Luceos
  • 6,629
  • 1
  • 35
  • 65
  • If `.data('timer')` is undefined you'll get a _TypeError: $(...).data(...) is undefined_ when checking `data.length`. This is most likely the basis of the OP's question, i.e. making sure that one can safely check `data.length` elsewhere. Besides, you wouldn't necessarily be able to say for sure whether `data` is a string, an array or an object, of which the latter may or may not contain `length` as a defined property. – WynandB Nov 20 '13 at 00:37
  • Yes my answer needs revision. Written in 2012.. But rewriting it would be useless as the answer is already given. – Luceos Nov 20 '13 at 07:38
0

And what about:

if ($('#dataTable[data-timer]').length > 0) {
    // logic here
}
dani24
  • 2,108
  • 2
  • 26
  • 28