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

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.

Related

HTML form in ng-if environment

Structure of my app is like following:
<div class="parent">
<div class="child" ng-if="showChild">
<div class="child-view-1" ng-if="!isShown">
</div>
<div class="child-view-2" ng-if="isShown">
</div>
</div>
</div>
Inside child-view-2 I have form element, and of course, it is undefined in controller, probably beacuse of ng-if (as it creates child scope).
isShown variable just switches divs from child-view-1 to child-view-2.
What do you suggest, how can I make form visible all time in controller?
EDIT: My fault, the outer child is controlled by showChild flag...
You have an outer ng-if (on div class="child") based on the value of isShown. When isShown is true the content will be added to the DOM, and the class="child-view-1" will obviously not be added to the DOM because of ng-if="!isShown"
The second div's ng-if is redundant because it is the same condition as the outer one:
<div class="parent">
<div class="child" ng-if="isShown">
<div class="child-view-1" ng-if="!isShown">
<!-- THIS WILL NEVER BE DISPLAYED -->
</div>
<div class="child-view-2" ng-if="isShown">
<!-- THIS WILL ALWAYS BE DISPLAYED WHEN isShown IS TRUE -->
</div>
</div>
</div>

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>

How to access key value in angular js using ng-repeat?

I am trying to show the value from my json files using ng-repeat in angular js but I am unable to do that.
This is my code which I am trying:
<div ng-repeat = "x in myWelcome.definition">
{{x.attributes[0].children[0].node_id}}
<hr>
</div>
I have tried this and it is working:
<!-- first attributes start -->
<div ng-repeat = "x in myWelcome.definition.attributes">
{{x.rm_attribute_name}}<hr>
<div ng-repeat="a in x.children">
<div ng-if ="a.attributes">
a: {{a.attributes[0].rm_attribute_name}}
<div ng-if= "a.attributes[0].children">
chld
</div>
</div>
</div>
</div>
<!-- second attributes end -->
I am trying to understand how this line is working {{a.attributes[0].rm_attribute_name}} why it is not working like this {{a.attributes1.rm_attribute_name}} this is confusing. How it is shwoing all the results when I am using 0 and index.
And my json file is here in the plunker:
Plunker link of json and code
So how can I iterate here using ng-repeat here this code:
{{myWelcome.definition.attributes[0]}}
is working how can I show this in my view using ng-repeat I need to show all the attributes and child using ng-repeat.
ng-repeat can be used in the following way:
<div ng-repeat = "(key,value) in myWelcome.definition.attributes">
Key:{{key}} and value :{{value}}
<hr>
</div>
OR you can Try this:
<div ng-repeat = "x in myWelcome.definition.attributes">
<div ng-repeat="a in x.children">
a:{{a.node_id}}
</div>
</div>
Edited Plunker
I can see you are trying to implement ng-if and ng-repeat for your json file. You need to understand how ng-repeat works you can always check the index of you array using {{$index}}. So for your kind of problem I think this is the solution you should try.
<!-- first attributes start -->
<div ng-repeat = "x in myWelcome.definition.attributes">
{{x.rm_attribute_name}}<hr>
<div ng-repeat="a in x.children">
{{$index}}
<div ng-if ="a.attributes">
<div ng-repeat="b in a.attributes">
<hr>
{{b.children.length}}
<div ng-if="b.children.length > 1">
If the array is more than 1 please do the magic here
</div>
</div>
<div ng-if= "a.attributes[0].children">
chld
</div>
</div>
</div>
</div>
<!-- second attributes end -->
You can always see the indexes using {{$index}} and you should always use .length to check if it has more than 1 value. This way you can achieve what you want and you should also learn something about arrays in javascript and what is the differnece between dot and bracket. Please read this http://www.dev-archive.net/articles/js-dot-notation/. I think you should learn the basics of javascript.

Angular ng-switch with boolean

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;
}
}

AngularJS using ng-switch without wrapper div

I would like to use ng-switch because I do not want the other elements that I do not want to show to be part of the DOM. That is why i did not use ng-hide/ng-show. In the example below, I would like to only have the span tag be in the DOM without the div wrappers from the ng-switch. What is the best way to accomplish this?
<div ng-switch on="user">
<div ng-switch-when="true">
<span>One</span>
</div>
<div ng-switch-when="false">
<span>Two</span>
</div>
</div>
You can use the ng-switch directive as a custom element and not specify the div in the first place. For example:
<ng-switch on="user">
<span ng-switch-when="true">One</span>
<span ng-switch-default>Two</span>
</ng-switch>
Here is a plunker to play around with: http://plnkr.co/edit/zni6raUWOguhQh9jDiY3
the solution provided by #ChrisAuer this still creates a wrapping element.
AFAIK you'd have to use a custome directive. You may want to use angular-ui if
<div ui-if="user">
<span>One</span>
</div>
<div ui-if="!user">
<span>Two</span>
</div>
Probably, in your case, you'd be fine using ng-show or ng-hide which only hide(display:none) the element - they don't remove it form the DOM.
<div ng-show="user"> <!-- same as ng-hide="!user" -->
<span>One</span>
</div>
<div ng-hide="user"> <!-- same as ng-show="!user" -->
<span>Two</span>
</div>
I would say use ng-if, like this:
<div>
<div ng-if="user==true">
<span>One</span>
</div>
<div ng-if="user==false">
<span>Two</span>
</div>
</div>
you can use <span> to prevent your html layout changing
because <span> is not like <div>, it won't take up any space.
<span ng-switch="user">
<span ng-switch-when="true">One</span>
<span ng-switch-default>Two</span>
</span>

Resources