353

I have a div with an attribute data-myval = "10". I want to update its value; wouldn't it change if I use div.data('myval',20)? Do I need to use div.attr('data-myval','20') only?

Am I getting confused between HTML5 and jQuery? Please advise. Thanks!

EDIT: Updated div.data('myval')=20 to div.data('myval',20), but still the HTML is not updating.

4
  • 2
    What is in div? A jQuery object or element? Commented Nov 23, 2012 at 6:31
  • 2
    div.data('myval')=20 wouldn't work to store a value only because the syntax is wrong - see the answers for the correct syntax. But note that .data() doesn't actually update the element attribute, it stores the data elsewhere. Commented Nov 23, 2012 at 6:40
  • For those who has the sense to avoid gQuery use this -> div.dataset.myval = '20'; Commented Jun 9, 2020 at 13:00
  • 2
    I feel bad saying this, but IMHO, users should completely ignore the highest voted answer and read one of the others. After over an hour of troubleshooting why data() didn't work as expected (for the nth time in my career), I finally decided to get to the bottom of it. I documented my findings in my own answer, but to summarize, data probably doesn't work the way you expect. attr probably does work the way you expect. Use attr. Commented Apr 7, 2024 at 8:17

9 Answers 9

663

HTML

<div id="mydiv" data-myval="10"></div>

JS

var a = $('#mydiv').data('myval'); //getter

$('#mydiv').data('myval',20); //setter

Demo

Reference

From the reference:

jQuery itself uses the .data() method to save information under the names 'events' and 'handle', and also reserves any data name starting with an underscore ('_') for internal use.

It should be noted that jQuery's data() doesn't change the data attribute in HTML.

So, if you need to change the data attribute in HTML, you should use .attr() instead.

HTML

<div id="outer">
    <div id="mydiv" data-myval="10"></div>
</div>

​jQuery:

alert($('#outer').html());   // alerts <div id="mydiv" data-myval="10"> </div>
var a = $('#mydiv').data('myval'); //getter
$('#mydiv').attr("data-myval","20"); //setter
alert($('#outer').html());   //alerts <div id="mydiv" data-myval="20"> </div>

See this demo

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

9 Comments

I dont know what consistency you need, but I would recommend to use data() to get and set HTML-5 data attributes.
@Jashwant might be a useful edit instead: think of a css rule like [data-myval="10"]{ color: red; }, it would style the tag according to value of data attribute.
.data doesn't work. .attr works. may be we can edit the answer to make it clear. it seems the first one is the solution, while it could be a little bit better exposed. i'm not sure about how to better explain, this is the reason why I don't edit the post.
@Gaucho .data will only work if you use newer jQuery >= 1.4.3, for older versions .attr will work.
>> Using the data() method to update data does not affect attributes in the DOM. To set a data-* attribute value, use attr. api.jquery.com/data
|
68

Vanilla JavaScript solution


HTML

<div id="mydiv" data-myval="10"></div>

JavaScript:

  • Using DOM's getAttribute() property

       var brand = mydiv.getAttribute("data-myval")//returns "10"
       mydiv.setAttribute("data-myval", "20")      //changes "data-myval" to "20"
       mydiv.removeAttribute("data-myval")         //removes "data-myval" attribute entirely
    
  • Using JavaScript's dataset property

      var myval = mydiv.dataset.myval     //returns "10"
      mydiv.dataset.myval = '20'          //changes "data-myval" to "20"
      mydiv.dataset.myval = null          //removes "data-myval" attribute
    

Comments

58

You can also use the following attr thing;

HTML

<div id="mydiv" data-myval="JohnCena"></div>

Script

 $('#mydiv').attr('data-myval', 'Undertaker'); // sets 
 $('#mydiv').attr('data-myval'); // gets

OR

$('#mydiv').data('myval'); // gets value
$('#mydiv').data('myval','John Cena'); // sets value

2 Comments

For me worked only with .attr. Is that even possible?
I am glad it worked. The .data() call is special - not only does it retrieve HTML5 data attributes it also attempts to evaluate/parse the attributes. So with an attribute like data-myval='{"hello":"world"}' when retrieved via .data() will return an Object while retrieval via .attr() will return a string.
36

Please take note that jQuery .data() is not updated when you change html5 data- attributes with javascript.

If you use jQuery .data() to set data- attributes in HTML elements you better use jQuery .data() to read them. Otherwise there can be inconsistencies if you update the attributes dynamically. For example, see setAttribute(), dataset(), attr() below. Change the value, push the button several times and see the console.

$("#button").on("click", function() {
  var field = document.querySelector("#textfield")

  switch ($("#method").val()) {
    case "setAttribute":
      field.setAttribute("data-customval", field.value)
      break;
    case "dataset":
      field.dataset.customval = field.value
      break;
    case "jQuerydata":
      $(field).data("customval", field.value)
      break;
    case "jQueryattr":
      $(field).attr("data-customval", field.value)
      break;
  }

  objValues = {}
  objValues['$(field).data("customval")'] = $(field).data("customval")
  objValues['$(field).attr("data-customval")'] = $(field).attr("data-customval")
  objValues['field.getAttribute("data-customval")'] = field.getAttribute("data-customval")
  objValues['field.dataset.customval'] = field.dataset.customval

  console.table([objValues])
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h1>Example</h1>
<form>
  <input id="textfield" type="text" data-customval="initial">
  <br/>
  <input type="button" value="Set and show in console.table (F12)" id="button">
  <br/>
  <select id="method">
    <option value="setAttribute">setAttribute</option>
    <option value="dataset">dataset</option>
    <option value="jQuerydata">jQuery data</option>
    <option value="jQueryattr">jQuery attr</option>
  </select>
  <div id="results"></div>
</form>

3 Comments

I feel like I should know this, but how do you know if you are using html5 data- attributes?
@DanielKaplan when you use a data- attribute in the HTML developer.mozilla.org/en-US/docs/Learn/HTML/Howto/…
So a non-html5 data- attribute does not exist. Gotcha.
19

To keep jQuery and the DOM in sync, a simple option may be

$('#mydiv').data('myval',20).attr('data-myval',20);        

1 Comment

$('#mydiv').attr('data-myval',20); this working well
8

If you're using jQuery, use .data():

div.data('myval', 20);

You can store arbitrary data with .data(), but you're restricted to just strings when using .attr().

13 Comments

Note that the .data() method does not update data- attributes - that is, the data it stores does not end up in an attribute (which is why it can store non-string values) even though it can retrieve the value from a data- attribute. Though I suspect the OP doesn't really need to set attributes even though that's what the question asked.
I don't think it would be a problem (besides what you mentioned, or if there is other code that uses .attr() to retrieve the attribute). I just thought it was worth pointing out given that the OP explicitly (if perhaps mistakenly) asked about updating attributes.
@Blender this doesn't really answer my question. I want to update the HTML, but at the same time, use element.data('myval') to retrieve it as well.
I need to do that because the elements generated on document load have those as data-attributes, and I want to do so for the new dynamic elements as well. I know there might be not a specific need for that, but I want to keep a consistency.
@PulkitMittal - Note that even with .attr() you're not really updating "the html", you're updating the DOM. When you ask the browser to give you the "html" (whether by .html() or the DOM element.innerHTML) the browser is effectively regenerating it for you based on the state of the DOM at the time. Sort of.
|
8

[jQuery] .data() vs .attr() vs .extend()

The jQuery method .data() updates an internal object managed by jQuery through the use of the method, if I'm correct.

If you'd like to update your data-attributes with some spread, use --

$('body').attr({ 'data-test': 'text' });

-- otherwise, $('body').attr('data-test', 'text'); will work just fine.

Another way you could accomplish this is using --

$.extend( $('body')[0].dataset, { datum: true } );

-- which restricts any attribute change to HTMLElement.prototype.dataset, not any additional HTMLElement.prototype.attributes.

Comments

4

TL;DR: div.attr('data-myval', 20)


Depending on your needs and your jQuery version, the highest voted answer might work, but you are better off using attr(`data-myval`)/attr(`data-myval`, newVal) because it'll always do what you expect:

jQuery attr() test

  1. The attr(`myval`, val) setter modifies the HTML.
  2. The attr(`myval`) getter returns the value of the HTML attribute.

let $div = $(`#jquery-3-7-1`);
console.log(`Using attr() in jquery 3.7.1`);
console.log("  HTML =", $div[0].outerHTML);
console.log("\t$div.attr(`data-myval`) // = ", $div.attr(`data-myval`));
console.log("  Running $div.attr(`data-myval`, '20');")
$div.attr(`data-myval`, '20');
console.log("\t$div.attr(`data-myval`) // = ", $div.attr(`data-myval`));
console.log("  HTML =", $div[0].outerHTML);
console.log(`\n`);
$.noConflict(true);

$div = $(`#jquery-1-4-3`);
console.log(`Using attr() in jquery 1.4.3`);
console.log("  HTML =", $div[0].outerHTML);
console.log("\t$div.attr(`data-myval`) // = ", $div.attr(`data-myval`));
console.log("  Running $div.attr(`data-myval`, '20');")
$div.attr(`data-myval`, '20');
console.log("\t$div.attr(`data-myval`) // = ", $div.attr(`data-myval`));
console.log("  HTML =", $div[0].outerHTML);
console.log(`\n`);
$.noConflict(true);

$div = $(`#jquery-1-4-2`);
console.log(`Using attr() in jquery 1.4.2`);
console.log("  HTML =", $div[0].outerHTML);
console.log("\t$div.attr(`data-myval`) // = ", $div.attr(`data-myval`));
console.log("  Running $div.attr(`data-myval`, '20');")
$div.attr(`data-myval`, '20');
console.log("\t$div.attr(`data-myval`) // = ", $div.attr(`data-myval`));
console.log("  HTML =", $div[0].outerHTML);
console.log(`\n`);
$.noConflict(true);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div id="jquery-1-4-2" data-myval="10"></div>
<div id="jquery-1-4-3" data-myval="10"></div>
<div id="jquery-3-7-1" data-myval="10"></div>

jQuery data() test

data(...), on the other hand, probably doesn't do what you want:

  1. The data(`myval`, val) setter does not modify the HTML.
  2. In jQuery <= 1.4.2, the data(`myval`) getter ignores HTML attributes.

let $div = $(`#jquery-3-7-1`);
console.log(`Using data() in jquery 3.7.1`);
console.log("  HTML =", $div[0].outerHTML);
console.log("\t$div.data(`myval`) // =", $div.data(`myval`));
console.log("  Running $div.data(`myval`, '20');")
$div.data(`myval`, '20');
console.log("\t$div.data(`myval`) // =", $div.data(`myval`));
console.log("  HTML =", $div[0].outerHTML, `<-------- !!! data-myval is still 10`);
console.log(`\n`);
$.noConflict(true);

$div = $(`#jquery-1-4-3`);
console.log(`Using data() in jquery 1.4.3`);
console.log("  HTML =", $div[0].outerHTML);
console.log("\t$div.data(`myval`) // =", $div.data(`myval`));
console.log("  Running $div.data(`myval`, '20');")
$div.data(`myval`, '20');
console.log("\t$div.data(`myval`) // =", $div.data(`myval`));
console.log("  HTML =", $div[0].outerHTML, `<-------- !!! data-myval is still 10`);
console.log(`\n`);
$.noConflict(true);

$div = $(`#jquery-1-4-2`);
console.log(`Using data() in jquery 1.4.2`);
console.log("  HTML =", $div[0].outerHTML);
console.log("\t$div.data(`myval`) // =", $div.data(`myval`), `<-------- !!!`);
console.log("  Running $div.data(`myval`, '20');")
$div.data(`myval`, '20');
console.log("\t$div.data(`myval`) // =", $div.data(`myval`));
console.log("  HTML =", $div[0].outerHTML, `<-------- !!! data-myval is still 10`);
console.log(`\n`);
$.noConflict(true);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div id="jquery-1-4-2" data-myval="10"></div>
<div id="jquery-1-4-3" data-myval="10"></div>
<div id="jquery-3-7-1" data-myval="10"></div>

This comment on the highest voted answer gives an explanation as to why, but I haven't confirmed it to be historically accurate.

In summary, use attr instead of data.

Comments

0

This doesn't work for me. There is some DOM thing so that .data("option", "value) doesn't work. It is only an internal storage process, unable to affect the data-value attr of the element. If you want future access, I prefer using .attr("data-option", "value"). That will be much better.

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.