Select element by data defined with jquery - javascript

I'm trying to select element by data attribute defined with jquery (it's not visible in DOM), therefore I cannot use $('.foo:data(id)')
example: if user clicks element I add data property to it as following
$(this).data('id', '1');
now I would like to find element which has
data-id == 1
how can I select this element by data-id?

Use filter()
$('.foo').filter(function(){
return $(this).data('id') === `1`
}).doSomething()

You could use the attribute selector [attribute=...].
In your case, this would be
$('[data-id=1]')
But keep in mind, if you change the data of an element with .data(), the change isn't reflected in the dom attribute, so you can't use this (or additionally change the dom attribute).
The other way would be to select every candidate and then filter for each element, which has a matching data value.
$('.foo').filter(function(){
return $(this).data('id') == 1;
});

Related

Check if a set of elements contains the event.target

I'd like to check which of the elements in a set returned by jQuery is the event.target element.
Is this possible?
Yes. I assume by "...which of the elements..." you mean the index of the element within the set. If you have the set in set, then index(element) will give you the index (0, 1, etc.) or -1 if it isn't in the set at all:
var index = set.index(event.target);
Of course, if you just want to do something with the element, you don't need the set at all. Just use $(event.target) to get a new set containing that element.

Get aria-expanded value

I didn't find a way to get aria-expanded value from DOM.
<a class="accordion-toggle collapsed" href="#collapse-One" data-parent="#accordion-1" data-toggle="collapse" aria-expanded="false">
<i class="fa fa-search-plus"></i>
test
</a>
I want to test if it's true then I can change <i> class to fa-search-minus. I tried this but I always get an undefined value:
console.log($(this).find('a.aria-expanded').val());
I wanted to add in a second pure javascript way to get the aria-expanded attribute
document.getElementById('test').getAttribute('aria-expanded')
The above will get the element by id after that you can get any attribute by name.
aria-expanded is an attribute on the element, not a class, so the selector is incorrect. Secondly, you should use the attr() function to get the value of that attribute. val() is intended to retrieve the value attribute from form related elements, such as input and textarea. Try this:
console.log($(this).find('a[aria-expanded]').attr('aria-expanded'));
You can use JavaScript to achieve this:
document.getElementsByTagName('a')[0].attributes[4].value
Step by step explanation:
Get the wanted element, by using some selector - here I use the
document.getElementsByTagName('a')[0]
but you can use any other selector you like.
Access the attributes array of the element and find the position of the wanted attribute - in this case that will be 4, because aria-expanded is the 5th attribute of the tag.
From there you just get the value, and that should give you "false" (in this case).
The only problem with this method is that it's a bit hard-coded, so if you add some more attributes to the tag, the position in the attributes array for the aria-expanded attribute might change.
UPDATE
Instead of using the index for accessing the Aria Expanded property, you can use the name:
document.getElementsByTagName('a')[0].attributes['aria-expanded'].value
This way you will always get the value for the Area Expanded property, regardless of it's position in the HTML tag.
Update 02/2023:
ariaExpanded property still does not work on Firefox. It will be undefined.
Another way to get aria values is to reference the properties directly:
For your instance, you could do something like this:
let firstAnchorTag = document.getElementsByTagName('a')[0]; // I don't know your situation but I recommend adding an id to this element, or making this an iterable array.
console.log(firstAnchorTag.ariaExpanded); // Should log 'false' for your example.
To get:
let el = document.getElementById('foobar');
console.log(el.ariaExpanded); // Should log the current value of aria-expanded.
To set:
let el = document.getElementById('foobar');
el.ariaExpanded = 'true';
console.log(el.ariaExpanded); // Should log 'true'.
Reference: Element.ariaExpanded MDN
In 2020, I could do:
document.querySelector('[aria-expanded]')?.getAttribute('aria-expanded')
to grab the first value and maybe something like:
Array.from(document.querySelectorAll('[aria-expanded]'))?
.map(el => el.getAttribute('aria-expanded'))
to make an array of all aria-expanded values.
attr() function is used to get value of attribute whereas val() is used to retrieve the value attribute from form the related elements, i.e. textbox,input etc. Also aria-expanded is an attribute not a class so you are using incorrect selector.
So you should use attr() instead of val().
Use this:
console.log($(this).find('a[aria-expanded]').attr('aria-expanded'))
You can get the element by the class name "accordion-toggle" (if you have it just one time), or better add an ID to the element, and then get the attribute.
$('.accordion-toggle').attr('aria-expanded')
Or
$('#id-name').attr('aria-expanded')

.data() JQuery returns undefined

im working with my first webapp, Im using ajax parsed object to add dynamic content to one specific .html... while doing so, I found an issue with adding data-* attribute to every option on a select dropdown... when the change function from JQuery executes, it returns undefined.
Here is my ajax function, (I know its not the best way to do it).
ajaxPost("link/x.php",{},function(result){
var json=JSON.parse(result);
var resultado=json.response;
if(json.error==0){
var estadosString='<option value=""></option>';
var cont=0;
for(estado in resultado){
estadosString+=('<option value="'+resultado[estado].nombre+'">'+resultado[estado].nombre+'</option>');
}
$('#estados').html(estadosString);
cont=0;
$('#estados option').each(function(){
$(this).attr('data-id',cont);
$(this).data('id',cont++);
});
}else{
alert("No hay estados");
}
});
The data-id attribute is sucefully added to each option, the issue starts when I use this code to get data-id on change select option.
$('#estados').on('change',function(){
alert($(this).data("id"));
});
It always return undefined, anyone can help me? Thanks..!
The value of this in that "change" handler will be the <select> element, not the <option> it's set to. You can find the option element via the select element's selectedIndex property, or via jQuery.
There's no reason to set the "data-id" attributes either; just set the value via .data().

JQuery - iterate through elements conditionally to addClass()

I have a few input fields that I'm trying to add a class to their parent container if they are not empty.
Here's the CoffeeScript:
$(".inputA, .inputB").parent().addClass(->
if !$(this).is(":empty")
"input-set"
)
This is successfully appending "input-set" to the parent class, but in all cases, not just empty input fields.
:(
Use jQuery.filter()
$(".inputA, .inputB").filter(function(){
return this.value !='';
}).parent().addClass("input-set");
Less function calls than using $.each
:empty will select elements that don't have children. Therefore, using it to conditionally select the parents of certain elements doesn't make any sense.
ref: https://developer.mozilla.org/en-US/docs/Web/CSS/:empty
If you're looking to add the class to the parents of inputs that haven't been populated then you could use something like:
$(".inputA, .inputB").each(function(){
if (this.value !== "") {
$(this).parent().addClass('input-set');
}
});
First, input elements are by definition empty..
Read the :empty documentation at http://api.jquery.com/empty-selector/
Second you are testing the parent elements and not the input ones.. (and since they are parents, meaning they are not empty they all fit the bill..)

JQuery selector by data attribute when data is added dynamically?

I have a ul with several items. I populate the list dynamically after page load using jquery. As I add each list item, I also add an "itemID" to the data of that element using the jquery ".data()" function. Something like this:
var item = $('<li>My Item Name</li>');
item.data('itemID', '123ABC456');
Later, I need a selector to determine if there is any item in my item list with a specific itemID. First I tried using:
$('*[data-itemID="123ABC456"]');
This didn't work - and on further research, I discovered that this syntax only works if the data attribute was set in the DOM when the page was loaded; it doesn't work if you use the ".data" jquery method dynamically.
Next I tried:
$(':data(itemID==123ABC456)');
For some reason, this doesn't work. If I run simply $(':data(itemID)'), however, then I do get all the li elements that have an itemID in their data.
I know that the itemID attribute is set correctly, as when I call .data() on that list item I get:
Object { itemID="123ABC456"}
How can I select all elements that have an itemID of "123ABC456" in their data?
http://jsfiddle.net/w28p9/1/ <-- jsFiddle example showing differences with data-attribute & jquery.data()
jQuery.data() is different than HTML5 data-NAME attributes which you are trying to search for.
http://api.jquery.com/jQuery.data/
jQuery.data() saves inside of the jquery element (this data is hidden from plain sight).
Looking for [data-itemID] would work if inside of the actual had: <li data-itemID="12345"></li>.
To retrieve and look for the actual hidden .data() try:
// of course be more specific than just searching through all <li>'s
$('li').each(function () {
if ( $(this).data('itemID') === '123ABC456' ) {
// do whatever you wanted to do with it
}
});
Hope that helps!
Instead of
$(item).data('itemID', '123ABC456')
use
$(item).attr('data-itemID', '123ABC456')
Then you can use
$('[data-itemID=123ABC456]')
as a selector
How about putting the itemID in the DOM:
var item = $('<li itemID="'+itemid+">My Item Name</li>');

Categories

Resources