1

I'd like to divide content with bootstrap tabs. This works fine except the html breaks when I attach the ng-controller in parent elements. Is there a way to use html elements to insert ng-controller without affecting the hierarchy necessary to display tabs in bootstrap?

Working tab layout:

<div ng-app="myApp">
  <div class="tab-content">
    <div id="tab1" class="tab-pane fade in active">{{ tab1_content }}</div> 
    <div id="tab2" class="tab-pane fade in">{{ tab2_content }}</div> 
    <div id="tab3" class="tab-pane fade in">{{ tab3_content }}</div> 
  </div> <!-- all tab-content -->
</div> <!-- end myApp -->

How I'd like to use my controllers (breaks the tab displays by putting content in all tabs:

<div ng-app="myApp">
  <div class="tab-content">
    <ng-controller ng-controller="test_controller1">   
      <div id="tab1" class="tab-pane fade in active">{{ tab1_content }}</div> 
      <div id="tab2" class="tab-pane fade in">{{ tab2_content }}</div> 
    </ng-controller> <!-- end test_controller1 -->
    <ng-controller ng-controller="test_controller2">   
      <div id="tab3" class="tab-pane fade in">{{ tab3_content }}</div> 
    </ng-controller> <!-- end test_controller2 -->
  </div> <!-- all tab-content -->
</div> <!-- end myApp -->

Demo: https://jsfiddle.net/L2b4yLfa/

3
  • FishBulbX i followed this approach and it solved loading different controller for each tab github.com/rpocklin/ui-router-tabs Commented Aug 10, 2017 at 19:50
  • you shouldn't be using bootstrap with angular, you should use [UI Bootstrap Bootstrap components written in pure AngularJS by the AngularUI ](angular-ui.github.io/bootstrap). Commented Aug 10, 2017 at 19:51
  • Thanks for the comments and suggestions... I do see that my current approach is not feasible. Commented Aug 10, 2017 at 20:58

2 Answers 2

1

Is this acceptable?

I have initialized the same controller for two tabs. Since its a small window the code snippet output will show mobile view. click on run code snippet -> full page

angular.module('myApp', []);
angular.module('myApp').controller('test_controller1', function($scope) {
	$scope.tab1_content = "Tab One Content";
	$scope.tab2_content = "Tab Two Content";
});

angular.module('myApp').controller('test_controller2', function($scope) {
	$scope.tab3_content = "Tab Three Content";
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<nav class="navbar navbar-default">
	<div class="container-fluid">
		<div class="navbar-header">
			<button type="button" class="navbar-toggle pull-left" data-toggle="collapse" data-target="#myNavbar"><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button>
			<a class="navbar-brand" href="#">Title</a>
		</div>
		<div class="collapse navbar-collapse" id="myNavbar">
			<ul class="nav navbar-nav">
				<li class="active"><a data-toggle="tab" href="#tab1">Tab 1</a></li>
				<li><a data-toggle="tab" href="#tab2">Tab 2</a></li> 
				<li><a data-toggle="tab" href="#tab3">Tab 3</a></li> 
			</ul>
			<ul class="nav navbar-nav navbar-right">
				<li>Testing</li>
			</ul>
		</div>
	</div>
</nav>

<div ng-app="myApp">
  <div class="tab-content">
      <div id="tab1" ng-controller="test_controller1" class="tab-pane fade in active">{{ tab1_content }}</div> 
      <div id="tab2" ng-controller="test_controller1" class="tab-pane fade in">{{ tab2_content }}</div> 
      <div id="tab3" ng-controller="test_controller2" class="tab-pane fade in">{{ tab3_content }}</div> 
  </div> <!-- all tab-content -->
</div> <!-- end myApp -->

So in the future you would need to share data between the same controller for the two tabs using services.

Sign up to request clarification or add additional context in comments.

2 Comments

Yes... I thought of that... and the issue of creating two scopes for test_controller1 would be problematic. Not sure if it is worth the effort for a simple layout issue.
It all depends on the situation and whether the tab1 and tab2 really need to communicate, if the communication is minimal then go for a third controller(one for each tab) or even a single controller for all three tabs( but I dont think we can use a single controller for two adjacent elements without it being as a parent element), services can be used to share the variables.
0

My solution was to switch to angular bootstrap ui, not use the built-in uib-tabs and use $rootscope to handle the 'active_tab' value.

<style> .uib-tab.nav-item { display:none; } .nav-tabs { border-bottom: inherit; } </style>
<div ng-app="myApp">
  <nav class="navbar navbar-default" role="navigation">
    <div class="navbar-header">
        <button type="button" class="navbar-toggle" ng-click="navCollapsed = !navCollapsed">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href="#">Title</a>
    </div> <!-- end navbar-header -->
    <div class="collapse navbar-collapse" uib-collapse="navCollapsed">
      <ul class="nav navbar-nav">
        <li ng-class="{active: active_tab == 1}" ng-click="active_tab = 1"><a href="#">Tab 1</a></li>
        <li ng-class="{active: active_tab == 2}" ng-click="active_tab = 2"><a href="#">Tab 2</a></li> 
        <li ng-class="{active: active_tab == 3}" ng-click="active_tab = 3"><a href="#">Tab 3</a></li> 
      </ul>
      <ul class="nav navbar-nav navbar-right">
        <li><a href="#">Selected Tab: {{ active_tab }}</a></li>
      </ul>
    </div> <!-- end uib-collapse -->
  </nav> <!-- end nav -->

  <uib-tabset active="active_tab">
    <ng-controller ng-controller="test_controller1">
      <uib-tab index="1" heading="heading not displayed">1: {{ tab1_content }}</uib-tab>
      <uib-tab index="2" heading="heading not displayed">2: {{ tab2_content }}</uib-tab>
    </ng-controller>
    <ng-controller ng-controller="test_controller2">
      <uib-tab index="3" heading="heading not displayed">3: {{ tab3_content }}</uib-tab>
    </ng-controller>
  </uib-tabset>
</div>

Demo: https://plnkr.co/edit/36tkl3pCV7hgNz8rbpTq?p=preview

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.