npm cheerio - add id to list elements - node.js

I have a list like
<ul>
<li>Name1</li>
<li>Name2 </li>
</ul>
Using npm cheerio how do I add each list element text as lowercase id to the element itself?
So the outcome would be
<ul>
<li id="name1">Name1</li>
<li id="name2">Name2 </li>
</ul>
At the moment I'm adding a static id using
var cheerio = require('cheerio'),
$ = cheerio.load('<ul><li>Hello world</li></ul>');
$('li').attr('id', 'new-id')
console.log( $.html() )
Thanks

This should do the trick..
$('li').each( function(i, elem) {
$(this).attr('id', $(this).text().toLowerCase().replace(/\s/g, '') );
})

Related

How to validate if cheerio doesn't find an element?

I'm trying to validate if an element is not found
const cheerio = require('cheerio')
const $ = cheerio.load(`<ul id="fruits">
<li class="apple">Apple</li>
<li class="orange">Orange</li>
<li class="pear">Pear</li>
</ul>`)
console.log($('xyz'))
It returns a valid object.
How can I validate the object wasn't found?
Using the length property does the trick
$('xyz').length
Prints 0

Unable to get desired data with cheerio

I am new in Cheerio js just want to iterate a specific li from the website li looks like the following
<li class="webcam">
<a href="/en/webcam/italia/lazio/roma/roma-colosseo.html">
<span class="inner-wrapper">
<span class="img-wrapper"><span class="label label-info lb_sm" style="position:absolute;">World
Wonder</span>
<img src="https://static.skylinewebcams.com/live1151.jpg"
data-original="https://static.skylinewebcams.com/live1151.jpg" alt="Italy - Rome - Colosseum"
class="lazy" style="display: inline;" width="318">
</span>
<span class="title">Italy - Rome - Colosseum</span>
<span class="description">Rome, view of the Colosseum and the ruins of the gladiator gymnasium</span>
</span>
</a>
</li>
I want to get href from a tag, data-original from img tag and .title from span tag.
Here is what I tried so far but didn't get any success,
this is the example of finding only with specific tag,
I didn't know how to find all my required thing in one go using cheerio.
request(url, (err, body) => {
if (err) { console.log(err); return; }
$ = cheerio.load(body);
links = $('img[class=lazy]'); //jquery get all hyperlinks
$(links).each(function (i, link) {
console.log(i, link.attribs.alt);
console.log(i, link.attribs.data-original);
});
})
Any help will be appreciated thanks
You want to iterate the lis not the imgs:
let data = $('li.webcam').get().map(li => {
return {
href: $(li) .find('a').attr('href'),
'data-original': $(li).find('img').attr('data-original'),
title: $(li).find('span.title').text()
}
})

how to create live search with knockout?

I have project where we need to create a live search with knockout, map with some titles, when the title enter in search field other titles should disappear, I try to use different code but non of them work, and there is no error to help me figure out.
my code for html :
Filter:
<ul data-bind="foreach: locations">
<li data-bind="text: title"></li>
</ul>
</div>
And for js:
function ViewModel(){
var self =this;
this.filter = ko.observable();
this.locations = ko.observableArray([{ title:'Safa Bridge'},{ title:'Holy Mosque'},{ title:'Diamond Tower'},{ title:'Albaik Resturant'},{ title:'Zamzam'}]);
this.visibleLocations = ko.computed(function(){
return this.locations().filter(function(location){
if(!self.filter() || location.title.toLowerCase().indexOf(self.filter().toLowerCase()) !== -1)
return location;
});
},this);
}
ko.applyBindings(new ViewModel());

cheerio selection of a list

On a page I need to scrape (with node.js and cheerio), I have this pattern:
<h2>
<span id="2015"></span>
<span class="ignore-me"></span>
</h2>
<div>
<ol>
<li>
<a title="TITLE1" href="HREF1"></a>
<a class="image" title="ignore-me-1" href="ignore-me-1"></a>
</li>
...
<li>
<a title="TITLE2" href="HREF2"></a>
<a class="image" title="ignore-me-2" href="ignore-me-2"></a>
</li>
</ol>
</div>
I would like to extract a list with TITLEs an HREFs.
I am trying something like this:
$('h2 > span[id="2015"]').next('ol > li > a').each(function(index, element) {
console.log('title:', element.attr('title'), 'href:', element.attr('href'));
});
without success (each loop is never entered...).
Any suggestion?
The ol element isn't actually the next element of span#2015. The ol element is inside a div which is the next element of h2. The right tree traversal is :
$('h2 > span[id="2015"]')
.parent()
.next('div')
.find('ol > li > a:not([class])')
.each(function() {
var $el = $(this);
console.log('title:', $el.attr('title'), 'href:', $el.attr('href'));
});
The h2 tag does not have an ID, thus your selector finds no results, nothing to loop over.
You could easily do it by looping anchor tags.
$("a").each(function(i, e) {
if (e.attr('title') && e.attr('href')) console.log("... stuff ...");
});
Or you can give your h2 an id, or remove the id from your selector. Many ways to loop.

Using knockoutjs to data-bind list data into bxslider

I have managed to get the code to display list data which is driven from a sharepoint list. The list only contains one column in each row item which is called Title. I need to display the titles through the bxslider, one item per slide.
Usual bxslider html
<ul class="bxslider">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
My html implementing data-bind
<ul class="bxslider" data-bind="foreach: items">
<li data-bind="text: Title"></li>
</ul>
For some reason the 'Titles' are all being generated in one li tag, rather than creating an li tag for each item in the list.
If anyone has come across this problem before or have any advice or suggestions it would be very much appreciated.
View Model
var items = ko.observable();
jQuery(document).ready(function () {
jQuery.getJSON( "ListURLHERE", {}, dataCallBack
);
ko.applyBindings();
});
function dataCallBack(data) {
items(data.d.results);
}
I have found the answer to the problem!
I was initiating the bxslider function before the knockout js code. I had to implement the bxslider function into the dataCallBack function and it worked.
function dataCallBack(data) {
News(data.d.results);
jQuery(document).ready(function(){
jQuery('.bxslider').bxSlider();
});
}
Thanks for your help everyone!

Resources