Question
How can I select elements in jQuery based on a data-* attribute?
For example, how can I select all anchor (<a>) elements that have a data-customerID attribute with a value of 22?
I would prefer not to misuse attributes like rel or other unrelated attributes to store this kind of information. However, I am not sure what the simplest and most direct way is to select elements based on values stored in data-* attributes.
Short Answer
By the end of this page, you will understand how to use jQuery attribute selectors to find elements by data-* attributes, how HTML5 custom data attributes work, when to use .data() versus CSS-style selectors, and how to avoid common mistakes with naming and value matching.
Concept
HTML5 data-* attributes let you store custom information directly on elements in a valid, semantic way.
For example:
<a href="#" data-customerid="22">View Customer</a>
These attributes are useful when an element needs extra metadata, such as:
- an ID from the database
- a status value
- a category name
- configuration flags for JavaScript behavior
In jQuery, there are two closely related ideas here:
- Selecting elements by attribute using a selector like:
$('a[data-customerid="22"]') - Reading stored data from an element using:
$(element).data('customerid')
These are not the same thing:
- Attribute selectors are for finding matching elements in the DOM.
.data()is for getting or setting data on an element after you already have it.
This matters because in real projects you often:
- mark up HTML with IDs or flags using
data-* - select the relevant elements with jQuery
- then read or update their values in JavaScript
Using data-* attributes is better than overloading unrelated attributes like rel, because data-* was specifically designed for custom metadata.
Mental Model
Think of each HTML element as a labeled storage box.
- The element itself is the box.
- A
data-*attribute is a sticky note attached to the box. - jQuery selectors let you search for boxes with a specific sticky note.
.data()lets you read the note after you have found the box.
So if you want all boxes labeled customerid = 22, you use a selector.
If you already have one box and want to read its label, you use .data().
Syntax and Examples
The most direct jQuery selector for a data-* attribute is an attribute selector.
Exact value match
<a href="#" data-customerid="22">Customer 22</a>
<a href="#" data-customerid="15">Customer 15</a>
<a href="#" data-customerid="22">Another Customer 22</a>
const links = $('a[data-customerid="22"]');
console.log(links.length); // 2
This selects all <a> elements whose data-customerid value is exactly 22.
Select elements that simply have the attribute
const linksWithCustomerId = $('a[data-customerid]');
This selects all anchors that contain the data-customerid attribute, regardless of value.
Reading the value after selecting
$('a[data-customerid="22"]').each(function () {
console.log($(this).data('customerid'));
});
This loops through matching elements and reads the data value.
Example with click handling
<a href="#" data-customerid="22">Open Customer</a>
<a href="#" data-customerid="30">Open Another Customer</a>
$('a[data-customerid]').on('click', function (event) {
event.preventDefault();
const customerId = $(this).data('customerid');
console.log('Clicked customer:', customerId);
});
Here:
- the selector finds all anchors with that attribute
- the click handler runs when one is clicked
.data('customerid')reads the value from the clicked element
Step by Step Execution
Consider this example:
<a href="#" data-customerid="22">Alice</a>
<a href="#" data-customerid="15">Bob</a>
<a href="#" data-customerid="22">Carol</a>
const matches = $('a[data-customerid="22"]');
matches.each(function () {
console.log($(this).text(), $(this).data('customerid'));
});
Step by step:
- jQuery evaluates the selector:
'a[data-customerid="22"]' - It looks for all
<a>elements. - For each
<a>element, it checks whether it has adata-customeridattribute. - It keeps only the ones whose value is exactly
22. - The result is a jQuery collection containing:
AliceCarol
.each(...)loops over those matching elements one by one.- Inside the loop,
$(this).text()gets the link text. $(this).data('customerid')reads the stored data value.- The console output is:
Alice 22
Carol 22
This shows the usual flow:
- select first
- process the matches
- read the data when needed
Real World Use Cases
data-* selectors are common in front-end code because they let HTML carry small pieces of metadata without mixing it into classes or unrelated attributes.
Common uses
-
Buttons tied to database records
<button data-userid="42">Delete User</button>Use jQuery to select the button and send the user ID in an AJAX request.
-
Filtering UI items
<div class="product" data-category="books"></div> <div class="product" data-category="games"></div>Select only products from one category.
-
Tabs and modals
<button data-target="settings-modal">Open Settings</button>JavaScript reads the target modal name from the element.
-
Feature flags in markup
<section data-enabled="true"></section>Scripts can enable or skip behavior based on the attribute.
-
Testing hooks Teams often use
data-*attributes as stable selectors for JavaScript or test automation when classes are mostly for styling.
Real Codebase Usage
In real projects, developers usually combine data-* attributes with patterns like event delegation, validation, and guard clauses.
Event delegation
When elements are added dynamically, developers often attach events to a parent:
$(document).on('click', 'a[data-customerid]', function (event) {
event.preventDefault();
const customerId = $(this).data('customerid');
if (!customerId) {
return;
}
console.log('Load customer', customerId);
});
This works even for links inserted later.
Guard clauses
Developers often exit early if required data is missing:
const customerId = $(this).data('customerid');
if (!customerId) {
return;
}
This keeps code simple and avoids deep nesting.
Configuration through markup
<div class="widget" data-page-size="10" data-sort="name"></div>
$('.widget').each(function () {
const pageSize = $(this).data('page-size');
const sort = $(this).data('sort');
console.log(pageSize, sort);
});
This is common when reusable components need per-element settings.
Validation before API calls
$('button[data-userid]').on('click', function () {
const userId = $(this).data('userid');
if (typeof userId === 'undefined') {
console.error('Missing user ID');
return;
}
// continue with AJAX request
});
In larger codebases, data-* attributes often act as a bridge between server-rendered HTML and client-side JavaScript.
Common Mistakes
1. Using the wrong attribute name format
HTML data-* attributes should be lowercase and hyphen-based.
Better HTML
<a data-customerid="22">Link</a>
or
<a data-customer-id="22">Link</a>
Selector
$('a[data-customerid="22"]')
or
$('a[data-customer-id="22"]')
Avoid mixed casing like this in HTML:
<a data-customerID="22">Link</a>
Even if browsers may tolerate it, lowercase naming is clearer and more reliable.
2. Confusing .data() with selectors
Broken idea:
$('a').data('customerid=22')
Why it is wrong:
.data()does not filter elements- it reads or sets data on an existing jQuery object
Correct:
$('a[data-customerid="22"]')
3. Forgetting quotes around string values in selectors
Broken:
$('a[data-customerid=22]')
This may work in many cases, but quoting attribute values is safer and clearer.
Preferred:
$('a[data-customerid="22"]')
4. Expecting number comparison instead of string matching
Attributes in HTML are stored as text.
<a data-customerid="22"></a>
Selector matching is based on the attribute text value:
$('a[data-customerid="22"]')
If you need numeric logic such as greater than or less than, select first and then filter in JavaScript.
5. Using classes for data
Classes should usually describe styling or UI state, not record IDs.
Less ideal:
<a class="customer-22">Link</a>
Better:
<a data-customerid="22">Link</a>
6. Mixing .attr() and .data() without understanding caching
jQuery may internally cache values used through .data().
If you change a data-* attribute later with .attr(), .data() may not behave as you expect in some situations.
If possible, use one approach consistently for reading and writing during a piece of logic.
Comparisons
| Approach | Purpose | Example | Best when |
|---|---|---|---|
| Attribute selector | Find elements by data-* value | $('a[data-customerid="22"]') | You need matching elements |
.data() | Read or write data on selected elements | $(el).data('customerid') | You already have the element |
.attr() | Read raw HTML attribute text | $(el).attr('data-customerid') | You want the literal attribute value |
| Class selector | Find elements by class | $('.customer-link') | The meaning is styling or reusable grouping |
data-* selector vs .data()
$('a[data-customerid="22"]') // select matching elements
$(this).data('customerid') // read value from one element
.attr() vs .data()
$(this).attr('data-customerid') // usually returns a string
$(this).data('customerid') // jQuery-friendly data access
Use .attr() when you specifically want the raw attribute.
Use .data() when working with jQuery-managed element data.
data-* vs rel
| Option | Recommended? | Reason |
|---|---|---|
data-* | Yes | Designed for custom metadata |
rel | Usually no | Intended for relationship semantics, not arbitrary app data |
class | Sometimes | Good for styling/state, not ideal for storing IDs |
id | No for this purpose | Should uniquely identify the element itself |
Cheat Sheet
// Select elements with a data attribute
$('[data-customerid]')
// Select anchors with a specific data value
$('a[data-customerid="22"]')
// Read a data value
$(element).data('customerid')
// Read raw attribute text
$(element).attr('data-customerid')
// Loop through matches
$('a[data-customerid="22"]').each(function () {
console.log($(this).data('customerid'));
});
Rules to remember
- Use
data-*for custom metadata in HTML. - Use attribute selectors to find matching elements.
- Use
.data()to read or write data after selection. - Prefer lowercase attribute names such as
data-customeridordata-customer-id. - Quote selector values for clarity:
[data-name="value"]
Common patterns
// Has the attribute
$('[data-role]')
// Exact match
$('[data-role="admin"]')
// Read from clicked element
$(this).data('role')
Edge case
If you need advanced comparisons like numeric filtering:
$('a[data-customerid]').filter(function () {
return Number($(this).data('customerid')) > 20;
});
FAQ
How do I select elements with a specific data attribute in jQuery?
Use an attribute selector:
$('a[data-customerid="22"]')
This selects all <a> elements whose data-customerid equals 22.
How do I select elements that only have a data attribute, regardless of value?
Use the attribute name without a value check:
$('a[data-customerid]')
Should I use .data() or an attribute selector?
Use an attribute selector to find elements.
Use .data() after selection to read the stored value.
Can I use camelCase in data-* attributes?
It is better to use lowercase and hyphens in HTML, such as data-customer-id or data-customerid.
What is the difference between .attr('data-x') and .data('x')?
.attr() reads the raw HTML attribute value.
.data() gives you jQuery's data access layer for the element.
Is data-* better than using rel for custom values?
Yes. data-* is the standard way to store custom metadata in HTML.
Can I filter by numbers in a data-* attribute?
Yes, but selectors match text exactly. For numeric comparisons, select the elements first and then filter them in JavaScript.
Mini Project
Description
Build a small customer link list where each link stores a customer ID in a data-* attribute. Then use jQuery to select links for a specific customer and attach click behavior that reads the stored ID. This demonstrates both selecting by data-* attribute and reading values with .data().
Goal
Create a page that highlights links for customer 22 and logs the clicked customer ID.
Requirements
- Create at least three anchor elements with
data-customeridvalues. - Select all anchors whose
data-customeridis22. - Add a CSS class to highlight the matching links.
- Attach a click handler to all customer links.
- Prevent the default link action and log the clicked customer ID.
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.
Apply CSS !important with jQuery .css()
Learn why jQuery .css() cannot set !important and how to use CSSStyleDeclaration.setProperty() to apply inline important styles safely.
CSS ::before and ::after on Input Elements
Learn why CSS ::before and ::after usually do not work on input elements, what replaced elements are, and practical alternatives.