← Back to jQuery Course | Chapter 11: Utility Methods | Lesson 6 of 6

Storing Metadata on DOM Nodes

The data method stores custom information on DOM elements. This is useful when an element needs extra values.
Syntax
javascript
$(selector).data("key", value);
$(selector).data("key");
$(selector).removeData("key");

What is data()?

The data() method attaches arbitrary JavaScript values to a DOM element without writing them into visible HTML attributes, storing them in an internal cache tied to that element instead. This keeps application state associated with the right element without cluttering the markup or exposing it in the page source.

Example: What is data()?

javascript
<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
  <style>
    body { font-family: sans-serif; padding: 12px; }
    button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
    button.secondary, #resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
    input[type=text] { padding: 6px 8px; margin: 0 6px 8px 0; border: 1px solid #888; border-radius: 4px; font: 14px sans-serif; }
    .stage { border: 2px dashed #888; border-radius: 4px; padding: 10px; margin: 8px 0; min-height: 40px; background: #fafafa; }
    .stage::before { content: attr(data-label); display: block; font-size: 12px; color: #666; margin-bottom: 6px; }
    .item { border: 1px solid #4a7fb5; background: #eaf2fb; padding: 6px 10px; margin: 4px 0; border-radius: 4px; }
    .fresh { background: #ffe066 !important; border-color: #d4a600 !important; }
    .done { text-decoration: line-through; color: #a33; }
    ul.stage { padding-left: 32px; }
    ul.stage:empty::after { content: "(empty)"; color: #999; }
    ul.stage > li { border: 1px solid #4a7fb5; background: #eaf2fb; padding: 6px 10px; margin: 4px 0; border-radius: 4px; }
    .box { border: 2px solid #4a7fb5; background: #f3f8fd; border-radius: 4px; padding: 8px 10px; margin: 8px 0; min-height: 54px; }
    .box .label { display: block; font-weight: bold; margin-bottom: 6px; color: #2c6aa0; }
    #output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; white-space:pre-wrap; }
    #output:empty::before { content: "Output appears here"; color: #888; }
  </style>
</head>
<body>
  <button id="runBtn">Store data</button><button id="resetBtn" class="secondary">Reset</button>
  <div id="card" class="item">Card</div>
  <div id="output"></div>
  <script>
    $("#runBtn").click(function () {
      $("#card").data("userId", 42);
      $("#output").text('$("#card").data("userId") -> ' + $("#card").data("userId"));
    });
    $("#resetBtn").click(function () {
      $("#card").removeData("userId");
      $("#output").text('$("#card").data("userId") -> ' + $("#card").data("userId"));
    });
  </script>
</body>
</html>

Read Data

Use data() with a key to read back stored information, and the value can be a string, number, object, array, or virtually any other JavaScript value — not just text, unlike a plain HTML data-* attribute. This makes it possible to attach rich structured data, like an entire object, directly to an element.

Example: Read Data

javascript
<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
  <style>
    button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
    #resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
    #output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; }
    #demo :where(p, div, span, li, h1, h2, h3, h4, td, th, blockquote, label, section, article, aside) { border:1px solid #4a7fb5; background:#eaf2fb; padding:6px 10px; margin:4px 0; border-radius:4px; }
    #demo :where(ul, ol) { border:1px dashed #888; background:#fafafa; padding:8px 8px 8px 32px; margin:6px 0; }
    #demo :where(table) { border-collapse:collapse; }
    #demo :where(td, th) { border-radius:0; }
    #demo :where(input, select, textarea) { margin:4px 0; }
  </style>
</head>
<body>
  <button id="runBtn">Run</button>
  <button id="resetBtn">Reset</button>
  <section id="demo">
    <div id="card">Card</div>

  </section>
  <div id="output"></div>
  <script>
    var original = $("#demo").html();

    $("#runBtn").click(function() {
      $("#card").data("userId", 42);
      $("#output").text(String($("#card").data("userId")));
    });

    $("#resetBtn").click(function() {
      $("#demo").html(original);
      $("#output").empty();
    });
  </script>
</body>
</html>

Store Multiple Values

You can store more than one piece of metadata on the same DOM element by calling data() with different keys, effectively giving that element its own small collection of custom properties. This is useful when a single element needs to track several unrelated pieces of state at once, like both a status and a timestamp.

Example: Store Multiple Values

javascript
<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
  <style>
    button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
    #resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
    #output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; }
    #demo :where(p, div, span, li, h1, h2, h3, h4, td, th, blockquote, label, section, article, aside) { border:1px solid #4a7fb5; background:#eaf2fb; padding:6px 10px; margin:4px 0; border-radius:4px; }
    #demo :where(ul, ol) { border:1px dashed #888; background:#fafafa; padding:8px 8px 8px 32px; margin:6px 0; }
    #demo :where(table) { border-collapse:collapse; }
    #demo :where(td, th) { border-radius:0; }
    #demo :where(input, select, textarea) { margin:4px 0; }
  </style>
</head>
<body>
  <button id="runBtn">Run</button>
  <button id="resetBtn">Reset</button>
  <section id="demo">
    <div id="card">Card</div>

  </section>
  <div id="output"></div>
  <script>
    var original = $("#demo").html();

    $("#runBtn").click(function() {
      $("#card").data("userId", 42);
      $("#card").data("status", "active");
      $("#output").text(JSON.stringify($("#card").data()));
    });

    $("#resetBtn").click(function() {
      $("#demo").html(original);
      $("#output").empty();
    });
  </script>
</body>
</html>

Remove Stored Data

The removeData method deletes previously stored metadata from an element, which is useful once that information is no longer relevant — for example, clearing a loading flag once a request finishes. Leaving stale data attached can lead to confusing bugs if old state is accidentally read later.

Example: Remove Stored Data

javascript
<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
  <style>
    body { font-family: sans-serif; padding: 12px; }
    button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
    button.secondary, #resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
    input[type=text] { padding: 6px 8px; margin: 0 6px 8px 0; border: 1px solid #888; border-radius: 4px; font: 14px sans-serif; }
    .stage { border: 2px dashed #888; border-radius: 4px; padding: 10px; margin: 8px 0; min-height: 40px; background: #fafafa; }
    .stage::before { content: attr(data-label); display: block; font-size: 12px; color: #666; margin-bottom: 6px; }
    .item { border: 1px solid #4a7fb5; background: #eaf2fb; padding: 6px 10px; margin: 4px 0; border-radius: 4px; }
    .fresh { background: #ffe066 !important; border-color: #d4a600 !important; }
    .done { text-decoration: line-through; color: #a33; }
    ul.stage { padding-left: 32px; }
    ul.stage:empty::after { content: "(empty)"; color: #999; }
    ul.stage > li { border: 1px solid #4a7fb5; background: #eaf2fb; padding: 6px 10px; margin: 4px 0; border-radius: 4px; }
    .box { border: 2px solid #4a7fb5; background: #f3f8fd; border-radius: 4px; padding: 8px 10px; margin: 8px 0; min-height: 54px; }
    .box .label { display: block; font-weight: bold; margin-bottom: 6px; color: #2c6aa0; }
    #output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; white-space:pre-wrap; }
    #output:empty::before { content: "Output appears here"; color: #888; }
  </style>
</head>
<body>
  <button id="runBtn">Store, then remove data</button><button id="resetBtn" class="secondary">Reset</button>
  <div id="card" class="item">Card</div>
  <div id="output"></div>
  <script>
    $("#runBtn").click(function () {
      $("#output").empty();
      $("#card").data("loading", true);
      $("#output").append($("<div>").text('after data("loading", true):  ' + $("#card").data("loading")));
      $("#card").removeData("loading");
      $("#output").append($("<div>").text('after removeData("loading"):  ' + $("#card").data("loading")));
    });
    $("#resetBtn").click(function () { $("#output").empty(); });
  </script>
</body>
</html>

Small data() Project

Attaching hidden metadata this way is especially useful for buttons, product cards, and other repeated UI elements where each instance needs to remember something — like an ID or a status — without adding extra visible markup or custom attributes for every piece of state.

Example: Small data() Project

javascript
<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
  <style>
    button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
    #resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
    #output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; }
    #demo :where(p, div, span, li, h1, h2, h3, h4, td, th, blockquote, label, section, article, aside) { border:1px solid #4a7fb5; background:#eaf2fb; padding:6px 10px; margin:4px 0; border-radius:4px; }
    #demo :where(ul, ol) { border:1px dashed #888; background:#fafafa; padding:8px 8px 8px 32px; margin:6px 0; }
    #demo :where(table) { border-collapse:collapse; }
    #demo :where(td, th) { border-radius:0; }
    #demo :where(input, select, textarea) { margin:4px 0; }
  </style>
</head>
<body>
  <button id="resetBtn">Reset</button>
  <section id="demo">
    <button class="product" data-id="7">Buy</button>

  </section>
  <div id="output"></div>
  <script>
    var original = $("#demo").html();

    function init() {
      $(".product").on("click", function() {
        $("#output").append($("<div>").text("Product ID: " + $(this).data("id")));
      });
    }
    init();

    $("#resetBtn").click(function() {
      $("#demo").html(original);
      $("#output").empty();
      init();
    });
  </script>
</body>
</html>
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Expecting .data("id", 5) to change the data-id attribute in the HTML, when it only stores the value in memory and the attribute stays the same.
  2. Calling .data("key") on a selection with many elements and expecting all values, when it returns the value for the first element only.
  3. Reading data-user-id with .data("user_id"), when jQuery converts hyphenated attributes to camelCase: .data("userId").
Chapter Summary
  • Type checking utilities identify what kind of value you have.
  • trim() cleans strings, and array helpers work with lists.
  • extend() merges objects, proxy() binds context, and metadata can be stored on DOM nodes.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.