jQuery how to find an element based on a data-attribute value?
Solution 1
You have to inject the value of current
into an Attribute Equals selector:
$("ul").find(`[data-slide='${current}']`)
For older JavaScript environments (ES5 and earlier):
$("ul").find("[data-slide='" + current + "']");
Solution 2
in case you don't want to type all that, here's a shorter way to query by data attribute:
$("ul[data-slide='" + current +"']");
FYI: http://james.padolsey.com/javascript/a-better-data-selector-for-jquery/
Solution 3
When searching with [data-x=...], watch out, it doesn't work with jQuery.data(..) setter:
$('<b data-x="1">' ).is('[data-x=1]') // this works
> true
$('<b>').data('x', 1).is('[data-x=1]') // this doesn't
> false
$('<b>').attr('data-x', 1).is('[data-x=1]') // this is the workaround
> true
You can use this instead:
$.fn.filterByData = function(prop, val) {
return this.filter(
function() { return $(this).data(prop)==val; }
);
}
$('<b>').data('x', 1).filterByData('x', 1).length
> 1
Solution 4
Without JQuery, ES6
document.querySelectorAll(`[data-slide='${current}']`);
I know the question is about JQuery, but readers may want a pure JS method.
Solution 5
I improved upon psycho brm's filterByData extension to jQuery.
Where the former extension searched on a key-value pair, with this extension you can additionally search for the presence of a data attribute, irrespective of its value.
(function ($) {
$.fn.filterByData = function (prop, val) {
var $self = this;
if (typeof val === 'undefined') {
return $self.filter(
function () { return typeof $(this).data(prop) !== 'undefined'; }
);
}
return $self.filter(
function () { return $(this).data(prop) == val; }
);
};
})(window.jQuery);
Usage:
$('<b>').data('x', 1).filterByData('x', 1).length // output: 1
$('<b>').data('x', 1).filterByData('x').length // output: 1
// test data
function extractData() {
log('data-prop=val ...... ' + $('div').filterByData('prop', 'val').length);
log('data-prop .......... ' + $('div').filterByData('prop').length);
log('data-random ........ ' + $('div').filterByData('random').length);
log('data-test .......... ' + $('div').filterByData('test').length);
log('data-test=anyval ... ' + $('div').filterByData('test', 'anyval').length);
}
$(document).ready(function() {
$('#b5').data('test', 'anyval');
});
// the actual extension
(function($) {
$.fn.filterByData = function(prop, val) {
var $self = this;
if (typeof val === 'undefined') {
return $self.filter(
function() {
return typeof $(this).data(prop) !== 'undefined';
});
}
return $self.filter(
function() {
return $(this).data(prop) == val;
});
};
})(window.jQuery);
//just to quickly log
function log(txt) {
if (window.console && console.log) {
console.log(txt);
//} else {
// alert('You need a console to check the results');
}
$("#result").append(txt + "<br />");
}
#bPratik {
font-family: monospace;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="bPratik">
<h2>Setup</h2>
<div id="b1" data-prop="val">Data added inline :: data-prop="val"</div>
<div id="b2" data-prop="val">Data added inline :: data-prop="val"</div>
<div id="b3" data-prop="diffval">Data added inline :: data-prop="diffval"</div>
<div id="b4" data-test="val">Data added inline :: data-test="val"</div>
<div id="b5">Data will be added via jQuery</div>
<h2>Output</h2>
<div id="result"></div>
<hr />
<button onclick="extractData()">Reveal</button>
</div>
Or the fiddle: http://jsfiddle.net/PTqmE/46/
Jannis
Updated on January 15, 2021Comments
-
Jannis over 3 years
I've got the following scenario:
var el = 'li';
and there are 5
<li>
's on the page each with adata-slide=number
attribute (number being 1,2,3,4,5 respectively).I now need to find the currently active slide number which is mapped to
var current = $('ul').data(current);
and is updated on each slide change.So far my tries have been unsuccessful, trying to construct the selector that would match the current slide:
$('ul').find(el+[data-slide=+current+]);
does not match/return anything…
The reason I can't hardcode the
li
part is that this is a user accessible variable that can be changed to a different element if required, so it may not always be anli
.Any ideas on what I'm missing?
-
xandy over 13 yearsyou sure within your
.find(el+[data-slide=+current+]);
is the code that you write? it seems you missed some quotations to"[data-slide]"
-
Avatar over 4 yearsThat's what helped me to select all data attributes (regardless the value):
$('*[data-slide]')
You can use it with e.g.$('*[data-slide]').each( function() { ... });
-
-
AaronLS over 11 yearsI worry that this won't work if data was added via jQuery .data(...) function, since this doesn't always render an attribute and soemtimes uses browser specific storage mechanism. Another reason that I wish jQuery core had a data specific selector.
-
Pawel over 10 yearsNotice that it doesn't work for elements where you set data with $('#element').data('some-att-name', value); but only for those with hardcoded attribute. I've got this problem and to make it work set data by writing the attribute directly $('#element').attr('data-some-att-name', value);
-
akousmata over 9 yearsFor those of you who care, given the structure
<ul><li data-slide="item"></li></ul>
this answer's selector will return undefined so it does not work given the user's scenario. This answer WILL work for the structure<ul data-slide="item"><li></li></ul>
While I understand why its popularity due to brevity, it is technically an incorrect answer. jsfiddle.net/py5p2abL/1 -
Artem over 2 yearsJust put a space between the ul and the brackets and it will work.