ng-switch not working as expected - angularjs

Instead of having two separate ng-if, I want to combine them and use ng-switch. However, the img() functions are not switching as expected. What should I do differently?
Turn this:
<img ng-src="{{img(myColor)}}" ng-if="myColor">
<img ng-src="{{img(myColor2)}}" ng-if="myColor2">
Into this:
<div ng-switch on = "myColor2">
<div ng-switch-when = "myColor2">
<img ng-src="{{img(myColor2)}}">
</div>
<div ng-switch-default = "myColor">
<img ng-src="{{img(myColor)}}">
</div>
</div>

Here's an example for ng-switch
http://jsfiddle.net/fbg3bLac/5/
You might be understanding it wrong.
ng-switch on = "myColor2" -- means you want to evaluate the value of the scope variable myColor2.
ng-switch-when = "myColor2" -- states that if the VALUE of myColor2 is equal to 'myColor2' then do this.
ng-switch-default -- should have no = value.
Please refer to http://www.c-sharpcorner.com/UploadFile/75a48f/switch-condition-in-angularjs/

Related

Geting incorrect $index value for parent ng-repeat loop

I have following code and try to use $index in delete function but it gives incorrect value of it.
<li ng-repeat="joinMember in data.teamMember | orderBy:'member.screenName || member.fname' ">
<div class="member-list-img">
<a ng-href="">
<img ng-src="{{joinMember.member.data.image ? (joinMember.member.data.imageType == 'avatar' ? '/public/images/avatars/' + joinMember.member.data.image : '/public/images/' + joinMember.member.data.image) : '/public/images/avatars/avatar-73.png'}}" width="100%" alt="{{joinMember.member.screenName ? joinMember.member.screenName : joinMember.member.fname + ' ' + joinMember.member.lname }}" />
</a>
</div>
<div class="member-list-cont">
<h4>
<a ng-href="#">
{{joinMember.member.screenName ? joinMember.member.screenName : joinMember.member.fname + ' ' + joinMember.member.lname }}
</a>
</h4>
<span>{{joinMember.created | date : "MMMM d, y"}}</span>
</div>
<div ng-if="data.canModify" class="membr-delete">
<a ng-href="">
<i class="fa fa-trash text_link" aria-hidden="true" ng-click="deleteTeamMember($parent.$index, joinMember.id)"></i>
</a>
</div>
</li>
That's because the directive ng-if creates a new scope for itself, when you refer to $parent, it access the immediate $parent's scope, i.e., the inner repeat expression's scope.
So if you want to achieve something you wanted like in the former, you may use this:
<div ng-repeat="i in list">
<div ng-repeat="j in list2">
<div ng-if="1">
({{$parent.$parent.$index}} {{$parent.$index}})
</div>
</div>
</div>
if you have more than one inner directives, you can use ng-init for storing $index in a variable for references in child scopes.
<div ng-repeat="i in list" ng-init="outerIndex=$index">
<div ng-repeat="j in list2" ng-init="innerIndex=$index">
<div ng-if="1">
({{outerIndex}} {{innerIndex}})
</div>
</div>
</div>
So try $parent.$parent.$index in your example and please check understanding the scopes
You are using $parent.$index in a div that have ng-if tag. which delete dom element(div) if condition is fall so that case you will receive incorrect $index value. but with ng-show it only add hide class to that div.
So try to ng-show if it is not important to remove div element instead just hide it.
Note:- You are also using orderBy filter in ng-repeat which will sort in only your DOM so if you will find incorrect object value in your controller.
As you can see in the official documentation of angularjs you should get a zero-based index via $index within a ng-repeat. Try the example by angularjs here. Try to debug data.teamMember in your controller to make sure that this is the correct array you'd like to iterate.

Angular: a part of view does not update

I have a directive template with the following code
<div class="colorpicker">
<div>Chosen color</div>
<div class="color_swatch" style="background-color: {{ngModel}}"> </div>
<div class="clearfix"></div>
<div>Standard colors</div>
<div class="color_squares">
<div ng-repeat="color in colorList">{{color.trim() == ngModel.trim()}} //does not update
<div class="color_swatch" style="background-color: {{ color }};"></div>
</div>
</div>
<div class="clearfix"></div>
In the directive, I update the ngmodel using the below code to the color that was clicked - the div next to "chosen color" is updated with the selected color.
But, the expression "{{color.trim() == ngModel.trim()}}" always amounts to false.
{{color.trim() == ngModel.trim()}}
I have debugged the code and the values are exactly the same.
What I am missing?
This is probably because your variable is precisely named 'ngModel' see that article for more explanation : http://zcourts.com/2013/05/31/angularjs-if-you-dont-have-a-dot-youre-doing-it-wrong/
To resume this article : never use raw fields use always a dot. So in your scope change
$scope.ngModel
By
$scope.data.ngModel
And in your html change ngModel by data.ngModel.
When using dot you may have some undefined error, this is because you have to initialize the object :
$scope.data={};
Of course you can jsut rename your variable, but you may still have a problem with others directives.
I solved this by removing curly braces around color and using ng-style
<div class="color_swatch" id="colorpicker_selected_color" ng-style="{'background-color': selectedColor}" > </div>

angular - failing to bind element's ng-show inside ng-repeat

There is a panel for each contact. I want to show the remove button on a specific panel only when the user mouse over that same panel.
...
<div class="col-sm-3" ng-repeat="contact1 in Contacts">
<div class="panel panel-success" ng-mouseenter="{{contact1.id}}=true" ng-mouseleave="{{contact1.id}}=false)">
<div class="panel-heading">
REMOVE BUTTON
</div>
...
I cant get the reason why this code doesnt work.
There is 2 things in your code that can create problem. First of all, ng-show / ng-mouseneter / ng-mouseleave need an expression. So you don't need to put the {{ }}.
But it wasn't the only one problem. The fact is you were using your id to manage the show property of your item. But this expression need a boolean and you can't just erase your id with a boolean like in ng-mouseneter. To do so, you have to use an other attribute in your item, isShow for example. This will keep your id safe and you will be able to manage your view with it.
So, it give something like this :
<div class="col-sm-3" ng-repeat="contact1 in Contacts">
<div class="panel panel-success" ng-mouseenter="contact1.isShow = true" ng-mouseleave="contact1.isShow = false">
<div class="panel-heading">
REMOVE BUTTON
</div>
....
Would be nice to see a working example, but for the start the angular directives you've used require an expressions, so try removing the {{}} from ng-mouseenter, ng-mouseleave and ng-show.
So, it should be like ng-show="contact1.id".
Try applying this. Hope it works for you.
Remove the brackets from your assignment statements.
The brackets are to render a variable. Since you're assigning, instead of ng-mouseenter="{{contact1.id}}=true" you'll want to do ng-mouseenter="contact1.id=true"
You're previous code was the equivalent of writing something like null=true, or whatever value was already assigned to contact.id. The new code assigns contact.id to the value you specified.
EDIT: You can just use a local variable.
<div class="col-sm-3" ng-repeat="contact1 in Contacts">
<div class="panel panel-success" ng-mouseenter="showButton=true" ng-mouseleave="showButton=false">
<div class="panel-heading">
REMOVE BUTTON
</div>
</div>
</div>

Why is my ng-hide / show not working with my ng-click?

I want to show the elements that contain displayCategory.name with the ng-click above it, but it's not working as expected.
.divider-row
.row-border(ng-hide="showMe")
.row.row-format
.col-xs-12.top-label
Find where you stand
%hr.profile
.row.labelRow
.col-xs-12
%ul
%li(ng-repeat='category in service.categories')
.clear.btn.Category(ng-click='thisCategory(category) ; showMe = true') {{category.name}}
.divider-row
.row-border(ng-show="showMe")
.row.row-format
.col-sm-12.col-md-12.top-label.nopadLeft
What do you think about {{displayCategory.name}}
I dropped your haml into a converter and this is what it spat out (clearly incorrect):
<div class="divider-row">
<div class="row-border">(ng-hide="showMe")
<div class="row row-format">
<div class="col-xs-12 top-label">
Find where you stand
</div>
</div>
<hr class="profile"/>
<div class="row labelRow">
<div class="col-xs-12">
<ul>
<li>(ng-repeat='category in service.categories')
<div class="clear btn Category">(ng-click='thisCategory(category) ; showMe = true') {{category.name}}</div>
</li>
</ul>
</div>
</div>
</div>
<div class="divider-row"></div>
<div class="row-border">(ng-show="showMe")
<div class="row row-format">
<div class="col-sm-12 col-md-12 top-label nopadLeft">
What do you think about {{displayCategory.name}}
</div>
</div>
</div>
</div>
So after some quick googling I found that you should be writing it like this:
.divider-row
.row-border{"ng-hide" => "showMe"}
.row.row-format
.col-xs-12.top-label
Find where you stand...
As that will convert to what you need:
<div class="divider-row">
<div class="row-border" ng-hide="showMe">
<div class="row row-format">
<div class="col-xs-12 top-label">
Find where you stand
Using curly braces instead of round ones for attributes
I cannot run your code to verify, but I think the problem is that the binding property showMe should be replaced with some object like status.showMe.
For example, define $scope.status = { showMe: false}; outside the ng-repeat (in your controller maybe).
Please check a working demonstration: http://jsfiddle.net/jx854d3y/1/
Explanations:
ng-repeat creates a child scope for each item. The child scope prototypical inherits from the parent scope. In your case, the primitive showMe is assigned to the child scope. While you use it outside the ng-repeat, where it tries to get the value from the parent scope, which is undefined. That is why it is not working.
Basic rule is: always use Object, instead of primitive types, for binding.
For more details, please refer to: https://github.com/angular/angular.js/wiki/Understanding-Scopes

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