Javascript to replace or strip inner html - javascript

I need to extract just V1 BAE from this html:
<ul class="checkout-bar">
<li> Info for V1 BAE </li>
</ul>
So far I have this:
function() {
var element = document.querySelector('ul.checkout-bar > li').textContent;
return element;
}
But it returns this:
\n\t\t\t\tInfo for V1 BAE\t\t\t
I need to just have the value V1 BAE so need to strip out all the '\n\t\t\t\tInfo for ' and '\t\t\t'.

You can use a combination of String#replace and String#trim :
.replace('Info for','').trim();
Demo:
var element=document.querySelector('ul.checkout-bar > li').textContent.replace('Info for','').trim();
console.log(element);
<ul class="checkout-bar">
<li> Info for V1 BAE </li>
</ul>

Use replace to replace Info for with null and then trim() the result to remove preceding and succeeding white spaces:
function test() {
var element=document.querySelector('ul.checkout-bar > li').textContent;
var res = element.replace('Info for', '').trim();
return res;
}
console.log(test());
<ul class="checkout-bar">
<li> Info for V1 BAE </li>
</ul>

You can use regex to capture things out of a string. The below example returns a collection containing all matches of this regex, and you can select which one you wish to return by using square brackets, eg: result[0]. This will also capture the required text even if the string is preceded or followed by anything.
function test() {
let element = document.querySelector('ul.checkout-bar > li').textContent;
let regex = /.+Info\s+for\s+(\w+\s\w+).+/;
let result = regex.exec(element);
return result;
}
console.log(test()[0]);
console.log(test()[1]);
<ul class="checkout-bar">
<li> Info for V1 BAE </li>
</ul>
Note that if you specifically want to capture the string V1 BAE, you can replace (\w+\s\w+) with (V1\sBAE), if there's a chance that the string will be different which you don't want to capture:
function test() {
let element = document.querySelector('ul.checkout-bar > li').textContent;
let regex = /.+Info\s+for\s+(V1\sBAE).+/;
let result = regex.exec(element);
return result;
}
console.log(test()[0]);
console.log(test()[1]);
<ul class="checkout-bar">
<li> Info for V1 BAE </li>
</ul>
Hope this helps.

Related

Get attributes for all (unknown) <li> elements with Javascript

I need to concatenate all the title value starting from second li elements with Javascript.
The problem is that I want to use it in different pages, so I can't know the exact number of li elements.
<div id="breadcrumb">
<ul>
<li title="One">One</li>
<li title="Two">Two</li>
<li title="Three">Three</li>
<li title="Four">Four</li>
</ul>
</div>
I use a variable for each element but if one or more element is missing the var is not valid and the concat function doesn't work.
var a = document.querySelector(".breadcrumb li:nth-child(2) > a").getAttribute("title");
var b = document.querySelector(".breadcrumb li:nth-child(3) > a").getAttribute("title");
var c = document.querySelector(".breadcrumb li:nth-child(4) > a").getAttribute("title");
var d = document.querySelector(".breadcrumb li:nth-child(4) > a").getAttribute("title");
var str = a.concat(b,c,d);
console.log(str)
Is there a way to do that?
Use querySelectorAll() and map():
const res = [...document.querySelectorAll("#breadcrumb li:not(:first-of-type)")].map(el => el.getAttribute("title")).join(" ")
console.log(res)
<div id="breadcrumb">
<ul>
<li title="One">One</li>
<li title="Two">Two</li>
<li title="Three">Three</li>
<li title="Four">Four</li>
</ul>
</div>
Using a little jquery i achieved this and it should solve your issues.
let list = [];
$('#breadcrumb li').each(function(i){
if(i !== 0) { list.push($(this).attr('title')); }
});
list.toString() //One,Two,Three,Four
The method you tried to use wont scale on a large list
Two minor remarks:
If you want to access the id=breadcrumb, you have to use #breadcrumb instead of .breadcrumb
There is no a tag in your HTML-code, therefore your querySelector won't give you any result
However, let's discuss a solution:
let listElements = document.querySelectorAll("#breadcrumbs li"); // get all list elements
listElements = Array.from(listElements); // convert the NodeList to an Array
listElements = listElements.filter((value, index) => index >= 1); // remove the first element
let titleAttributes = listElements.map(listElement => listElement.getAttribute("title")); // get the title attributes for every list elements. The result is an array of strings containing the title
console.log(titleAttributes.join(", ")); // concatenate the titles by comma
You can write the above statements in a single line:
Array.from(document.querySelectorAll("#breadcrumbs li"))
.filter((value, index) => index >= 1)
.map(listElement => listElement.getAttribute("title"))
.join(", ");
EDIT: I fix my answer, thanks to Barmar
something like that ?
const All_LI = [...document.querySelectorAll('#breadcrumb li')];
let a = ''
for (let i=1; i<All_LI.length; i++) { a += All_LI[i].title }
console.log('a-> ', a )
// .. or :
const b = All_LI.reduce((a,e,i)=>a+=(i>0)?e.title:'', '' )
console.log('b-> ', b )
<div id="breadcrumb">
<ul>
<li title="One">One</li>
<li title="Two">Two</li>
<li title="Three">Three</li>
<li title="Four">Four</li>
</ul>
</div>

Trying to compare classes of different elements

I'm looking to find a way to check if classes in an element matches those in another element. I have tried using code below:
Using dataset seems to work, however, I'm looking to explore the possibility of doing this through pure Javascript. The line that works is commented out (var matches = first.dataset.name === second.dataset.name;) and the line that I'm having difficulty getting to work is (var matches = first.classList === second.classList;)
javascript:
//check for 2 matching squares
function checkIfMatches() {
//var matches = first.dataset.name === second.dataset.name;
var matches = first.classList === second.classList;
matches ? disable() : unflip();
}
html:
<li class="card">
<i class="pa pa-test"></i>
</li>
<li class="card">
<i class="pa pa-test"></i>
</li>
Thanks for any help. If more details are needed you can comment.
Use Array spread [...classList] to make the classList an Array, then check if every member is contained in the classList of the other using Array.prototype.every().
function sameClassList({classList: x},{classList: y}) {
return [...x].every(z=>y.contains(z))
&& [...y].every(z=>x.contains(z));
}
console.log(sameClassList(a,b)); // true
console.log(sameClassList(a,c)); // false
console.log(sameClassList(b,c)); // false
<div class="foo bar" id="a"></div>
<div class="bar foo" id="b"></div>
<div class="foo bar baz" id="c"></div>
Taking the comments into account, this solves it independently of the order.
Changed the example a bit, so it could be executed.
//check for 2 matching squares
function checkIfMatches() {
var elements = document.getElementsByClassName('card')
var first = elements[0].getElementsByTagName('i')[0]
var second = elements[1].getElementsByTagName('i')[0]
var matches = first.classList.length === second.classList.length
first.classList.forEach(entry => matches = matches && second.classList.contains(entry))
console.log(matches)
// matches ? disable() : unflip();
}
checkIfMatches()
<li class="card">
<i class="pa pa-test"></i>
</li>
<li class="card">
<i class="pa pa-test"></i>
</li>

How can I getElementsByClassName from HTML and push them into a JavaScript Array? How can I then alert this array?

I am trying to gather these HTML objects through getElementsByClassName, and push them into a JavaScript array and then I want to create a JavaScript alert to display these names. I’ve been trying this for hours. Am I doing something wrong?
var names = []
var elm = document.getElementsByClassName('name');
names.push(elm);
var arr = names.join();
alert(arr)
<h2>
List of People:
</h2>
<ul class='people'>
<li class='name'>
Clara
</li>
<li class='name'>
James
</li>
<li class='name'>
Sara
</li>
</ul>
getElementsByClassName does not give you the text inside the elements, but the elements themselves.
Also you won't get them as a proper JavaScript array, but a collection of HTMLElements.
Here's what you can do:
var names = []
var elements = document.getElementsByClassName('name');
for(var i=0; i<elements.length; i++) names.push(elements[i].textContent)
var nameList = names.join()
alert(nameList)
Alternatively you may use Array.from and map:
Array.from(elements).map((elem) => elem.textContent)
Note that I'm using elements[i].textContent to get the text inside each element.
Simply Try with querySelectorAll() .Then apply Nodelist#forEach() to iterate the node list .Finally push into array with element or element attribute which you want
var names = []
var elm = document.querySelectorAll('.name').forEach(function(a){
names.push(a.innerHTML);
});
var arr = names.join();
console.log(arr);
alert(arr)
<h2>
List of People:
</h2>
<ul class='people'>
<li class='name'>
Clara
</li>
<li class='name'>
James
</li>
<li class='name'>
Sara
</li>
</ul>
When we call elements by class name it returns array so you have run loop...
List of People:
<ul class='people'>
<li class='name'>
Clara
</li>
<li class='name'>
James
</li>
<li class='name'>
Sara
</li>
var names = []
var elm = document.getElementsByClassName('name');
for(var i = 0; i < elm.length; i++) {
names.push(elm[i].innerHTML);
}
names.join();
alert(names);
here is jsfiddle running example https://jsfiddle.net/9pt0hf0s/1/

How to convert html tree in to a customized json tree using jquery?

<ul id='parent_of_all'>
<li>
<span class='operator'>&&</span>
<ul>
<li>
<span class='operator'>||</span>
<ul>
<li>
<span class='operator'>&&</span>
<ul>
<li>
<span class='condition'>1 == 1</span>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul>
<li>
<span class='condition'>1 != 0</span>
</li>
</ul>
</li>
</ul>
to
{"&&":[{'||':[ {'&&':[ {"lhs": "1", "comparator": "==", "rhs":"1"} ]} ] } , {"lhs": "1", "comparator": "!=", "rhs":"0"}]}
As of now, I know the basics of jQuery, JavaScript. I need to know where to start thinking in order to accomplish the above conversion.
And the html tree could be more complex with more children.
You can do this with each and map
var obj = {}
var span = $('li > span').not('ul li span').text();
$('ul li span').each(function() {
var text = $(this).text().split(' ');
obj[span] = (obj[span]||[]).concat({lhs: text[0], comparator: text[1], rhs: text[2]});
});
console.log(obj)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li>
<span>&&</span>
<ul>
<li>
<span>1 == 1</span>
</li>
</ul>
<ul>
<li>
<span>1 != 0</span>
</li>
</ul>
</li>
You will need a way to select the first level of li, I assumed you have a parent element with an id such as list. I wrote the following code using basic jquery so you can understand it.
var result = {};
var $all_li = $('#list').children('li'); // selecting the first level of li
for(var i in $all_li){ // iterating all_li using for (you may use forEach )
var $current_li = $( $all_li[i] ); // getting operator from first span
var operator = $current_li.children('span').html(); // the text of the operator
var $inner_spans = $current_li.find('>ul >li >span'); // getting list of children spans (from path $list>li>ul>li>span)
var li_spans = []; // an array where we will put the inner span objects
for(var j in $inner_spans){ // iterating the inner spans
var text = $($inner_spans[j]).html().split(" "); // splitting the html
li_spans.push({
lhs: text[0],
comparator: text[1],
rhs: text[2]
}); // adding the splitted html to an object. Note: error if text didn't have 2 white spaces
}
result[operator] = li_spans; // adding the operator key and li_spans value to the result json
}
This code will parse the html and construct the result json, it should work for the html format you provided. Keep in mind that it does not handle errors (such as bad tree format).
simmiar html formats.
Thanks #Alexandru and #Nenad for giving a start. I have been able to complete this on my own.
Below is the function that generates json.
function prepare_json(current_node){
var object = {}
var span = $(current_node).children('span')
if (span.hasClass('condition')){
var text = span.html().split(" ");
object = {lhs: text[0], comparator: text[1], rhs: text[2]}
}
else if(span.hasClass('operator')){
var operator = span.text()
object[operator] = (object[operator] || [])
var children = $(current_node).children('ul').children('li')
for(var i = 0; i < children.length; i++){
var child_pql = prepare_json([children[i]])
object[operator].push(child_pql)
}
}
return object
}
Below is the code that calls that function:
var parent_node = $('#parent_of_all').children('li')
var json = JSON.stringify(prepare_pql_json(parent_node), null, 2)

get an array of data-val values from a list of elements of a certain css class

I would like to get an array of the values from the data-val attributes of .my-li elements
<ul id="stuff">
<li class='my-li' data-val='1'>
<li class='my-li' data-val='2'>
<li class='my-li' data-val='3'>
<li class='my-li' data-val='4'>
<li class='my-li' data-val='5'>
<ul>
here the result should be [1,2,3,4,5];
anybody knows a good way of doing this ?
Try:
var foo = $('#stuff .my-li').map(function () {
return $(this).data('val');
});
try this simple one.
var array = [];
$('.my-li').each(function(){
array.push($(this).attr('data-val'));
});
alert(array);
fiddle : http://jsfiddle.net/pp5pw/
var foo = $('#stuff .my-li').map(function () {
return $(this).attr('data-val');
});
console.log(foo[0])
jsfiddle goes to http://jsfiddle.net/granjoy/KxQAr/

Categories