How to debug and fix incompatible AngularJS components? - angularjs

I am using angular.tree and the Accordion in UI Bootstrap. The tree properly receives events when placed outside of the accordion, but not when placed within it.
Demo here: Plunker
<p>Accordion: Click "Tree in accordion" below to show tree</p>
<div ng-controller="TestController">
<accordion close-others="true">
<accordion-group heading="Tree in accordion">
<ul ng-tree="model" multiple>
<!-- PROBLEM: doSelected() is not called -->
<li select="doSelected()">{{item.name}}</li>
</ul>
</accordion-group>
<accordion-group heading="Other">
<h1>Other</h1>
</accordion-group>
</accordion>
<hr>
<p>Another tree</p>
<ul ng-tree="model2" multiple>
<!-- doSelected2() is correctly called, see alert output -->
<li select="doSelected2()">{{item.name}}</li>
</ul>
</div>

Related

Allowing multiple directives to transclude in a recursive template

I am currently receiving a tree of managers and their subordinates from the back end. I'm using a recursive template to display this.
<script type="text/ng-template" id="managerTmp">
<div class="accordion">
{{user.firstName}} {{user.lastName}}
<ul class="list-group" ng-if="user.subordinates" >
<li class="list-group-item" ng-if="user.subordinates" ng-repeat="user in user.subordinates" ng-include="'managerTmp'">
</li>
</ul>
</div>
</script>
<div class="col-lg-12" ng-show="section === 5">
<uib-accordion close-others="oneAtATime" ng-show="portal.acManagers && !spinning">
<ul class="list-group" id="1q2w3e">
<li class="list-group-item" ng-repeat="user in portal.acManagers" ng-include="'managerTmp'" ></li>
</ul>
</uib-accordion>
</div>
This all works fine and I get a ul/li of the tree. However, whenever I try changing the ul/li to the angularUI accordion (uib-accordion & uib-accordion-group) i get an error saying
Error: [$compile:multidir] Multiple directives [ngInclude, uibAccordionGroup (module: ui.bootstrap.accordion)] asking for transclusion on: <uib-accordion-group class="list-group-item" ng-if="user.subordinates" ng-repeat="user in user.subordinates" ng-include="'managerTmp'" id="azqx">
I don't fully understand the issue or why angularjs does not allow this? Any help would be greatly appreciated.

Data not binding in the angular dropdown

I have created a dropdown using angularjs and bootstrap.
i want to open a link if it clicks any value from the the dropdown.
But not able to get the data in the dropdownlist.
Below is the fiddle link.help is much appreciated:-
Code goes here:-
HTML Code
<div ng-app="myApp" ng-controller="myController">
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" data- toggle="dropdown">Dropdown Example
<span class="caret"></span></button>
<ul class="dropdown-menu" ng-repeat="item in items">
<li>{{item.GroupName}}</li>
</ul>
</div>
</div>
Controller
var myApp=angular.module("myApp",[]);
myApp.controller("myController",['$scope',function($scope){
$scope.items=[{"GroupID":"15","GroupName":"Client Management Product"},
{"GroupID":"5","GroupName":"DevOps"},
{"GroupID":"18","GroupName":"Resource Centre"},
{"GroupID":"16","GroupName":"SEF"},
{"GroupID":"17","GroupName":"Shared Services"}]
}]);
http://jsfiddle.net/smsh/st4hn14a/
Hi you have not added boootstrap.min.js and jQuery as external resources in your example
Check this Demo
<ul class="dropdown-menu">
<li ng-repeat="item in items">{{item.GroupName}}</li>
</ul>

angular load ui-bootstrap tabbed content dynamically

I am using angular ui-bootstrap tabs for developing tabs.
But how I load tabbed data dynamically after each tab click.
I am able to load the static content. But I want to load data dynamically from ajax.
Each tab containing different HTML files.
controller
$scope.customerInfoTabs =
{
"General":[
"General",
"Employment",
"Relationship Status",
],
"Identification":[]
}
$scope.customerInfo = $scope.customerInfoTabs['General'];
template
<div class="well">
<div class="tabbable">
<ul class="nav nav-tabs">
<li ng-class="{'active': $index == 0}" ng-repeat="infotabs in customerInfo"><a showtab="" href= data-toggle="tab" ng-click="">{{infotabs}}</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab1">
<p>I'm in Section 1.</p>
</div>
<div class="tab-pane" id="tab2">
<p>Howdy, I'm in Section 2.</p>
</div>
<div class="tab-pane" id="tab3">
<p>Howdy, I'm in Section 3.</p>
</div>
</div>
</div>
</div>
If you want to show dynamic content for each tab you will need to use $http service to fetch the html, then bind it using ngBindHtml.
Here is how:
<tabset>
<tab ng-repeat="tab in tabs" heading="{{tab.title}}" select="loadData()">
<div ng-bind-html="tabDynamicContent"></div>
</tab>
</tabset>
The above example is a simplification where all the tabs will have the same html. Also make sure you include the ngSanitize module.
Here is the plunkr: http://plnkr.co/edit/Yege43KerzfFKE8k5OGc?p=preview
I think this question was answer by this stackoverflow:
first link or second link
So you could use a tab set in order to do the work you need.

UI-Bootstrap Accordion Directive not working

I downloaded the angularjs UI Bootstrap accordion directive found here: UI Bootstrap
However, I cannot get it to work and the <accordion> tag generates errors. I included the ['ui.bootstrap'] dependency in my angular module and I put references to files directly on page. Can anyone tell me what I am missing?
Here is my module:
var myApp = angular.module("dashboardManagement", ['ui.bootstrap'])
Here is my view:
#section scripts{
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/angular-animate.js"></script>
<script src="~/Scripts/app/app.js"></script>
<script src="~/Scripts/app/Contractor/contractorController.js"></script>
<script src="~/Scripts/app/Contractor/contractorService.js"></script>
<script src="~/Scripts/ui-bootstrap-custom-tpls-0.13.3.js"></script>
<script src="~/Scripts/app/Test/AccordionDemoCtrl.js"></script>
}
<h2>Index</h2>
<div ng-app="dashboardManagement">
<div>
<div>
<div ng-controller="AccordionDemoCtrl">
<p>
<button type="button" class="btn btn-default btn-sm" ng-click="status.open = !status.open">Toggle last panel</button>
<button type="button" class="btn btn-default btn-sm" ng-click="status.isFirstDisabled = ! status.isFirstDisabled">Enable / Disable first panel</button>
</p>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="oneAtATime">
Open only one at a time
</label>
</div>
<accordion close-others="oneAtATime">
<accordion-group heading="Static Header, initially expanded" is-open="status.isFirstOpen" is-disabled="status.isFirstDisabled">
This content is straight in the template.
</accordion-group>
<accordion-group heading="{{group.title}}" ng-repeat="group in groups">
{{group.content}}
</accordion-group>
<accordion-group heading="Dynamic Body Content">
<p>The body of the accordion group grows to fit the contents</p>
<button type="button" class="btn btn-default btn-sm" ng-click="addItem()">Add Item</button>
<div ng-repeat="item in items">{{item}}</div>
</accordion-group>
<accordion-group is-open="status.open">
<accordion-heading>
I can have markup, too! <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
</accordion-heading>
This is just some content to illustrate fancy headings.
</accordion-group>
</accordion>
</div>
</div>
`
there's a couple of different issues I can see here. First is, you are including both the minified and unminified versions of these resources, so you have the same code twice. So make sure to just include <script src="~/Scripts/ui-bootstrap-custom-tpls-0.13.3.js"></script> and remove the other three similar overlapping scripts. Are you also including Angular above these scripts? because that is a dependency and will throw errors if not included before
second, is the provided example code what you're actually using? Because of course just having this:
<accordion>
</accordion>
will not do very much. You have to provide content for this directive like:
<accordion>
<accordion-group heading="{{group.title}}" ng-repeat="group in groups">
{{group.content}}
</accordion-group>
</accordion>
Check out the plnkr demo for full working example code:
http://plnkr.co/edit/MlcqWL?p=preview
What I discovered is that the Accordion feature is not working as expected because my _Layout.cshtml has a nav-sidebar in it. If I comment out the navbar, the Accordion works as expected. I plan to post a "new" question regarding the found issue.

Adding ng-click event with jQuery

Being new to Angularjs, I need a bit of help with this issue. I am attempting to add ng-click="getGallery(57)" to a modal tab. Adding via jQuery is not the issue, however I realize when I do this, Angular is not compiling the newly added ng-click. I have a simple controller
function imageGalleryCtrl ($scope, $http) {
//get gallery info on click
$scope.getGallery = function(id)
{
$http.post('/beta/images/get_images',{'id': id}).success(function(data)
{
$scope.images = data.thisGal_images;
$scope.images.galID = id;
});
};
}
I add the ng-click to the element with jQuery
//Edit image tab to use angularjs
$('#image_edit a').attr('ng-click','getGallery(' + settings.id + ')');
How do I force Angular to compile this newly added ng-click?
Thanks!
HTML Modal:
This is the modal that is called when the gallery name is clicked.
<div class="modal fade hide modal-creator" id="imageUploader" tabindex="-1" data-focus-on="input:first">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"></button>
<h3>Create New Gallery</h3>
</div>
<div class="modal-body">
<ul id="myTab" class="nav nav-tabs">
<li id="image_home" class="">
Home
</li>
<li id="image_upload" class="">
Upload Image Gallery
</li>
<li id="image_edit" class="">
Edit Image Gallery
</li>
</ul>
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade in" id="home">
<?php include('create.php'); ?>
</div>
<div class="tab-pane fade" id="upload">
<?php include('upload.php'); ?>
</div>
<div class="tab-pane fade" id="edit">
<div class="span9">
<ul id="imageSort" class="gallery-container">
<li ng-repeat="image in images">
<img ng-src="http://images.onlinealbumproofing.com/imageGallery/{{image.galleryID}}/{{image.imageName}}" alt="">
{{image.orgName}}
</li>
</ul>
</div><!-- /span9 -->
</div><!-- /row -->
</div>
</div>
</div><!-- /modal-body -->
<div class="modal-footer">
Close
Next
</div>
</div>
Update
So really attempting to do this the Angular way, and after some studies here is where I am at.
The controller is the same as above and I have updated the tabs on the modal as follows.
<div class="modal-body">
<ul id="myTab" class="nav nav-tabs">
<li id="image_home" class="">
Home
</li>
<li id="image_upload" class="">
Upload Image Gallery
</li>
<li id="image_edit" class="">
<a ng-click="getGallery(57)" href="#edit" data-toggle="tab">Edit Image Gallery</a>
</li>
</ul>
If I hard code the ng-click as above, the tab updates as expected. What I am trying to make happen, is when the modal is called, (#image_edit a) gets a defined ng-click="getGallery(id). I need to tell Angular to look at the ng-click again for the id.
Although I too think that you should try and find another approach, the answer to your question
How do I force Angular to compile this newly added ng-click?
is
// remove and reinsert the element to force angular
// to forget about the current element
$('#button1').replaceWith($('#button1'));
// change ng-click
$('#button1').attr('ng-click','exec2()');
// compile the element
$compile($('#button1'))($scope);
See this working example: http://plnkr.co/edit/SgvQzaY0TyFHD1Mf0c3F?p=preview
Basically what I'm getting at is you want to probably make this happen:
<ul id="imageSort" class="gallery-container">
<li ng-repeat="image in images">
<img
ng-src="http://images.onlinealbumproofing.com/imageGallery/{{image.galleryID}}/{{image.imageName}}"
alt=""
ng-click="getGallery(image.galleryID)"
>
{{image.orgName}}
</li>
</ul>
The problem is I'm unsure of the relationship between the settings.id and the galleryID for a particular image. If you can set up this relationship in the data so it just automatically binds you're in better shape.

Resources