ng-if Function Gets Called on Click - angularjs

I have my code on Plnkr:
http://plnkr.co/edit/6wz4zub2sEOfhrqps0c8
The html code is quite simple:
<div ng-app="myApp" ng-controller="MainCtrl">
<div ng-dropdown-multiselect="" options="myData" selected-model="myModel" extra-settings="mySettings" events="myEvents"></div>
<div ng-repeat="item in Items">
<item-input></item-input>
</div>
</div>
</div>
Basically, the problem is my function in ng-if gets called every time I click anywhere on the page. I think it has something to do with the multi-select control but I'm not sure where I should fix it. Any help is appreciated.
Thanks.
UPDATED
What I don't really understand is why this behavior stops when I comment out the multi-select dropdown (<div ng-dropdown-multiselect="" options="myData" selected-model="myModel" extra-settings="mySettings" events="myEvents"></div>)?

As shown in the picture below, taken from Chrome DevTools, the multi-select dropdown is generating two click event handlers :
One event is on the button and one on the whole document. Therefore, a click on the document is triggering at least that last event handler, which potentially changes the model. Angular then do a digest cycle, and that implies that the displayMe function bound to the ngIf directive is evaluated in case the element should be removed of the DOM or not.
If you remove the dropdown component, and thus these two click handlers, you are left with 3 text inputs. Indeed, now there are no digest after a click on the document because no handler are executed, but you can still trigger digests essentialy by typing inside the input elements.
This answer by Miško Hevery has some valuable info about the dirty-checking process in Angular 1.x.

Related

Angular UI Bootstrap accordion heading not working correctly with checkbox

I'm using a check box in the heading of the accordion control in bootstrap, but the model will only update the first time it's clicked. Here's the HTML for the accordion:
<accordion ng-repeat="timesheet in timesheets">
<accordion-group>
<accordion-heading>
Title
<input type="checkbox" ng-model="approvals.rejected" ng-click="approvals.timesheetChecked($event)"/>
</accordion-heading>
</accordion-group>
</accordion>
the click method is in my typescript controller:
timesheetChecked($event: Event) {
$event.stopPropagation();
$event.preventDefault();
}
If I just use the stopPropagation() method by itself it updates the model correctly and the check box is checked, however, it will then refresh the page. The preventDefault() method stops this from happening, but then it will then only update the model once and not check the check box.
I have tried using ng-bind and that will actually update the model with correctly, but it will not change the check box to checked.
If I use the check box outside of the accordion it works as expected and I have no problems with it. I'm not really sure what I am doing wrong here?
I believe your code would work, but it only works with Angularjs 1.2.x and ui-bootstrap-tpls version 0.11 (earlier versions may work).
Your code is similar to the following post...
https://stackoverflow.com/a/24502123/3807872
If you are using Angular 1.3.x, then you will want to add the stop propagation inside of the ng-click...
<input type="checkbox" ng-model="approvals.rejected" ng-click="approvals.timesheetChecked($event);$event.stopPropagation();"/>
This example was in thanks to the following post...
https://stackoverflow.com/a/14545010/3807872
This really worked for my situation as well.
By the way, I don't know if you have fixed this issue but I have the same problem, however for displaying the right checked checkbox I've added this:
ng-checked="approvals.rejected == 'true'"
and I only stopPropagation method.
But actually it doesn't work for the first click!

ng-change in a checkbox fired more than one time, because an ng-click over it

As a code is better than 1000 words, I've created a plunker in order to show my problem:
http://bit.ly/1uiR2wy
Given the specific DOM element, thing is that I have an input checkbox with an ng-change, I want to add an ng-click to the li that wraps it in order to be able to click in the whole area.
This new ng-click makes the method in the ng-change to happens twice. And is even worse for an SPAN DESCRIPTION 2 that is happening 3 times.
<li class="odd" ng-click="changeToggleModel($event)">
<span class="overcomeDescription ellipsis-overflow">span description</span>
<label>
<span>SPAN DESCRIPTION 2</span>
<input type="checkbox" ng-change="toggleSelection($event)" ng-model="isSelected">
</label>
</li>
I've tried with stopPropagation and it seems that it doesn't solve the issue.
Any ideas about it?
If you check the plunker and open the console you'll see the issue perfectly.
Thanks in advance to everyone
You need to stop event propagation on label level. Try this:
<label ng-click="$event.stopPropagation()" ...>
Demo: http://plnkr.co/edit/AjD9GlA3zjxABix6hegg?p=preview
The reason why it happens is that the label (connected to corresponding checkbox) sort of generates one more click event in order to pass click to the input. This click event causes described strange issues, because it still bubbles like normal event (well it is normal event), and hence is detected by ngClick directives.
Late to the party but encountered the same issue- it seems like AngularJS propagates the click event separately and explicitly. Instead of stopping propagation on the label, you can catch it on the input explicitly:
<input
type="checkbox"
ng-click="$event.stopPropagation()"
ng-change="toggleSelection($event)"
ng-model="isSelected"
>

binding a css class to a element via angular directive

I want to attach a directive to a element. The directive will be responsible for the following:
1. Attach a click event to the element
2. Upon click.. show a drop-down
In order to perform the first activity I have added directive called "sortDirective" to my element below:
<span class="glyphicon glyphicon-arrow-down" style="font-size:0.6em" sort-directive></span>
This is done in the file layout.html
I am facing two issues:
1. the click event is not working
2. the drop-down should be shown only on click event. Right now you will notice that the drop-down (blue in color) is being shown at all the times.
I believe i am missing something here since my directive sort-directive is falling within another directive custom-table.
Am I thinking in the right direction or am I totally off ?
Plnkr Here
I wouldn't call the click event with the directive. My advice would be just to put ng-click to the span that you want to call the function from (and move the function to the controller).
You might want to look at this thread:
trigger click event from angularjs directive
Also a quick css tip - add these rules
cursor:pointer;
padding:0 0 0 5px;
to the class .header-cells.
Finally, don't you think that the arrow is too small to click it? Try binding the click event to the whole container.
i finally managed to lay this out. Those interested in seeing how it is done ..here is a plnkr
http://plnkr.co/edit/TG6aCEu2TgPq28Jcj0nM?p=info
just click on any of the headers (in orange) and you should see the results.

Angularjs ng-repeat-start /end and filter weird behaviour

I am trying to create Master Details in table
here is the plnkr Code
but as i start putting filter for the ng-repeat the dom rendering behaves weird
click the + button to expand row and the search the textbox
am i doing some thing wrong
My guess is that ng-repeat-end and ng-if do not play well together. If you place the ng-if in the <p> element, your example is working. Of course this has the (undesired?) effect of allways including the details row in the DOM, event though it will be hidden.

jPanelMenu is breaking AngularJS ng-click

I am using jPanelMenu in a ToDo application for the left side menu. I have created a directive to apply the jPanelMenu to the appropriate elements.
Everything is working as expected except there is a nested ng-repeat with a nested ng-click inside of the element that gets reassigned with jPanelMenu.
<jpmenu>
<ul class="unstyled">
<li ng-repeat="category in categories">
{{ category }}
</li>
</ul>
</jpmenu>
The ng-click event is not firing in the created jpanel menu.
Notes:
jPanelMenu coppies the jpmenu element and applies it's styles to it, not using the original dom elements
The original DOM elements still exist and they are "display:none;"
the class ng-scope is missing from the recreated jpanel menu element
The ng-click element fires properly on the original DOM element if I unhide it and click it, but the recreated elements do NOT fire at all.
I've added a timeout to the directive to delay the jpanel menu recreation (to wait for angular to finish it's other directives first) but that didn't help
Here is a jsfiddle example of exactly what's going on (THIS FIDDLE DOES NOT RUN IN CHROME BECAUSE OF CROSS SITE SECURITY): http://jsfiddle.net/47PXj/
If you click the unhidden original menu items in the jsfiddle you'll see the text updating, but if you click the menu items in the left menu they do not work.
You forgot to bootstrap your app. Try this:
<body ng-app="myApp">

Resources