Angularjs demo with modal popup

Coded for this SO question: http://stackoverflow.com/questions/29807422/creating-popup-window-with-form-content-and-then-show-output-in-parent-page-and?

by aman1981

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.0/angular.min.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.min.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular-sanitize.min.js"></script>
<div class="container" ng-app="myApp">
   <div  ng-controller="ctrl">
      <div class="panel panel-default data-table">
         <div class="panel-heading">
            <ul class="nav nav-pills">
               <li role="presentation" ng-class="{'active': targetTable == t}" ng-repeat="t in tables"><a href="#" ng-click="select(t)">{{t.name}}</a></li>
               <li><a href="#" ng-click="select(t)">+ Add Table</a></li>
            </ul>
         </div>
         <div class="panel-body">
            <table class="table table-bordered">
               <colgroup>
                  <col class="unique-id">
               </colgroup>
               <thead>
                  <tr>
                     <th class="unique-id">Name #</th>                     
                     <th contenteditable="true" ng-repeat="c in targetTable.columns" ng-model="c.label"></th>
                     <!--<th class="view-next-set"><a href="#">...</a></th>-->
                     <td class="center add-column"><a href="#" ng-click="addColumn()">+ Add Column</a></td>
                  </tr>
               </thead>
               <tbody>
                  <tr ng-repeat="r in targetTable.rows">
                     <td contenteditable="true" class=""></td>
                     <td contenteditable="true" ng-repeat="column in targetTable.columns" ng-model="r[column.id]" ng-blur="!r.id? addNewRow(r[column.id], r): undefined"></td>
                     <!--<td class="blank" colspan="2"></td>-->
                  </tr>               
               </tbody>
            </table>
         </div>
      </div>
     <div...

CSS

body { margin:60px 0px; }

.data-table .nav-pills li { text-transform: capitalize; }
.nav.nav-pills li span { padding: 20px; }
.table .unique-id { width: 10px !important; text-align: center; background-color:#f5f5f5; }
.table td, .table th { width: 120px; }
.table .center { text-align: center; }
.table th.font-normal { font-weight: normal; }
.table .view-next-set { width:5px; text-align:center; font-size:0.9em; }
.table .add-column { width:60px; font-size:1em; vertical-align: middle; }

.table .unique-id, .table td.blank { background-color:#f5f5f5; }

JavaScript

angular.module('customControl', ['ngSanitize']).
directive('contenteditable', ['$sce', function($sce) {
  return {
    restrict: 'A', 
    require: '?ngModel', 
    link: function(scope, element, attrs, ngModel) {
      var disable = (attrs.contenteditable === "false") || !Boolean(attrs.contenteditable);
      if (!ngModel || disable) return; // do nothing if no ng-model
      
      // Write data to the model
      var read = function(value) {
        var html = element.html() || (typeof value === "string"? value: "");
        
        // When we clear the content editable the browser leaves a <br> behind
        // If strip-br attribute is provided then we strip this out
        if ( attrs.stripBr && html == '<br>' ) { html = ''; }
        ngModel.$setViewValue(html);
      };  

      // Specify how UI should be updated
      ngModel.$render = function() {
        element.html($sce.getTrustedHtml(ngModel.$viewValue || ''));
      };

      // Listen for change events to enable binding
      element.on('blur keyup change', function() {
        scope.$evalAsync(read);
      });
      
      setTimeout(function(){
        read(ngModel.$modelValue); // initialize
      });
      
    }
  };
}]);


var app = angular.module('myApp', ['customControl']);

// Define the `appController` controller on the `ReportsMockUpsApp` module
app.controller('ctrl', function($scope) {
   var table =  {
     id: 0,
     name: "table 1",
     columns: [],
     rows: [{}],
     uniqueIdCounter: 1037
   };
  
   $scope.tables = [table];  
   $scope.targetTable = $scope.tables[0];
  
  $scope.select = function(tbl) {
    $scope.selectedTable = tbl;
  };
  
  $scope.addColumn = function() {
    var columns = $scope.targetTable.columns, id = columns.length;
    $scope.targetTable.columns.push({
      id: columns.length, 
      label: `Column ${id}`
    });
  };  
  
  $scope.addNewRow = function(value, row) { 
    if(!value || value === "" || typeof value !== 'string') return;
   ...