How can I locate text within a list and replace it with new text? - javascript

I'm trying to write a function that searches the DOM for one text and replace it with another. In other words, I have this html:
<ul>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
<li>Item4</li>
<li>Item5</li>
</ul>
Now I want to find 'Item4' and replace it with 'newItem4'.
I've been able to find 'Item4' but can't figure out how to replace it with new text. Here's the code inside my function so far:
var array = ['Item1', 'Item2', 'Item3', 'Item4', 'Item5'];
function replace() {
var x = document.querySelectorAll('ul');
var newText = document.createTextNode('newItem4');
for (var i = 0; i < array.length; i++) {
if (array[i] === 'Item4') {
}
}
That's as far as I've gotten. Not sure if I'm on the right track or not.

This is how you find it in HTML,
var lis = document.querySelectorAll('li');
lis.forEach(function(li){
if(li.innerText.trim() == "Item4" )
li.innerText = "NewItem4";
});
<ul>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
<li>Item4</li>
<li>Item5</li>
</ul>
This is how you do with array
var array = ['Item1', 'Item2', 'Item3', 'Item4', 'Item5'];
array[array.indexOf('Item4')] = 'newItem4'

function replace() {
var li = document.getElementsByTagName("li");
for (var i = 0; i < li.length; i++) {
if(li[i].innerHTML =="Item4")
li[i].innerHTML ='newItem4';
}
}
replace();
document.getElementsByTagName("ul")[0].setAttribute("id", "myID");
<ul>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
<li>Item4</li>
<li>Item5</li>
</ul>

//index is the child number(li) and text is string to replace
function findAndReplace(index, text) {
$("ul li:nth-child(" + index + ")").html(text);
}

You could do something like this to replace.
document.querySelector("button").addEventListener("click",
function() {
let searchText = document.querySelector("#searchText").value,
replaceText = document.querySelector("#replaceText").value;
[].forEach.call(document.querySelectorAll("li"), function(element) {
if (element.innerText === searchText) {
element.innerText = replaceText;
};
});
});
<ul>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
<li>Item4</li>
<li>Item5</li>
</ul>
Search Text:
<input type="text" id="searchText" />Replace Text:
<input type="text" id="replaceText" />
<button>Change
</button>
You could also simply do this, if you use jQuery
$(function() {
$("li:contains('Item4')").html("NewItem4");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
<li>Item4</li>
<li>Item5</li>
</ul>

Related

Loop through ul li elements and get the li text excluding childrens

Hello how can i loop through ul li elements and get the text content only from the li, excepting the text content of its children?
<li class="lom">#paul<div class="on-off">offline</div></li>
<li class="lom">#alex<div class="on-off">offline</div></li>
<li class="lom">#jhon<div class="on-off">offline</div></li>
I want to get only the #paul without offline,
I have tried this:
var lnx = $('.cht(ul class) .lom');
for (let i = 0; i < lnx.length; i++) {
var txt = lnx[i].textContent;
console.log(txt + '\n');
}
But i get #pauloffline
Iterate through the .childNodes, filtering by nodeType of 3 (text node), to get only nodes that are text node children:
const texts = [...document.querySelector('.lom').childNodes]
.filter(node => node.nodeType === 3)
.map(node => node.textContent)
.join('');
console.log(texts);
<ul>
<li class="lom">#paul<div class="on-off">offline</div></li>
</ul>
Jquery solution using replace
https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/String/replace
$('.lom').each(function(index, value) {
var getContent = $(this).text();
var replaceTxt = getContent.replace('<div class="on-off">offline</div>','').replace('offline','');
//$(this).find('.on-off').remove();
if (replaceTxt == '#paul') {
console.log(replaceTxt);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<li class="lom">#paul<div class="on-off">offline</div></li>
<li class="lom">#alex<div class="on-off">offline</div></li>
<li class="lom">#jhon<div class="on-off">offline</div></li>
Here's a jQuery variant that uses the .ignore() micro plugin
$.fn.ignore = function(sel) {
return this.clone().find(sel||">*").remove().end();
};
// Get LI element by text
const $userLI = (text) =>
$(".lom").filter((i, el) => $(el).ignore().text().trim() === text);
// Use like
$userLI("#paul").css({color: "gold"});
<ul>
<li class="lom">#paul <span class="on-off">offline</span></li>
<li class="lom">#alex <span class="on-off">offline</span></li>
<li class="lom">#jhon <span class="on-off">offline</span></li>
<li class="lom">#paul</li>
</ul>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

Filter list using jQuery

I have a JS code that filters the list with an input field. Currently, the filter is a case sensitive. For example, if you have "item1" you have to type the exact word to filter.
$(function(){
$('input.search').keyup(function(){
var searchText = $(this).val();
$('ul.tabs-menu > li').each(function(){
var currentLiText = $(this).text(),
showCurrentLi = currentLiText.indexOf(searchText) !== -1;
$(this).toggle(showCurrentLi);
});
});
});
Is there any way to optimize it?
Here's a link: http://jsfiddle.net/EFTZR/897/
You can convert the items to lowerCase before comparing like this
$(function() {
$('input.search').keyup(function() {
var searchText = $(this).val();
$('ul.tabs-menu > li').each(function() {
var currentLiText = $(this).text(),
showCurrentLi = currentLiText.toLowerCase().indexOf(searchText.toLowerCase()) !== -1;
$(this).toggle(showCurrentLi);
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="search" />
<ul class="tabs-menu" id="category1">
<li>item1</li>
<li>item2</li>
<li>item3</li>
</ul>
<ul class="tabs-menu">
<li>item27</li>
<li>item28</li>
</ul>
I add some visual feedback to see what you are looking for in your list (with the same code as the other anwser for the searching function) and change your item list to see it better.
$(function() {
$('input.search').keyup(function() {
var searchText = $(this).val().trim();
$('ul.tabs-menu > li').each(function() {
var currentLiText = $(this).text(),
showCurrentLi = currentLiText.toLowerCase().indexOf(searchText.toLowerCase()) !== -1;
$(this).toggle(showCurrentLi);
$(this).html(currentLiText.replace(searchText, "<span class='bold'>" + searchText + "</span>"))
});
});
});
.bold {
font-weight: bold;
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="search" />
<ul class="tabs-menu" id="category1">
<li>first item</li>
<li>second item</li>
<li>one more item</li>
</ul>
<ul class="tabs-menu">
<li>item test</li>
<li>check item</li>
</ul>
Here is a clean and optimized way to do that ( It is case-insensitive ):
$(function(){
var timer;
function search( searchText ) {
$('ul.tabs-menu > li').each(function(){
var $this = $(this),
currentLiText = $this.text().trim().toLowerCase(),
showCurrentLi = currentLiText.indexOf( searchText ) !== -1;
$this.toggle( showCurrentLi );
});
}
$('input.search').keyup(function(){
var searchText = $(this).val().trim().toLowerCase();
// Checks the value of searchText.
if (searchText) {
// Clears the timer.
if ( timer ){
clearTimeout(timer);
}
// Gives the user 1 second to finish typing.
timer = setTimeout( search.bind(this, searchText ), 1000 );
}
});
});
I hope you like it : JSFiddle

radomize ul tag not working

this is probably an easy question for you guys but I'm very new to coding and can't figure out this. I have a code that I want to randomize the given choices in the questions, and I've found a script online that does that but it's not working. I don't know what the
// shuffle only elements that don't have "group" class
$ul.find("li[class!='single_question', 'question', 'title', 'text']").each(function() {
means so I tried to put all id that I don't need to randomize in it but it's still not working.
Can someone help me this please? Also is there anyway I can add choice "A", choice "B", choice "C", and choice "D" in front of each given options so even after the options(answers) are randomized, the A,B,C,D options will still be in order? Thank you. Here's the code:
HTML:
<!DOCTYPE html>
<html>
<body>
<script src="JQ.js"></script>
<script src="function.js"></script>
<link href="style.css" rel="stylesheet" />
<div id="quiz_container">
<ul class="quiz_container">
<li class="single_question" data-question-id="1" data-correct-answer="1">
<div class="question">
<h1 class="title">P.1 Grammar Review</h1>
<p class="text">1. "What is your name__"</p>
</div>
<ul class="options">
<li value="1">?</li>
<li value="2">.</li>
<li value="3">,</li>
</ul>
<div class="result"></div>
</li>
<li class="single_question" data-question-id="2" data-correct-answer="b">
<div class="question">
<p class="text">2. "Do you like the banana__"</p>
</div>
<ul class="options">
<li value="a">.</li>
<li value="b">?</li>
<li value="c">,</li>
</ul>
<div class="result"></div>
</li>
</div>
</body>
</html>
JS:
$(document).ready(function () {
/*
* shuffles the array
* #param {Array} myArray array to shuffle
*/
function shuffleArray(myArray) {
for (var i = myArray.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = myArray[i];
myArray[i] = myArray[j];
myArray[j] = temp;
}
return myArray;
}
var $ul, $li, li_content, li_list;
// find all lists to shuffle
$("#quiz_container > ul").each(function () {
$ul = $(this);
li_list = [];
// shuffle only elements that don't have "group" class
$ul.find("li[class!='single_question', 'question', 'title', 'text']").each(function () {
// add content to the array and remove item from the DOM
li_list.push($(this).html());
$(this).remove();
});
// shuffle the list
li_list = shuffleArray(li_list);
while (li_content = li_list.pop()) {
// create <li> element and put it back to the DOM
$li = $("<li />").html(li_content);
$ul.append($li);
}
});
$("#contact_div").show();
});
$(document).on('click', '.single_question .options li', function () {
// Save the question of the clicked option
question = $(this).parents('.single_question');
// Remove If Anyother option is already selected
question.find('.selected').removeClass('selected');
// Add selected class to the clicked li
$(this).addClass('selected');
// selected option value
selected_answer_value = $(this).attr("value");
// Value of correct answer from '.single-question' attribute
correct_answer_value = question.attr("data-correct-answer");
correct_answer_text = question.find('.options').find("li[value='" + correct_answer_value + "']").text();
if (correct_answer_value == selected_answer_value)
result = "<div class='correct'> Correct ! </div>";
else
result = "<div class='wrong'> Correct answer is -> " + correct_answer_text + "</div>";
// Write the result of the question
$(this).parents('.single_question').find('.result').html(result);
// Calculate the score
score_calculator();
});
/**
* It loops through every question and increments the value when "data-correct-answer" value and "option's value" are same
*/
function score_calculator() {
score = 0;
$('.single_question').each(function () {
question = $(this);
if (question.attr('data-correct-answer') == question.find('.selected').attr("value")) {
score++;
}
});
$('.correct_answers').html(score);
}
It looks like you're using jQuery, even though the question isn't tagged as such. If that's the case, you can use a code snippet written by Chris Coyier of CSS-Tricks called shuffle children.
Here's an example of the code in action.
$.fn.shuffleChildren = function() {
$.each(this.get(), function(index, el) {
var $el = $(el);
var $find = $el.children();
$find.sort(function() {
return 0.5 - Math.random();
});
$el.empty();
$find.appendTo($el);
});
};
$("ul.randomized").shuffleChildren();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h4>Static List:</h4>
<ul>
<li>First element</li>
<li>Second element</li>
<li>Third element</li>
<li>Fourth element</li>
</ul>
<h4>Randomized List:</h4>
<ul class="randomized">
<li>First element</li>
<li>Second element</li>
<li>Third element</li>
<li>Fourth element</li>
</ul>
In order to apply it to your own code, all you'd need to do is modify the CSS selector at the bottom of the jQuery snippet. In your case, ul.options might be a good choice.
Here are a couple of examples using your markup:
jsFiddle
Self-Contained HTML Doc

Group list-items into sub-lists based on a data attribute

I want to append the <li> from one <ul> to another <ul> that's created on the fly. I want to group the list-items into new sub-lists based on their data-group attribute.
<ul id="sortable1">
<li data-group="A">test</li>
<li data-group="A">test1</li>
<li data-group="B">test2</li>
<li data-group="B">test3</li>
<li data-group="C">test4</li>
</ul>
Basically I'm trying to loop through this list and grap all <li> from each group, and then move it to another <ul>.
This is what I have so far, but I'm not getting the expected results. I have done this in Excel in the past but can't get it to work with jQuery.
var listItems = $("#sortable1").children("li");
listItems.each(function (idx, li) {
var product = $(li);
//grab current li
var str = $(this).text();
if (idx > 0) {
//append li
str += str;
if ($(this).data("group") != $(this).prev().data("group")) {
//I should be getting test and test1.
//but alert is only giving test1 test1.
alert(str);
//need to break into groups
//do something with groups
}
}
});
How about something like this:
$(function() {
var sortable = $("#sortable1"),
content = $("#content");
var groups = [];
sortable.find("li").each(function() {
var group = $(this).data("group");
if($.inArray(group, groups) === -1) {
groups.push(group);
}
});
groups.forEach(function(group) {
var liElements = sortable.find("li[data-group='" + group + "']"),
groupUl = $("<ul>").append(liElements);
content.append(groupUl);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="sortable1">
<li data-group="A">test</li>
<li data-group="A">test1</li>
<li data-group="B">test2</li>
<li data-group="B">test3</li>
<li data-group="C">test4</li>
</ul>
<div id="content">
</div>
I hope I didn't misunderstand you.

how to filter through json object

Javascript
var obj = {
"name" : ["alex","bob","ajhoge"],
"age" : [30,31,33]
};
to output "alex" for instance
document.write(obj["name"][0])
so how to filter through obj to fetch all data like
html
<ul>
<li>name
<ul>
<li>alex</li>
<li>bob</li>
<li>ajhoge</li>
</ul>
</li>
<li>age
<ul>
<li>30</li>
<li>31</li>
<li>33</li>
</ul>
</li>
</ul>
thank you
var x;
for (x in obj) {
if (obj.hasOwnProperty(x)) {
<li>x</ul>
<ul>
obj[x].forEach(function (elem) {
return "<li>" + elem + "</li>";
});
</ul>
}
}
You could work with something of this kind. Please note
Do not use an document.write
The inner loops inside the for are pseudo code.

Categories