How to validate if cheerio doesn't find an element? - node.js

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

Related

How to get className of an element in jsdom?

first time posting so sorry if I mess something up. Below is the code I have tried:
const domPreParse = new JSDOM(incident); //incident is the html fragment I want to parse
const dom = domPreParse.window.document;
const cNameHome = dom.querySelector('[data-type="home-icon"], svg').className;
So cNameHome returns an object with only the first class name. There are multiple class name on the element (e.g. class="class1 class2"). How can I return all the classes in a space separated string preferably.
And this is the code I'm trying to parse:
<div class="sco" data-type="middle">
<div class="clear">
<span class="inc" data-type="home-icon"></span>
<span class="score" data-type="score"> </span>
<span class="inc" data-type="away-icon">
<svg class="inc yellowcard"><use xlink:href="#icon-yellowcard"></use></svg>
</span>
</div>
</div>
Thanks for the help.
The problem was my CSS selectors. I should have used [data-type="home-icon"] > svg.

Jsviews filter search

How do I create a filter search in JSViews? Usually I'd grab the html element by its class with the .getElementsByClassName() and .value() methods and add a === comparison to satisfy the right criteria. How can I do something similar in JsViews
I've already tried to add listItem in the IF to match the value of the html input (search bar), but I don't know how to grab the value of the search element (JQuery would be easy using $(".search")), or compare it to the listItems using regExp.
{^{if list && list.length}}
<ul autoselectitem="true" tabindex="-1" operationalindex="1" allindex="1">
{^{for list}}
{{include tmpl="listItem" /}}
{{/for}}
</ul>
{{else}}
<p>Nothing Found</p>
{{/if}}
This currently displays all items in the list, however I only want the elements in the list to be displayed that match with RegEx the .value of an search HTML element:
<input type="text" class="search" data-link="search" placeholder="Search...">
So for example, if I type in "e" into the search bar, all the items in the list that don't have the letter "e" should disappear.
The code linked all work, but what i've tried has given me null pointer errors because I'm not grabing the input element correctly by its class or data-link. How could I do this in the simplest way possible? Thanks
Here is one way of doing it:
<script id="myTmpl" type="text/x-jsrender">
<input type="text" class="search" data-link="search" placeholder="Search...">
{^{if list && list.length}}
<ul autoselectitem="true" tabindex="-1" operationalindex="1" allindex="1">
{^{for list filter=~flt depends="search"}}
<li data-link="#data"></li>
{{/for}}
</ul>
{{/if}}
</script>
<div id="page"></div>
<script>
var myTmpl = $.templates("#myTmpl"),
data = {
list: ["a", "b"],
search: ""
},
helpers = {
flt: function(item, index, items) {
return item.indexOf(data.search) > -1;
}};
myTmpl.link("#page", data, helpers);
</script>

NodeJS Extracting input value from url

I have html stored in a var
var html = "<div class="RiP" style="text-align: left;"><div class="clr"></div><input name="extraMP" value="999" type="hidden"><div class="txta dropError">Slide to activate</div><div class="bgSlider"><div class="Slider ui-draggable"></div></div><div class="clr"></div><input name="randomValue" value="randomValue2" type="hidden"></div>"
I want to extract "randomValue" and "randomValue2".
Maybe I should use cheerio? I tried with it but I had hard time managing to do it.
If cheerio is hard for you - you could use regular expression to get the values.
For easily access you could provide class attribute for the <input> like:
<input class="className" name="randomValue" value="randomValue2" type="hidden">
your regexp will be:
const match = html.match(/<input\s*class="className"\s*name="(.+?)"\s*value="(.+?)"/m)
match[1] // randomValue
match[2] // randomValue2
With cheerio it will be:
const cheerio = require('cheerio');
const html = `<div class="RiP" style="text-align: left;"><div class="clr"></div><input name="extraMP" value="999" type="hidden"><div class="txta dropError">Slide to activate</div><div class="bgSlider"><div class="Slider ui-draggable"></div></div><div class="clr"></div><input class="myClass" name="randomValue" value="randomValue2" type="hidden"></div>`
const $ = cheerio.load(html);
$('.myClass').val(); // randomValue2
$('.myClass').attr('name'); // randomValue
What you might do using cheerio is to find the last input inside the RiP class and get the name and value attribute:
var html = `<div class="RiP" style="text-align: left;"><div class="clr"></div><input name="extraMP" value="999" type="hidden"><div class="txta dropError">Slide to activate</div><div class="bgSlider"><div class="Slider ui-draggable"></div></div><div class="clr"></div><input name="randomValue" value="randomValue2" type="hidden"></div>`;
const cheerio = require('cheerio');
const $ = cheerio.load(html);
let input = $('.RiP input').last();
console.log(input.attr('name'));
console.log(input.val());
Result:
randomValue
randomValue2
Note that it is not advisable to parse html with regex

If element hasClass, add another class to its title value

I'm using slick carousel, and once a div is active I want to open the corresponding description.
Problem I'm having is with this code:
if ($('div').hasClass('active')) {
var title = $(this).attr('title');
$('ul li').removeClass('open');
$(title).addClass('open');
}
What I'm trying to achieve:
Once a div gets class 'active', I want to take its title value, and use it as a id link to list element I want to display(add class to).
Here is a FIDDLE.
Use event handling, not class monitoring.
The slick carousel API has events for this, I believe you want to use the afterChange event to act on the active element after it has been made visible.
Check out the docs and examples, especially the section titled "Events" on Slick page: http://kenwheeler.github.io/slick/
And I think you don't want to use title attribute for this because that is for tooltips. I recommend data-* attributes instead. And element IDs should generally start with a letter and not a number (was required in HTML4 and makes life easier when mapping IDs to JavaScript variables; though if you are using HTML5 I think this requirement is no longer in effect).
HTML
<div id="carousel">
<div data-content-id="content1">
Selector 1 </div>
<div data-content-id="content2">
Selector 2 </div>
<div data-content-id="content3">
Selector 3 </div>
</div>
<ul class="content">
<li id="content1">Content 1</li>
<li id="content2">Content 2</li>
<li id="content3">Content 3</li>
</ul>
JavaScript
$('#carousel').on('afterChange', function(event, slick, currentSlide) {
// get the associated content id
var contentId = $(slick.$slides.get(currentSlide)).data("content-id");
if(contentId && contentId.length)
{
var $content = $("#" + contentId);
$(".content>li").removeClass("open"); // hide other content
$content.addClass("open"); // show target content, or whatever...
}
});
I have found a solution:
$('.slider').on('afterChange', function(event, slick, currentSlide, nextSlide){
var contentId= $(slick.$slides.get(currentSlide)).data('content');
if(contentId)
{
$(".content li").removeClass('open');
$('#' + contentId).addClass('open');
}
});
Working fiddle

npm cheerio - add id to list elements

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, '') );
})

Resources