It is also possible to use dynamic content to fill the modal's body content; we will see an example of this in the next topic.
Creating tab directives
In this recipe, we will see how to use another important interface component, Tabs, using the
$http function to load some content.
Getting ready
To accomplish this task, we will create a controller and use the get method of the $http function to retrieve the contents of a JSON file, but first, let's create the JSON content.
We are still using the same code base of the previous example.
Chapter 3
2. A simple array with two properties, save the file in the home directory. Append the following code in the homeCtrl.js file right after the modal directive:
.controller('BootstrapTabCtrl', function ($scope, $http) { // Added some content to Tab / can be from a JSON with $http or $resource
$http.get('app/home/tab-content.json').
success(function(data) {
// Get dynamic data from JSON file $scope.tabs = data;
}).
error(function(status) { // if error, show status console.log(status);
});
})
3. Now, let's add the HTML code to the home.html file, right after the modal code:
<!-- Bootstrap Tab -->
<div style="width:600px; margin:20px auto;">
<div ng-controller="BootstrapTabCtrl">
<tabset>
<tab ng-repeat="tab in tabs" heading="{{tab.title}}"
active="tab.active" disabled="tab.disabled">
{{tab.content}}
</tab>
</tabset>
</div>
</div>
Customizing and Using Bootstrap UI Directives
48
4. Following the same format as the previous example, we will now create a custom directive to extend the UI Bootstrap functionality:
.directive('customTabs', function() { return {
restrict: 'E', transclude: true, scope: {},
controller: [ "$scope", function($scope) { var panes = $scope.panes = [];
'<div class="tabbable">' + '<ul class="nav nav-tabs">' +
'<li ng-repeat="pane in panes" ng- class="{active:pane.selected}">'+
'<a href="" ng-
click="select(pane)">{{pane.title}}</a>' + '</li>' +
'</ul>' +
'<div class="tab-content" ng-transclude></div>' + '</div>',
Chapter 3
49 link: function(scope, element, attrs, tabsCtrl) {
tabsCtrl.addPane(scope);
},
// Using inline template template:
'<div class="tab-pane" ng-class="{active: selected}"
ng-transclude>' +
<!-- Custom Boostrap Tab -->
<div style="width:600px; margin:20px auto;">
<custom-tabs>
<pane title="Custom Tab One">
<div>Tab One Content.</div>
</pane>
<pane title="Custom Tab Two">
<div>Tab Two Content.</div>
</pane>
<pane title="Custom Tab Three">
<div>Tab Three Content.</div>
</pane>
</custom-tabs>
</div>
Note that the style tag on the HTML examples is not a good practice, but we use it just to center the example code on the screen. Please don't do that in production, keep your CSS files in separated files.
How it works…
In large-scale applications, it is very common to use dynamic content to populate the interface components. Our first example demonstrates how easy it is to use this type of content, by implementing a simple Bootstrap tab directive as the following code:
<div ng-controller="BootstrapTabCtrl">
<tabset>
<tab ng-repeat="tab in tabs" heading="{{tab.title}}"
active="tab.active" disabled="tab.disabled">
Customizing and Using Bootstrap UI Directives
The $http.get ()method makes a call to an external file, in this case the tab-content.
json file, to load the tab contents of the directive.
$http.get('app/home/tab-content.json').
success(function(data) {
// Get dynamic data from JSON file $scope.tabs = data;
}).
error(function(status) { // if error, show status console.log(status);
});
In the second example, we created a directive and used an inline template with the inline controller.
controller: [ "$scope", function($scope) { var panes = $scope.panes = [];
Chapter 3
51 '<div class="tabbable">' +
'<ul class="nav nav-tabs">' +
'<li ng-repeat="pane in panes" ng- class="{active:pane.selected}">'+
'<a href="" ng-click="select(pane)">{{pane.title}}</a>' + '</li>' +
'</ul>' +
'<div class="tab-content" ng-transclude></div>' + '</div>',
replace: true };
})
Note that this directive comprises two parts: the first simulates the links behavior as tabs, and the second activates the selected panel:
.directive('pane', function() {
link: function(scope, element, attrs, tabsCtrl) { tabsCtrl.addPane(scope);
},
// Using inline template template:
'<div class="tab-pane" ng-class="{active: selected}" ng- transclude>' +
'</div>', replace: true };
})
It is very common for a directive to be composed of one or more parts. A directive, in this case, depends on the operation of the other. They remain connected using the link property:
link: function(scope, element, attrs, tabsCtrl) { tabsCtrl.addPane(scope);
},
Customizing and Using Bootstrap UI Directives
52
There's more…
We can combine both examples to load external content easily using a controller and an external template in the second example, as performed in the previous examples:
.directive('customTabs', function() { return {
restrict: 'E', transclude: true,
// Declaring scope: {} we using the isolate scope and we can use the directive many times in the same page
scope: {},
controller: customCtrl.js, // Using external template
template:app/common/tabs-custom-tpl.html, replace: true
};
})
See also
f You can find more about dynamic content in the last example of this chapter. You can also check the AngularJS UI Bootstrap documentation at https://github.com/
angular-ui/bootstrap/wiki