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')
Related
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;
});
I have this following html:
which has a class and a custom attribute, I have several header's with the same className. I wanted to know how to uniquely get this element and click on it.
<h4 class="font-white topic-heading progress-header no-margin width-80 d-table-cell" data-collapse-id="1">I. Introduction</h4>
This is what i tried:-
I tried to get the attribute of the class="font-white..." with data-collapse-id="1" :
var element = driver.findElement(By.xpath("//*[#class='font-white topic-heading progress-header no-margin width-80 d-table-cell']")).getAttribute('data-collapse-id="1"');
console.log(element); // this prints a promise.
element.click(); //element.click is not a function exception
I also tried:-
var element = driver.findElement(By.xpath("//*[#data-collapse-id='1']"));
element.click(); // element.click is not a function exception.
I wanted to know how to fetch this element in selenium and click on it.
this is the entire div:
<div class="page-width d-table topic-heading-div">
<h4 class="font-white topic-heading progress-header no-margin width-80 d-table-cell" data-collapse-id="1">I. Introduction</h4>
<i class="fa fa-check font-white font-18 width-20 d-table-cell text-center vertical-center" aria-hidden="true"></i>
</div>
Did you try:
driver.findElement(By.cssSelector("h4[data-collapse-id='1']")).click();
Finding element through this attribute should work because this is unique. Also it sometimes unable to click on element found by xpath. I think this should work
It seem that your element variable intends to return attribute. However, getAttribute() method should receive attribute name value as argument and return an attribute value which is a simple string... And here you got few problems:
you're trying to pass wrong argument: 'data-collapse-id="1"' instead of 'data-collapse-id'
attribute value, a string, is not clickable!
Simple answer to your question- there is no way you can click on a custom attribute
Class is meant to define a group of elements having similar features. In this case, the topic-heading class is used to group the <h4> tags alongwith a unique ID attribute called as data-collapse-id. But in such case's we can't use ID to identify/specify each web element as the elements of same class can be hundreds/thousands.
You can try locating any header element uniquely using the following ways:
var exactHeadingText = "I. Introduction"; // Exact heading
By locExactTopicHeading = By.xpath("//h4[contains(#class,'topic-heading') and text()='"+ exactHeadingText + "']");
var partialHeadingText = "Introduction"; // Partial heading
By locPartialTopicHeading = By.xpath("//h4[contains(#class,'topic-heading') and contains(text(),'"+ partialHeadingText + "')]");
Ideally you should pass the exactHeadingText/partialHeadingText as a function parameter/argument so that the code can be reused to fetch any topic heading.
You can then use findElement() and perform any operation on it.
This is the HTML structure:
<div data-step="1"></div>
<div data-step"2" class="active"></div>
Something along those lines (the following is obviously wrong, it's just to provide an idea)
if($("div").attr("data-step", "2").hasClass("active")) {
//do this...
}
Use attribute equals selector to get the element with a certain attribute value. With attr() method it simply sets the attribute value and returns the jQuery element object.
if($("div[data-step='2']").hasClass("active"))
// or simply combine the class with selector and
// check existance simply by checking its length
if($("div[data-step='2'].active").length)
I wanted to put an id in my element's parent element. Below is my code:
<div>
<div id="child"></div>
<div>
Im aware that jquery has a way to select a parent element , but I dont know how what method shall I use to put an id to it. Below is my jquery code:
div_resizable = $( "#child" ).parent();
div_resizable.id = "div_resizable";
Above code doesnt work with me. It doesnt throw an error, but no changes had taken effect. Any solution to my problem?
For achieve what you want, you can use the jquery attr:
$("#child" ).parent().attr('id', 'newID');
Or you can use the prop:
$("#child" ).parent().prop('id', 'newID');
And you can check the difference between the two here: difference between prop() and attr()
Of course div_resizable.id = "div_resizable" doesn't work. div_resizeable is an jQuery array and you are trying to assign id to it.
Try .attr instead:
$("#child").parent().attr({id: "div_resizable"});
To set a property on the first element inside a jQuery result object:
div_resizable = $( "#child" ).parent()[0];
// ^^^
div_resizable.id = "div_resizable";
This picks the first Element from the result so that you can directly access the property.
Or:
$('#child').parent().prop('id', 'div_resizable');
Use the .prop() helper method to accomplish the same thing.
I'm trying to do something similar to this question, but it's a bit different, so the solution there isn't working for me.
<span class="a-class another-class test-top-left"></span>
I have an element (this code shows a span but it could be div span or anything). This element has a class beginning with test- (test-top-left, test-top-right etc.) I've triggered a click event on classes starting with test- and saved the clicked object as var object = this;. Simple stuff so far.
What I'm trying to do now is get the full name of that class (test-top-left). I know it starts with test- but what's the full name. The thing is that there are other classes a-class another-class and test-top-left. Can hasClass be used to get the full name of the class? I'd prefer not to use find() or filter() just because there may be additional elements within that also have class="test-"
Edit:
The code I have now is, but it gives me ALL the classes. What I need is the single class beginning with test-.
var object = this;
$(object).attr('class');
So now I for loop through all the classes and test each one separately, which seems like a lot of unnecessary code. I'm hoping jQuery has a clever way to get the exact class that was clicked right away.
Description
You can use jQuerys Attribute Contains Selector, .attr() and .click() method.
Attribute Contains Selector - Selects elements that have the specified attribute with a value containing the a given substring.
.attr() - Get the value of an attribute for the first element in the set of matched elements.
.click() - Bind an event handler to the "click" JavaScript event, or trigger that event on an element.
Sample
html
<span class="anyclass test-hello">Hello World</span>
jQuery
$("[class*='test']").click(function() {
var object = $(this);
alert(object.attr("class").match(/(test-.*?)(?:\s+|$)/)[1])
;});
Check out the updated jsFiddle
Update
If you dont want to use regex you can do this.
$("[class*='test']").click(function() {
var object = $(this);
alert("test-" + object.attr("class").split("test-")[1].split("-"))
;});
More Information
jQuery - Attribute Contains Selector
jQuery - .attr()
jQuery - .click()
jsFiddle Demonstration
This should work for you:
var object = this;
var className = object.className.match(/(test-.*?)(?:\s+|$)/)[1];
Class name is the name of the class you are looking for.
If you don't want to use split or regex, you can try having the class in a separate attribute
<span class="someclass test-something" _rel="test-something">test<span>
or
<span class="someclass" _rel="test-something">test<span>
with the script
$("[_rel*='test-']").click(....
And to retrieve the attribute, use $(this).attr("_rel")