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?
This question is related to
jquery
jquery-selectors
custom-data-attribute
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/
$("ul").find("li[data-slide='" + current + "']");
I hope this may work better
thanks
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
This selector $("ul [data-slide='" + current +"']");
will work for following structure:
<ul><li data-slide="item"></li></ul>
While this $("ul[data-slide='" + current +"']");
will work for:
<ul data-slide="item"><li></li></ul>
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 + "']");
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_x000D_
function extractData() {_x000D_
log('data-prop=val ...... ' + $('div').filterByData('prop', 'val').length);_x000D_
log('data-prop .......... ' + $('div').filterByData('prop').length);_x000D_
log('data-random ........ ' + $('div').filterByData('random').length);_x000D_
log('data-test .......... ' + $('div').filterByData('test').length);_x000D_
log('data-test=anyval ... ' + $('div').filterByData('test', 'anyval').length);_x000D_
}_x000D_
_x000D_
$(document).ready(function() {_x000D_
$('#b5').data('test', 'anyval');_x000D_
});_x000D_
_x000D_
// the actual extension_x000D_
(function($) {_x000D_
_x000D_
$.fn.filterByData = function(prop, val) {_x000D_
var $self = this;_x000D_
if (typeof val === 'undefined') {_x000D_
return $self.filter(_x000D_
_x000D_
function() {_x000D_
return typeof $(this).data(prop) !== 'undefined';_x000D_
});_x000D_
}_x000D_
return $self.filter(_x000D_
_x000D_
function() {_x000D_
return $(this).data(prop) == val;_x000D_
});_x000D_
};_x000D_
_x000D_
})(window.jQuery);_x000D_
_x000D_
_x000D_
//just to quickly log_x000D_
function log(txt) {_x000D_
if (window.console && console.log) {_x000D_
console.log(txt);_x000D_
//} else {_x000D_
// alert('You need a console to check the results');_x000D_
}_x000D_
$("#result").append(txt + "<br />");_x000D_
}
_x000D_
#bPratik {_x000D_
font-family: monospace;_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>_x000D_
_x000D_
<div id="bPratik">_x000D_
<h2>Setup</h2>_x000D_
<div id="b1" data-prop="val">Data added inline :: data-prop="val"</div>_x000D_
<div id="b2" data-prop="val">Data added inline :: data-prop="val"</div>_x000D_
<div id="b3" data-prop="diffval">Data added inline :: data-prop="diffval"</div>_x000D_
<div id="b4" data-test="val">Data added inline :: data-test="val"</div>_x000D_
<div id="b5">Data will be added via jQuery</div>_x000D_
<h2>Output</h2>_x000D_
<div id="result"></div>_x000D_
_x000D_
<hr />_x000D_
<button onclick="extractData()">Reveal</button>_x000D_
</div>
_x000D_
Or the fiddle: http://jsfiddle.net/PTqmE/46/
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 data-js="carousel"></section>
<section></section>
<section></section>
<section data-js="carousel"></section>
This is my jQuery selector:
$('section[data-js="carousel"]');
// this will return array of the section elements which has data-js="carousel" attribute.
document.querySelectorAll(`[data-slide='${current}']`);
I know the question is about JQuery, but readers may want a pure JS method.
Source: Stackoverflow.com