Protractor ng-if condition and element availability - angularjs

I want to check whether element displayed or not depends upon ng-if condition,
<div id="discount_percent" ng-if="data.isDiscount">
<div id="dis_available"> Discount: {{data.discount}} % </div>
</div>
I want to check if data.isDiscount is true than div "discount_percent" & dis_available should display.
Note: div "discount_percent" and "dis_available" won't be present in DOM if data.isDiscount is false.
I did following way, but I'm not fully satisfied with my solution.
var discountPercentId = element(by.id('discount_percent'));
discountPercentId.isPresent().then(function (present){
if(present){
expect(discountPercentId.evaluate("data.isDiscount")).toBeTruthy();
expect(discountPercentId.element(by.id("dis_available")).isDisplayed()).toBeTruthy();
}
});
Any better approach to do? If condition true than check its availability!!!

try this:
var elem = element(by.css('[ng-if="data.isDiscount"]'));
elem.isPresent().then(function(fnct){
if(fnct){
//do whatever
}
else{
//do something else
}
});
also, I am not sure, but you might want to get the value of data.IsDiscount first. You can get the value of this with the following function:
elem.getAttribute('value').then(function(value) {
//do something with the value
});

Related

Ng-show or ng-if condition if a date equals one of multiple dates in an array

With AngularJS, I'm trying to use ng-show or ng-if in such a way that if today equals one of multiple dates in an array, it should show a specific div. Is there any way to do something such as:
<div ng-show="dateFlag in datesToTrigger">It worked!</div>
or
<div ng-if="dateFlag in datesToTrigger">It worked!</div>
To achieve this you need to write a custom function that will check for your date whether it exists in the array and return boolean value based on the result.
$scope.checkExists = function () {
if(array.includes("yourString")
{
return true;
}
return false;
}
and in template
<div ng-if="checkExists()">It worked!</div>

Why does not hide element ng-hide?

I need to hide element if value is zero. I tried:
<span ng-hide="currentCount.appointment == 0">{{currentCount.appointment}}</span>
In console.log(currentCount.appointment) I see that after changes value of currentCount.appointment is zero, but why span block does not hide?
Full code:
request.success(function () {
$scope.currentCount = CounterNotificationService.setCounterInc('appointment', 'decr');
console.log($scope.currentCount.appointment);
});
seems to work,
{{currentCount.appointment == 0}}
evaluates to
true
i created a fiddle with the ng-hide and the ng-class approach
Try this:
<span ng-hide="currentCount.appointment == '0'">{{currentCount.appointment}}</span>

Make a negative number appear positive, but maintain actual value

I'm going out on a whim here, but I figured I'd ask here to check.
I have an integer value that I use to determine how other elements on the page act, the actual value of the integer is important (whether it is negative or positive), however actually displaying the prefixed hyphen when it's negative isn't desired.
Is there any way to "hide" the hyphen without altering the actual value of the integer? Keeping in mind that the value is being $watched so multiplying it by -1 is out of the question.
Template:
<p>{{ value }}</p>
Directive:
scope.$watch('value', function()
{
if (scope.value > 0)
{
//do something
}
else
{
//do something else
}
});
Added code, not that I believe it's really necessary
you can use filter
.filter('positive', function() {
return function(input) {
if (!input) {
return 0;
}
return Math.abs(input);
};
})
so in your template use
{{value | positive}}
Pass it through a function like this:
View
<p>{{ positiveLookingValue() }}</p>
Controller
$scope.positiveLookingValue = function(){
return Math.abs($scope.value);
}

Execute different Event on First and second click angular js

I have a situation where i need to execute different event on first and second click on div.
On first click div will be expanded and in second click it will be redirected to it's detail page. Div contains details of post.
<div ng-click="select(comment._id);"
ng-dblclick="changeurl(user.username,data.type,comment._id)"
enter ng-repeat="user in data.user">
Till now i was expanding div on first click and then on double click i was redirecting it to it's detail page.
what would be the best way to do it.
right now my idea is to make a counter on ng-click and then execute event.
can we execute it on the DOM End.
<div ng-click="counter = counter + 1" ng-repeat="user in data.user" ng-init="counter = 0" >
is there any other directive where i can execute select(comment._id) changeurl(user.username,data.type,comment._id) conditionally or how can i call these functions conditionally ?
Update: on Diana advice here is updated status:
Here i have no of div's coming from ng-repeat, here i have two type of layouts which are displayed according to data.
<div ng-repeat="data in comments">
<div ng-if="data.type=story">
<div ng-click="clickEvent($index,comment._id, user.username,data.type);" enter ng-repeat="user in data.user">
//displaying data here
</div>
</div>
<div ng-if="data.type=news">
<div ng-click="clickEvent($index,comment._id, user.username,data.type);" enter ng-repeat="user in data.user">
//displaying data here
</div>
</div>
</div>
$scope.secondClick = [];
//scope data
myservice.data().then(function(response){
$scope.comments = response.data;
for (i=0; i< $scope.comments.length;i++){
$scope.secondClick[i] = false;
}
});
$scope.clickEvent = function(index,id, userName, type){
if(!$scope.secondClick[index]){
// Execute first-click logic (call select function with the id).
$scope.secondClick[index] = true;
}
else{
// Execute second-click logic (call changeurl function with the id, userName, and type).
}
}
I tried providing index to function and manipulate them. Because of nested ng-repeat i am getting index '0'. .
UPDATE2:
I tried to understand your setup from the question and came up with a full working demo accordingly. I hope this works for your case!
http://plnkr.co/edit/ARsDpRH7orzZQLU1pin1
Please let me know how this goes.
/////////////////////////////////////
You could have some boolean variable that is initially set to false, say $scope.secondClick - when you click the button the first time set it to true. When clicking it the next time the variable is true so you execute the "second click" logic.
Something like:
<div ng-click="clickEvent(comment._id, user.username,data.type);" enter ng-repeat="user in data.user">
In your controller, define:
$scope.secondClick = false;
$scope.clickEvent = function(id, userName, type){
if(!$scope.secondClick){
// Execute first-click logic (call select function with the id).
$scope.secondClick = true;
}
else{
// Execute second-click logic (call changeurl function with the id, userName, and type).
}
}
UPDATE:
Given that you have more than one div, we can tweak the solution a bit by having an array of boolean values in the scope and passing the index to know which is which:
<div ng-click="clickEvent($index, comment._id, user.username,data.type);" enter ng-repeat="user in data.user">
In the controller:
$scope.secondClicks = [];
//Initialize all values to false, based on the number of divs.
for(var i = 0; i<NoOfDivs; i++){
$scope.secondClicks[i] = false;
}
$scope.clickEvent = function(index, id, userName, type){
if(!$scope.secondClicks[index]){
// Execute first-click logic (call select function with the id).
$scope.secondClicks[index] = true;
}
else{
// Execute second-click logic (call changeurl function with the id, userName, and type).
}
}
Let us know if this works please. If someone has a neater solution, I'd like to check it out as well :)
I think this may be a simple way to tell JavaScript to do different things depending on the number of clicks. This example shows swapping of two different events. Basicly, I just limited the counting from 0 to 1 and made sequence circular. Ofc, you can make more than just two. I think the advantige of this is that is circular, so the user may navigate freely (first he expands something, than he shrinks it back, than he expands it again etc...). Maybe by following this principle you will solve your code.
<!DOCTYPE html>
<head>
<style>
#division {background-color: red;color: white;width: 10%;height: 20%;position: fixed;top: 10%;left: 10%;-webkit-transition: 1s;-moz-transition: 1s;-ms-transition: 1s;-o-transition: 1s;transition: 1s;}
#division:hover {background-color: blue;cursor: pointer;}
</style>
</head>
<body>
<script type="text/javascript">
var clicks = 0;
function onClick() {
clicks += 1;
if (clicks != 1) {
clicks = 0;
};
if (clicks == 1) {
document.getElementById("division").style.left = 30+'%';
}else {
document.getElementById("division").style.left = '10%';
};
};
</script>
<div onClick="onClick()"><a id="division">Click me Twice!</a></div>
</body>
</html>
I did this by putting post id in cookie. On first click that post's id is stored in cookie and if user click again it is founded in cookie store second click action is triggered. Hence we do action on first and second click.
$scope.clickEvent = function(id,name,type){
var favoriteCookie = $cookieStore.get('divonclick');
$cookieStore.put('divonclick',id);
if(favoriteCookie == id){
//second click action
}else{
//first click action
}
}
Try This:
In html div:
ng-init="count=0"
ng-click="select(count)(count=count+1);"
In JS:
$scope.select = function(count) {
if(count%2 == 0 ) {
here write your SECOND click functionality.
} else {
here write your FIRST click functionality.
}
}

setTimeout with loop issue with field update

I'm trying to loop through a list on a timer (currently 1 second but I want it faster). The problem is that the current value isn't being updated visually & I can't see why.
When I loop through with Firebug it works as intended but without firebug it's not showing the text change...is it skipping the text update somehow?
I set the timer to 1 second; surely a .html() call wouldn't take longer? Thanks for any info.
My HTML is simply:
<div id="winner2"><h1></h1></div>
<div id="button"">
<img id="start" src="start.png" />
<img id="stop" src="stop.png" />
</div>
My JS is:
var people = ["a", "b", "c"];
var counter = 1;
var run;
$(document).ready(function(){
$("#winner2 h1").html("a");
$("#stop").hide();
$( "#start" ).click(function() {
$("#start").hide();
$("#stop").show();
run = setTimeout (nameIncrement(),1000);
});
$( "#stop" ).click(function() {
$("#stop").hide();
$("#start").show();
clearTimeout(run);
});
function nameIncrement() {
if(counter == people.length) {
counter=0;
}
$("#winner2 h1").html(people[counter]);
counter++;
run = setTimeout (nameIncrement(),1000);
}
});
You are calling nameIncrement() and passing its return value to setTimeout(), rather than passing nameIncrement.
Remove the parentheses:
run = setTimeout(nameIncrement, 1000);
jsfiddle
It looks like you are running a recursive function without defining exit condition. this probably causes overload to the browser which decided not to run the function.
Try:
function nameIncrement() {
if(counter == people.length) {
counter=0;
return;
}
$("#winner2 h1").html(people[counter]);
counter++;
run = setTimeout (nameIncrement(),1000);
}
});
on debug mode, however, the browser is less defensive, so you can see your erors yourself.

Resources