ngRepeat $scope messing with nested ngClick - angularjs

So i have four progress bars that on click open and close via the close button in the top right....problem is the ngrepeat is messing with something....i've tried adding $parent to the child ngClick but it doesnt work. I've looked at all the other stack examples of this and just can't seem to figure out how to apply it to this specific situation
http://codepen.io/anon/pen/JorZoE
<div class="progress-bar repeat-animation" ng-click="showClose = false" ng-class="!showClose ? 'grow' : ''" progress-morph style="width: {{item.percent}}%" ng-repeat="item in list">
<div class="close" ng-hide="showClose" ng-click="onClickClose($event)" ><img src="close42.svg" alt=""></div>
</div>

I assumed that you wanted to open/close the bars individually.
If that's the case, your code wasn't working because you were binding all the progress bars state to the same $scope variable.
Having that in mind, I tweaked your code a little bit to make it work, and also used a more readable logic (imho).
Please take a look and let me know:
http://codepen.io/anon/pen/WbZygb?editors=101

Related

Angular-Elements are not refreshing after aborted drag&drop

I have the following angular-List (reduced the content to make it better readable):
<div ng-repeat="element in bigBlock.Elements track by $index"
class="singleBlockElement"
ng-drop="dragSource=='Block'"
ng-drop-success="To($index, $data, bigBlock)">
<div class="bbRange"> </div>
<i class="fa {{GetImage(element)}}" />
<div ng-drag="element.ElementType!=='placeholder'"
ng-drag-data="element"
ng-drag-start="Start()"
ng-drag-success="From(element,bigBlock, $index, bigBlock.$index)"
ng-drag-stop="Stop(element, bigBlock, $index, bigBlock.$index)"
class="cutOff">
{{element.Title}}
</div>
<div class="edit ng-show="GetLinkText(element, true)">
<span class="isvisible">
<i title="{{element.Present?'Präsentieren':'Nicht präsentieren'}}" class="fa fa-{{element.Present?'eye':'eye-slash'}}"></i>
</span>
{{GetLinkText(element,true)}}
</div>
</div>
This is how it looks like:
This is while dragging:
And this is how it looks like when I simply don't drop like described below:
I can now (successfully) drag & drop the two elements ("Welcome" and "Go Away") inside that block changing the order of these two.
But if I abort the drag/drop. e.g. Dragging "Welcome" and not moving it downwards or moving it to an area where I cannot drop (outside the block) the text "Welcome" disappears.
There are no errors. The drop is just not happing (as expected), but Angular seems to be unable to redisplay the text of that element. ({{element.Title}})
I event tried forcing a refresh using $apply(), but this did not change a thing (not creating an error either).
However, if I do ANYTHING on the page like clicking on an edit-button or anything else that causes an event, the date is correctly shown again.
So it looks like a refresh issue for me.
I am using ngDraggable for this (https://github.com/fatlinesofcode/ngDraggable)
(Update: Analyzing the page source in Developer Console of Chrome the text still seems to be there and even "should" be visible (display:block), so this might be more of a browser-issue (chrome) than an angular-issue)
This seems to be a pure Browser/CSS-Issue and not an Angular-Issue. I solved this by forcing the browser to refresh the parent container:
$('.mm-Right')[0].style.display = 'none';
$('.mm-Right')[0].offsetHeight;
$('.mm-Right')[0].style.display = 'block';
where my structure is
<div class='mm-Right'>
<div class='singleBlockElement>[..]</div>
<div class='singleBlockElement>[..]</div>
<div class='singleBlockElement>[..]</div>
</div>
That did solve the problem but looks like cheating for me. I would prefer that this bug not even appears instead of hiding the symptoms. So I am happy to accept any better answer for that problem.

Self contained Angular Template is not setting variables correctly

I am trying to build a star ranking purely in an angular template file without using controllers, I have the following code which fails, I can build this using controllers (calling setRanking method ng-click) but I want to understand why the following code is not working. User should be able to click on a star and all the stars up to the selected star should be highlighted.
<div class="item" ng-init="user_rating = 0">
<i
ng-repeat="star in [1,2,3,4,5]"
ng-class="(star>user_rating) && 'ion-ios-star-outline' || 'ion-ios-star'"
ng-click="user_rating = star"></i>
<h3>Starts: {{user_rating}} </h3>
</div>
I think the issue is with the scope of the user_rating(as it is not getting updated).
As each ng-repeat creates the isolated scope, so the way you are updating user_rating is creating a local copy of user_rating associated to the local scope of each ng-repeat.
To fix it you can replace the code
ng-init="user_rating = 0"
with
ng-init="r={}; r.user_rating = 0;"
Also refer user_rating with r.user_rating wherever you are referring user_rating.
Also the correct way of using ng-class is what #Shailendra mentioned in his answer. Thanks!
You need to make changes in this code for 'ng-class' as like below-
<div class="item" ng-init="user_rating = 0">
<i
ng-repeat="star in [1,2,3,4,5]"
ng-class="star>user_rating? 'ion-ios-star-outline': 'ion-ios-star'"
ng-click="$parent.user_rating=star;"></i>
<h3>Starts: {{user_rating}} </h3>
</div>
I Hope this may help you..

AngularJs multiple ng-click

I have tried to do the following:
<accordion-heading ng-click="doSomething(); isopen=!isopen">
Should this work? or is it not possible to string there call together?
ng-click="doThis(param); doThat(param);"
I just need pointed in the right direction :-)
EDIT:
this:
ng-click="doThis(param); doThat(param);"
works as expected, I think it is:
isopen=!isopen
that is causing the problem, I realise I didn't say this initially.
I go around this by adding an extra div into the accordion heading, like this:
<accordion-heading ng-click="isopen=!isopen">
<div ng-click="showMainView()">
<i class="glyphicon" ng-class="{'glyphicon glyphicon-minus': isopen, 'glyphicon glyphicon-plus': !isopen}"></i>
{{item.model}}<br>{{item.model_engine}}
</div>
</accordion-heading>
possible !! possible !! possible !! possible !! possible
You can call multiple functions with ';'
See here
Using ng-click to call two different functions
How to add many functions in ONE ng-click?
How to use ng-click with multiple expressions?
It works:
http://plnkr.co/edit/fwSdBT3NIBrlk80aTgaB?p=preview
However be careful not to do too much logic in there. You should put the logic in the controller and only call it from the view. (isopen = !open for example doesn't belong on the view)

angular ui-router maintaining state between tabs

Would like to know the best way to preserve state between tabs. I use bootstrap tabs and angular ui-router. I've a google map in one of the tabs and don't want to reload the map when user selects that tab. Please advise.
Thanks
I think what you are looking for is discussed in this issue: https://github.com/angular-ui/ui-router/issues/63
They are mostly discussing iframes but I believe the same should hold for Google Maps. Unfortunately in the thread they decided that this isn't something that should be implemented in the core release. I haven't tried out the directive they provide (if I get a chance I'll let you know how it goes) but you may be able to get something working with that.
I have actually come across the exact problem you had. My solution was to use styled buttons as my tabs and ng-show for the map tab:
<div id="info-btns">
<button class="btn" ng-model="view" btn-radio="'info'">
Info
</button>
<button class="btn" ng-model="view" btn-radio="'map'" ng-click="loadMap()">
Map
</button>
</div>
<div class="content" ng-show="view != map">
<div ui-view="info"></div>
</div>
<div id="map-container" ng-show="view == 'map'">
<div id="map" class="content" sitemap>
</div>
</div>
ng-show simply uses display:none to hide the map and hence doesn't cause a refresh. You will need to trigger the map to load the first time it is not hidden otherwise it will render incorrectly, hence loadMap()
If I get a chance I'll set up a jsfiddle of this in practice.

AngularJS Animations ng-switch ng-repeat

I am trying to do what looks like a simple process: to display a list of items received from an HTTP request with animation.
First of all, here is my way of doing it ( I am open to any suggestions to do it in a better angular way ):
I define a scope variable state that I initialize to loading in my controller and that I change to loaded when I receive data from the HTTP request.
I initialize a scope variable items with the received data.
In my view, I use ng-switch for the states, and ng-repeat with the items.
I define an animation with css on ng-repeat.
Here is a plunkr ( with a $timeout instead of the request ).
I cannot understand why the animation does not work.
Any help will be appreciated. Thanks.
The reason it is happening is because your ng-when. The same thing happens with ng-if, but would work fine if you used ng-show.
The problem is that when your ng-when condition returns true, the ng-when first renders it's content in a detatched dom (so animations do not happen). This dom is then attached to the dom tree (this step is animated but you would have to put your animation class on the ng-when).
When using something like ng-show or ng-hide things work as expected because the dom is always attached (it is simply shown/hidden).
This might be considered either a bug or a limitation of ng-animate, you might want to post a github issue and see if the angular guys have any thoughts.
It seems to be a "feature" of angular that it won't add .ng-enter to repeat items inside ng-switch-when block. You can remove ng-switch-when="loaded" and it will work (You don't really need it as ng-repeat won't do anything if there is no items)
<div ng-switch="state">
<div ng-switch-when="loading">
<p>Please wait...</p>
</div>
<div >
<ul ng-repeat="item in items" class="animate-items">
<li>{{item}}</li>
</ul>
</div>
</div>
http://plnkr.co/edit/ocEj7BSQPSeIdnnfAOIE?p=preview

Resources