I have a nested list item with deep sublevels. For instance:
a
a,a
a,b
a,b,a
a,b,b
b
b,a
b,b
b,c
b,d
b,d,a
b,d,b
The last list is a tel link.
Let's say the tel link for b,d,a is <li><a class="tel-link" href="tel:8888">b,d,a</a></li>
How can I track the hierarchy and add the numbered sublevels to the end of the tel link so it becomes <li><a class="tel-link" href="tel:8888,2,4,1">b,d,a</a></li> and adds ,2,4,1 to the end of the tel link?
Here's a jsFiddle
Use jQuery's .index() function (see the docs, https://api.jquery.com/index/)
If no argument is passed to the .index() method, the return value is an integer indicating the position of the first element within the jQuery object relative to its sibling elements.
I've put together a fiddle to demonstrate.
The highlight is a recursive function:
function getAncestory(el)
{
if (el.parent().parent().is("li"))
// If this <li> element is a child, prepend the parent indices
return getAncestory(el.parent().parent()) + "," + el.index();
else
return el.index()
}
// Only register clicks on <li> elements that don't have children
// (there are other ways to do an equivalent selector)
$("li:not(:has(*))").click(function(event){
alert(getAncestory($(this)))
})
This fiddle returns your desired_result - 1. I've left it like that because it's trivial to increment all the values by 1 but it's simpler to understand the code without the increment.
Related
I am currently writing a Nightwatch test to select a new document from a list. And I will need to be able to select the next in the list. Is there a way to manually override the child number that needs selecting?
For example the current selector being used is :
<ul class="dv-packdocs">
<li class="dv-packdoc"<div class="icon-todo"></li>
<li class="dv-packdoc"<div class="icon-todo"></li>
<li class="dv-packdoc"<div class="icon-todo"></li>
<li class="dv-packdoc"<div class="icon-todo"></li>
</ul>
and the test would be something like :
viewer.selectNewDocument([2])
would this select the second child under the ul?
Or would I have to specify each child element?
If I understand correctly, you are trying to dynamically find the appropriate child element (li) from a dynamical length list (ul, where the list is populated based on user input, or other site actions). Correct?
I see two scenarios with two different approaches:
1. You have a set/fixed condition (way of identifying your target element): for example, in your list, the second li would be targeted by the below command.
viewer.selectNewDocument('ul.dv-packdocs li:nth-child(2)') (considering you are passing a complete selector to the selectNewDocument function)
, or
viewer.selectNewDocument(2), passing a number & form the selector inside the command (if you care for aesthetics):
selectNewDocument: function(index) {
this.api.perform((done) => {
// Click the second document in the list:
let selector = `ul.dv-packdocs li:nth-child(${index})`;
this.api.click(selector);
done();
});
return this;
},
Alternatively, if you would want the last document added, then you would have to issue a elements call on the ul to retrieve the length of the list, then use that in the same way to determine which li you have to click: viewer.selectNewDocument('ul.dv-packdocs li:nth-child('+length+')') (where length is the result of your elements call).
2. You don't have a fixed condition (I'll fill this up if the first part doesn't cover it, or later today, kinda slammed after the holidays)
Hope it's what you were looking for! Cheers!
I have a simple structure like:
HTML
<ul id="costsDropdown">
<li data-position="bla bla"></li>
</ul>
and I want to change each "data-position" attribute of my list Elements.
My first Jquery Shot was this here:
$("#costsDropdown ul").each(function() {
$("li").attr("data-position", "TEST-VALUE123");
});
but it doesnt work, I think my selector are wrong...
could anyone give me a hint please?
Thanks for any help!
Greetz
Your selectors are a bit off
$("#costsDropdown ul").each
That is trying to select the child ul of the container #costsDropdown (which is the ID of the ul) - what you want is:
$("#costsDropdown li").each(function() {
$(this).attr("data-position", "TEST-VALUE123");
});
ID's are unique - no need to double up the selector with an ID and the type of element it is.
Note that I used $(this), not $("li"), inside the each callback. $("li") selects all li elements, anywhere on the page; we just want a jQuery wrapper for the one specific one we're handling inside the each.
In fact, the each is completely unnecessary because of the set-based nature of jQuery; if you use the .attr setter, it sets the attribute on all elements in the set:
$("#costsDropdown li").attr("data-position", "TEST-VALUE123");
That will set the value on all of the li elements inside #costsDropdown.
If you need to set separate individual values on the individual li elements, you still don't need each (though it's fine if you want to use it); you can use the version of attr that accepts a callback that it uses to find out what value to set:
$("#costsDropdown li").attr("data-position", function(index) {
return "Test value " + index;
});
That will set "Test value 0" on the first li, "Test value 1" on the second, etc. And like the each example above, if you need to, you can use this within the callback to refer to the li for that call (possibly using $(this) to wrap it if you need a jQuery wrapper).
$("#costsDropdown ul") matches no elements, it has to be $("#costsDropdown") (#costsDropdown is the ul).
And even that is unnecessary. Go
$("li[data-position]").attr("data-position", "TEST-VALUE123");
instead.
Ok, so I need to be able to get the n (zero based) position of an element based on a mutual match between the page & element ID...
It's probably easier if I give an example (Assume the current page ID is 488);
<ul id="work-grid">
<li id="item-486" class="work-item"><!--/content--></li>
<li id="item-487" class="work-item"><!--/content--></li>
<li id="item-488" class="work-item"><!--/content--></li>
<li id="item-489" class="work-item"><!--/content--></li>
<li id="item-490" class="work-item"><!--/content--></li>
</ul>
As you can see the list item with the matching numeric ID 488 is the third in the list (So would have an n value of 2).
The problem is, this grid appears on multiple pages (With different ID's) and the list is populated dynamically so I never know the position of the matching element. Is there a way that I can get it using jQuery and add it to the following snippet (Replacing 2 for the correct n position)
$('#work-grid').trigger("colio", ["expand", 2]);
This probably made little to no sense so if anything needs clarification please just let me know.
I think index() is what you want:
var index = $('#item-488').index();
$('#work-grid').trigger("colio", ["expand", index]);
Assuming your element appears once on the page, you can do:
$('#item-488').index();
to find out the index of the element. Read up on index() here: http://api.jquery.com/index/ The bit that applies to this scenario is:
If no argument is passed to the .index() method, the return value is an integer indicating the position of the first element within the jQuery object relative to its sibling elements.
Here's an example: http://jsfiddle.net/bnF6h/
var page = 488;
var a = $( "li[id$='"+ page +"']");
You can use this to dynamically select the item id based on the page id.
Applying it:
var page = 488;
var a = $( "li[id$='"+ page +"']").index();
$('#work-grid').trigger("colio", ["expand", a]);
You mean jQuery's index() method?
http://api.jquery.com/index/
If no argument is passed to the .index() method, the return value is an integer indicating the position of the first element within the jQuery object relative to its sibling elements.
I have a jQuery object that is an HTML li element. How do I find what is the index of it in the context of its parent ul?
So if I have this:
<ul>
<li>abc</li>
<li id="test">def</li>
<li>hij</li>
</ul>
And this object:
$("test")
Is there a way to get the index number of this element. In this case it would be 1 (if you count 0 being the first index). Is there something I can do with $("test").parent()?
You can simply use $("#test").index(). Note the use of the id selector #.
When .index() is called without any parameters,
the return value is an integer indicating the position of the first
element within the jQuery object relative to its sibling elements.
In this case this would be 1 -- see it in action.
.index() is what you're looking for. Evaluates against its siblings, see the jQuery documentation.
You can use index():
var index = $('#test').index();
Or, you can supply a selector, to get the index from a different set of matched elements:
var index = $('#test').index('li.className');
Which will get the index point for the #test element from among those elements with the .className (assuming that #test also had this class).
References:
index().
using jQuery's .next function I want to show next 2 items. By default it selects only just next item.
I need control, like sometimes I need next 2, sometime next 3
You can use .nextAll() and a :lt() selector, for example:
.nextAll(':lt(2)') //next 2
.nextAll(':lt(3)') //next 3
Try it out here. If you need it to be programmatic (instead of string concatenation) and change it easily, use .slice() instead:
.nextAll().slice(0, 2) //next 2
.nextAll().slice(0, 3) //next 3
This method allows you to pass as a parameter the number you need a bit easier. You can test it here.
If you want to select the next number of elements and include the selected element you can do something like:
$('div#myTarget').nextAll('div').andSelf().slice(0,4)
The above code returns the next 4 div elements after the div myTarget and includes the myTarget div itself.
.slice(0,4) selected the next 4 elements and .andSelf() included the original selected element
Use .nextAll instead of .next to get all following siblings, and then use .slice to narrow that down to a range.