AngularJS ng-show when some value is true - javascript

I want to display one symbol (🗸) when one or more of the values in a scope ($filter.producers) is set to true, and another one (X) when all the values are false. I am trying to do show with ng-show, but I cannot find the way to make it work.
My html goes like this:
<div ng-app="myApp" ng-controller="Ctrl">
{{ctrlTest}}
<span ng-show="filter.producers == false">X</span>
<span ng-show="filter.producers != false">🗸</span>
<hr/>
<div ng-repeat="elements in filter">
<div>
<li ng-repeat="(key,value) in filter.producers" ng-show="value">{{key}}
<a ng-click="filter.producers[key]=false"> X</a>
</li>
</div>
{{filter.producers}}
</div>
</div>
And my controller:
angular.module('myApp', [])
.controller('Ctrl', function($scope) {
$scope.ctrlTest = "Filters";
$scope.filter = {
"producers": {
"Ford": true,
"Honda": true,
"Ferrari": true
}
}
});
Here is a working plunker
Thanks in advance!

The value of filter.producers in your case, is this object: {"Ford": true, ..}. It certainly will not equals to true or false! If I get you question correctly, what you should do is plucking all it's value and check if any of these value is true or false, something like this:
//In your controller
$scope.anyProducerTrue = function() {
var anyTrue = false;
angular.forEach($scope.filter.producers, function(value, key) {
if (true == value) anyTrue = true;
});
return anyTrue;
}
//In your view
<span ng-show="!anyProducerTrue()">X</span>
<span ng-show="anyProducerTrue()">🗸</span>

you need another function to check all properties are true or false initially and when click (X) link to set false for a specific property and do not need two ng-repeat in your DOM. you can try my solution.
like:
your controller:
angular.module('myApp', [])
.controller('Ctrl', function($scope) {
$scope.ctrlTest = "Filters";
$scope.filter = {
"producers": {
"Ford": true,
"Honda": true,
"Ferrari": true
}
};
$scope.hideMe = function(key) {
$scope.filter.producers[key]=false;
$scope.checkAllproperty(); // call again to check all property
};
$scope.checkAllproperty = function() {
var allTrue = false;
for(var key in $scope.filter.producers) {
if($scope.filter.producers[key] === true){
allTrue = true;
}
}
$scope.allTrue = allTrue;
};
$scope.checkAllproperty(); // initial call when loaded
});
in html: call a hideMe function to set false
<div ng-app="myApp" ng-controller="Ctrl">
{{ctrlTest}}
<span ng-show="!allTrue">X</span>
<span ng-show="allTrue">🗸</span>
<p>
{{filter.brewers}}
</p>
<hr/>
<div>
<div>
<li ng-repeat="(key,value) in filter.producers" ng-show="value">{{key}}
<a ng-click="hideMe(key)"> X</a> // call to set this key false
</li>
</div>
{{filter.producers}}
</div>
</div>

use
Object.keys(filter.producers).length;
<span ng-show="Object.keys(filter.producers).length != 0">🗸</span>
JSBIN

you can use the JS Array.prototype.some function in your controller as follows:
$scope.flag = Object.keys($scope.filter.producers).some(
function(el) {
return $scope.filter.producers[el];
});
and in your HTML use the flag as follows:
<span ng-show="!flag">X</span>
<span ng-show="flag">🗸</span>

Related

reuse function in angularjs

I've this easy code that works fine.
html snippet:
<div class="iconbar" ng-controller="icons">
<span ng-click="iconclk()">icon</span>
<div ng-if="icon1">value</div>
</div>
and the js:
app.controller('icons', function($scope)
{
$scope.icon1 = false;
$scope.iconclk = function(){
if(!$scope.icon1) $scope.icon1 = true;
else $scope.icon1 = false;
};
});
now the problem is that i wont to pass icon1 as a parameter in iconclk to use the same function with multiple icons (icon1,icon2,icon3...)
I've tried this:
html:
<div class="iconbar" ng-controller="icons">
<span ng-click="iconclk(icon1)">icon</span>
<div ng-if="icon1">value</div>
</div>
and the js:
app.controller('icons', function($scope)
{
$scope.icon1 = false;
$scope.iconclk = function(icon){
if(!icon) icon = true;
else icon = false;
};
});
But doesn't work. some help please? thanks in advance!
The main problem is that you're passing by value, so modifying icon will not change icon1. Instead, I would change your icon variables to an array and reference by index:
<div class="iconbar" ng-controller="icons">
<span ng-click="iconclk(1)">icon</span>
<div ng-if="icon[1]">value</div>
</div>
Others will be iconclk(2)&icon[2], iconclk(3)&icon[3], and so on...
Controller:
app.controller('icons', function($scope) {
$scope.icon = [false, false, false]; // or just [] if you want it to be simple
$scope.iconclk = function(icon) {
$scope.icon[icon] = !$scope.icon[icon];
};
});

How to get a type of scope variable in Angular expression?

Let's define simple boolean on the scope:
var mymodal = angular.module('mymodal', []);
mymodal.controller('MainCtrl', function ($scope) {
$scope.b = false;
});
How can I get type of a variable in the expression? typeOf and Object.prototype.Tostring.call don't work.
<div ng-controller="MainCtrl" class="container">
<div>
{{ b }}
{{ typeOf(b) }}
{{ Object.prototype.toString.call(b) }}
</div>
</div>
Here's JSFiddle: http://jsfiddle.net/g8Ld80x3/2/
i think the best way is to create a custom filter and use it as you wish within you expression, you can check this link that use for get the Object.keys of an object
for your case you can use
angular.module('customfilter', []).filter('typeof', function() {
return function(obj) {
return typeof obj
};
});
Just to show Zamboney's answer applied to my sample code:
Controller:
angular.module('customfilter', []).filter('getType', function() {
return function(obj) {
return typeof obj
};
});
var mymodal = angular.module('mymodal', ['customfilter']);
mymodal.controller('MainCtrl', function ($scope) {
$scope.b = false;
});
View:
<div ng-controller="MainCtrl" class="container">
<div>
{{ b }}
{{ b | getType }}
<div ng-if="(b | getType) == 'number'">
It's a number
</div>
<div ng-if="(b | getType) == 'boolean'">
It's a boolean
</div>
</div>
</div>
And fiddle: http://jsfiddle.net/g8Ld80x3/5/
You can't do it and for the good reason: Angular expression parser disallows such sort of things in the templates.
If you really want to be able to do so, I recommend to explicitly set helper methods on the $rootScope so it will be available in all your templates:
mymodal.run(function($rootScope) {
$rootScope.typeOf = function(value) {
return typeof value;
};
});
You can even reference Angular own utility methods:
mymodal.run(function($rootScope) {
['isArray', 'isDate', 'isDefined', 'isFunction', 'isNumber', 'isObject', 'isString', 'isUndefined'].forEach(function(name) {
$rootScope[name] = angular[name];
});
});
and use {{ isArray(arr) }} in templates.
Try something like this in the controller(I don't think is possible directly in the expression as you want to do):
var mymodal = angular.module('mymodal', []);
mymodal.controller('MainCtrl', function ($scope) {
$scope.b = false;
$scope.getBType = function(test){
return( typeof test);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='mymodal' ng-controller="MainCtrl" class="container">
<div>
{{ getBType(b) }}
</div>
</div>
As you are trying to access the type typeof of the specific value and in the current code you are doing this in the view which is quite late for such operation.
Instead you can make a function in the controller's scope and just return it from there:
var mymodal = angular.module('mymodal', []);
mymodal.controller('MainCtrl', function ($scope) {
$scope.b = false;
$scope.getTypeof = function(it){ return typeof(it); };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='mymodal' ng-controller="MainCtrl" class="container">
<div>
{{ b }} : {{ getTypeof(b) }}
</div>
</div>
HTML
<div ng-controller="MainCtrl" class="container">
<div>
{{ b }}<br>
{{ typeOf(b) }}<br>
</div>
</div>
JS
var mymodal = angular.module('mymodal', []);
mymodal.controller('MainCtrl', function ($scope) {
$scope.b = false;
$scope.typeOf = function (v){ return (typeof v)};
});
RESULT
false
boolean
$scope.b = new String('name');
// according to the above statement, the object will be the result of the typeof operator. It does not check the type of the typeof operator: http://bonsaiden.github.io/JavaScript-Garden/#types.typeof

get element from DOM

hello i'm trying to get element from the DOM in angular directive.
this element:
click image
i'm trying to get this element by unknow id this is the code:
pass user object:
<dashboard user="user" action="pageSelect(name,pageNumber)"></dashboard>
in templateUrl directive:
<section>
<li id="Dashboard{{$index}}" ng-repeat="dashboard in user.NavigationMenu">
<h3 class="PovDashboard">
<i class="fa fa-tachometer"></i>
{{dashboardName}}
</h3>
<ul class="povPages">
<li ng-repeat="page in dashboard.Pages"> <i class="povIconRight fa fa-angle-double-right"></i></li>
</ul>
</li>
and this is the problem:
scope.$watch('user', function(newValue) {
if (newValue !== undefined) {
console.log(scope.user.NavigationMenu[0].Pages);
var defaultDashboard = scope.user.DefaultDashboardID;
console.log(scope.user);
angular.forEach(scope.user.NavigationMenu,function(value,key){
if(value.ID === defaultDashboard){
console.log(key);
// i tried everything
var s = '#Dashboard' + key;
var e = angular.element.find(s)
//e is empty
console.log(e);
//i'm trying to do
//e.('.povPages').first().css("display","block");
}
})
}
});
thanks in advance
You are not using the jqLite wrapper angular.element() syntactically correct, i guess you should try with this:
angular.element(s).find('ul').css('display', 'block');
If you are not using jQuery then .find() will have a lookup at tagnames only.
From the docs:
find() - Limited to lookups by tag name
Or better do it with angular way with ng-show/ng-hide:
<ul class="povPages" data-ng-show='isVisible'>
initialize $scope.isVisible = false;now in the .$watch() do this:
scope.$watch('user', function(newValue) {
if (newValue != undefined) {
console.log(scope.user.NavigationMenu[0].Pages);
scope.isVisible = newValue != undefined ? true : false;
console.log(scope.user, scope.isVisible);
}
});
A sample demo:
angular.module('demoapp', []).controller('demoCtrl', ['$scope', '$timeout',
function($scope, $timeout) {
$scope.arr = [{
text: "one"
}, {
text: "two"
}];
$scope.isVisible = false;
$timeout(function() {
$scope.isVisible = true;
}, 2000);
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app='demoapp' ng-controller='demoCtrl'>
<div ng-repeat="obj in arr">
<h1>see if list is visible == {{isVisible}} {{obj.text}}</h1>
<ul ng-show='isVisible'>
<li>should be visible after value change. {{obj.text}}</li>
</ul>
</div>
</div>

How to access a key of an object by its variable name in DOM using angular

I have a controller which adds to scope a variable called comments
$scope.showComments = function(id){
dataService.getComments(id).then(function(data){
$scope.comments[id] = data.comments;
console.log($scope.comments);
});
}
I want to call the ng-repeat on a specific id. The following method is not working. Any ideas?
<div class="commentsContainer" id="{{id}}">
<div class="eachcomment" ng-repeat="comment in comments.{{id}}">
<p>{{comment.content}}
</div>
</div>
The desired id is given to the outer div. But ng-repeat is not working.
You should use a filter to achieve this functionality as follows:
<div class="eachcomment" ng-repeat="comment in comments | filterId: id">
<p>{{comment.content}}
</div>
Now, write a filter:
app.filter('filterId', function(){
return function(collection, id) {
var output = [];
angular.forEach(collection, function(item) {
if(item.id == id) {
output.push(item)
}
})
return output;
}
})
Or you can use an easier way:
<div class="eachcomment" ng-repeat="comment in comments | filter: checkId">
<p>{{comment.content}}
</div>
And in your controller:
$scope.checkId = function(item) {
if($scope.id == item.id) {
return true;
}
return false;
}
You can do that with:
<div ng-app="myApp" ng-controller="dummy">
<div class="commentsContainer" id="{{id}}">
<div class="eachcomment" ng-repeat="(key, comment) in comments">
<p ng-show="key === id">{{comment.content}}</p>
</div>
</div>
</div>
JS:
angular.module('myApp', [])
.controller('dummy', ['$scope', function ($scope) {
$scope.id = 0;
$scope.comments = [{
content: 'Hello'
}, {
content: 'World'
}];
}]);
JSFiddle
You should use bracket notation to access property by variable key:
<div class="commentsContainer" id="{{id}}">
<div class="eachcomment" ng-repeat="comment in comments[id]">
<p>{{comment.content}}
</div>
</div>

AngularJS : How to change a value in all items in an ng-repeat

I have a data model that comes in, by default I give the first ticker a selected status of true.
Now when a user clicks another item, I need to efficiently deselect all the others and set the selected value to true for the item clicked:
<li class="ticker-li"
ng-repeat="ticker in tickers"
ng-hide="ticker.removed"
ng-class="{'selected':ticker.selected}"
ng-mouseleave="hideTickerOptions()">
<div class="ticker"
ng-click="unselectAll(); ticker.selected = !ticker.selected;
selectTicker(ticker);">
{{ticker.ticker}}
</div>
</li>
Tried a forEach function here, but with the error [object Array] is not a function:
var vs = $scope;
vs.unselectAll = function() {
vs.tickers.forEach(vs.tickers, function(ticker) {
ticker.selected = false;
});
};
A regular for-loop will work, but is it an efficient way to toggle all the selected values to false?
for (var i = 0; i < vs.tickers.length; i++) {
vs.tickers[i].selected = false;
}
My thinking here is run this unselectAll function to deselect everything, then the next code in the markup which select the current item:
<div class="ticker"
ng-click="unselectAll(); ticker.selected = !ticker.selected;
selectTicker(ticker);">
{{ticker.ticker}}
</div>
I tried to do it using radio inputs.
var app = angular.module('AppForm', []);
app.controller('ctrForm', function ($scope) {
$scope.choices = [
{ id: 'Choice1', check: false },
{ id: 'Choice2', check: false },
{ id: 'Choice3', check: false },
{ id: 'Choice4', check: false },
{ id: 'Choice5', check: false },
{ id: 'Choice6', check: false },
{ id: 'Choice7', check: false }
];
$scope.setDefault = function (item) {
angular.forEach($scope.choices, function (p) {
p.check = false; //set them all to false
});
item.check = true; //set the clicked one to true
};
});
.selected {
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div ng-app="AppForm" ng-controller="ctrForm">
<ul>
<li style="list-style:none" ng-class="{'selected':item.check}" ng-repeat="item in choices"><input type="radio" name="group" ng-model="item.check" ng-click="setDefault(item)" value="true" />{{item.id}}...{{item.check}}</li>
</ul>
</div>
The foreach wouldn't be less efficient than anything angular could do 'for free'. Either way it'll have to set the others as unselected..
What'd I'd propose instead would be to have a single thing "selectedItem" and a set of things "items".
then you can 'say'
<li class="ticker-li"
ng-repeat="ticker in tickers"
ng-hide="ticker.removed"
ng-class="{'selected':ticker == selectedTicker}"
ng-mouseleave="hideTickerOptions()">
<div class="ticker" ng-click="selectedTicker = ticker">
{{ticker.ticker}}
</div>
</li>
you could then access selectedTicker to get it's properties
<div>{{selectedTicker.name}}</div>
If your set on using ticker.selected, you can use a jquery .each loop to unselect all of them.
$scope.selectTicker = function(ticker)
{
//deselect all tickers
$.each(tickers, function() { this.selected = false; });
//select the ticker you passed in
ticker.selected = true;
}
and in your view:
<div class="ticker"ng-click="selectTicker(ticker);">
{{ticker.ticker}}
</div>

Categories

Resources