jquery / cheerio: how to select multiple elements? - node.js

I need to parse some markup similar to this one, from an html page:
<a href="#">
<i class="icon-location"></i>London
</a>
I need to get London.
I did try something like (using cheerio):
$('a', 'i[class="icon-location"]').text();
or
$('a > i[class="icon-location"]').text();
without success...
I'd like to avoid methods like next(), since the expression should be passed to a method which just extracts the text from the selector.
What expression should I use (if it's feasible) ?

There's a solution, which is pretty unusual, but it works :
$("#foo")
.clone() //clone the element
.children() //select all the children
.remove() //remove all the children
.end() //again go back to selected element
.text();
Demo : https://jsfiddle.net/2r19xvep/
Or, you could surround your value by a new tag so you just select it:
<i class="icon-location"></i><span class="whatever">London</span>
Then
$('.whatever').text();

$('a').text();
will get text as 'London'.

$("a .icon-location").map(function(){
return $(this).text()
}).get();

Related

How to click on Web check box using Excel VBA?

How do I check the table checkbox?
I tried clicking.
ie.Document.getElementsByClassName("x-grid3-hd-checker").Checked = True
<div class="x-grid3-hd-inner x-grid3-hd-checker x-grid3-hd-checker-on" unselectable="on" style="">
<a class="x-grid3-hd-btn" href="#"></a>
<div class="x-grid3-hd-checker"> </div>
<img class="x-grid3-sort-icon" src="/javascript/extjs/resources/images/default/s.gif">
</div>
I can't see a checkbox in the HTML code. But you use getElementsByClassName() in a wrong way for your case. getElementsByClassName() generates a node collection. If you need a specific node, you must get it by it's index in the node collection. First element has index 0.
Please note that the div tag with the CSS class class="x-grid3-hd-inner x-grid3-hd-checker x-grid3-hd-checker-on " is also included in the Node Collection, because a part of the class identifier is identical to "x-grid3-hd-checker ". [Edit: I'm not realy sure if the part must maybe stand at the begin of the identifier]
If you want to check this:
<div class="x-grid3-hd-checker"> </div>
Your code needs the second index of the node collection:
ie.Document.getElementsByClassName("x-grid3-hd-checker")(1).Checked = True
But if there are more tags with the class name "x-grid3-hd-checker" the above line don't work. I can't say anymore until you don't post more HTML and VBA code. The best would be a link to the site.

Click on outer element with inner element with specific text in Puppeteer

How can I click on an outer element that contains a span with specific text via puppeteer?
For example I have the following HTML code:
<div role="button">
<div>
<span>
<span>OK</span>
</span>
</div>
</div>
And I would like to click on the most outer element (role = button). In order to click on the span with the Ok text I would do the next thing:
const [button] = await page.$x("//span[contains(., 'Ok')]");
if (button) {
await button.click();
}
But how can I click on the outer element using this text identifier?
You can use the descendant expression to query for child elements. Quote from the link:
The descendant axis indicates all of the children of the context node, and all of their children, and so forth.
Your XPath expression then looks like this:
//div[#role='button' and descendant::span[contains(., 'Ok')]]
Depending on your use case you might also want to check out this information about the difference of contains(text(), ...) and contains(., ...).

How can i click the third href link?

<ul id='pairSublinksLevel1' class='arial_14 bold newBigTabs'>...<ul>
<ul id='pairSublinksLevel2' class='arial_12 newBigTabs'>
<li>...</li>
<li>...</li>
<li>
<a href='/equities/...'> last data </a> #<-- HERE
</li>
<li>...</li>
Question is how can i get click third li tag ??
In my code
xpath = "//ul[#id='pairSublinksLevel2']"
element = driver.find_element_by_xpath(xpath)
actions = element.find_element_by_css_selector('a').click()
code works partially. but i want to click third li tag.
The code keeps clicking on the second tag.
Try
driver.find_element_by_xpath("//ul[#id='pairSublinksLevel2']/li[3]/a").click()
EDIT:
Thanks #DebanjanB for suggestion:
When you get the element with xpath //ul[#id='pairSublinksLevel2'] and search for a tag in its child elements, then it will return the first match(In your case, it could be inside second li tag). So you can use indexing as given above to get the specific numbered match. Please note that such indexing starts from 1 not 0.
As per the HTML you have shared you can use either of the following solutions:
Using link_text:
driver.find_element_by_link_text("last data").click()
Using partial_link_text:
driver.find_element_by_partial_link_text("last data").click()
Using css_selector:
driver.find_element_by_css_selector("ul.newBigTabs#pairSublinksLevel2 a[href*='equities']").click()
Using xpath:
driver.find_element_by_xpath("//ul[#class='arial_12 newBigTabs' and #id='pairSublinksLevel2']//a[contains(#href,'equities') and contains(.,'last data')]").click()
Reference: Official locator strategies for the webdriver

Search title from input tag by classname and action

I want to get the title called "ABCD" as output from below :
Note I can't use input id to search and have to use classname. Also, note that I have several <div class="promptChoiceListBox" > and class="promptTextField promptTextFieldReadOnly" exist and this is just one example.
Also this Title is dynamic and changed with dropdown selection.
How can I check it in onclick event if the text inside the text is changed?
How can I achieve this ? any help is appreciated.
<div class="promptChoiceListBox" >
<input id="xyz123" type="text" class="promptTextField promptTextFieldReadOnly" readonly="" title="ABCD">
I have tried below and it doesn't work:
console.log($('.promptTextField').attr('title'));
thanks
Javascript way of doing it:
console.log(document.getElementById("xyz123").title);
JQuery (on-click example):
$("input:promptTextField promptTextFieldReadOnly").click(function(){
$("input:promptTextField promptTextFieldReadOnly").toggle();
});
$('.promptTextField').map(x=>x.title)

HTMLPurifier allow attributes

I'm having troubles making HTMLPurifier do not filter tag attributes but without success until now and im going crazy.
$config = HTMLPurifier_Config::createDefault();
$config->set('Core.Encoding', 'UTF-8');
$config->set('Core.CollectErrors', true);
$config->set('HTML.TidyLevel', 'medium');
$config->set('HTML.Doctype', 'XHTML 1.0 Transitional');
$config->set('URI.DisableExternalResources', false);
$config->set('HTML.Allowed', 'table[border|width|style],tbody,tr,td,th,img[style|src|alt],span[style],p[style],ul,ol,li,strong,em,sup,sub');
$PHTML = new HTMLPurifier($config);
echo htmlspecialchars($PHTML->purify($html));
// The input string:
"Some <span style="text-decoration: underline;">cool text</span> <img src="http://someurl.com/images/logo.png" alt="" />.
// The output string:
"Some <span>cool text</span> <img src="%5C" alt="" />.
I want to allow the given attributes for specified elements which are defined in HTML.Allowed option.
Turn off magic quotes. (Note the %5C)
Bit of a late suggestion, but I've run into a similar issue with HTMLPurifier stripping style attributes even though they were configured in the HTML.Allowed setting.
The solution I found requires that you also configure CSS.AllowedProperties which looks a bit like this:
$config->set('CSS.AllowedProperties', 'text-align,text-decoration,width,height');
Use this in conjunction with HTML.Allowed:
$config->set('HTML.Allowed', 'img[src|alt|style],span[style]');
I hope someone else finds this useful, you can read more about CSS.AllowedProperties here.

Resources