How to chain contains and not-contains in xpath? - html

How do I chain contains and "not-contains" in xpath?
I want to make sure a button has the class add-to-cart-button and doesn't have the class btn--disabled.
How can I do this? Here is what I have so far:
button[contains(#class, "add-to-cart-button")]
EDIT: In my project I have a list of products. Now I want to select the first Article-Container on the page whose button doesn't have the class btn--disabled
Here is the HTML
<main>
<div class="grid shop-list__results offer-tiles">
<div class="offer-tiles__item offer-tiles--odd offer-tiles--top-border">
<article itemscope="itemscope" itemtype="http://schema.org/Product" class="offer-tile">
<div itemprop="offers" itemscope="itemscope" itemtype="http://schema.org/Offer" class="offer-tile__content">
<ul class="offer-tile__actions">
<li class="offer-tile__action offer-tile__action--add-to-cart">
<button type="button" class="btn add-to-cart-button btn--disabled">Cart</button></li>
</ul>
</div>
</article>
</div>
<div class="offer-tiles__item offer-tiles--even offer-tiles--top-border">
<article itemscope="itemscope" itemtype="http://schema.org/Product" class="offer-tile">
<div itemprop="offers" itemscope="itemscope" itemtype="http://schema.org/Offer" class="offer-tile__content">
<ul class="offer-tile__actions">
<li class="offer-tile__action offer-tile__action--add-to-cart">
<button type="button" class="btn add-to-cart-button">Cart</button></li>
</ul>
</div>
</article>
</div>
And here is my xpath selector so far(this is obviously wrong):
//main//article[contains(descendant::button/#class, "add-to-cart-button")][not(descendant::button/#disabled)]

Try this:
button[contains(#class, "add-to-cart-button") and not(contains(#class, "btn-disabled"))]
where:
and is an operator between two statements. Example //div[x and y]
or //div[x or y]
not() is for opposite of statement in the function. Example //div[x and not(y)]
EDIT:
As per HTML block you have provided, you can use this xPath:
//button[#class = 'btn add-to-cart-button']
or, if there many add-to-cart-button, you can use something like this:
//div[#class = 'offer-tiles__item offer-tiles--even offer-tiles--top-border']/article[#itemtype = 'http://schema.org/Product']/div[#itemtype = 'http://schema.org/Offer']//button[#class = 'btn add-to-cart-button']

Related

How to hide element with AngularJS based on DOM element

I have an Umbraco setup. And when I edit in the CMS I would like for the "Preview" button to disappear whenever there is not a text-editor present in the DOM.
Angular file in localtion Umbraco/Views/content/edit.html
<form novalidate name="contentForm"
ng-controller="Umbraco.Editors.Content.EditController"
ng-show="loaded"
ng-submit="save()"
val-form-manager>
<umb-panel umb-tabs ng-class="{'editor-breadcrumb': ancestors && ancestors.length > 0}">
<umb-header tabs="content.tabs">
<div class="span7">
<umb-content-name placeholder="#placeholders_entername"
ng-model="content.name" />
</div>
<div class="span5">
<div class="btn-toolbar pull-right umb-btn-toolbar">
<div class="btn-group" ng-animate="'fade'" ng-show="formStatus">
<p class="btn btn-link umb-status-label">{{formStatus}}</p>
</div>
<umb-options-menu ng-show="currentNode"
current-node="currentNode"
current-section="{{currentSection}}">
</umb-options-menu>
</div>
</div>
</umb-header>
<umb-tab-view>
<umb-tab id="tab{{tab.id}}" rel="{{tab.id}}" ng-repeat="tab in content.tabs">
<div class="umb-pane">
<umb-property property="property"
ng-repeat="property in tab.properties">
<umb-editor model="property"></umb-editor>
</umb-property>
<div class="umb-tab-buttons" detect-fold ng-class="{'umb-dimmed': busy}">
<div class="btn-group" ng-show="listViewPath">
<a class="btn" href="#{{listViewPath}}">
<localize key="buttons_returnToList">Return to list</localize>
</a>
</div>
<div class="btn-group" ng-show="!isNew">
<a class="btn" ng-click="preview(content)">
<localize key="buttons_showPage">Preview page</localize>
</a>
</div>
<div class="btn-group dropup" ng-if="defaultButton">
<!-- primary button -->
<a class="btn btn-success" href="#" ng-click="performAction(defaultButton)" prevent-default>
<localize key="{{defaultButton.labelKey}}">{{defaultButton.labelKey}}</localize>
</a>
<a class="btn btn-success dropdown-toggle" data-toggle="dropdown" ng-if="subButtons.length > 0">
<span class="caret"></span>
</a>
Return to list
<!-- sub buttons -->
<ul class="dropdown-menu bottom-up" role="menu" aria-labelledby="dLabel" ng-if="subButtons.length > 0">
<li ng-repeat="btn in subButtons">
<a href="#" ng-click="performAction(btn)" prevent-default>
<localize key="{{btn.labelKey}}">{{btn.labelKey}}</localize>
</a>
</li>
</ul>
</div>
</div>
</div>
</umb-tab>
</umb-tab-view>
<ul class="umb-panel-footer-nav nav nav-pills" ng-if="ancestors && ancestors.length > 0">
<li ng-repeat="ancestor in ancestors">
{{ancestor.name}}
</li>
<li></li>
</ul>
</umb-panel>
</form>
I am not certain this is the correct file - but it seems to be the place where the Preview button is created.
The question now is. Can I somehow determine with angular if the text editor is active and then if it is, show the Preview button next to the Save and publish?
I would suggest the following
1) Determine what properties are accessible on the object that is passed through to the <umb-editor> directive.
Digging into the code I can see things like it has a .view property. You could inspect this at runtime in the browser console to see what additional properties are available
2) You can write a rule on the button to show if the collection of fields contains one with a certain property you might have identified
something like this...
Hope this helps
I found a second solution I might as well add here. I used the Umbraco Plugin Backoffice Tweaking.
Here I added this to my Config\BackofficeTweaking.config file
<?xml version="1.0" encoding="utf-8"?>
<Config>
<Rules>
<Rule Type="HideButtons" Enabled="true" Names="preview" Users="" UserTypes="" ContentTypes="Omraader,Grund,Udstykning,Indstillinger,Niveau,Oversigt_Mappe,Oversigt,Information_Mappe,Information,Afstande_Mappe,Afstande" Description="" />
</Rules>
<Scripts>
<Script Name="example"></Script>
</Scripts>
</Config>
Here you can also make some scripting or do many other things. The plugin also has a visual editor for Umbraco. Pretty easy to use.

routerLink from Object in Angular2

I'm trying to build a "Team Member" page from JSON data.
I can create the page with basic things like firstName, lastName, position.
Each team member has their own page with a little more information
What I cant figure out is how to include the team members url to my [routerLink].
My router link would look like this which I have setup in my routes
<a [routerLink]="['./glenn']">
And this is how I'm attempting to use it
<div class="team-members" *ngFor="let teammember of teammembers" >
<div class="clearfix">
<div class="col-xs-12 col-sm-8 col-md-8 col-lg-6 team-member member-item" style="cursor: pointer;">
<a [routerLink]="['./"{{teammember.firstName}}"']">
<div class="member-pic-holder">
<img alt="" src='{{teammember.photo}}' />
<div class="member-overlay"></div>
</div>
<h4>{{teammember.firstName}}<br/>{{teammember.lastName}} <span class="fa fa-arrow-right"></span></h4>
<p class="company-position">{{teammember.position}}</p>
</a>
</div>
</div>
</div>
Any thoughts on this one please?
It's also breaking when I'm trying to include the team-members photo
<img alt="" src='{{teammember.photo}}' />
However one thing at a time!
Thanks
GWS
You are using the {{ foo.bar }} binding incorrectly, the {{ }} syntax allows you to do one way binding, what you want is to use regular js expressions when binding to your objects properties.
When binding to an html element attribute, you can use the [attr.{id|href|etc}] binding, in your case, for the href of the image you can use:
<img alt="" [attr.href] = 'teammember.photo' />
And for the router, simply use [routerLink] = "[teammember.firstName]" (not sure why you need the ./, if you do need it, you could append it using a getter on your team member class, as shown bellow.
For your routes, you could do something along the lines of:
Team Member Class
export class TeamMember {
// ...properties and constructor
private memberUrl: string = "foobar"
get MemberRoute(){
return `./${this.memberUrl}`;
}
}
Template:
<div class="team-members" *ngFor="let teammember of teammembers" >
<div class="clearfix">
<div class="col-xs-12 col-sm-8 col-md-8 col-lg-6 team-member member-item" style="cursor: pointer;">
<a [routerLink]="[teammember.MemberRoute']">
<div class="member-pic-holder">
<img [attr.href] = 'teammember.photo' />
<div class="member-overlay"></div>
</div>
<h4>{{teammember.firstName}}<br/>{{teammember.lastName}} <span class="fa fa-arrow-right"></span></h4>
<p class="company-position">{{teammember.position}}</p>
</a>
</div>
</div>
</div>
Hope this helps!
can you try like this:
['./',teammember.firstName]
for img use
<img alt="" [src]="teammember.photo" />

how to select child element in my test case

I am trying to test a click event for my html
html
<div class="testGroup">
<div ng-repeat="test in tests">
<a ng-click="clickMe(test.id)">{{test.name}}</a>
<a ng-click="clickMe(test.id)">{{test.name}}</a>
<a ng-click="clickMe(test.id)">{{test.name}}</a>
<a ng-click="clickMe(test.id)">{{test.name}}</a>
</div>
</div>
<div class="testGroup">
<div ng-repeat="test in tests">
<a ng-click="clickMe(test.id)">{{test.name}}</a>
<a ng-click="clickMe(test.id)">{{test.name}}</a>
<a ng-click="clickMe(test.id)">{{test.name}}</a>
</div>
</div>
<div class="testGroup">
<div ng-repeat="test in tests">
<a ng-click="clickMe(test.id)">{{test.name}}</a>
<a ng-click="clickMe(test.id)">{{test.name}}</a>
<a ng-click="clickMe(test.id)">{{test.name}}</a>
</div>
</div>
Three divs are identical but I want to select the first testGroup class and click the first a tag. I also want to click the first a tag on the second testGroup class.
In my spec.js
element.all(by.css('.testGroup')).get(0).then(function(elem) {
element(by.repeater('test in tests').row(0)).click();
});
I am getting undefined is not a function error. I think it's because the get(0) is not a promise. How do I trigger click on the first a tag in the first testGroup div and first a tag in second testGroup div? Thanks for the help.
Would something like this work alright?
var testGroupOneTag = $$('.testGroup').get(0).$('[ng-click="clickMe(test.id)"]');
var testGroupTwoTag = $$('.testGroup').get(1).$('[ng-click="clickMe(test.id)"]');
testGroupOneTag.click():
testGroupTwoTag.click():
$$ is short for element.all by css.
There is no then() on an ElementFinder anymore (since 2.0).
Chain element and element.all(), use by.repeater() and column():
var testGroups = element.all('.testGroup');
var testGroupOneTag = testGroups.first().element(by.repeater("test in tests").column("test.name"));
var testGroupTwoTag = testGroups.get(1).element(by.repeater("test in tests").column("test.name"));
testGroupOneTag.click();
testGroupTwoTag.click();

similar to nth-child(even) for a <ul>

I did an ng-repeat on a ul.
Obviously, I cant use nth-child(even) to apply it on ul to change the background-color of the even ul
Anyone knows something similar
ngRepeat exposes the boolean $even and $odd properties, which you can combine with ngClass:
<ul>
<li ng-repeat="item in items" ng-class="{'some-class':$odd}">
{{item.someText}
</li>
</ul>
Note: $even and $odd are based on the currnt $index which is zero-based, so you might need to use $odd instead of $even.
Or you can use the ngClassEven / ngClassOdd directives:
<ul>
<li ng-repeat="item in items" ng-class-even="'some-class'">
{{item.someText}
</li>
</ul>
See, also, this short demo.
Try this out
Working Demo
html
<div ng-app="">
<div ng-init="predicate='name'; reverse=false;">Sort: predicat:{{predicate}} reverse:{{reverse}} </div>
<div ng-click="reverse=!reverse">[change reverse]</div>
<div ng-click="predicate='name'; reverse=!reverse;">[set predicate: name + change reverse]</div>
<div ng-click="predicate='id'; reverse=!reverse;">[set predicate: id + change reverse]</div>
<div ng-init="lines=[{'name':'eee', 'id':7}, {'name':'aaa', 'id':9}, {'name':'ccc', 'id':8}, {'name':'bbb', 'id':2}, {'name':'ddd', 'id':3}]">
<ul ng-repeat="line in lines | orderBy:predicate:reverse" ng-class-odd="'odd'" ng-class-even="'even'">
<li >{{ line.name }}</li>
</ul>
</div>
</div>
Output

Code in editor looks fine, in browser it changes

I have this weird problem.
When i wrap a anchor tag around a div, the html markup completely changes.. cleared cache and everything.
Its about the anchor with the class outgoing link
Html in the code editor (correct code):
<a class="outgoing-link" href="#">
<div id="content-element">
<div class="top-info">
<span class="title-provider">Vodafone</span>
<img src="phone-placeholder.png"
alt="placeholder"
width="58px"
height="50px"/>
<div class="bg-circle"></div>
<span class="dur-discount">1e 3 maand</span>
<span class="price-discount">€ 16,50</span>
<span class="dur-normal">Daarna</span>
<span class="price-normal">€ 20,00</span>
</div>
<h3>iPhone 4GS abonnement</h3>
<p><span>100</span> min & sms <span>500</span> mb</p>
<p><span>2 jr</span>telefoon abonnement</p>
<p>Prijs telefoon: <span>Gratis</span></p>
<div class="hover-extra-info">
<p>Aansluitkosten: <span>€ 24,95</span></p>
<p>Vodafone abonnement</p>
<p>aanbieder: Student Mobiel</p>
<p>Totale kosten over 2 jaar</p>
<p>€ 547,22</p>
</div>
</div><!-- end content-element-->
</a>
Code in the browser:
<a class="outgoing-link" href="#"></a>
<div id="content-element">
<a class="outgoing-link" href="#">
<div class="top-info">
<span class="title-provider">Vodafone</span>
<img src="phone-placeholder.png"
alt="placeholder"
width="58px"
height="50px"/>
<div class="bg-circle"></div>
<span class="dur-discount">1e 3 maand</span>
<span class="price-discount">€ 16,50</span>
<span class="dur-normal">Daarna</span>
<span class="price-normal">€ 20,00</span>
</div>
</a>
<h3>iPhone 4GS abonnement</h3>
<p><span>100</span> min & sms <span>500</span> mb</p>
<p><span>2 jr</span>telefoon abonnement</p>
<p>Prijs telefoon: <span>Gratis</span></p>
<div class="hover-extra-info">
<p>Aansluitkosten: <span>€ 24,95</span></p>
<p>Vodafone abonnement</p>
<p>aanbieder: Student Mobiel</p>
<p>Totale kosten over 2 jaar</p>
<p>€ 547,22</p>
</div>
</div><!-- end content-element-->
It adds another link and puts them at the wrong places.
Any ideas as to what's going on? Or am i just missing something.
Any help would be appreciated :)
i think its because nested anchor tags are illegal
see: http://www.w3.org/TR/html401/struct/links.html#h-12.2.2
it should be easy to do without the nested anchor tag while keeping the functionality the same.
Could be a try to automatically fix invalid HTML ( => Quirksmode ?), as an achor-tag should not contain -Tags.
Try to add a DOCTYPE statement at the beginning of the file, does that change the behavoir?
The Doctype-Statement (must be on the first line HTML file / output) could be like this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">