The angularjs tab don't switch? - angularjs

why the tab don't switch? when i click the tab 2 or other,it seems to do nothing.
<div class="container">
<h1>Bootstrap AngularJS Tabs</h1>
<div ng-app="">
<div ng-init="names = [{name:'one'}, {name:'two'}, {name:'three'}, {name:'four'}, {name:'five'}]">
<ul class="nav nav-tabs">
<li ng-repeat="name in names" ng-class="{active: $index == 0}">
Tab {{$index + 1}}
</li>
</ul>
<div class="tab-content">
<div class="tab-pane fade in" id="tab{{$index + 1}}" ng-repeat="name in names" ng-class="{active: $index == 0}">
<span>{{$index + 1}}</span><span>{{$index+2}}</span>
</div>
</div>
</div>
</div>
</div><!--/container-->
<script src="./angular.min.js"></script>
<script src="./bootstrap.min.js"></script>

It's because you're always setting the first tab to active by doing ng-class="{active: $index == 0}". You need to compare $index to a property on the scope which you change when the user clicks on the tab header (by combining both the href on your anchor, and an ng-click). Something like this simplified version: http://jsbin.com/tesosisi/1/edit
That example sets $scope.names.activeIndex = 0; in the controller, but you'd want to inspect the current location hash to see which tab should be active from the start.

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.

AngularJS add new tabs to boostrap tab list

I try to implement a tabs nav bar in my app. I use Bootstrap3 and follow this example Boostrap Tabs and Pills.
I have one tab (#home) that is presented every Time. The other tabs i want to generate when i click on addInput() function. I.e tab1, tab2, tab3.
I dont know exactly how to get the combination togther. How can i create a list element with href="#menu1" for the navbar and fitting id="menu1" for the content inside tab.
Here is my example CodePen.io
<div ng-app="myApp" ng-controller="myCtrl">
<form>
<div class="form-group">
<label for="txtDevice" class="control-label">Form Field 1</label>
<input type="text" class="form-control" ng-model="info.name" id="txtDevice">
</div>
<div class="form-group">
<label for="txtIP" class="control-label">Form Field 2</label>
<input type="text" class="form-control" ng-model="info.ip" id="txtIP">
</div>
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#home">Home</a></li>
</ul>
<div class="form-group tab-content">
<div id="home" class="tab-pane fade in active">
<h4>Home</h4>
<p>content</p>
</div>
<div ng-repeat="site in info.sites track by $index">
<h4>tab {{$index +1}}</h4>
<p>content</p>
</div>
</div>
</form>
<button ng-click="addInput()">+add more inputs</button>
{{info | json}}
<hr>
tags = {{tags | json}}
</div>
There were about four things wrong with your pen, that I have fixed here (http://codepen.io/anon/pen/eBRwev?editors=1010)
Your tabs navigation did not include an ng-repeat for the tab headings
<ul id="myTabs" class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#home">Home</a></li>
<li ng-repeat="site in info.sites track by $index" class="tab-pane fade in">
<a data-toggle="tab" href="#tab-{{$index}}" >Tab #{{$index}}</a>
</li>
</ul>
You forgot to include jQuery and Bootstrap JS libraries which are required to use the bootstrap tabs.
You have to call the following snippet of JS to activate the bootstrap click handling on the tabs
$('#myTabs a').click(function (e) {
e.preventDefault();
$(this).tab('show');
});
You're looking something like this?
id="{{ 'menu' + $index }}"

$index restart each row in ng-repeat

I want to repeat this code for each element in my array:
<div class="container" ng-init="parentIndex = $index" ng-repeat="urn in apsocket.mensajes | filter:searchTextURN">
<button style="width:100%" type="button" class="btn btn-info" data-toggle="collapse" data-target="{{'#urn_'+$index}}">{{urn.urn }}</button>
<div id="{{'urn_'+$index}}" class="collapse">
{{urn.timestamp}}
<br>
<p>
<div align="right" ng-repeat="meas in urn.measurements track by $index">
<button style="width:90%;background-color: #68ec6a;border-color:#8bf48c;" type="button" class="btn btn-success" data-toggle="collapse" data-target="{{'#meas_'+parentIndex + '_' +$index}}">{{meas.phenomenon}} </button>
<div style="width:90%" id="{{'meas_'+parentIndex + '_' +$index}}" class="collapse">
{{meas.value + ' ' + meas.uom}}
</div>
</div>
</p>
</div>
</div>
But, while first button in each row works fine and creates a working collapsible, the inner ng-repeats seem not.
Each inner element in each outter row, have the same id. So, for each "container", parentIndex is the same and starts in 0.
What should I do in this case? This is not a fixed array which I load at the beggining. This array recevies data from socket and it get bigger each time a message is received.
If you need any more code or so, just ask.
I would recommend just using the pure angular way. In a repeat, each item has it's own scope so you can do an ng-click="collapse = ! collapse" (something like that), I made you an example here
http://jsfiddle.net/X8era/82/
I just made a fake data structure for examples sake
<ul>
<li ng-repeat="item in objs" ng-click="collapse = ! collapse">
{{item.id}}
<ul ng-show="item.more.length > 0 && collapse">
<li ng-repeat="child in item.more" ng-click="collapse = ! collapse; $event.stopPropagation();" >
{{child.id}}
<ul ng-show="child.more.length > 0 && collapse">
<li ng-repeat="baby in child.more">
{{baby.id}}
</li>
</ul>
</li>
</ul>
</li>
</ul>
If you would like to use the collapse class for an animation or whatever, you can change the part of the ng-show that is collapse to
ng-class="{ 'collapse' : collapse }"
The first 'collapse' being whatever class you want to be toggled.
You don't have to use ng-init="parentIndex = $index". You can access to parent $index like this $parent.$index.
Each ng-repeat creates new scope, that's why you can access to parent by using $parent keyword.
Demo:
var app = angular.module('app',[]);
app.controller('ctrl', function($scope) {
$scope.items = [0, 1, 2, 3, 4];
});
<div ng-app="app" ng-controller="ctrl">
<ul>
<li ng-repeat="item in items track by $index">
<ul>
<li ng-repeat="item in items track by $index">
parent: {{$parent.$index}}
current: {{$index}}
</li>
</ul>
</li>
</ul>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

AngularJS multidir error

so I'm stacking on this problem.
I try to create tabs with loading via ng-include the contents. But doesn't matter what kind of url I include I get always this error http://goo.gl/yyNeQb
I don't have anything else included (Controller,...)
Someone any idea?
<ul class="nav nav-tabs">
<li ng-class="{active: main.active.tab == 'register'}" class="active">
<a ng-click="main.active.tab = 'register'">Register</a>
</li>
<li ng-class="{active: main.active.tab == 'login'}">
<a ng-click="main.active.tab = 'login'">Login</a>
</li>
</ul>
<div class="tab-content">
<div ng-switch="main.active.tab">
<div
ng-switch-when="register"
ng-include src="'../angular/views/register.html'">
</div>
<div
ng-switch-when="login"
ng-include src="'../angular/views/login.html'">
</div>
</div>
</div> <!-- tab content-->
If I include a Controller like this
<script type="text/javascript" src="../angular/controller/RegisterController.js"></script>
The source will be load and I can work with it.
Have not tested it immediately but can you try this instead?
<div class="tab-content">
<div ng-switch="main.active.tab">
<div ng-switch-when="register">
<ng-include src="'../angular/views/register.html'"></ng-include>
</div>
<div ng-switch-when="login">
<ng-include src="'../angular/views/login.html'"></ng-include>
</div>
</div>
</div>

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