Pulkit Mittal
Pulkit Mittal

Reputation: 6086

How to set data attributes in HTML elements

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.

Upvotes: 351

Views: 653597

Answers (9)

Daniel Kaplan
Daniel Kaplan

Reputation: 67504

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.

Upvotes: 4

Albair
Albair

Reputation: 11

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.

Upvotes: 0

rajesh kakawat
rajesh kakawat

Reputation: 10906

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
    

Upvotes: 67

Jashwant
Jashwant

Reputation: 29025

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

Upvotes: 659

J. McNerney
J. McNerney

Reputation: 636

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

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

Upvotes: 19

Cody
Cody

Reputation: 10025

[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.

Upvotes: 8

Baqer Naqvi
Baqer Naqvi

Reputation: 6514

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

Upvotes: 58

Johann Echavarria
Johann Echavarria

Reputation: 9965

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>

Upvotes: 36

Blender
Blender

Reputation: 298532

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().

Upvotes: 8

Related Questions