How to select the closest element with a specific tag in chai protractor - protractor

If the html looks as follow:
<form>
<div>
<field-component>
<div class='field'></div>
</field-component>
</div>
<div>
<div class='icon'></div>
</div>
</form>
I am able to get the field using fieldElement = element(by.css('.field')), but how can I get the closest element with the icon class?

try this:
var form = element(by.css('form'));
return form.element(by.css('.field')).isPresent().then((present) => {
if (present) {
return form.element(by.css('.icon')).click(); #click or whatever on this element
}
});

Related

Template not reactive in meteor on adding new data?

This are the event listeners for my two templates,specified in events.js
// event listeners on the addSiteForm template
Template.addCommentForm.events({
// this runs when they click the add button... you need to compete it
'click .js-add-comment':function(event){
var comment_text = $('#comment_input').val();// get the form value using jquery...
var user = 'anonymous person';
// the 'this' variable contains
// the data that this template is displaying
// which is the Website item
var site = this;
if (Meteor.user()){
user = Meteor.user().emails[0].address
}
var comment = {"text":comment_text,
"siteId":site._id,
"createdOn":new Date(),
"createdBy":user};// create a simple object to insert to the collectoin
Comments.insert(comment);
console.log("events start");
console.log("totla coomets are "+Comments.find({}).count()+"\n");
console.log("commenst in site "+Comments.find({siteId:site._id}).count()+"\n");
console.log("site id is "+site._id);
console.log("events end");
return false;
}
});
// event listeners on the addSiteForm template
Template.addSiteForm.events({
// this runs when they click the add button... you need to compete it
'click .js-add-site':function(event){
var url = $('#url_input').val();// get the form value using jquery...
var user = 'anonymous person';
if (Meteor.user()){
user = Meteor.user().emails[0].address
}
var site = {"url":url,
"createdOn":new Date(),
"createdBy":user};// create a simple object to insert to the collectoin
Websites.insert(site);
return false;
}
});
The router function is specified in router.js
Router.configure({
layoutTemplate: 'ApplicationLayout'
});
// the main route. showing the list of sites.
Router.route('/', function () {
this.render('siteList');
});
// this route is for the discussion page for a site
Router.route('/discussSite/:_id', function () {
var siteId = this.params._id;
site = Websites.findOne({_id:siteId});
this.render('discussSite', {data:site});
});
the main.js contain the collections
// shared code
Websites = new Mongo.Collection("websites");
Comments = new Mongo.Collection("comments");
helpers is
// this helper gets the data from the collection for the site-list Template
Template.siteList.helpers({
'all_websites':function(){
return Websites.find({});
},
'safer_email':function(email){
if (email.indexOf('#')!=-1){// we have an email
return email.split('#')[0];
}
else{// probably anonymouse.
return email;
}
}
});
Template.discussSite.helpers({
'comments':function(siteId){
//console.log("helper comments "+this.site);
// complete the code here so that it reruns
console.log(this.params.site._id);
return Comments.find({siteId:siteId});
// all the comments with a siteId equal to siteId.
}
});
the html file is in main.html.here it first displays the websites available in the webpage.On clicking this the user is routed to a new page.Here the user can add comments for the website
<head>
<title>week_4_peer_assessment</title>
</head>
<body>
</body>
<!-- this is the template that iron:router renders every time -->
<template name="ApplicationLayout">
<div class="container">
Home
{{>loginButtons}}
<h1>SiteAce - discuss your favourite websites</h1>
<!-- iron router will select what to render in place of yield-->
{{> yield }}
</div>
</template>
<template name="discussSite">
<h3>Discussing: {{url}} </h3>
{{> addCommentForm}}
<!-- write some code here that iterates through the comments and displays
the comment text and the author -->
<!-- clue - you have already written the 'comments' helper function -->
<ul>
{{#each comments}}
<li>{{text}} (added by {{safer_email createdBy}})
</li>
{{/each}}
</ul>
</template>
<template name="addCommentForm">
<div class="row">
<div class="col-lg-6">
<div class="input-group">
<input type="text" id="comment_input" class="form-control" placeholder="Enter your comment">
<input type="hidden" id="site_id" class="form-control" placeholder="Enter your comment">
<span class="input-group-btn">
<button class="btn btn-default js-add-comment" type="submit">Add!</button>
</span>
</div><!-- /input-group -->
</div><!-- /.col-lg-6 -->
</div>
</template>
<template name="siteList">
Fill in the form and click submit to add a site:
{{>addSiteForm}}
<h3>Sites you have added:</h3>
<ul>
{{#each all_websites}}
<li>{{url}} (added by {{safer_email createdBy}})
<br/>discuss
<br/>visit site
</li>
{{/each}}
</ul>
</template>
<template name="addSiteForm">
<div class="row">
<div class="col-lg-6">
<div class="input-group">
<input type="text" id="url_input" class="form-control" placeholder="Enter website URL...">
<span class="input-group-btn">
<button class="btn btn-default js-add-site" type="submit">Add!</button>
</span>
</div><!-- /input-group -->
</div><!-- /.col-lg-6 -->
</div>
</template>
The starup.js contains the start up code run by the server
Meteor.startup(function(){
if (!Websites.findOne()){// nothing in the database yet
var site = {"url":"http://www.google.com",
"createdOn":new Date(),
"createdBy":"Michael"};// create a simple object to insert to the collectoin
Websites.insert(site);
site = {"url":"http://www.yeeking.net",
"createdOn":new Date(),
"createdBy":"Janet"};// create a simple object to insert to the collectoin
Websites.insert(site);
site = {"url":"http://www.coursera.org",
"createdOn":new Date(),
"createdBy":"Jose"};// create a simple object to insert to the collectoin
Websites.insert(site);
}
});
This is what your template should be: (I removed safer_email. It was erroring. Not sure if it was something else you were working on.)
<template name="discussSite">
<h3>Discussing: {{url}} </h3>
{{> addCommentForm}}
<!-- write some code here that iterates through the comments and displays
the comment text and the author -->
<!-- clue - you have already written the 'comments' helper function -->
<ul>
{{#each comments}}
<li>{{text}} (added by {{createdBy}})</li>
{{/each}}
</ul>
</template>
helper:
your helper function is designed to take in siteId as an input, yet you are not passing one to it.
this._id or Router.current().params._id will get you the siteId that you are looking for. You'd used this.site._id which used to error out as this.site was not valid.You can further see what the this object contains by doing a console.log(this). That would have helped you sort this out faster.
'comments':function(){
console.log("site id in helper is ",this._id); // or Router.current().params._id;
console.log(Comments.find({siteId:this._id}).fetch());
return Comments.find({siteId:this._id});
}

Show tags under their own specific tab

I'm creating a tag system on my website. So far it's all working great. But now I wish to create a page that shows all my tags under their own tab like you have with a portfolio page.
Example: http://www.don-zalmrol.be/tags?tag=Electronics
My page already displays the tags for a specific tag under it's own tab (i.e. electronics), but as you might guess I wish to populate the other tags in their respective tab as well.
So in short you land a view that displays the tag you've selected, but on the same page you can see the others as well.
Anybody has any idea how I can do this? I don't think I'm far away from the solution as I can already load the projects for specific tags under it's own tab. Now I only need to populate the remaining tabs with the tags!
Thanks!
This is my code so far:
http://pastebin.com/jwGW0NKZ
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{
var portfolio = Umbraco.TagQuery.GetAllContentTags().OrderBy(t => t.Text);
var tagList = Umbraco.TagQuery.GetAllContentTags().OrderBy(t => t.Text);
string tag = Request.QueryString["tag"];
if (!tag.IsNullOrWhiteSpace())
{
var publishedContent = Umbraco.TagQuery.GetContentByTag(tag);
if (publishedContent.Count() > 0)
{
#* Show title *#
<div class="media contact-info wow fadeInDown" data-wow-duration="1000ms" data-wow-delay="600ms">
<center>
<div>
<i class="fa fa-tags"></i>
</div>
<br />
<div class="media-body">
<h2>Tags</h2>
<p>Browse content by tag</p>
</div>
</center>
<br />
</div>
#* Show tag titles in tabs *#
<ul class="portfolio-filter text-center">
<li><a class="btn btn-default" href="#" data-filter="*">All tags</a></li>
#foreach (var tags in tagList)
{
<!-- Create a selected tag -->
if(#tags.Text == #tag)
{
<li><a class="btn btn-default active" href="#" data-filter=".#tag">#tag</a></li>
}
#* Show all other tags *#
else
{
<li><a class="btn btn-default" href="#" data-filter=".#tags.Text">#tags.Text</a></li>
}
}
</ul>
<div class="row">
<div class="portfolio-items">
#* Start picture content *#
#foreach (var tags in tagList)
{
#* Put selected tag in the right tag tab *#
if(#tags.Text == #tag)
{
#* Show tag content *#
foreach (var item in publishedContent.OrderByDescending(i => i.CreateDate))
{
<div class='portfolio-item #tag col-xs-12 col-sm-4 col-md-3'>
<div class="recent-work-wrap">
#* IF the project has a picture *#
#if(item.HasValue("pictureOfTheProject"))
{
var featureImage = Umbraco.TypedMedia((int)item.GetPropertyValue("pictureOfTheProject"));
<img class="img-responsive" src="#featureImage.GetCropUrl(250, 250)" alt='#item.GetPropertyValue("titleOfTheProject")' />
<div class="overlay">
<div class="recent-work-inner">
<h3>#item.GetPropertyValue("titleOfTheProject")</h3>
<a class="preview" href="#featureImage.GetCropUrl(250, 250)" rel="prettyPhoto">
<i class="fa fa-eye"></i> View
</a>
</div>
</div>
}
#* Else when the project doesnt have a picture, show default one *#
else
{
var noImage = "http://www.don-zalmrol.be/media/1440/no_image_available.png";
<img class="img-responsive" src="#noImage.GetCropUrl(250, 250)" alt="No image" />
<div class="overlay">
<div class="recent-work-inner">
<h3>#item.GetPropertyValue("titleOfTheProject")</h3>
<a class="preview" href="#noImage.GetCropUrl(250, 250)" rel="prettyPhoto">
<i class="fa fa-eye"></i> View
</a>
</div>
</div>
}
</div>
</div>
}
}
#* Put the other tags under there own tab *#
else
{
}
}
#* End dynamic tags *#
</div>
</div>
}
#* No content matching the tag? *#
else
{
<p>There isn't any content matching that tag.</p>
#Html.Partial("TagList")
}
}
#* Show the tag list with amount *#
else
{
#Html.Partial("TagList")
}
}
EDIT 27-03-2016
Ok so I now know that I need to play around with my tag query or use the IEnumerable. But I can't seem to find it out how I can do this without breaking the code...
#* Get all tags and order them by name *#
var tagList = Umbraco.TagQuery.GetAllContentTags().OrderBy(t => t.Text);
#* Get requested tag *#
string tag = Request.QueryString["tag"];
#* Show all content by requested tag *#
var publishedContent = Umbraco.TagQuery.GetContentByTag(tag);
Above are the pieces of code that list all the tags I have in a var, gets the name from the URL (i.e. Electronics) and one that then displays all content that matches said queried tag.
So in short I need to change the last part of the TagQuery to list all content that has a tag and then filter it out by the querystring to display them in their own category.
But how can list all tagcontent?
Cheers,
Don
Your issue is on line 76 of the pastebin where you loop through the published content, which is already filtered by the selected tag. Because of this, only content with the selected tag ever gets written to the template.
What you need to do is use the loop on line 70 where you're looping through all tags. The jQuery plugin you're using will handle the filtering by using the CSS class you add on line 78. You can get rid of the loop on line 76.
For clarity, I would also change the
#foreach (var tags in tagList)
to
#foreach (var item in tagList)
since the foreach is producing a single tag rather than plural "tags" as your code insinuates. This has the added bonus of allowing you to keep the rest of your code the same once you remove the loop on line 76.

create custom durandal modal

I am trying to develop custom modal plugin for durandal 2.1 to have my own logic and abstract it from the rest of my app here is what I have so far but something does not work and modal gets inserted in DOM twice
define(['jquery', 'knockout', 'plugins/dialog'], function ($, ko, dialog) {
var modal = {
install: function (config) {
dialog.addContext("Modal", {
addHost: function (theDialog) {
var body = $("body");
$('<div id="Dialog" class="AlignC"><div class="ModalHost"></div></div>').appendTo(body);
theDialog.host = $('#Dialog').get(0);
},
removeHost: function (theDialog) {
alert("demoving host");
$("#Dialog").remove();
},
compositionComplete: function (child, parent, context) {
var theDialog = dialog.getDialog(context.model);
}
});
}
};
return modal;
});
and here is how i call it from my viewmodel
dialog.show(this, null, 'Modal');
can anyone tell me what is wrang with this code why my model ELEMENT is inserted twice and ovelay each other. how can i fix that.
second element does not have content inside.
by the way here is view I am trying to show inside modal
<span class="Loader"></span>
<div class="Modal">
<h2 class="Caps">SomeName</h2>
<div class="Row">
<input type="text" />
</div>
<div class="Desc">
description
<br />
XXY YYX XXY
</div>
<div class="Buttons">
<span class="Green">Check</span>
<span>Add</span>
</div>
</div>
Ok I managed to fix this behavior. the problem with click binding was firing twice and this was the problem associated with inserting tow HTML elements in DOM after fixing click handler, everything works just fine.

Dynamically added elements - using $(this)

When adding a element to the dom dynamically like this:
row = """
<div class="ipad-row">
<h3>Sample Row</h3>
<div id="wrapper-placeholder">
<div class="scrollView" style="">
<a class="btn btn-primary add-row-item">Add an item</a>
</div>
</div>
</div>
"""
$(".add-row").live "click", ->
$(".ipad .body").append row
false
How come when I try and get this from the a link inside that row element, I get window:
$(".add-row-item").live "click", =>
f = $ this
console.log f // this logs window object, not the link element?
f.parent().append row_item
Can someone please explain this behavior and how i can use $(this) like you would if the element did exist when the dom loaded?
Thanks
=> changes this to the this in the parent context:
$(".add-row-item").live "click", =>
f = $(this)
compiles to
var _this = this;
$(".add-row-item").live("click", function() {
var f = $(_this);
Use -> instead, which won't modify this.

jQuery: Convert to a single tag

I want to convert the below HTML to single tag:
Before :
<div class="Parent1">
<div class="Child1">
Child1
</div>
<div class="Child2">
Child2
</div>
</div>
<div class="Parent2">
<div class="Child1">
Child1
</div>
<div class="Child2">
Child2
</div>
</div>
After :
<div class="Parent1">
<button>Child1</button>
<button>Child2</button>
</div>
<div class="Parent2">
<button>Child1</button>
<button>Child2</button>
</div>
i tried with wrapping/unwrapping. But it does not work. This I want to be generic.
Try this (demo):
$('div[class^="Parent"]').each(function(index, parent) {
var html = [];
$('a', parent).each(function(index, child) {
html.push('<button>'+$(child).html()+'</button>');
});
$(parent).html(html.join(''));
});
It assumes that there is a pattern to the parent divs but that that isn't some common class name.
One way to do it:
$("a").unwrap().wrap("<button>").parent().text(function () {
return $(this).text();
});
http://jsfiddle.net/Tomalak/Gct7H/
Another one in the same spirit:
$("a").unwrap().replaceWith(function () {
return $("<button>", {text: $(this).text()});
});
PS: In reality you would want to select something more specific than just $("a"). Maybe $("#container a") or $("a.someClass"), depending on your markup.