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?

2

9 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 + "']"); 
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:

2

When 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 
0

Without 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>

Or the fiddle:

0

I 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. 
0

This 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 + "']");