Apply AngularJS directive when div is visible - angularjs

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.

Related

Radio buttons stop displaying their value when a radio button is selected in another object within the array

We have a section of our website where users can submit data. This section allows users to add additional entries and submit them all at once. We had to rewrite this section after we updated the version of AngularJS the site used to the most recent. When a user first accesses the page, the first entry is ready and available for the user to fill out. They can click on a button and it will add another entry. These entries can be navigated via tabs. Once a second entry has been added and a radio button selected, the selected radio button on the first entry is deselected in the view. If you go back to the first entry and re-select a radio button, any selected radio button on the second entry is de-selected. Checking the model, the values are still stored and if the user saves, then the correct values are saved to the database. I don't know if it matters in this case, but the radio button options are populated via data from the database. Everything in the controller appears to be working correctly.
Here is a concentrated bit from the template:
<uib-tabset active="activeTabIndex" ng-show="!nothingToShow && showThisStuff">
<uib-tab ng-repeat="entry in things.items" active="{{entry.active}}" ng-model="entry">
<uib-tab-heading>Heading Here</uib-tab-heading>
<div>
<!-- some other stuff here -->
<div>
<label>Label Here</label>
<br />
<div ng-repeat="input in inputTypes">
<input name="inputTypes" type="radio" data-ng-value="input.theTypeId" ng-model="entry.theTypeId">
<label>{{input.localizedName | translate}}</label>
</div>
</div>
<!-- More stuff here-->
</div>
</uib-tab>
</uib-tabset>
I have a feeling that I'm not doing something right since ng-repeat is involved, but I feel that since the selection points to entry that multiple entries should be isolated from each other. Very well could be wrong, though.
Here's a list of things I've looked at to try and resolve this issue:
AngularJS - ng-repeat multiple radio button groups, values to array
AngularJS - Using ng-repeat to create sets of radio inputs
AngularJs: Binding ng-model to a list of radio buttons
AngularJS multiple radio options
Selected value in radio button group not retained in angularjs
How can I get the selected values of several radio buttons to be bound to an object (model)?
If I understand you correctly, you try to set multiple selection instead of single selection, do you?
Try one of the following: either remove the 'name' attribute from the input, or use $index in order to give every input its unique name (example: name="inputTypes_{{$index}}").

Getting checkbox values in angularjs and passing them into another controller

I am transitioning from jquery to angularjs. I am trying to develop a small app in SPA style. Left side is the menu that controls the content on the right side. Left side menu has its own controller. When the user selects a checkbox and clicks on 'Go', the checkbox value should be passed to the controller that controls the right side content. Here is the link to the app. Below are the issues I have.
1)I am stumped on a simple problem of accessing checked values of a checkbox. How do I access values of checked checkboxes. The checboxes are on left side menu, and I am using ng-model to currently access the values as below
index.html
<div id="searchOne">
<ul>
<li ng-repeat="searchOneCB in main.checkBoxOneData">
<input type="checkbox" name="firstSearch" id="firstSearch_{{searchOneCB.code}}" ng-model="main.selected[searchOneCB.code]" />
{{searchOneCB.description}}
</li>
</ul>
<button class="btn btn-primary" style="width:80px;margin-right: 10px" ng-click="main.submit()">
Go
</button>
</div>
MainCtrl.js to access the checkbox value.
main.submit = function() {
console.log(main.selected);
}
The values are now in the form of an array as below
[BBBB: true, AAAA: true].
Is this the right way to access the values? What is the best way to retrieve only the checked checbox values?
2) Another question is, once I get the list of checked checkboxes values, how can I pass them to the contentCtrl.js that controls the content on right side?
You should inject the controller into the controller you want to use. The answer has already been answered here is the link.
How do I inject a controller into another controller in AngularJS

How different controllers can relay of each other while page is being loaded?

Think about this simple scenario:
<div ng-controller="ctrl1">
... drop down list...
</div>
<div ng-controller="ctrl2">
...grid list...
</div>
The first <div> contains a dropdown and the second <div> contains grid.
According to the selected item in dropdown, ctrl2 should update the grid with new data. This is working great after loading, I fire event and catch it using $broadcast and $on.
BUT, I am having trouble doing the first load of the grid. The dropdown list loads with a list of items and the first item is selected by default, so the grid should show data according to that default selection. I can't use events here because if I fire event on $init of ctrl1, the $on of ctrl2 didn't initialized yet so it will not work. What is the right way to do this first load?
Please advice.

simple on-click event in angular to switch between two states

I'm building a fairly simple demo in angular and the app has what equates to a main screen and a menu, similar to a landscape mode tablet app where there is a menu on the left of the screen which is always visible, and the main content on the right.
Both the menu and the main content page have their own controllers.
I'm trying to make it so that I can expand the menu out, and collapse it back to 20% width again, while keeping the main page in view.
My problem is that it seems like overkill to create a controller which holds the menu and main page as items, and then to try to nest the menu and main_page controllers within that top level controller.
As far as I've got right now is
<body ng-controller="ViewCtrl">
<div id="menu" ng-controller="MenuCtrl" >
<div ng-click="toggleMenu($event)" > open menu </div>
// all my ng-repeats for menu page content
</div>
<div id="main" ng-controller="MainCtrl">
//all my ng-repeats for the main page content
</div>
<body>
in my ViewCtrl, I have
function ViewCtrl($scope) {
$scope.toggleMenu = function($event){
alert('clicked')
}
}
The problem is that I think I need a way to check if the menu is open, and if so, close it, or else, open it. I've got to set classes on both the MenuCtrl and the MainCtrl for when the menu is opened and closed, and I'd like to be able to close the menu from a click within the MainCtrl.
What is the best way to handle this with angular.
Is there a way to set a class on a parent, if so, I would could do that? Or get any div within the current controller, even if the div isn't created by an angular model? Or do I somehow associate existing divs to the controller?
Most of these sorts of solutions seem quite messy.
The problem is that I think I need a way to check if the menu is open, and if so, close it, or else, open it. I've got to set classes on both the MenuCtrl and the MainCtrl for when the menu is opened and closed, and I'd like to be able to close the menu from a click within the MainCtrl.
There are two ways you can accomplish this.
You can trigger custom angular events in the MainCtrl and listen for them in the MenuCtrl.
You can set a flag(model) on the parent scope (which happens to be ViewCtrl).
Note: You shouldn't modify classes of a DOM element from a controller. Directives should be used for this.

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