JSFiddle - React, Tailwind, and code Playground

by bunting

HTML

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.min.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<div ng-app="myApp">
    <div class="panel panel-default" ng-controller="myCtrl">
        <div class="panel-heading">
            <ul class="nav nav-tabs">
                <li class="active">
                    <a class="h4">My App</a>
                </li>
                <li class="dropdown">
                    <a href="" class="dropdown-toggle h4" data-toggle="dropdown">
                        Analysis
                        <span class="caret"></span>
                    </a>
                    <ul class="dropdown-menu">
                        <li>
                            <button id="createTabLink" class="h4" ng-click="createTabClick()">Create Tab</button>
                        </li>
                    </ul>
                </li>
            </ul>
        </div>
        <div class="panel-body">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <ul id="createTabDiv" class="nav nav-tabs"></ul>
                </div>
                <div class="panel-body">
                    <div id="viewWrapper" ng-switch="" on="viewSelected">
                        <div id="Default" ng-switch-when="Default">Default</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

CSS

html, body {
    min-height:100%;
    padding: 10px;
}

a {
    padding-right: 1em;
}

JavaScript

/*

THE IDEA:

The user creates as many tabs as he wants. Each tab's layout will be derived from the same template and controller, but each tab's content is independent from one another (i.e., when I edit tab #2 will have no effect on tab #1). Think of this as two separate MS Word docs: both start out with the same layout and have the same "controller", but edits in one are not reflected in another. To simplify my question, I have made it so each tab displays a static reference to its name/number.

The controller sets the default view for the ng-switch directive, and sets $scope.count = 0 to keep track of the number of tabs. I then add two functions: $scope.createTabClick() and $scope.tabClick().

$scope.createTabClick() dynamically creates a new tab by appending a parent div with a div containing the new tab. It then compiles this using $compile (as per the second solution to this question -- http://stackoverflow.com/a/19268415/3126107). Then, I similarly append a parent div with a new div containing the content of the new tab using the ng-switch-when directive, followed by a compile.

$scope.tabClick() changes the view to the click tab's content by changing $scope.viewSelected (associated to the ng-switch's on attribute) to the new viewName.

*/

angular.module('myApp', []);

function myCtrl($scope, $compile) {
    $scope.count = 0;
    $scope.viewSelected = "Default";

    $scope.tabClick = function($event) {
        var tab = $event.target;
        //console.log(tab);

        var viewName = tab.getAttribute("value");
        //console.log(viewName)
        
        $scope.viewSelected = viewName;
    };

    $scope.createTabClick = function() {

        $scope.count++;
        var viewName = "view" + $scope.count;
        //console.log(viewName);

        var createTabDiv = angular.element(document.querySelector('#createTabDiv'));
        //console.log(createTabDiv);
        
        var viewWrapper = angular.element(document.querySelector('#viewWrapper'));
...