<!DOCTYPE html>
<html>

  <head>
    <script data-require="jquery@*" data-semver="2.1.4" src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
    <script data-require="bootstrap@*" data-semver="3.3.5" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <script data-require="angular.js@~1.4.3" data-semver="1.4.6" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js"></script>
    <script data-require="angular-messages@*" data-semver="1.4.3" src="https://code.angularjs.org/1.4.3/angular-messages.js"></script>
    <script src="//rawgit.com/angular/bower-angular/master/angular.js"></script>
    <link data-require="bootstrap@*" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
    <link rel="stylesheet" href="style.css" />
    <script src="//rawgit.com/shaunxu/angular-toolkits/master/tabs/sx-tabs-tpls.js"></script>
    <script src="//rawgit.com/shaunxu/angular-toolkits/master/tabs/sx-tabs.js"></script>
    <!--
    <script src="shaunxu/angular-toolkits/master/tabs/sx-tabs-tpls.js"></script>
    <script src="shaunxu/angular-toolkits/master/tabs/sx-tabs.js"></script>
-->
    <script src="script.js"></script>
    <script src="tabs/general.js"></script>
    <script src="tabs/shared-data.js"></script>
    <script src="tabs/enter-validate.js"></script>
  </head>

  <body ng-app="Demo" ng-controller="HomeCtrl">
    
    <div class="panel panel-info">
        <div class="panel-heading">Shared Scope</div>
        <div class="panel-body">
            <pre>{{context | json}}</pre>
        </div>
    </div>

    <div sx-tabs="tabs" 
         sx-tabs-context="context" 
         sx-tabs-enabled="onTabEnabled(tab)" 
         sx-tabs-disabled="onTabDisabled(tab)" 
         sx-tab-switched="onTabSwtiched(tab)">
    </div>
    
    <div class="panel panel-info">
        <div class="panel-heading">Tabs Event
            <button type="button" class="close" title="Clear Messages" aria-label="Clear" ng-click="clearMessages()">
                <span aria-hidden="true">&times;</span>
            </button>
        </div>
        <div class="panel-body">
            <pre>{{messages | json}}</pre>
        </div>
    </div>
  </body>

</html>
(function () {
    window.app = window.angular.module('Demo', ['ngMessages', 'sx.tabs']);
    
    window.app.controller('HomeCtrl', function ($scope, $q, $timeout) {
        $scope.messages = [];
        $scope.clearMessages = function () {
            $scope.messages = [];
        };
        
        var context = {
            user: 'Shaun',
            company: 'Worktile Inc.',
            department: 'Web'
        };
        // $scope.context = context; 
        $scope.context = $q(function (resolve, reject) {
            $timeout(function () {
                return resolve(context);
            }, 1000);
        });
        
        $scope.tabOptions = {};
        
        $scope.onTabEnabled = function (tab) {
            $scope.messages.push('Tab enabled: ' + tab.id);
        };
        $scope.onTabDisabled = function (tab) {
            $scope.messages.push('Tab disabled: ' + tab.id);
        };
        $scope.onTabSwtiched = function (tab) {
            $scope.messages.push('Tab switched: ' + tab.id);
        };
        
        var tabs = {
            'general': {
                id: 'general',
                title: 'General',
                order: 1110,
                enabled: true,
                templateUrl: 'tabs/general.html',
                controller: 'sxTabGeneralCtrl'
            },
            'shared-data': {
                id: 'shared-data',
                title: 'Shared Data',
                order: 1120,
                enabled: true,
                templateUrl: 'tabs/shared-data.html'
            },
            'enter-validate': {
                id: 'enter-validate',
                title: 'Load & Validation',
                order: 1150,
                enabled: true,
                templateUrl: 'tabs/enter-validate.html',
                controller: 'sxTabEnterValidateCtrl'
            },
            'more-tabs-1': {
                id: 'more-tabs-1',
                title: 'More Tabs 1',
                order: 1210,
                enabled: false,
                template: '<h1>More Tabs 1</h1>'
            },
            'more-tabs-2': {
                id: 'more-tabs-2',
                title: 'More Tabs 2',
                order: 1220,
                enabled: false,
                template: '<h1>More Tabs 2</h1>'
            },
            'more-tabs-3': {
                id: 'more-tabs-3',
                title: 'More Tabs 3',
                order: 1230,
                enabled: false,
                template: '<h1>More Tabs 3</h1>'
            }
        };
        
        // define 'tabs' as an object
        // $scope.tabs = tabs;
        
        // define 'tabs' as a promise
        $scope.tabs = $q(function (resolve, reject) {
            $timeout(function () {
                return resolve(tabs);
            }, 1000);
        });
    });
}());
/* Styles go here */

<div class="jumbotron" style="background-color: #fff;">
  <h1>Hello, tabs!</h1>
  <p>Welcome to use "{{productName}}" in Shaun's Angular Toolkits</p>
</div> 
(function () {
    window.app.controller('sxTabGeneralCtrl', function ($scope) {
        $scope.productName = 'sx.tabs';
    });
}())
(function () {
    window.app.controller('sxTabSharedDataCtrl', function ($scope) {
        
    });
}())
<form>
  <div class="form-group">
    <label for="user">User</label>
    <input type="text" class="form-control" id="user" placeholder="User" ng-model="$context.data.user">
  </div>
  <div class="form-group">
    <label for="company">Company</label>
    <input type="text" class="form-control" id="company" placeholder="Company" ng-model="$context.data.company">
  </div>
  <div class="form-group">
    <label for="dept">Department</label>
    <input type="text" class="form-control" id="dept" placeholder="Department" ng-model="$context.data.department">
  </div>
</form>
<div class="panel panel-info">
    <div class="panel-heading">In-Tab Scope</div>
    <div class="panel-body">
        <pre>Entering: {{_entering}}</pre>
        <pre>Leaving: {{_leaving}}</pre>
    </div>
</div>

<form name="inputForm" novalidate>
  <div class="form-group">
    <label for="user">User</label>
    <input type="text" class="form-control" name="user" id="user" placeholder="User" required ng-model="$context.data.user">
    <div ng-messages="inputForm.user.$error" class="text-danger">
        <div ng-message="required">Name is required.</div>
    </div>
  </div>
  <div class="form-group">
    <label for="company">Company</label>
    <input type="text" class="form-control" name="company" id="company" placeholder="Company" required ng-model="$context.data.company">
    <div ng-messages="inputForm.company.$error" class="text-danger">
        <div ng-message="required">Company is required.</div>
    </div>
  </div>
  <div class="form-group">
    <label for="dept">Department</label>
    <input type="text" class="form-control" name="dept" id="dept" placeholder="Department" required ng-model="$context.data.department">
    <div ng-messages="inputForm.dept.$error" class="text-danger">
        <div ng-message="required">Department is required.</div>
    </div>
  </div>
</form>
(function () {
    window.app.controller('sxTabEnterValidateCtrl', function ($scope, $timeout) {
        $scope._entering = false;
        $scope._leaving = false;
        
        $scope.$context.behavior.entering = function (options, callback) {
            $scope._entering = true;
            if (options.entered) {
                $scope._entering = false;
                return callback ();
            }
            else {
                $timeout(function () {
                    $scope._entering = false;
                    return callback();
                }, 1000);
            }
        };

        $scope.$context.behavior.leaving = function (options, callback) {
            $scope._leaving = true; 

            if (options.byTabDisable) {
                $scope._leaving = false;
                return callback(true);
            }
            else {
                $timeout(function () {
                    $scope._leaving = false;
                    return callback($scope.inputForm.$valid);
                }, 1000);
            }
        };
    });
}())