I'm working on my angular e2e test project. I've the following html generated as part of my ng-repeat with out any id, I would like to choose the second element that is with heading Topic - xyz and also then click the button which is a child of it's sibling. How can I do that.
<div class="row ng-scope" ng-repeat="post in posts">
<div class="col-md-7">
<h4 class="ng-binding">Topic - ABC</h4>
<div class="text-right">
<button class="btn btn-none btn-sm" ng-click="posts.newPost()">
Create Post
</button>
</div>
</div>
</div>
<div class="row ng-scope" ng-repeat="post in posts">
<div class="col-md-7">
<h4 class="ng-binding">Topic - XYZ</h4>
<div class="text-right">
<button class="btn btn-none btn-sm" ng-click="posts.newPost()">
Create Post
</button>
</div>
</div>
</div>
<div class="row ng-scope" ng-repeat="post in posts">
<div class="col-md-7">
<h4 class="ng-binding">Topic - EFG</h4>
<div class="text-right">
<button class="btn btn-none btn-sm" ng-click="posts.newPost()">
Create Post
</button>
</div>
</div>
</div>
This is what I've tried to so far which is not working
var button = $$(by.repeater('post in posts')).get(1).$(by.css('[ng-click="posts.newPost()"]'))
button.click(); // click is not showing up
$$(by.repeater('post in posts')) and $(by.css('[ng-click="posts.newPost()"]')) - these are not correct syntax of using the by.repeater() or by.css() locator. $$ is a shortcut for the element.all(by.css()) and should not be used for the "repeater" locator. If you use $(), there is no need to wrap your selector into by.css():
var button = element.all(by.repeater('post in posts')).get(1).$('[ng-click*=newPost]');
button.click();
If you want to filter the repeater element by the topic name, you can use .filter():
var button = element.all(by.repeater('post in posts')).filter(function (post) {
return post.$("h4").getText().then(function (postTitle) {
return postTitle === "Topic - XYZ";
});
}).get(1).$('[ng-click*=newPost]');
button.click();
Also see if using the by.buttonText locator would work as well (a little bit cleaner):
var post = element.all(by.repeater('post in posts')).get(1);
var button = post.element(by.buttonText("Create Post"));
button.click();
Related
I have a ng-show inside ng repeat. Whenever i click the comment button it shows the div tag contains comment box which shows previous comments of that list.
The actual problem is when i click one comment button, it shows comment box with contents but when i click the another comment button, comment box with contents will be shown but it also changes the contents of previous comment box also (i mean showallcomments which is over-writing every time when i click on comment button).
Note: In more simple words the problem is- On clicking comment button , the previously opened comment box by clicking comment button doesnt close
Note: Comment box is not a model which doesn't popup
So my solution is whenever i click the second comment button, it should hide all previous comment box.(I need to hide the all previously opened comment box when i click comment button each time)
How can i do this? can anyone help me out
I think u may understand the question if you look my code.
My code is,
<div class="col-lg-12" ng-repeat="dat in details | orderBy : sortColumn : reverseSort | filter : { product_name : textname} as results">
<ul>
<li><b>Product:</b><span> {{dat.product_name}}</span></li>
<li><b>Product Manager:</b><span> {{dat.first_name}} {{dat.last_name}}</span></li>
<li><b>Status:</b><span> {{dat.status}}</span></li>
<li><b>Description:</b><span> {{dat.description}}</span></li>
</ul>
<!--Comment Button -->
<button style="background-color:#4C97C8;color:white;height:30px" class="btn" ng-click="comment=true;$parent.showcomments(dat.id)"><span class="glyphicon glyphicon-comment"></span><strong> Comment</strong></button>
<!--Comment Box -->
<div ng-show="comment">
<div class="detailBox col-lg-12">
<div class="titleBox">
<label>Comment Box</label>
<button type="button" class="close" aria-hidden="true" ng-click="comment=false">×</button>
</div>
<div class="actionBox">
<ul class="commentList">
<li ng-repeat="sh in showallcomments">
<div class="commenterImage">
<img src="" />
</div>
<div class="commentText">
<p class="">{{sh.comment}}</p> <span class="date sub-text">{{sh.date_created}}</span>
</div>
</li>
</ul>
<div class="input-group ">
<input type="text" id="commentarea" name="commentarea" class="form-control" placeholder="Your Comments" aria-describedby="basic-addon2" ng-model="takecomment">
<span class="input-group-addon" id="basic-addon2" ng-click="takecomment=mycomment(dat.id,takecomment)"><span class="glyphicon glyphicon-send"></span></span>
</div>
</div>
</div>
</div>
</div>
Can you try:
<button style="background-color:#4C97C8;color:white;height:30px" class="btn" ng-click="$parent.commentId=dat.id;$parent.showcomments(dat.id)"><span class="glyphicon glyphicon-comment"></span><strong> Comment</strong></button>
and
<div ng-show="dat.id===$parent.commentId">
I think you are showing the content through modal "showallcomments". which is over-writing every time when you click on comment button.
I mean to say you are binding same variable in all comment boxes.
<div class="col-lg-12" ng-repeat="dat in details | orderBy : sortColumn : reverseSort | filter : { product_name : textname} as results">
<ul>
<li><b>Product:</b><span> {{dat.product_name}}</span></li>
<li><b>Product Manager:</b><span> {{dat.first_name}} {{dat.last_name}}</span></li>
<li><b>Status:</b><span> {{dat.status}}</span></li>
<li><b>Description:</b><span> {{dat.description}}</span></li>
</ul>
<!--Comment Button -->
<button style="background-color:#4C97C8;color:white;height:30px" class="btn" ng-click="showCommentBox($index);$parent.showcomments(dat.id)">
<span class="glyphicon glyphicon-comment"></span><strong> Comment</strong></button>
<!--Comment Box -->
<div ng-show="dat.showComment">
<div class="detailBox col-lg-12">
<div class="titleBox">
<label>Comment Box</label>
<button type="button" class="close" aria-hidden="true" ng-click="comment=false">×</button>
</div>
<div class="actionBox">
<ul class="commentList">
<li ng-repeat="sh in showallcomments">
<div class="commenterImage">
<img src="" />
</div>
<div class="commentText">
<p class="">{{sh.comment}}</p> <span class="date sub-text">{{sh.date_created}}</span>
</div>
</li>
</ul>
<div class="input-group ">
<input type="text" id="commentarea" name="commentarea" class="form-control" placeholder="Your Comments" aria-describedby="basic-addon2" ng-model="takecomment">
<span class="input-group-addon" id="basic-addon2" ng-click="takecomment=mycomment(dat.id,takecomment)"><span class="glyphicon glyphicon-send"></span></span>
</div>
</div>
</div>
</div>
</div>
showCommentBox = function(index){
angular.forEach('details', function(value, key){
if(key == index){
value.showComment = true;
}else{
value.showComment = false;
}
})
}
I'm working with ng-repeat .In the ng-repeat i'm repeating panel.The panel body consist of two part .First part is a paragragh which i fetch from the database using $http.get(). In the second part i have a button (edit button).When i click the edit button the paragraph in the first part should be hidden and text-area should appear with the content in the paragraph as default.But when i'm trying to achieve this im getting an idea when i click one edit button all of my paragragh hides and the textarea appear .How can i restrict it .
$scope.editorEnabled = false;
$scope.enableEditor = function() {
$scope.editorEnabled = true;
};
<div ng-repeat="(key,rec) in recordcomment">
<div class="row">
<div class="col-md-10">
<div class="panel panel-default">
<div class="panel-heading">
heading
</div>
<div class="panel-body" style="background-color:white;">
<p ng-hide="editorEnabled">{{rec.comment}}</p>
<textarea ng-model="rec.comment" ng-show="editorEnabled"></textarea>
<button class="btn btn-primary pull-right" ng-click="enableEditor()">Edit</button>
</div>
</div>
</div>
</div>
</div>
<div class="panel-body" style="background-color:white;">
<p ng-hide="rec.editorEnabled">{{rec.comment}}</p>
<textarea ng-model="rec.comment" ng-show="rec.editorEnabled"></textarea>
<button class="btn btn-primary pull-right" ng-click="enableEditor(rec)">Edit</button>
</div>
$scope.enableEditor = function(context) {
context.editorEnabled = true;
};
Use rec instead of this
Because this means current context of ng-repeat directive..
So to make it effective we need to modify the object...
Hence we need to pass it as i have use rec in function param
Try this in case do comment
Add the editorEnabled object with ng-rpeat object. so it will be consider with the array object. and you can pass this current object via click function() and set true/false the editorEnabled object.
Code looks like.
<div class="panel-body" style="background-color:white;">
<p ng-hide="rec.editorEnabled">{{rec.comment}}</p>
<textarea ng-model="rec.comment" ng-show="rec.editorEnabled"></textarea>
<button class="btn btn-primary pull-right" ng-click="enableEditor(this)">Edit</button>
</div>
$scope.enableEditor = function(context) {
context.editorEnabled = true;
};
I have a editable-select nested inside other, when I submit the nested editable-select changes, it does not call the onaftersave assigned function ('vm.addOperation()'), it also shows the outter editable-select edit form.
I want it just to show the nested edit form and the function call to work.
My html code:
<div editable-select="vm.selectedUser"
e-ng-options="user.objectId as user.displayName for user in vm.users"
onshow="vm.getUsers()"
onaftersave="vm.addUser()">
<div class="container" ng-repeat="u in entity.authorizedUsers">
<div class="row">
<div class="col-xs-2">
{{u.id}}
</div>
<div class="col-xs-4">
<div editable-select="vm.selectedOperation"
e-ng-options="operation.id as operation.name for operation in vm.operations"
onshow="vm.getOperations()"
onaftersave="vm.addOperation()">
<div class="container" ng-repeat="op in u.authorizedOperations">
<div class="row">
<div class="col-xs-3">
{{op.name}}
</div>
<div class="col-xs-push-2">
<button class="btn btn-xs btn-danger"
ng-click="vm.removeOperation(entity.id, u.id, op.id)">
<i class="fa fa-trash-o"></i>
</button>
</div>
</div>
</div>
</div>
</div>
<div class="col-xs-push-4">
<button class="btn btn-xs btn-warning pull-left"
ng-click="vm.removeuser(entity.id, u.id)">
<i class="fa fa-trash-o"></i>
</button>
</div>
</div>
</div>
</div>
I've manage to fix the problem with the following code. It's an ugly workaround tho, please if someone has a more elegant solution I'd very much appreciate it.
in html:
<div editable-select="vm.selectedOperation"
e-form ="nestedForm"
onshow="vm.getOperations()"
ng-click="nestedForm.$show(); vm.xEditableNestedFormFix(nestedForm); $event.stopPropagation()"
e-ng-options="operation.id as operation.name for operation in vm.operations"
onaftersave="vm.addOperation()">
in js:
vm.xEditableNestedFormFix = function (form) {
var editorElement = form.$editables[0].controlsEl[0].firstChild;
editorElement.onclick = function (event) {
event.stopPropagation();
}
var submitButton = form.$editables[0].buttonsEl[0].firstChild
submitButton.onclick = function (event) {
form.$submit();
event.stopPropagation();
}
var cancelButton = form.$editables[0].buttonsEl[0].lastChild
cancelButton.onclick = function (event) {
event.stopPropagation();
}
}
I want to filter an ng-repeat, using buttons (later I will use inputs) and when I click a filter button everything disappears, and when I click the button with no filters everything keeps hidden.
I copied part of my code in this fiddle: http://jsfiddle.net/3g3L0ca8/
<div ng-app>
<a id="filter-by-date" class="btn btn-success wide-btn" href="#" ng-click="myFilter = {date: 1900-12-31}">Select by date</a>
<a id="filter-by-date" class="btn btn-success wide-btn" href="#" ng-click="myFilter = null">All the events</a>
<div ng-controller="Test">
<div class="events-right-bar scrollable-content" id='hideshow' value='hide/show'>
<section ng-repeat="event in events | orderBy:'date' | filter:myFilter">
<div class="panel panel-default single-event">
<div class="panel-heading">
<h3>
<button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#dialogTestDialog{{$index}}">{{event.title}}</button>
<em class="pull-right">Created by user: {{event.username}}</em>
</h3>
</div>
<div class="panel-body">
Description:<br>{{event.description}} <br>
<em class="pull-right">{{event.date | date:'dd-MM-yyyy' }} - {{event.hour | date:"H:mm"}}</em> <br>
{{event.duration}} minutes <br>
</div>
</div>
</div>
</div>
</section>
</div>
</div>
In the fiddle when I press the filter by date everything disappears too, I think it could by by the date format, but I'm not sure.But in the fiddle when I click no filter button everything appears again, in my project the no filter button does nothing.
I solved the no filter button changing the "myFilter:null" by "myFilter:''"
Now I only have to solve the date problem, and I keep thinking it is a format problem.
edit: as I expected it was a format error. Even when the date is displayed as dd-MM-yyy it seems that in the filter it must be written yyyy-MM-dd. So the date I was trying as 27-11-2015 was wrong, it works writing it as 2015-11-27
Now it works
I'm trying to implement a shortlisting functionality in a case where I'm using ng-click inside ng-repeat.
While the $index is being displayed correctly outside the ng-click, $index is only the index of the last object in the JSON array in all the cases where the html is generated using ng-repeat.
I was expecting the respective venue or venue.id to be passed as an argument to shortlistThis(). I'm guessing that this could be an issue related to event binding.
Can someone help me understand what's going wrong here and probably a better way to do this if possible.
I did try checking this Bind ng-model name and ng-click inside ng-repeat in angularjs The fiddle here works just fine but, mine doesn't.
Update: I've found something interesting here. When the shortlist button is placed just under the ng-repeat, it work just as intended. But when, nested inside a div with a ng-class, it isn't working as intended. Can anyone explain and suggest a fix for this ?
//locationsapp.js var locationsApp = angular.module('locationsApp', []);
var venues = [{
id: "Flknm",
name: "ship",
}, {
id: "lelp",
name: "boat",
}, {
id: "myp",
name: "yacht",
}, ];
var shortlistedVenues = [];
var locationsApp = angular.module('locationsApp', ['ui.bootstrap']);
locationsApp.controller("getvenues", function($scope) {
$scope.venues = venues;
$scope.shortlistThis = function(venue) {
console.log(venue);
if (shortlistedVenues.indexOf(venue) == -1) {
shortlistedVenues.push(venue);
//alert('If');
} else {
console.log('already shortlisted')
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="locations" ng-app="locationsApp">
<div ng-controller="getvenues">
<div ng-repeat="venue in venues" ng-mouseover="" class="venue">
<div ng-controller="manageInfo">
<div class="row-fluid">
<div class="control" ng-click="showInfo()">
</div>
<div class="maps" class="info">
<div ng-class="class">
<div class="close-info" ng-click="hideInfo()">
<i class="fa fa-times">
</i>
</div>
<div class="row full-venue-contents" ng-app="ui.bootstrap.demo">
<div class="">
<div class="row-fluid myclass">
<div class="button-holder">
<div class="row-fluid">
<div class="col-md-4 col-xs-4 text-center btn-grid">
<button type="button" class="btn btn-default btn-lg btn-sup" ng-click="shortlistThis(venue)">
Shortlist{{$index}}
</button>
</div>
</div>
</div>
</div>
</div>
<!-- End of Full Info Container -->
</div>
</div>
</div>
</div>
<div class="compare">
<button type="button" class="btn btn-default btn-lg btn-sup">
Compare ( {{shortlistedVenues.length}} )
</button>
</div>
</div>
</div>
</div>
</div>
The problem is with your button div which was position: fixed, it is actually showing the 1st button but clicking on it firing last button click, I'd suggest you should suggest you render only the shortlist button which has been selected by you. For that you can use ng-if and render those button which index is the same as that of selected $index
HTML
<div ng-if="selected==$index" class="button-holder">
<div class="row-fluid">
<div class="col-md-4 col-xs-4 text-center btn-grid">
<button type="button" class="btn btn-default btn-lg btn-sup"
ng-click="shortlistThis($parent.$index)">Shortlist{{$index}}</button>
</div>
</div>
</div>
& then put ng-click="selected='$index'" on ng-repeat div like
<div ng-repeat="venue in venues" class="venue" ng-click="selected=$index">
Working Fiddle
Hope this could help you, Thanks.