jPanelMenu is breaking AngularJS ng-click - angularjs

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">

Related

ng-if Function Gets Called on Click

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.

Apply AngularJS directive when div is visible

I have added a custom directive in Angular JS. I have added one page in which I have 4 div tag. These 4 div tag are not displayed at once, but they are getting displayed in tabs, so on click of particular tab respective div gets displayed.
But when the page loads all div tag are loaded so directive is called when page is loaded. But what I want to achieve is when the div tag gets visible (on click of tab) it should execute that directive.
Is there a way to achieve this ?
Thanks.
-- Update - 1
let me explain my problem with more details ..
I am displaying tabs using boot-strap data-toggle="tab", so when I select particular tab it displays that tab content.. but on click of tab bootstrap is showing / hiding tabs by applying css.
<a href="!#tab_1" data-toggle="tab">
<a href="!#tab_2" data-toggle="tab">
<a href="!#tab_3" data-toggle="tab">
<div class="tab-pane fade" id="tab_1">
... some content
</div>
<div class="tab-pane fade" id="tab_2">
<table>
<tr ng-repeat="user in userList">
<td>{{user.name}}</td>
<td>{{user.contact}}</td>
View
Edit
</tr>
</table>
</div>
<div class="tab-pane fade" id="tab_3">
... some content
</div>
<new-user-modal username="name"></new-user-modal>
so, now when i load page by default tab_1 is selected / active, but other tabs are already loaded but are hidden. Here <new-user-modal> is a custom directive, which points to a template using templateUrl ../../newUserTemplate.html, which has div with id new_user_modal.
So when I select tab_2, i see list of users, all user row will have View action, and when i click on View action, it displays pop-up using newUserTemplate.html template. I have implemented a custom directive to display all fields in form as read-only, so when user clicks on View action it should display all fields in read only mode.
template (../../newUserTemplate.html) div with id new_user_modal has this custom directive read-only added to it, so when i load page first time when by default tab_1 is selected that time its calling read-only custom directive.
But I want it to be called when action is clicked, so based on it i can open modal either in read-only or edit mode.
let me know if you need any other details..
-- Update-2
basically I have created two directives one is new-user-modal and other is read-only.
First directive is to load user details in a modal(popup) which as i explained is getting generated using data-toggler=modal. This directive new-user-modal has template which is a form with user related fields, so when user clicks on any user records, this modal will be displayed with user information..
new-user-modal directive is pointing to template file ../newUserTemplate.html, where i have all user fields. In this template i have added my another custom directive read-only, so if user clicks on view user action, it will open this modal in read only view means all form fields will be read only, and if user clicks on edit user action, same modal will open in edit mode.
But, as this modal is getting generated using bootstrap, this modal is already loaded when the page is loaded first time, but its hidden. So directive is getting called when page is loaded not when modal is shown ..
You could use ng-if for directives and check if the current tab is open. ng-if recompiles the directive from scratch only when the value is true, or in your case
Something like this:
<tabs>
<pane title="Tab1">
<directive ng-if="tab1.active"> </directive>
</pane>
<pane title="Tab2">
<directive ng-if="tab2.active"> </directive>
</pane>
</tabs>
Is this something you want? There is also another way using $compile but it's not so correct.

need dom element containg angularjs directive to be destroyed and created again so that directive's compile and link functions run again

i have custom angular directive 'my-directive' as follows:
<div my-directive>
<div ng-repeat="image in images">
<img ng-src="{{image.url}}"/>
</div>
</div>
what my-directive does is in it's link function gets the element to which it is applied and initializes jquery carousel plugin on that element.
My issue is that when i click on button with click handler setting scope.images to another value then carousel is broken. So in button click handler after i set scope.images to another value i want to do some action which will cause the dom element to be destroyed and created again. In that case directive's link function will run again and the carousel will be initialized with new images.
Ideally i should not make any change to directive itself because it is a generic directive used in multiple places and in different situations.
Thanks in advance.

ng-if is not working as expected

I'm trying to use ng-if to show and hide some data based on tabs because I don't want all the html to be on the DOM all the time. Here's what I'm trying to do. It seems the ng-if is working only when the page is loaded, after that on the click of the sub tabs, it's still updating the scope variable, but I don't see the change on the UI. Please help.
Thanks.
Remove ng-href="#" from your links. This is all you need:
<li ng-repeat="subTab in tabData.SubTabs">
<a ng-click="subTabClicked(subTab)">{{subTab.Name}}</a>
</li>
With ng-href present, currentTabId is being updated on a child scope for each tab. On the parent scope, where ng-if is watching, currentTabId was never changed.
Here is a demo: http://plnkr.co/ISwjaWKggdbGL38BW078

ng-repeat: adding a new element with an effect

Currently I am using ng-repeat to show a division.
<div class="something" ng-repeat="item in items">{{item.name}}</div>
In my controller the moment I add one more item to items it shows in my page. But it just displays the new content. What I want is to show an effect while its added like the new div should slide down while being added to the page. How I can I achieve it?
Try adding a ngAnimate attribute with animation values. You can find more information here
http://www.yearofmoo.com/2013/04/animation-in-angularjs.html#animating-ng-repeat

Resources