AngularJS Example

HTML

<!-- <div ng-app="zippyModule">
  <div ng-controller="Ctrl3">
    Title: <input ng-model="title"> <br>
    Text: <textarea ng-model="text"></textarea>
    <hr>
    <div class="zippy" zippy-title="Details: {{title}}...">{{text}}</div>
  </div>
</div> -->
<div ng-app="tabModule">

    <tab > 


    </tab>
    
</div>

CSS

.tab-content div{
    
    display: none;
}


</style> <!-- Ugly Hack due to jsFiddle issue: http://goo.gl/BUfGZ --> 
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.min.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">

<script id="tab-template" type="text/template">
    <ul class="nav nav-tabs">
        <li data-tab-id="{{tab.id}}" class="btn btn-default" ng-repeat="tab in tabs" > {{tab.name}}  </li> 
    </ul>   

    <div class="tab-content"> 
<div id="{{tab.id}}" ng-repeat="tab in tabs"> {{tab.content}}  </div>
    </div>

</script>

JavaScript

function TabCtrl($scope) {
    $scope.tabs =  convert ( ["first", "second", "third"] ) ;
};

function convert ( array )  {
    var arr = [];
    
    array.forEach( function ( item ) {
        arr.push( {
            name: item,
            id:"tabId" + Math.random().toString().slice(2),
            content: "tabId" + Math.random().toString().slice(2)
        });
                   
    });

    return arr;
                    
}

      //  var first = document.getElementById( scope.tabs[0].id );
       //   first.style.display = "block";


angular.module('tabModule', [])
  .directive('tab', function(){
     var template = document.getElementById("tab-template").innerHTML;
      
    return {
      controller: TabCtrl,
      restrict: 'E',
      // Этот HTML заменит директиву zippy.,
      transclude: true,
      template: template,
      compile: function compile(tElement, tAttrs, transclude) {
          return {
            pre: function preLink(scope, iElement, iAttrs, controller) {
                iElement.bind("click", onClick);
            },
            post: function postLink(scope, iElement, iAttrs, controller) { 
               
            
            }
          }
    }
    }
  });

var prevTab, prevContent, elem;

function onClick( e ) {
    
    var id = e.target.getAttribute("data-tab-id");
        
    
    if ( !id )  return;
    
    e.target.classList.add( "active" );
    
    if( prevTab )
        prevTab.classList.remove("active");
                
    prevTab = e.target;
    
    elem = document.getElementById( id );
    elem.style.display = "block";
    
    if( prevContent )
        prevContent.style.display = "none";
    
    prevContent = elem;

}