Select an item from a list with javascript - javascript

I am using javascrypt with selenium. I need to search and select one of the items in this list, but I am unable to select it. I can find it, but not select the element.
Please help me, thank you very much
var input = document.evaluate("//li[contains(., 'ATACAMA')]", document, null, XPathResult.ANY_TYPE, null );
var thisregion = input.iterateNext();
thisregion.click();

You could try the following below:
var input = document.evaluate("//li[text()='ATACAMA']", document, null, XPathResult.ANY_TYPE, null );
var thisregion = input.iterateNext();
thisregion.click();

So I don't have a clue about Xpath, but like you said, there is nothing stopping you from using querySelector or in this case querySelectorAll instead.
Here I create an array of all the li elements and use .find to get the element that has the text "Item 3" in it. I then click the element programmatically. All of the li elements have onClick event inline in the html.
Would this work for you?
let li_item = Array.from(document.querySelectorAll('li'))
.find(x => x.textContent === 'Item 3');
li_item.click();
function select(element, n) {
element.style.color = "red";
console.log(`${n} has been selected!`);
}
<ul>
<li onClick = "select(this, 1)">Item 1</li>
<li onClick = "select(this, 2)">Item 2</li>
<li onClick = "select(this, 3)">Item 3</li>
<li onClick = "select(this, 4)">Item 4</li>
<li onClick = "select(this, 5)">Item 5</li>
</ul>

Related

How to iterate through <ul> child elements using DOM JS

So I have a menu, I want it to display information accordingly, for example:
<ul id="menu-list">
<li id="about-me">About Me</li>
<li id="skills">Skills</li>
<li id="experience">Experience</li>
<li id="education">Education</li>
<li id="projects">Projects</l>
<li id="contacts">Contacts</li>
</ul>
and on my JS file I did this in order to access "li" elements:
let navMenu = document.getElementById("menu-list");
let menuList = navMenu.getElementsByTagName("li");
let skillsButton = document.getElementById("skills");
let skillsEvent = document.getElementById('main-section-skills').hidden = true;
(text that will display on click is pre-set to hidden = true)
The goal is to iterate through "li" items to find which one of those has ".hidden = false" value and change it to ".hidden = true" so that when you click on different menu buttons, each button will so only relevant info and others that are not relevant will bi hidden.
Thanks for your help.
You can get the array of children using element.children
https://developer.mozilla.org/en-US/docs/Web/API/Element/children
for (let child of navMenu.children) {
your logic here
}
For checking the class you can use element.hasClass or even:
element.style.display = 'none'
element.style.display = 'block'

How to keep a menu-item selected in html with javascript

This is my html code. How can I keep a menu-item (link to another page) selected when I'am browsing ? I'd like to do it with javascript. Thank you in advance.
<ul class="header-menu" id="nav">
<li class="menu-item">HOME</li>
<li class="menu-item">NEWS</li>
<li class="menu-item">TOUR DATES</li>
<li class="menu-item">GALLERY</li>
<li class="menu-item">ABOUT</li>
</ul>
There are multiple ways to achieve that effect. Let's first state that you have an "active" class that you can use on the menu items that will make them pop out, how would you go about applying that class?
First of all, I would assign a specific class or id to all the menu items, to make them easy to reference within the css (or javascript).
Let's say that now your situation is like this:
<ul class="header-menu" id="nav">
<li class="menu-item home-item">HOME</li>
<li class="menu-item news-item">NEWS</li>
<li class="menu-item tour-item">TOUR DATES</li>
<li class="menu-item gallery-item">GALLERY</li>
<li class="menu-item about-item">ABOUT</li>
</ul>
Now, with javascript, you could do it like this:
// Get the page name
let pathArray = location.pathname.split("/");
let page = pathArray[pathArray.length-1];
// Get all menu items and convert them to an Array
let menuItems = document.querySelectorAll(".header-menu .menu-item");
menuItems = new Array(...menuItems);
let lookFor = "";
// Based on the page, set the variable lookFor as the identifying class
switch (page) {
case "home.html":
lookFor = "home-item";
break;
case "news.html":
lookFor = "news-item";
break;
// ...
}
// Get the element that contains the class
let item = menuItems.filter( (item) => item.classList.contains(lookFor) )[0];
// Set the "active" class on the element
item.classList.add("active");
Here you can check out a codesandbox with the working code.

I want to click my list item in random but can't

I would like to add a click event to my list of items. It's a TO-DO-LIST, so a list item should have a line-through style whenever I click it. However, I can't get it right. The console always says:
Uncaught TypeError: togList.addEventListener is not a function
var togList = document.getElementsByTagName("li");
function togglesOnOff() {
togList.classList.toggle("done");
}
togList.addEventListener("click", togglesOnOff);
You are getting the error because getElementsByTagName doesn't return an element it returns a collection of elements.
so, you need to loop over the collection:
var togList = document.getElementsByTagName("li");
function togglesOnOff() {
this.classList.toggle("done");
}
Array.from(togList).forEach(item => item.addEventListener("click", togglesOnOff));
.done {
background: red;
}
<ul>
<li>Item one</li>
<li>Item two</li>
<li>Item three</li>
</ul>
You will also need to change the function to use the current element to toggle the class. To do so, we just change togList to this.

append / appendChild not working on all items

I'm trying to move all the list items from an list to another using only javascript but for some reason only half of them are actually moved.
Heres a working example of what I'm doing:
var results_ul = document.getElementById('results');
var stores_li = document.getElementsByClassName('store-list-item');
for (var x = 0; x < stores_li.length; x++) {
document.getElementById('hide').appendChild(stores_li[x]);
stores_li[x].className += ' teste';
}
<p>results</p>
<ul id="results">
<li class="store-list-item">Teste 1</li>
<li class="store-list-item">Teste 2</li>
<li class="store-list-item">Teste 3</li>
<li class="store-list-item">Teste 4</li>
</ul>
<p>Hide:</p>
<ul id="hide"></ul>
What seems to be the problem?
getElementsByClassName returns a live list.
When you append the element to a different element, you change its position in the list.
So it starts off as:
1 2 3 4
Then you move the first one:
2 3 4 1
Then you access the second one … but the second one is now 3 because everything has shuffled down the list.
You could copy each element into an array (which will not be a live list) and then iterate over that array to move them (so they won't change positions as you go).
Alternatively, you could use querySelectorAll which returns a non-live list.
You should better use querySelectorAll than getElementsByClassName
var results_ul = document.getElementById('results');
var stores_li = document.querySelectorAll('.store-list-item');
stores_li.forEach((item)=>{
document.getElementById('hide').appendChild(item);
item.className += ' teste';
});
<p>results</p>
<ul id="results">
<li class="store-list-item">Teste 1</li>
<li class="store-list-item">Teste 2</li>
<li class="store-list-item">Teste 3</li>
<li class="store-list-item">Teste 4</li>
</ul>
<p>Hide:</p>
<ul id="hide"></ul>
Try use querySelectorAll . It'll returns a non-live list. That's what you need.
var stores_li = document.querySelectorAll('.store-list-item');
To increase more information:
Live : when the changes in the DOM are reflected in the collection. The content suffers the change when a node is modified.
Non-Live : when any change in the DOM does not affect the content of the collection.
document.getElementsByClassName() is an HTMLCollection, and is live.
document.querySelectorAll() is a NodeList and is not live.
In your code you are removing each element from the first list and inserting into the new list. After you remove 2 elements it will have only 2 elements in the first list but now you are searching the 3 rd index in the loop which is not there. So to make it work i have prepended each element from the last.
var results_ul = document.getElementById('results');
var stores_li = document.getElementsByClassName('store-list-item');
var hide_ul = document.getElementById('hide');
for (var x = 0, y = stores_li.length; x < y; x++) {
hide_ul.insertBefore(stores_li[y-x-1],hide_ul.firstChild);
stores_li[x].className += ' teste';
}
<p>results</p>
<ul id="results">
<li class="store-list-item">Teste 1</li>
<li class="store-list-item">Teste 2</li>
<li class="store-list-item">Teste 3</li>
<li class="store-list-item">Teste 4</li>
</ul>
<p>Hide:</p>
<ul id="hide"></ul>
Or you may want to clone the element with Jquery and you can push into the clonned ones then delete the orginals from top. I could not find any equivalent of clone() for js but if you want to check link is here
var results_ul = document.getElementById('results');
var stores_li = document.getElementsByClassName('store-list-item');
while(stores_li.length>0) {
document.getElementById('hide').appendChild(stores_li[0]);
stores_li[x].className += ' teste';
}

Hide parent div if list is empty

I have the following....
<div class="validationbox">
<h1>Errors</h1>
<ul class="validationerrors">
<li>Error 1</li>
<li>Error 2</li>
<li>Error 3</li>
</ul>
</div>
The error list items are generated dynamically so sometimes there are none, I would like to hide the 'validationbox' div if there are no list items.
I imagine it is javascript or jquery that I should be looking at, does anyone have any examples?
In jQuery you can do it as simple as:
$(".validationbox:not(:has(li))").hide();
In pure JavaScript you need to iterate ".validationbox" elements and search for <li> nodes inside:
var div = document.getElementsByClassName("validationbox");
for (var i = 0, len = div.length; i < len; i++) {
if (!div[i].getElementsByTagName("li").length) {
div[i].style.display = "none";
}
}
$('.validationbox').toggle( $('.validationerrors li').length );
toggle() accepts a boolean value as an argument. $('.validationerrors li').length will evaluate to false if there is no <li> elements, else true, which will show the error list.
you can use not .
$('div .validationbox').not(':has(li)').hide();
hope it's help to you

Categories