20

I have this button:

<button type="button" class="themeChanger" data-themeValue="grid" value="Grid">
   <img src="templateImages/Icon_200.png" />                
</button>

And this jQuery:

$(".themeChanger").click(function () { 
    alert($(this).attr("data-themeValue")); 
    alert($(this).data("themeValue")); 
});

For some reason the first alert shows "grid" like it should, but the second shows undefined. Is there something stupid I'm missing?

0

4 Answers 4

33

I think data will look on lowercases: alert($(this).data("themevalue")) //grid

or if you want to use themeValue you need to use:

edit:

I was wrong, it doesnt have anything to do with lowercases, you can use themeValue if you are having the attribute: data-theme-value then you call itwith $(element).data("themeValue")

<button class="themeChanger" data-themeValue="Theme1" data-theme-value="Theme2"></button>

$(".themeChanger").click(function() {
    var el = $(this);

    alert($(this).data("themeValue")); //Theme2
    alert($(this).data("themevalue")); //Theme1
});
Sign up to request clarification or add additional context in comments.

1 Comment

It is hyphenation & camel-casing more than lower case that was the issue with the OP's question
25

As noted in this Learning jQuery article, HTML5 data-* attributes are handled by the browser->JS conversion in the same way that CSS names are handled--that is:

  1. the leading data- is removed (a step not needed in the CSS name comparison I drew above)
    • data-specialInfo becomes specialInfo
    • data-more-specialInfo becomes more-specialInfo
  2. the remaining attr name is split on -
    • specialInfo becomes [ specialInfo ]
    • more-specialInfo becomes [ more, specialInfo ]
  3. the first of the resulting split parts is dropped to all lower case
    • [ specialInfo ] becomes [ specialinfo ]
    • [ more, specialInfo ] becomes [ more, specialInfo ] (no change as first part was already lower)
  4. the rest of the resulting split parts are dropped to lower case, but their first letter is made upper case
    • [ specialinfo ] becomes [ specialinfo ] (no change because there were no other parts)
    • [ more, specialInfo ] becomes [ more, Specialinfo ]
  5. The now case-modified parts are rejoined on empty string
    • [ specialinfo ] becomes specialinfo
    • [ more, Specialinfo ] becomes moreSpecialinfo

This being the case, your data-themeValue attribute is accessible via $(this).data("themevalue"). Whereas a data-theme-value attribute would be accessible via $(this).data("themeValue").

It's terribly confusing unless you recognize the mechanism in use.

4 Comments

I don't really understand what you mean. Who is "they"? Anyway, the above process is necessary (and not actually all that complicated) due to sytanx differences between HTML and JavaScript.
Thanks for this answer. I find it quite annoying - why does jQuery enforce me to use a specific notation?
No problem, glad it helped. The data attr API exists in a certain form without jQuery in many modern browsers. jQuery is providing it where it does not already exist, and augmenting it where it does. This being the case, they must make it compatible. Its not really all that bad anyway--just gotta get used to it. It's no different than setting CSS values from JS.
BRAVO @JAAulde excellent examples... can't think of a better way to summarize the perils/gotchas of "data-*" attributes! I suppose that's a good reason to stick to kebab case and never use camelCase "data-" attributes.
5

The problem is the camel case. For clarity I'd stick to the data-theme-value format for your attributes.

http://jsfiddle.net/NkHEx/2/

jquery automatically converts .data('some-value') to data('someValue')

Note that both alert calls return grid

Comments

4

I think it is the camel casing of hyphenated words in the data tag implementation that is the gotcha here

Try this jsfiddle - http://jsfiddle.net/FloydPink/fb6Y6/

<button type="button" class="themeChanger" data-theme-value="grid" value="Grid">
   data-theme-value                
</button>

<button type="button" class="themeChanger" data-themeValue="grid" value="Grid">
   data-themeValue
</button>

$(".themeChanger").click(function () {
    alert($(this).attr("data-themeValue"));
    alert($(this).data("themeValue"));
});

Comments

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.