Angular ng-switch with boolean - angularjs

I want to check boolean data with angular ng-switch
this is my code. but it is not working
<div ng-switch={{Item.ItemDetails.IsNew}}>
<div ng-switch-when="true">
<p class="new fontsize9 fontWeightBold">NEW</p>
</div>
</div>
<div ng-switch={{Item.ItemDetails.IsFeatured}}>
<div ng-switch-when="true">
<div class="featured">
<p class="fontWeightBold fontsize8">featured</p>
</div>
</div>
</div>
values of {{Item.ItemDetails.IsNew}} and {{Item.ItemDetails.IsFeatured}} are true or false

Convert the boolean to a string:
<div ng-switch="Item.ItemDetails.IsNew.toString()">
<div ng-switch-when="true">

If you are just checking for true values, ng-if seems more appropriate and reduces the need for additional divs containing the code, reducing your sample too:
<div ng-if="Item.ItemDetails.IsNew">
<p class="new fontsize9 fontWeightBold">NEW</p>
</div>
<div class="featured" ng-if="Item.ItemDetails.IsFeatured">
<p class="fontWeightBold fontsize8">featured</p>
</div>
Full docs at: http://docs.angularjs.org/api/ng.directive:ngIf

This syntax works for me:
<div ng-switch="Item.ItemDetails.IsFeatured">
<div ng-switch-when="true">FEATURED ITEM HTML</div>
<div ng-switch-default>REGULAR ITEM HTML (not featured)</div>
</div>

You should remove the {{}} from the ng-switch:
Change this <div ng-switch={{Item.ItemDetails.IsNew}}>
to <div ng-switch=Item.ItemDetails.IsNew>

The attribute value of ng-switch are interpreted as literal string values to match against. (Meaning that cannot be expressions.) For example, ng-switch-when="someVal" will match against the string "someVal" not against the value of the expression $scope.someVal.
If you really have to use ng-switch, it can be forced to semi-use evaluative expressions by the workaround of the .toString() javascript method. Example, using the scope variables numeric 'lastSortIndex' and the boolean 'reverseSorted', plus the AngularJS HTML variable '$index':
<div ng-switch="((lastSortIndex === $index).toString()+(reverseSorted).toString())">
<div ng-switch-when="truetrue">
<span class="glyphicon glyphicon-chevron-up">{{ header }}</span>
</div>
<div ng-switch-when="truefalse">
<span class="glyphicon glyphicon-chevron-down">{{ header }}</span>
</div>
<div ng-switch-default>{{header}}</div>
</div>
Note the above example is concatenating the booleans together and then evaluating their string contents. Would be better to move this into a callable function that returns a string to be evaluated in the switch-case.
Though I would recommend if possible for you to keep the logic in the logic-controllers area of the code (the javascript files). You can use the ng-html-safe AngularJS directive in combination with their Sanitize feature to call a function in Javascript that switches and returns desired snippets of HTML code for you. Example:
index.html:
<html ng-app="myApp">
<head>
<script src="https://code.angularjs.org/1.3.13/angular-sanitize.js">
</head>
<body ng-controller="MainController">
<!-- add your other code, like a table code here -->
<div ng-bind-html="HeaderSortIcon(lastSortIndex, $index, reverseSorted, header)">
</div>
</body>
script.js:
var myApp = angular.module('myApp ', ['ngSanitize']);
$scope.HeaderSortIcon = function (lastSortIndex, $index, reverseSorted, header) {
if (lastSortIndex === $index) {
if( reverseSorted )
{
return '<div><span class="glyphicon glyphicon-chevron-up"></span>' + header + '</div>';
}
else{
return '<div><span class="glyphicon glyphicon-chevron-down"></span>' + header + '</div>';
}
}
else {
return header;
}
}

Related

can we have ng-show and ng-if in one div tag?

Following code snippet does not work
Please suggest any other way of doing it
<html>
`<div id="tablediv" ng-model="ngtable">
<div ng-show="ngtable">
<div ng-if="currentdevicetype == 'condition1'">
<!-- Other code to display contents -->
</div>`
</div>
</div>
</html>
Yes you can, Both are different.
ng-show
sets the display:none of the element when expression evaluates to false while ng-if removes the element from the DOM when the expression evaluates to false
Check out this question to know the differences between ng-show and ng-if & where and How to use them:
When to favor ng-if vs. ng-show/ng-hide?
In your html code , you are using something wrong, because you are using ng-model for a div .
<html>
<div id="tablediv" ng-model="ngtable">
<div ng-show="ngtable">
<div ng-if="currentdevicetype == 'condition1'">
<!-- Other code to display contents -->
</div>
</div>
</div>
</html>
ng-model is used to bind the value of any inputbox/textarea/select like tags, you can not bind any value like this:
<div id="tablediv" ng-model="ngtable">
if you remove this ng-model then your code would be like this:
<html>
<div id="tablediv">
<div ng-show="ngtable">
<div ng-if="currentdevicetype == 'condition1'">
<!-- Other code to display contents -->
</div>
</div>
</div>
</html>
Now, if ngtable have some value it means ng-show=true then
<div ng-show=true>
// all the elements are visible on the DOM.
</div>
but , if if ngtable do not have any value it means ng-show=false then :
<div ng-show=false>
// all the elements are not visible on the DOM.
</div>
And inside this code:
<div ng-if="currentdevicetype == 'condition1'">
<!-- Other code to display contents -->
</div>
if ng-if="currentdevicetype == 'condition1'" returns true then all the elements would be create, otherwise element will not be created.

angular conditionally show div in nested ng-repeat

<div class="sunti_contain" ng-repeat="sunti in suntis track by $index">
<div class="individual_sunti" ng-click="update_ancestor(sunti)">
<!--needs a unique div#id via angularz-->
<div class="sunti_content" ng-bind="sunti.content"></div>
<div class="sunti_tags" ng-bind="sunti.tags"></div>
<div class="sunti_author" ng-bind="sunti.author"></div>
<div class="sunti_shortid" ng-bind="sunti.short_id"></div>
<div class="sunti_ancestor" ng-bind="sunti.ancestor"></div>
</div>
<div class="sunti_reply_carriage_wrapper">
<div class="sunti_reply_carriage" ng-show="!sunti.descendents.length">
<div class="individual_sunti reply_carriage_sunti" ng-repeat="descendent in sunti.descendents">
<div class="sunti_content" ng-bind="descendent.content"></div>
<div class="sunti_tags" ng-bind="descendent.tags"></div>
<div class="sunti_author" ng-bind="descendent.author"></div>
<div class="sunti_shortid" ng-bind="descendent.short_id"></div>
</div>
</div>
</div>
</div>
I want to only show the div.sunti_reply_carriage if there are any descendents rendered in the ng-repeat. If there are no descendents, I don't want the div sunti_reply_carriage to appear at all. However, the ng-show="!sunti.descendents.length" does not work, presumably because it's just outside/before the ng-repeat that references descendents in sunti.descendents
How can I do this?
ng-show="!sunti.descendents.length"
Above code does not show the following code block if length is greater than zero
Ex: If sunti.descendents.length is 1 then
!1 is false then ng-show="false"
If sunti.descendents.length is 0 then !0 is true then ng-show="true"
So, change the expression to ng-show="sunti.descendents.length"
You can use ng-if as well if you want to completely remove the code block from DOM if the expression evaluates to false.
<div class="sunti_reply_carriage" ng-show="!sunti.descendents.length">
<div class="individual_sunti reply_carriage_sunti" ng-repeat="descendent in sunti.descendents">
<div class="sunti_content" ng-bind="descendent.content"></div>
<div class="sunti_tags" ng-bind="descendent.tags"></div>
<div class="sunti_author" ng-bind="descendent.author"></div>
<div class="sunti_shortid" ng-bind="descendent.short_id"></div>
</div>
</div>
You can use sunti.descendents.length instead of !sunti.descendents.length
If length property returns 0 then it will be hidden because it is falsey value in JavaScript, if it will return some value i.e. a number then it will be shown because it is truthy value in JavaScript.
If you want to show or hide you can use ng-show or ng-hide directives, if you want to completely remove/insert the DOM conditionally then you can use the ng-if directive in this case.
Using the ng-show directive
<div class="sunti_reply_carriage_wrapper">
<div class="sunti_reply_carriage" ng-show="sunti.descendents.length">
<!-- code omitted for brevity -->
</div>
</div>
Using the ng-if directive
<div class="sunti_reply_carriage_wrapper">
<div class="sunti_reply_carriage" ng-if="sunti.descendents.length">
<!-- code omitted for brevity -->
</div>
</div>

AngularJS - Display Banner after 2 rows, followed by another 2 Rows

I'm trying to display a Banner <div> after 2 rows of 4 x "col-md-3", followed by another 2 Rows - so the resulting markup would look like:
<div class="col-md-3">1</div>
<div class="col-md-3">2</div>
<div class="col-md-3">3</div>
<div class="col-md-3">4</div>
<div class="col-md-3">5</div>
<div class="col-md-3">6</div>
<div class="col-md-3">7</div>
<div class="col-md-3">8</div>
<div class="col-md-12" id="Banner">Banner</div>
<div class="col-md-3">9</div>
<div class="col-md-3">10</div>
<div class="col-md-3">11</div>
<div class="col-md-3">12</div>
<div class="col-md-3">13</div>
<div class="col-md-3">14</div>
<div class="col-md-3">15</div>
<div class="col-md-3">16</div>
Trying to simulate this using AngularJS so would have to use ng-repeat - but cannot seem to get this working. Any help appreciated: My Plunker
<div ng-repeat="n in Numbers">
<div class="col-md-3">{{n}}</div>
</div>
There are just a couple of problems with your plunker. First maincontroller.js is missing the .js extension, so it is never loaded.
Next all of the references to load angular should start with https instead of just http.
To display the banner after a certain number of rows place it within the first div and use something like:
<div class="col-md-12" id="Banner" ng-if="$index==5">Banner</div>
Not sure if 5 is the number you want there or if you want to use some kind of expression to see if ng-if is divisible by a certain value, but using $index and ng-if should get you there.
You could use ng-repeat-start and ng-include with a ng-if to conditionally include the banner if it's at the correct index with n===8.
Please have a look at the code below or in this plunkr.
angular.module("app", [])
.controller("MainController", mainController);
function mainController($scope) {
$scope.Numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="container" ng-controller="MainController" ng-app="app">
<h1>Demo</h1>
<div class="col-md-3" ng-repeat-start="n in Numbers">{{n}}</div>
<div ng-include="'banner.html'" ng-if="(n === 8)" ng-repeat-end></div>
<script type="text/ng-template" id="banner.html">
<div class="col-md-12" id="Banner">Banner</div>
</script>
</div>

Angular.js ng-switch-when not working with dynamic data?

I'm trying to get Angular to generate a CSS slider based on my data. I know that the data is there and am able to generate it for the buttons, but the code won't populate the ng-switch-when for some reason. When I inspect the code, I see this twice (which I know to be correct as I only have two items):
<div ng-repeat="assignment in assignments" ng-animate="'animate'" class="ng-scope">
<!-- ngSwitchWhen: {{assignment.id}} -->
</div>
My actual code:
<div ng-init="thisAssignment='one'">
<div class="btn-group assignments" style="display: block; text-align: center; margin-bottom: 10px">
<span ng-repeat="assignment in assignments">
<button ng-click="thisAssignment = '{{assignment.id}}'" class="btn btn-primary">{{assignment.num}}</button>
</span>
</div>
<div class="well" style="height: 170px;">
<div ng-switch="thisAssignment">
<div class="assignments">
<div ng-repeat="assignment in assignments" ng-animate="'animate'">
<div ng-switch-when='{{assignment.id}}' class="my-switch-animation">
<h2>{{assignment.name}}</h2>
<p>{{assignment.text}}</p>
</div>
</div>
</div>
</div>
</div>
EDIT: This is what I'm trying to emulate, though with dynamic data. http://plnkr.co/edit/WUCyCN68tDR1YzNnCWyS?p=preview
From the docs —
Be aware that the attribute values to match against cannot be expressions. They are
interpreted as literal string values to match against. For example, ng-switch-when="someVal"
will match against the string "someVal" not against the value of the expression
$scope.someVal.
So in other words, ng-switch is for hardcoding conditions in your templates.
You would use it like so:
<div class="assignments">
<div ng-repeat="assignment in assignments" ng-animate="'animate'">
<div ng-switch="assignment.id">
<div ng-switch-when='1' class="my-switch-animation">
<h2>{{assignment.name}}</h2>
<p>{{assignment.text}}</p>
</div>
</div>
</div>
Now this might not fit your use case exactly, so it's possible you'll have to rethink your strategy.
Ng-If is probably what you need — also, you need to be aware of "isolated" scopes. Basically when you use certain directives, like ng-repeat, you create new scopes which are isolated from their parents. So if you change thisAssignmentinside a repeater, you're actually changing the variable inside that specific repeat block and not the whole controller.
Here's a demo of what you're going for.
Notice I assign the selected property to the things array (it's just an object).
Update 12/12/14: Adding a new block of code to clarify the use of ng-switch. The code example above should be considered what not to do.
As I mentioned in my comment. Switch should be thought about exactly like a JavaScript switch. It's for hardcoded switching logic. So for instance in my example posts, there are only going to be a few types of posts. You should know a head of time the types of values you are going to be switching on.
<div ng-repeat="post in posts">
<div ng-switch on="post.type">
<!-- post.type === 'image' -->
<div ng-switch-when="image" class="post post-image">
<img ng-src="{{ post.image }} />
<div ng-bind="post.content"></div>
</div>
<!-- post.type === 'video' -->
<div ng-switch-when="video" class="post post-video">
<video ng-src="{{ post.video }} />
<div ng-bind="post.content"></div>
</div>
<!-- when above doesn't match -->
<div ng-switch-default class="post">
<div ng-bind="post.content"></div>
</div>
</div>
</div>
You could implement this same functionality with ng-if, it's your job to decide what makes sense within your application. In this case the latter is much more succinct, but also more complicated, and you could see it getting much more hairy if the template were any more complex. Basic distinction is ng-switch is declarative, ng-if is imperative.
<div ng-repeat="post in posts">
<div class="post" ng-class="{
'post-image': post.type === 'image',
'post-video': post.type === 'video'">
<video ng-if="post.type === 'video'" ng-src="post.video" />
<img ng-if="post.type === 'image'" ng-src="post.image" />
<div ng-bind="post.content" />
</div>
</div>
Jon is definitely right on. Angular does not support dynamic ngSwitchWhen values. But I wanted it to. I found it actually exceptionally simple to use my own directive in place of ngSwitchWhen. Not only does it support dynamic values but it supports multiple values for each statement (similar to JS switch fall-throughs).
One caveat, it only evaluates the expression once upon compile time, so you must return the correct value immediately. For my purposes this was fine as I was wanting to use constants defined elsewhere in the application. It could probably be modified to dynamically re-evaluate the expressions but that would require more testing with ngSwitch.
I am use angular 1.3.15 but I ran a quick test with angular 1.4.7 and it worked fine there as well.
Plunker Demo
The Code
module.directive('jjSwitchWhen', function() {
// Exact same definition as ngSwitchWhen except for the link fn
return {
// Same as ngSwitchWhen
priority: 1200,
transclude: 'element',
require: '^ngSwitch',
link: function(scope, element, attrs, ctrl, $transclude) {
var caseStms = scope.$eval(attrs.jjSwitchWhen);
caseStms = angular.isArray(caseStms) ? caseStms : [caseStms];
angular.forEach(caseStms, function(caseStm) {
caseStm = '!' + caseStm;
ctrl.cases[caseStm] = ctrl.cases[caseStm] || [];
ctrl.cases[caseStm].push({ transclude: $transclude, element: element });
});
}
};
});
Usage
Controller
$scope.types = {
audio: '.mp3',
video: ['.mp4', '.gif'],
image: ['.jpg', '.png', '.gif'] // Can have multiple matching cases (.gif)
};
Template
<div ng-switch="mediaType">
<div jj-switch-when="types.audio">Audio</div>
<div jj-switch-when="types.video">Video</div>
<div jj-switch-when="types.image">Image</div>
<!-- Even works with ngSwitchWhen -->
<div ng-switch-when=".docx">Document</div>
<div ng-switch-default>Invalid Type</div>
<div>

Angularjs: ng-repeat + ng-switch-when != expected

The following code doesn't seem to work correctly:
<div ng-switch on="current">
<div ng-repeat="solution in solutions" ng-switch-when="{{solution.title}}">
{{solution.content}}
</div>
</div>
The output of {{solution.title}} is literally {{solution.title}}. It doesn't get processed by angular.
The ng-switch-when tag requires a constant, you can't put a variable in it.
You can rework your code as follows:
<div ng-repeat="solution in solutions">
<div ng-show="current == solution">
{{solution.content}}
</div>
</div>

Resources