Question
I am using the jQuery Quicksand plugin and need to read the data-id value from a clicked list item, then pass that value to a web service.
How can I correctly get the data-id attribute?
I am rebinding the click event with .on() because the items are sorted dynamically.
$("#list li").on('click', function() {
// ret = DetailsView.GetProject($(this).attr("#data-id"), OnComplete, OnTimeOut, OnError);
alert($(this).attr("#data-id"));
});
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<ul id="list" class="grid">
<li data-id="id-40" class="win">
<a id="ctl00_cphBody_ListView1_ctrl0_SelectButton" class="project" href="#">
<img src="themes/clean/images/win.jpg" class="project-image" alt="get data-id" />
</a>
</li>
</ul>
Short Answer
By the end of this page, you will understand how to read custom data-* attributes in jQuery, when to use .attr() versus .data(), and how to attach click handlers correctly for dynamically updated elements.
Concept
Custom data-* attributes let you store extra information directly on HTML elements. In your example, the li element stores a project identifier in data-id:
<li data-id="id-40"></li>
In jQuery, you can read this value in two common ways:
$(this).attr('data-id')
$(this).data('id')
The main issue in the original code is this part:
$(this).attr("#data-id")
That is incorrect because .attr() expects the attribute name only, not a CSS selector. The correct attribute name is data-id, not #data-id.
Why this matters:
data-*attributes are widely used for IDs, flags, categories, and configuration.
Mental Model
Think of an HTML element as a labeled storage box.
- The element itself is the box.
- Normal attributes like
id,class, andhrefare built-in labels. data-*attributes are your own extra sticky notes.
So this element:
<li data-id="id-40"></li>
is like a box with a note that says:
data-id = id-40
When a user clicks the element, jQuery lets you open the box and read that note.
Syntax and Examples
The two most common ways to read a data-id value in jQuery are:
$(this).attr('data-id')
$(this).data('id')
Basic example
$("#list li").on("click", function () {
alert($(this).attr("data-id"));
});
This reads the data-id attribute from the clicked li.
Using .data()
$("#list li").on("click", function () {
alert($(this).data("id"));
});
This also works and is often cleaner when working with attributes.
Step by Step Execution
Consider this code:
$("#list").on("click", "li", function () {
const projectId = $(this).data("id");
alert(projectId);
});
And this HTML:
<ul id="list">
<li data-id="id-40">Project A</li>
</ul>
Here is what happens step by step:
- jQuery attaches one click listener to
#list. - You click on the
lielement. - The click event bubbles up to
#list. - jQuery checks whether the clicked target matches the selector
li. - Since it does match, the handler runs.
- Inside the handler,
thisrefers to the clickedli.
Real World Use Cases
data-* attributes are very common in real applications.
Common uses
- Storing a database record ID on a row or card
- Attaching product IDs to "Add to cart" buttons
- Keeping category names for filtering items
- Marking elements with status flags like
data-active="true" - Passing small configuration values from HTML to JavaScript
Example: product card
<button class="add-to-cart" data-product-id="101">Add to cart</button>
$(document).on("click", ".add-to-cart", function () {
const productId = $(this).data("product-id");
console.log("Add product", productId);
});
Example: table row actions
<tr =>
Alice
View
Real Codebase Usage
In real projects, developers usually combine data-* attributes with event delegation and small handler functions.
Common pattern: delegated click handling
$("#list").on("click", "li", function () {
const projectId = $(this).data("id");
if (!projectId) return;
DetailsView.GetProject(projectId, OnComplete, OnTimeOut, OnError);
});
This uses a guard clause:
if (!projectId) return;
That avoids making a bad request if the attribute is missing.
Common pattern: click on child, read from parent
Sometimes the click happens on an inner link or image, but the ID is stored on the parent:
$("#list").on("click", "a.project", function (event) {
event.();
projectId = $().().();
(!projectId) ;
.(projectId, , , );
});
Common Mistakes
1. Using #data-id instead of data-id
Broken code:
$(this).attr("#data-id")
Why it is wrong:
#data-idlooks like a CSS selector..attr()expects just the attribute name.
Correct code:
$(this).attr("data-id")
or:
$(this).data("id")
2. Binding directly to elements that get replaced
Broken approach:
$("#list li").on("click", function () {
alert($(this).data());
});
Comparisons
| Approach | Example | Best use | Notes |
|---|---|---|---|
.attr('data-id') | $(this).attr('data-id') | Read the raw attribute value | Good when you want the exact attribute string |
.data('id') | $(this).data('id') | Work with data-* values in jQuery | Cleaner and more semantic for custom data |
| Direct binding | $('#list li').on('click', fn) | Static elements already on the page | May fail if elements are replaced dynamically |
| Delegated binding | $('#list').on('click', 'li', fn) | Dynamic or re-rendered elements |
Cheat Sheet
Reading data-* in jQuery
$(element).attr('data-id')
$(element).data('id')
Correct examples
$(this).attr('data-id')
$(this).data('id')
Incorrect example
$(this).attr('#data-id')
Event binding
Static elements
$('#list li').on('click', function () {
console.log($(this).data('id'));
});
Dynamic elements
$().(, , () {
.($().());
});
FAQ
How do I get a data-id attribute in jQuery?
Use either:
$(this).attr('data-id')
or:
$(this).data('id')
Why does $(this).attr('#data-id') return undefined?
Because #data-id is not an attribute name. The # symbol is used in CSS selectors for IDs. The correct attribute name is data-id.
Should I use .attr() or .data() in jQuery?
For data-* attributes, .data() is usually more readable. .attr() is also valid when you want the raw attribute value.
How do I handle clicks on elements added after page load?
Use delegated events:
Mini Project
Description
Build a small project list where each item has a data-id. When a user clicks a project link, your script should read the ID and display which project would be loaded. This demonstrates reading data-* attributes, delegated click handling, and accessing data stored on parent elements.
Goal
Create a clickable project list that reads data-id values correctly and uses them in JavaScript logic.
Requirements
- Create a list with at least three
liitems, each containing a uniquedata-id. - Put a clickable link inside each list item.
- Use delegated event binding with
.on()on the parent list. - Prevent the default link behavior.
- Read the
data-idfrom the clicked item's parentliand show it on the page.
Keep learning
Related questions
Allow Only Numeric Input (0-9) in HTML Input Using jQuery
Learn how to allow only digits 0-9 in an HTML input using jQuery, with examples, validation tips, common mistakes, and best practices.
CSS :not() Selector for Excluding a Class or Attribute
Learn how to use the CSS :not() selector to target elements that do not have a specific class or attribute, with examples and common mistakes.
Can HTML Checkboxes Be Readonly? Understanding readonly vs disabled in HTML Forms
Learn why HTML checkboxes do not support readonly, how disabled differs, and practical ways to prevent changes while still submitting values.