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.
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 can use the following to create a indexed list of each instance of a particular item in a class.
var x = document.getElementsByClassName("page");
I can use the following to direct users to a particular id:
function CalledBySelectBox(value)
{
document.getElementById(value).scrollIntoView();
}
However, the elements I want to direct users to are not uniquely identified with Id's. How do I modify the second snippet above, to direct users to a particular instance/occurrence of x in the first snippet. Or to put it differently, how do I direct them to a particular instance of the class.
If its helpful, here is some sample html:
Some text of unknown length full of random tags and what have you.<span class="page">104</span> A bunch more text but we don't know how much and full of other tags.<span class="page">105</span> Some text of unknown length full of random tags and what have you <span class="page">106</span>
I think you are looking for something like this:
function ScrollToPage( page_num )
{
document.getElementsByClassName( 'page' )[ page_num ].scrollIntoView();
}
What getElementsByClassName(className) gives you is an array of elements, what document.getElementById(id) gives you is a single element. To scroll to an indexed element in the array you get, just call scrollIntoView() on that element.
var x = document.getElementsByClassName("page");
x[5].scrollIntoView();
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.
what's the different between using:
// assuming using elements/tags 'span' creates an array and want to access its first node
1) var arrayAccess = document.getElementsByTagName('elementName')[0]; // also tried property items()
vs
// assuming I assign an id value to the first span element/tag
// specifically calling a node by using it's id value
2) var idAccess = document.getElementById('idValue');
then if I want to change the text node....when using example 1) it will not work, for example:
arrayAccess.firstChild.nodeValue = 'some text';
or
arrayAccess.innerText/innerHTML/textContent = 'some text';
If I "access" the node through its id value then it seems to work fine....
Why is it that when using array it does not work? I'm new to javascript and the book I'm reading does not provide an answer.
Both are working,
In your first case you need to pass the tag name instead of the element name. Then only it will work.
There might be a case that you trying to set input/form elements using innerHTML. At that moment you need to use .value instead of innerHTML.
InnerHTML should be used for div, span, td and similar elements.
So your html markup example:
<div class="test">test</div>
<div class="test">test1</div>
<span id="test">test2</span>
<button id="abc" onclick="renderEle();">Change Text</button>
Your JS code:
function renderEle() {
var arrayAccess = document.getElementsByTagName('div')[0];
arrayAccess.innerHTML = "changed Text";
var idEle = document.getElementById('test');
idEle.innerHTML = "changed this one as well";
}
Working Fiddle
When you use document.getElementsByTagName('p'), the browser traverses the rendered DOM tree and returns a node list (array) of all elements that have the matching tag.
When you use document.getElementById('something'), the browser traverses the rendered DOM tree and returns a single node matching the ID if it exists (since html ID's are unique).
There are many differences when to use which, but one main factor will be speed (getElementById is much faster since you're only searching for 1 item).
To address your other question, you already have specified that you want the first element in the returned nodeList (index [0]) in your function call:
var arrayAccess = document.getElementsByTagName('elementName')[0];
Therefore, arrayAccess is already set to the first element in the returned query. You should be able to access the text by the following. The same code should work if you used document.getElementById to get the DOM element:
console.log(arrayAccess.textContent);
Here's a fiddle with an example:
http://jsfiddle.net/qoe30w2w/
Hope this helps!
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().