Protractor - Finding elements by any attribute - javascript

<ul class="menu">
<li ui-sref-active="active">
<a class="ng-scope" translate="menu.home" href="#/home">Home</a>
</li>
<li ui-sref-active="active">
<a class="ng-scope" ui-sref="customer.list" translate="menu.customers" href="#/customers">Customers</a>
</li>
</ul>
I want to search for the element using the text "Home" as in code below:
element(by.linkText("Home")).click();
But I need use too any other available attribute, in this case translate, to make it more accurate.
Is there any possibility in doing that? I've seen things like this
by.css(".ng-scope input[translate='menu.customers']");
But it does not seem to work.

by.css(".ng-scope input[translate='menu.customers']");
This basically translates to: give me the input element having menu.customers translate attribute value, somewhere inside the parent element having ng-scope class. This is not working since there is no parent element with ng-scope class in the HTML you've provided and it is a instead of input you are looking for.
Instead, you probably meant to:
a.ng-scope[translate='menu.customers']
Though, I would not recommend relying on the quite broad ng-scope class.
Here are several rather precise CSS selectors, given the HTML you've provided:
ul.menu > li > a[href*=home] // href contains "home"
ul.menu > li > a[href$=home] // href ends with "home"
ul.menu > li > a[translate="menu.home"] // translate equals to "menu.home"
ul.menu > li > a[translate$=home] // translate contains "home"

Related

Register single click on list item child elements

I have the following HTML structure:
<li class="is_tab" id="geometry_tab">
<a data-toggle="collapse" href="#geometry_tab_collapse">
<i class="pe-7s-plugin"></i>
<p>Geometry
<b class="caret"></b>
</p>
</a>
<div class="collapse" id="geometry_tab_collapse">
<ul class="nav">
<li class="is_tab" id="pipe_geometry_tab">Pipe Geometry</li>
</ul>
</div>
</li>
Using jQuery, my objective is to retrieve the <li> id on click, irrespective of whether the user clicks li.is_tab, li.is_tab > a, li.is_tab > a > p, or li.is_tab > a > i. Moreover, I would like the same event handler to be capable of distinguishing between clicks on #pipe_geometry_tab and #geometry_tab, i.e., simply returning a single, correct id when one or the other is clicked.
My question is this:
Given the following snippet,
$(<selector>).on("click", function(){...})
is there a <selector> that will register a single click on li.is_tab regardless of whether it or its a, i, or p children is clicked?
If not, I would appreciate any recommendations on how to go about this.
PS I've tried quite a few things, but rather than bloat this post with them, I'm hoping someone more experienced feels this has an obvious solution.
$('li.is_tab').on("click", function(e){...});
^^ that should work fine and anything that is clicked on the li will be handled.
If you want the li that was clicked you can look at e.currentTarget if you want to see the actual element that was clicked you can use e.target
So if you want the id of the li that was clicked you can use e.currentTarget.id

jQuery target next `ul` element from `li` with class `active`

Cannot figure what I am doing wrong, as I get no errors. Essentially I want to target the very next ul element from the one and only li containing a class of active.
My HTML is:
<li id="abc"></li>
<li id="account" class="active">
<img class="menu-logo-symbol" src=" /img/app/logo-symbol.png">Your Account
<ul class="nav-pills nav-stacked sub-nav nav-list" style="display: none;">
<li id="account-details"></li>
......
</ul>
</li>
I have tried the following:
var checkElement = $('li.active').next('ul');
checkElement.slideDown('normal');
and
$('li.active').next('ul').show();
and also
$('li.active').next('ul').slideDown('normal');
Thanks
In jQuery, next() and prev() find siblings, or elements at the same depth in the DOM. In this case, since the ul is a child element of .active, you'd actually need to use the find() method like so: $('li.active').find('ul').first().show();
Using first() in combination with find() ensures that it'll only return that single ul element and not any others that may be nested deeper.
Done as follows:
$('.active ul:first').slideDown('normal');
I still do not understand why this did not work
$('li.active').next('ul').show();

Trouble using .closest function

I'm trying to make a sidebar menu for a dashboard. I want to implement this with .closest as it will fit with my code right. Here is a simple example of what I'm trying to do: https://jsfiddle.net/eu8kjzh4/10/
Why isn't the closest span's (and the only span in this case) text being replaced with a '-'? In my code, I have
$('.' + Key).closest( '.' + Key ).css("color", "#000");
This code works just fine, but the one in the jsfiddle does not.
closest traverses up the DOM and is used for nested elements.
In your markup, your div is not a descendant of your span, not even a sibling.
You have
1. To retrieve the previous sibling (the first li after the body)
2. And find the span inside the li
$(document).ready(function() {
$(".sub").prev().find('span').text('-');
});
Also, in your fiddle, you forgot to include jQuery.
Here is a working code : https://jsfiddle.net/qwc6pepr/1/
Incorrect function: .closest( selector ) Returns: jQuery
Description: For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree
What you want is the prev which finds the first sibling prior to the element
$(document).ready(function() {
$('.sub').prev('li').find('span').text('-');
});
From jQuery documentation
Given a jQuery object that represents a set of DOM elements, the .closest() method searches through these elements and their ancestors in the DOM tree and constructs a new jQuery object from the matching elements
Your span is neither a Parent Element of your div.sub in the DOM, nor matches with the $(".sub") rule.
The only way to make your jQuery code work with your HTML structure :
$("#plusMinus1").text("-");
Or modify your HTML structure to match with the .closest() method requierements
Fiddle
When you go to the parent you'll end up in the body. From there you can find the span.
$(document).ready(function() {
$(".sub").parent().find("span").text("-");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<body>
<li>
<a class="selected" href="#" onclick="return false;">Dashboard 1 <span id="plusMinus1">+</span></a>
</li>
<div class="sub">
<ul>
<li><a id="s1" href="">Test A</a>
</li>
<li><a id="s2" href="">Test B</a>
</li>
<li><a id="s3" href="">Test C</a>
</li>
</ul>
</div>
</body>

Jquery selecting hierarchies

Before I begin this question, if you're new to backbone.js and want to implement the following functionality you have to use the backbone relational model, or at least that's what it seems like.
I'm trying to create a hierarchy that will be implemented through backbone.js and I was wondering how to structure the hierarchy and access the elements. I need to be able to add and remove Lists/Sets/Items and hopefully keep a consistent numbering policy. (List1 would have a displayed name of list1. If I deleted Set1 I would want Set2 to become Set1 while retaining its corresponding items)
List1
^--->Set1
^--->Item1
^--->Item2
^--->Set2
^--->Item1
List2
^--->Set1
^--->Item1
^--->Set2
^--->Item1
^--->Item2
etc.
My question is this: How do you structure this in a way such that a set of functions following the same hierarchy can access them in the most compact and logical manner?
One idea I had:use div and just have your div id be something like id="List"+currentlistnum()+"Set"+currentsetnum()+"Item"+currentitemnum()
Is there a better way to do it than this?
If you have list of items that is semantically a "list", use ordered list(ol) or unordered list(ul). Then if you have sub lists nest more lists.
<ul id="mylist">
<li>
<span>List 1</span>
<ul>
<li>
<span>Set1</span>
<ul>
<li>List1Set1Item1</li>
<li>Item2</li>
<li>Item3</li>
</ul>
</li>
<li>
<span>Set2</span>
<ul>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
</ul>
</li>
</ul>
</li>
</ul>
And use jQuery nth Child selector and immediate child > for rest of logic to select particlar elements, so you can keep application logic away from HTML.
$('#mylist > li:nth-child(1) > span').text(); // List1
$('#mylist > li:nth-child(1) > ul > li:nth-child(1) > ul > li:nth-child(1)')
.text(); //List1Set1Item1
If you want a numbering system attached: Example refresing all Set to update its number according to present view:
$('#mylist > li > ul > li > span').each(function(){
var ordinalPositionOfMyParent = $(this).parent().index() + 1;
$(this).text('Set' + ordinalPositionOfMyParent);
});

How to aceess span directly using jQuery

I want to know how to get access of this [span class="myclass"] in below html structure..
<ul>
<li class="first">
<span class="myclass"></span>
<div class="xx">
<span></span>
........
</div>
<li >
<span class="myclass"></span>
<div class="xx">
<span></span>
........
</div>
</ul>
Here I need to write one function in [span class="myclass"], but i cant do it using $(".myclass") [I have few issues] I just want to directly access the span itself.How to do this..?
EDIT:the sln by phoenix is working fine..but lets say(just for my knowledge) the structure is
<li >
<span class="myclass"></span>
<div class="xx">
<li>
<span></span>
</li>
........
</div>
</ul>
so why the span inside 2 nd li(which is under div) is not getting the ref, is it bcoz they are not in the same level..if I need to access them do I need to do some thing like
enter code here
$("li").next(".xx").find(li span:first-child )..or something else is there?
Thanks.
$("li span.myclass")
EDIT: Okay then maybe with
$("li span:first") //EDIT: Don't do that. See below.
apparently :first stops after the first hit. So :first-child is the way to go.
which will select the first span in every li-element. But this can be tricky in case you have other li-elements with spans inside...
EDIT: If you can't use the class you already have, maybe assigning an additional class helps?
<span class="myclass newClass"></span>
...
var spans = $("li span.newClass");
EDIT:
As phoenix pointed out
$("li span:first-child")
returns a list with all span elements that are the first child of a li-element. I don't know if jQuery treats textnodes as child nodes. So if you have a space between <li> and <span>, this might be counted as the first-child. So check if you have any whitespace between your elements beside line breaks.
If span is the first child then you can use
first-child
selector
$("li span:first-child");

Categories

Resources