65

I am trying to set a variable in jQuery. The value is supposed to be set on the click event of the button. The onclick event fires but the x10Device variable remains undefined.

I am on jquery 1.7.1.

jQuery:

 $x10Device = $(this).data("X10");

HTML:

<button class="toggleStatus" data-X10="C5">

I can't see what's wrong.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Jason Millington
  • 691
  • 1
  • 5
  • 11

6 Answers6

133

jQuery's data() method will give you access to data-* attributes, BUT, it clobbers the case of the attribute name. You can either use this:

$('#myButton').data("x10") // note the lower case

Or, you can use the attr() method, which preserves your case:

$('#myButton').attr("data-X10")

Try both methods here: http://jsfiddle.net/q5rbL/

Be aware that these approaches are not completely equivalent. If you will change the data-* attribute of an element, you should use attr(). data() will read the value once initially, then continue to return a cached copy, whereas attr() will re-read the attribute each time.

Note that jQuery will also convert hyphens in the attribute name to camel case (source -- i.e. data-some-data == $(ele).data('someData')). Both of these conversions are in conformance with the HTML specification, which dictates that custom data attributes should contain no uppercase letters, and that hyphens will be camel-cased in the dataset property (source). jQuery's data method is merely mimicking/conforming to this standard behavior.

Documentation

Chris Baker
  • 49,926
  • 12
  • 96
  • 115
  • 2
    Also with .data(), when you use Camel Case like $(this).data("giveMeMyBananas") it will retrieve the html data of data-give-me-my-bananas="NO!" – Kalzem Jun 27 '13 at 19:16
  • 1
    Added that note, @BabyAzerty, as well as part of the reason for it (the HTML spec dictates custom attributes contain no capital letters) – Chris Baker Jun 27 '13 at 19:18
  • @JasonMillington Glad to help! Check the note I put in about `attr()` vs. `data()` -- you might be more interested in `attr()` anyway, depending on how you will use the attributes. – Chris Baker Jun 27 '13 at 19:57
  • I also found that `data()` will return an integer e.g. `1` whereas `attr()` returns a string, e.g. `"1"`. This just means use `==` to compare, instead of `===`. – Mirror318 May 17 '16 at 04:55
  • I would rather say that data() stores the data in memory, while attr() stores on the DOM (html), so do not mix both functions when dealing with one specific element. So it means that you will never face the problem with the cached value from data() – Barbz_YHOOL Feb 24 '21 at 19:55
  • Surely whether stored in cache/memory or DOM, changing the data value should change the data value. I appreciate and am helped by the warning about using attr when the data value will change but it make *no* sense to me that calling data to set a new value doesn't just reset the cache value as well. – wwkudu Nov 22 '22 at 06:56
3

Iyap . Its work Case sensitive in data name data-x10

var variable = $('#myButton').data("x10"); // we get the value of custom data attribute

Mayank
  • 1,351
  • 5
  • 23
  • 42
Indra
  • 31
  • 1
2

Make sure to check if the event related to the button click is not propagating to child elements as an icon tag (<i class="fa...) inside the button for example, so this propagation can make you miss the button $(this).attr('data-X10') and hit the icon tag.

<button data-x10="C5">
    <i class="fa fa-check"></i> Text
</button>

$('button.toggleStatus').on('click', function (event) {
    event.preventDefault();
    event.stopPropagation();
    $(event.currentTarget).attr('data-X10');
});
Everton Z. P.
  • 371
  • 3
  • 8
1

Use plain javascript methods

$x10Device = this.dataset("x10");
Yana Agun Siswanto
  • 1,932
  • 18
  • 30
1

Changing the casing to all lowercases worked for me.

Marvin Glenn Lacuna
  • 1,682
  • 1
  • 19
  • 25
1

You can change the selector and data attributes as you wish!

 <select id="selectVehicle">
       <option value="1" data-year="2011">Mazda</option>
       <option value="2" data-year="2015">Honda</option>
       <option value="3" data-year="2008">Mercedes</option>
       <option value="4" data-year="2005">Toyota</option>
  </select>

$("#selectVehicle").change(function () {
     alert($(this).find(':selected').data("year"));
});

Here is the working example: https://jsfiddle.net/ed5axgvk/1/

curiousBoy
  • 6,334
  • 5
  • 48
  • 56