I've got the following scenario:
var el = 'li'; and there are 5 <li>'s on the page each with a data-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 an li.
Any ideas on what I'm missing?
29 Answers
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 + "']"); 2in case you don't want to type all that, here's a shorter way to query by data attribute:
$("ul[data-slide='" + current +"']"); 2When searching with [data-x=...], watch out, it doesn't work with jQuery.data(..) setter:
$('<b>' ).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 0Without JQuery, ES6
document.querySelectorAll(`[data-slide='${current}']`); I know the question is about JQuery, but readers may want a pure JS method.
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=""></script> <div> <h2>Setup</h2> <div>Data added inline ::</div> <div>Data added inline ::</div> <div>Data added inline ::</div> <div>Data added inline ::</div> <div>Data will be added via jQuery</div> <h2>Output</h2> <div></div> <hr /> <button onclick="extractData()">Reveal</button> </div>0I have faced the same issue while fetching elements using jQuery and data-* attribute.
so for your reference the shortest code is here:
This is my HTML Code:
<section></section> <section></section> <section></section> <section></section> This is my jQuery selector:
$('section[data-js="carousel"]'); // this will return array of the section elements which has attribute. 0This selector $("ul [data-slide='" + current +"']"); will work for following structure:
<ul><li></li></ul> While this $("ul[data-slide='" + current +"']"); will work for:
<ul><li></li></ul>
$("ul").find("li[data-slide='" + current + "']"); I hope this may work better
thanks
Going back to his original question, about how to make this work without knowing the element type in advance, the following does this:
$(ContainerNode).find(el.nodeName + "[data-slide='" + current + "']");