How get last result with complex css selector? - css-selectors

<div id="container">
<p>
<div>a</div>
<div>b</div>
<div><span>foo</span>c</div>
</p>
<p>
<div>e</div>
<div>f</div>
</p>
<p>
<div>g</div>
<div><span>foo</span>h</div>
<div>i</div>
</p>
</div>
I would like to get last div which contains foo, ie div with h.
Online test : http://try.jsoup.org/~Ef0KHIiN77L_DANA7e4SpYZSVEM

You can't do this with a selector alone. The best you can do is
#container div:has(span:containsOwn(foo))
but you'll still need to grab the last element separately using .last() after you run the selector.

I would try this, but it is not a pure CSS solution, since you can't select easily the last element of a selection.
Element el = doc.select("div:contains(foo):not(:has(div))").last();
My selector selects all divs that contain "foo" but do not contain any other divs.

Related

CSS :empty pseudo-selector combined with :after pseudo-element

I'm looking for a way to add a :content pseudo-element to an empty element and ran into the :empty CSS pseudo-selector which looks like it would serve the purpose I'm looking for. Basically, I want to add a generic message like "Nothing found" :after an empty element like a list.
For whatever reason my attempts to style empty elements aren't working, here's an example:
https://codepen.io/kylegill/pen/ZVLEBg
This is the Markup/HTML:
<ul class="list">
</ul>
<!-- ^ Not getting selected by :empty:after -->
<ul class="list">
<li>This list is not empty.</li>
</ul>
And the CSS:
.list:empty:after {
content: "Nothing found";
}
I found this article that helped answer my question.
The :empty class has some weird behavior and won't select elements with a space or a return/line break in them.
Ex: <div> </div> won't be selected, but <div></div> will.
The CSS4 spec includes :blank in this use case, which will select elements with whitespace, where :empty will not.
Here's an updated example:
https://codepen.io/kylegill/pen/vvgYZe

How to click on a parent whose child contains a particular text

I am new to webdriver and I am automating a site. In which I have to find a text on that page and I want to click on its parent div. Can anyone please help?
Below is the HTML code.
<div class="col-md-6 col-sm-6 col-lg-6">
<p>
<strong class="detailShow ng-binding" ng-click="showJobs('NonInvite',item.taskId)"> TEST CR1 START DATE </strong>
</p>
</div>
The easiest way to achieve this is directly using xpath.
You can choose the 'more ugly' way like this:
.//strong[contains(#class,'detailShow')]/../..
Explanation:
/.. - this is how you get the parent element. Having just one, means that you'll get the <p> tag, so to get the <div> you need another one.
Or, you can go in a better manner like this:
.//strong[contains(#class,'detailShow')]/ancestor::div[#class='col-md-6 col-sm-6 col-lg-6']
Explanation:
ancestor::div - this one goes up until and returns all parent that are <div> tags. Since you need only the first <div> parent, you need to specify which one, therefore: ancestor::div[#class='col-md-6 col-sm-6 col-lg-6']
Now, if the bootstrap class is your only identifier, and there is a chance you may be inside a <table> you can also go with ancestor::div[1]

Can't render date in template

I have this in my template:
<div ng-repeat="item in mainCtrl.items" class="item">
<h4 ng-bind="item.title"><small ng-bind="item.pub_date"><strong></strong></small></h4>
<p ng-bind="item.content"></p>
</div>
the item.content and item.content shows respectively. However, the item.pub_date don't show the value in there. I get empty portion at where the date should be in my rendered template.
Using Batarang, I realized the pub_date value shows in the template, but doesn't render or what.
This is how it appears when I look it up in batarang
pub_date: 2014-12-05T18:27:30.939Z
Do I need to add a date filter to make it work? I'm not exposing the value within the pub_date item properly or? Thanks
That is because your h4 tag wrapping small tag which overrides its content. The ngBind directive basically replaces the existing content.
Either move small out of h4 or use double curly notation for the title as:
<h4>{{item.title}}<small ng-bind="item.pub_date"><strong></strong></small></h4>

Model update not triggering consistently

I'm experiencing some very peculiar behaviour--I'm new to angular, to spare you the noob questions, I tired my best to find the solution but after many hours, I think it's time to give in and ask.
Code Summary: Alphabet array, is looped(ng-repeat) and each letter is linked to a function called clickLetter(), this function sets a $scope variable that reflects the current chosen alphabet letter.
Problem: the model/variable in charge of displaying the current active letter is not updating ALL the time, it only appears to update sometimes, randomly it seems.
Code (plunker)
My guess is, angular is not updating the model (two-way data-binding?) as fast as it should?
It looks like the <a> tag is triggering a route change. Either add an $event.preventDefault() to it or remove the <a> altogether. (doesn't seem like it's adding any value)...
<div class="ui icon button padding5" ng-class="{'active': letter == activeLetter}" ng-repeat="letter in letters" ng-click="clickLetter(letter, $event)">
{{letter}}
</div>
or
<div class="ui icon button padding5" ng-class="{'active': letter == activeLetter}" ng-repeat="letter in letters" ng-click="clickLetter(letter, $event)">
{{letter}}
</div>
The problem is, when you click on letter and not on button,the link stops the propagation of your mouse click.
Add this class in your css file and apply to <a> tag, which holds the letter:
.ignore-mouse-event {
pointer-events: none;
}
<a> tag should be changed to this:
{{letter}}

Why does using ng-repeat to iterate html fail when the html contains divs?

When I use ng-repeat to iterate the following code, everything is fine:
<p ng-repeat="user in users">
<input size="50" ng-model="user.name"></input>
<span>Foo</span>
</p>
However, using the following fails:
<p ng-repeat="user in users">
<input size="50" ng-model="user.name"></input>
<div>Foo</div>
</p>
In the latter case, it looks like the div is excluded from the loop and appended only once after the input tags that have been repeated as expected.
I'm trying to understand the difference in behaviour towards div tags.
Thanks for any insights.
EDIT: The question was already answered, but here's a js-fiddle that allowed me to demonstrate the issue: http://jsfiddle.net/f26Cg/5/
You cannot nest <div> elements in <p> element: as shown here, it's permitted to contain so-called phrasing content only.
As <div> opening tag is considered to be an end of <p> element, technically its corresponding element is outside of <p> in the second case - that's why it's not repeated.
I'll quote Josh's answer to this question : Directive inside ng-repeat only appears once
It is actually related to how your browser will handle blocks inside a non-allowing blocks tag.
I imagine this is the browser's doing. Technically, paragraph tags are
only allowed to contain inline elements, which div is not. Some
browsers (most?) will automatically close the <p> when hits an
unauthorized tag. If you inspect the DOM, you will see that even the
div that makes it into the DOM from the ngRepeat is not inside the
generated paragraph.
Josh

Resources