Jquery select all elements that have $jquery.data()
JavascriptJqueryJquery SelectorsJavascript Problem Overview
Select elements that i have previously set with jquery.data();
i.e. Select all elements with .data('myAttr')
already been set.
SOLUTION
A jsfiddle to demostrate is Fiddle
Javascript Solutions
Solution 1 - Javascript
You could do
$('[data-myAttr!=""]');
this selects all elements which have an attribute data-myAttr
which is not equal to '' (so it must have been set); (only for elements that have their data attribute set in HTML not via jQuery)
you could also use filter() (which works for data attributes set from jQuery)
$('*').filter(function() {
return $(this).data('myAttr') !== undefined;
});
Solution 2 - Javascript
The best and simple way to select them is:
$('[data-myAttr]')
More Information:
I tested a lot of things.
Using $('[data-myAttr!=""]')
doesn't work for all cases. Because elements that do not have a data-myAttr
set, will have their data-myAttr
equal to undefined
and $('[data-myAttr!=""]')
will select those as well, which is incorrect.
Solution 3 - Javascript
You can use filter():
var elements = $("*").filter(function() {
return $(this).data("myAttr") !== undefined;
});
Solution 4 - Javascript
You could use this jQuery Selector extention: Querying element data
$(':data'); // All elements with data
$(':not(:data)'); // All elements without data
Solution 5 - Javascript
You can use JQuery UI with the :data() selector
> Selects elements which have data stored under the specified key.
Check this jsfiddle for an example
To get all elements matching .data('myAttr')
you can use
var matches = $(':data(myAttr)');
This should work for both elements with data-
attributes and elements with data stored using $.data()
because
> As of jQuery 1.4.3 HTML 5 data- attributes will be automatically pulled in to jQuery's data object.
But this doesn't work very well. Check this jsfiddle and you will see that the second time the selector is called it should match 2 elements and is only matching one. This is due to "a bug" in the jquery-ui library.
This is taken from the core jquery-ui file.
$.extend( $.expr[ ":" ], {
data: $.expr.createPseudo ?
$.expr.createPseudo(function( dataName ) {
return function( elem ) {
return !!$.data( elem, dataName );
};
}) :
// support: jQuery <1.8
function( elem, i, match ) {
return !!$.data( elem, match[ 3 ] );
}
});
As you can see they are using $.data(elem, match)
instead $(elem).data(match)
which causes the cache not to be updated in case you are requesting elements with data-
attributes. If the element has been tested for data()
storage this works well but if not it will not be included in the resulting matches.
This might not be a bug at all if what you want is to match only elements with data information set by you but if not you are left with two options.
-
Don't use jquery-ui and extend your own pseudo-selector
$(:mydata(myAttr))
$.extend($.expr[":"], { mydata: $.expr.createPseudo ? $.expr.createPseudo(function(dataName) { return function(elem) { return !!$(elem).data(dataName); }; }) : function(elem, i, match) { return !!$(elem).data(match[3]); } });
// pseudoselector code
$.extend($.expr[":"], {
mydata: $.expr.createPseudo ?
$.expr.createPseudo(function(dataName) {
return function(elem) {
return !!$(elem).data(dataName);
};
}) : function(elem, i, match) {
return !!$(elem).data(match[3]);
}
});
// end pseudoselector
testSelector = function() {
var matched = $(':mydata(test)'),
results = $('#results');
results.append('<div>You matched ' + matched.length + ' elements</div>');
matched.css('border', 'black 3px solid');
console.log(matched);
console.log('You matched ' + matched.length + ' elements');
};
testSelector();
$('#addData').click(function() {
$(".bar").data('test', 'value2');
testSelector();
});
.foo {
background-color: red;
color: white;
}
.bar {
background-color: blue;
color: white;
}
#addData {
margin-top: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<span class="bar">without data attribute</span>
<span class="foo" data-test="value1">with data attribute</span>
</div>
<button id="addData" type="button">Add data</button>
<div id="results"></div>
-
Use jquery-ui with the
:data
pseudoselector and join the results of selecting[data-myAttr]
to include the ones that might be skippedvar matches = $(':data(myAttr)', '[data-myAttr]')
testSelector = function() {
var matched = $(':data(test), [data-test]'),
results = $('#results');
results.append('<div>You matched ' + matched.length + ' elements</div>');
matched.css('border', 'black 3px solid');
console.log(matched);
console.log('You matched ' + matched.length + ' elements');
};
testSelector();
$('#addData').click(function() {
$(".bar").data('test', 'value2');
testSelector();
});
.foo {
background-color: red;
color: white;
}
.bar {
background-color: blue;
color: white;
}
#addData {
margin-top: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<div>
<span class="bar">without data attribute</span>
<span class="foo" data-test="value1">with data attribute</span>
</div>
<button id="addData" type="button">Add data</button>
<div id="results"></div>
Solution 6 - Javascript
$('[data-myAttr]').each(function() {
var element = $(this);
// Do something with the element
});
Solution 7 - Javascript
> Select elements that i have previously set with jquery.data();
> The question is for finding all elements with a specific key and not > any data.
Try utilizing jQuery.data()
$(".myClass").each(function(i){
if( i % 2 == 0 ){
$(this).data("myAttr",i + 1);
}
});
var res = $(".myClass").map(function(i) {
console.log($(this).data("myAttr"));
return $.data(this, "myAttr") !== undefined ? this : null
});
console.log(res);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div class="myClass">1</div>
<div class="myClass">2</div>
<div class="myClass">3</div>
<div class="myClass">4</div>
<div class="myClass">5</div>
jsfiddle http://jsfiddle.net/xynZA/142/