I want to rename CAR BUS to MY CAR, rename WATER to BREAKFAST, and delete the cocacola and fanta, to now be shown. People tell me it must be replaced with JS but I have no idea.
<li class="dropdown">
<a href="#" data-toggle="dropdown" data-hover="dropdown" aria-expanded="false">
CARS BUS<b class="caret"></b></a>
<ul class="dropdown-menu">
<li>WATER</li>
<li>COCA COLA</li>
<li>FANTA</li>
</ul>
</li>
If you have access to the underlying HTML, there's no need to use JavaScript at all. So if you have access, change it in the HTML.
In case you don't have access, you have to do these steps:
1) Grab elements to change with a DOM query (document.querySelector & document.querySelectorAll)
2) Change their innerHTML to the desired text
Based on the HTML you've shown, the most tricky part of it will be the DOM query. Mainly because there isn't much which allows to identify the correct elements (via id or class). To find out if you are working with the correct elements, you also have to compare their content.
This should work:
function queryAll(s, r) {
return Array.prototype.slice.call((r || document).querySelectorAll(s));
}
function isTarget(needle, element) {
var regex = new RegExp(needle);
return regex.test(element.innerHTML);
}
function changeText (needle, replacement, element) {
element.innerHTML = element.innerHTML.replace(needle, replacement);
}
var dropdowns = queryAll('a[data-toggle="dropdown"]');
dropdowns.forEach(function (anchor) {
if (isTarget('CARS BUS', anchor)) {
var subAnchors = queryAll('a', anchor.nextElementSibling);
changeText('CARS BUS', 'MY CAR', anchor);
subAnchors.forEach(function (sub) {
if (isTarget('WATER', sub)) {
changeText('WATER', 'BREAKFAST', sub);
} else {
sub.parentNode.style.display = 'none';
}
});
}
});
<li class="dropdown">
<a href="#" data-toggle="dropdown" data-hover="dropdown" aria-expanded="false">
CARS BUS<b class="caret"></b></a>
<ul class="dropdown-menu">
<li>WATER</li>
<li>COCA COLA</li>
<li>FANTA</li>
</ul>
</li>
// Plain JS
// `document.querySelector` will get the first element that matches
// inside selector `>` means that you want to get the direct child of --- in this case `.dropdown`
var $carbus = document.querySelector( 'li.dropdown > a' ), // element
$dropdownMenu = document.querySelector( '.dropdown-menu' ), // dropdown-menu
$firstLi = $dropdownMenu.querySelector( 'li > a' ), // element with water text
$notFirstLi = $dropdownMenu.querySelectorAll( 'li:not(:first-of-type)' ); // last two `li` items
replaceWord( $carbus, 'cars bus', 'my car' ); // replacing `cars bus` with `my car`
replaceWord( $firstLi, 'water', 'breakfast' ); // replacing `water` with `breakfast`
// removing last two items
$notFirstLi.forEach(function (item) {
item.remove();
});
/**
* #param {Element} el - target element
* #param {String} oldWord - Old word you want to change
* #param {String} newWord - New word you want to show
*/
function replaceWord(el, oldWord, newWord) {
var re = new RegExp( oldWord.toUpperCase(), 'i' ),
newTxt = el.innerText.replace(re, newWord.toUpperCase());
el.innerText = newTxt;
}
<li class="dropdown">
CARS BUS<b class="caret"></b>
<ul class="dropdown-menu">
<li>WATER</li>
<li>COCA COLA</li>
<li>FANTA</li>
</ul>
</li>
Related
I am beginner web developer.
I have small problem with my code:
var nodes = document.querySelectorAll('.breadcrumb-item');
if(nodes != undefined && nodes !=''){
var first = nodes[0];
console.log('xxxxxx' , first);
}
It's return me:
[Log] xxxxxx
<li role="presentation" class="breadcrumb-item">
Home
</li>
I need check:
if a href is "Home" then replace href from "#/" to "/dashboard"
if a href is not "Home" then show console.log('not find').
How can I make it?
I have dynamic string. For example:
<li role="presentation" class="breadcrumb-item">
Home
</li>
<li role="presentation" class="breadcrumb-item">
Dogs
</li>
<li role="presentation" class="breadcrumb-item">
calls
</li>
<li role="presentation" class="breadcrumb-item">
cats
</li>
I need replace URL ONLY for Home
I've written assuming that Home will always be first in order. If you're going to change its order, you'll will have to change the index for nodes inside if block.
const nodes = document.querySelectorAll(".breadcrumb-item");
if (nodes.length > 0) {
const first = nodes[0].firstElementChild;
first.href = "/dashboard";
console.log(first);
}
Previous answer is correct. Maybe the following gives you a clearer understanding:
const nodes = document.querySelectorAll('.breadcrumb-item');
if (nodes.length > 0) {
const first = nodes[0].firstElementChild;
let currentUrlTitle = first.text.trim().toLowerCase();
if (currentUrlTitle == 'home') {
console.log(first.text);
first.href = '/dashboard';
console.log(first.href);
} else {
console.log(currentUrlTitle);
}
}
So I have these list items in the div below:
<div class="container">
<h2>Dissapearing Game</h2>
<div>
<li class="list-group-item go" id="item">Door#1</li>
<li class="list-group-item go" id="item">Door#2</li>
<li class="list-group-item go" id="item">Door#3</li>
<li class="list-group-item go" id="item">Door#4</li>
<li class="list-group-item go" id="item">Door#5</li>
</div>
My Goal is to make them dissapear upon typing the string "None" into it. The JavaScript goes as so:
<script type="text/javascript">
var TextInsideLi0 = document.querySelectorAll('li')[0].innerHTML; // Retrieving text line 1
var TextInsideLi1 = document.querySelectorAll('li')[1].innerHTML; // Retrieving text line 2
var TextInsideLi2 = document.querySelectorAll('li')[2].innerHTML; // Retrieving text line 3
var TextInsideLi3 = document.querySelectorAll('li')[3].innerHTML; // Retrieving text line 4
var TextInsideLi4 = document.querySelectorAll('li')[4].innerHTML; // Retrieving text line 5
var MenuItems = document.querySelectorAll('.go'); // Retrieves the Menu Item by Class 'go'
//BELOW executes the CSS to hide the list item when "None" string is entered:
if (TextInsideLi0 == "None") {
MenuItems[0].classList.add('hidden')
} else if (TextInsideLi1 == "None") {
MenuItems[1].classList.add('hidden')
} else if (TextInsideLi2 == "None") {
MenuItems[2].classList.add('hidden')
} else if (TextInsideLi3 == "None") {
MenuItems[3].classList.add('hidden')
} else if (TextInsideLi4 == "None") {
MenuItems[4].classList.add('hidden')
}
</script>
ABOVE works for the 5 list items.. I just want clues in adding a for loop for it which will allow me to enter infinite list items with the same functionality.
you cannot give each item the same id.
<li class="list-group-item go" id="item1">Door#1</li>
<li class="list-group-item go" id="item2">Door#2</li>
<li class="list-group-item go" id="item3">Door#3</li>
<li class="list-group-item go" id="item4">Door#4</li>
<li class="list-group-item go" id="item5">Door#5</li>
you can do the whole thing with these. Using the loop on the li elements on the page, you control each of them innerHTML and give them a class.
const allElements = document.querySelectorAll(".list-group-item");
allElements.forEach(element => {
if(element.innerHTML == "None") {
element.classList.add("hidden");
}
});
As CanUver mentioned, it's not allowed to use the same ID for more than one html element. Besides that, your problem doesnt need any ids for every menu entry. As you already said, you can get your menu element, so all you need to do is loop through the inner elements of you menu, check for the inner html and attach your desired css class.
You can get the children of container or any parent element and loop through them
document.querySelector('.container').children
Visit here for reference https://www.w3schools.com/jsref/prop_element_children.asp
Ehy there!
You can use this snippet to do what you've described:
document
// select all `li.go` items
.querySelectorAll("li.go")
// set `hidden` attribute to `true` when the specified text has been found
.forEach((item) => (item.innerText === "None" ? (item.hidden = true) : null));
Here what i've used:
forEach method
innerText property
hidden attribute
Bye !
I have a simple list:
<ul id="list">
<li id="item-1">1</li>
<li id="item-2" style="display: none">2</li>
<li id="item-3">3</li>
<li id="item-4">4</li>
<li id="item-5">5</li>
</ul>
And need to get index of a specific item disregarding hidden items.
var list = document.getElementById('list');
var items = list.querySelectorAll('li:not([style*="display: none"])');
I try to convert NodeList in Array:
var list_items = Array.from(items);
But don't known how to run something like that: list_items.indexOf('item-3')
https://codepen.io/marcelo-villela-gusm-o/pen/RwNEVVB?editors=1010
You can make a function to find the id you need in a list you want, passing two parameters, that way you can use this function dynamically.
Based on id, inside the function just need to use .findIndex() that returns the index or -1 if not found.
See here:
var list = document.getElementById('list');
var items = list.querySelectorAll('li:not([style*="display: none"])');
var list_items = Array.from(items);
function getIndexById(idToSearch, list){
//ES6 arrow function syntax
return list.findIndex(elem => elem.id == idToSearch)
//normal syntax
//return list.findIndex(function(elem) {return elem.id == idToSearch})
}
console.log("found at index: ", getIndexById("item-3", list_items))
<ul id="list">
<li id="item-1">1</li>
<li id="item-2" style="display: none">2</li>
<li id="item-3">3</li>
<li id="item-4">4</li>
<li id="item-5">5</li>
</ul>
Not exactly related to the question, but if possible, I would suggest you to change your HTML to remove that inline style of display: none and change it to a class, (e.g: class='hidden'), it would be better for your .querySelector when using :not, for example: li:not(.hidden), since any space in your inline style can break your selector. ("display:none" != "display: none", spot the space)
Maybe like this:
var item = list_items.find(function(item) {
return item.id === "item-3";
});
I would recommend using :not(.hidden) instead of "grepping" for a match on the style tag. Then, simply find the index after casting the NodeList to an array.
For the Vue.js inclined, see this fiddle: https://jsfiddle.net/634ojdq0/
let items = [...document.querySelectorAll('#list li:not(.hidden)')]
let index = items.findIndex(item => item.id == 'item-4')
console.log('item-4 index in visible list is', index)
.hidden {
display: none;
}
<ul id="list">
<li id="item-1">1</li>
<li id="item-2" class="hidden">2</li>
<li id="item-3">3</li>
<li id="item-4">4</li>
<li id="item-5">5</li>
</ul>
Maybe you can use map. First you can create an object with id and value. Then use map function to create array of this object. Then you can access it with foreach, when id = 'item-3'.
I would like to know how to create a JSON or serialize (both is fine) from a ul including
<ul class="menu send ui-sortable">
<li id="pageid_1" class="ui-sortable-handle">Inscription
<ul class="menu send ui-sortable">
<li id="pageid_2" class="ui-sortable-handle">Joueurs en ligne
<ul class="menu send ui-sortable"></ul>
</li>
</ul>
</li>
I cannot find how to create something like this:
pageid[]=1&pageid[1]=2 OR [{"pageid":1,"children":[{"pageid":2}]}]
Meaning, including parent ID in [].
Thank you for your help!
This code will produce the output required
var result = [].map.call(document.querySelectorAll('ul.menu.send.ui-sortable li.ui-sortable-handle'), function(li) {
var parent = '';
if (li.parentNode && li.parentNode.parentNode && li.parentNode.parentNode.nodeName == 'LI' && li.parentNode.parentNode.matches('li.ui-sortable-handle')) {
parent = li.parentNode.parentNode.id.replace(/\D+/g, '');
}
return "pageid[" + parent + "]=" + li.id.replace(/\D+/g, '');
}).join('&');
console.log(result); // pageid[]=1&pageid[1]=2
I haven't thought about how to do the second format, because the first format is easier to produce
I have this unordered list and would like to get the data-file attribute value of a link element inside the list element of the unordered list, then delete the whole list element in which it lies if it is not in array z.
<ul id="hithere"class="image-list">
<li class='image-list'>
<div class='controls'>
<a href='#' class='image-list' data-name='myname'><img src='stop.png' ></a>
</div>
<span class='name'>myname12</span
</li>
<li class='image-list'>
<div class='controls'>
<a href='#' class='image-list' data-name='myname2'><img src='stop.png' ></a>
</div>
<span class='name'>myname1312</span
</li>
</ul>
And this is my jQuery but it deletes all the list elements
var z = ["myname", "yourname"];
$("li.image-list a.image-list ").filter(function () {
if ($.inArray($(this).attr('data-name'), z) == -1) {
$(this).parent("li.image-list").empty().remove();
}
});
here is the code recieving from server:
var box = $('#drone');
box.f_drop({
url: 't_file.php',
check_data:function(i,file,response){
z=[];z.push(response.Oname);
$("li.image-list ").filter( function () {
return $.inArray($(this).find('a[data-name]').attr('data-name'), z) == -1
}).remove();
},
});
why is it that all the lists are now being removed instead of just one ie the one not in array?? Also, how can i rename the data-name attribute,to say "xyz" instead.
There are few problems in your script
The array is called z not _out
The anchor element does not have a class
the data property is called name, not filename
Try
var z = ["myname", "yourname"];
$("li.image-list").filter(function () {
return $.inArray($(this).find('a[data-name]').attr('data-name'), z) == -1
}).remove();
Demo: Fiddle