Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html ng-app="app">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
</head>
<body ng-controller="demoController">
  <button ng-click="undo()" ng-if="canUndo">Undo</button>
  <button ng-click="redo()" ng-if="canRedo">Redo</button>
 <div scrolly="increaseLimit()" class="scrollit" >
  <table  class="table table-bordered" ng-keypress="onKeyPress($event)">
        <!-- {{ itemsArr }} -->
        <thead>
            <tr>
                <th>Operation Description</th> 
                <th>Requirements</th>
                <th>Potential Failure Mode</th>
                <th>Potential Effects of failure mode</th>
            </tr>
        </thead>
        <tbody  ng-repeat="(opIndex, items) in itemsArr | limitTo:limit">
            <tr ng-repeat="Requirement in items.Requirements" >
                      <td  ng-style="items.isItemDeleted && {'background-color': '#f2dede'}" rowspan="{{items.Requirements.length}}" ng-if="$first">
                         <span  ng-hide="items.itemEditing" ng-click="editItem(items,'itemEditing')" >{{items.operation}}</span>
                         <input ng-show="items.itemEditing" ng-model="items.operation" ng-blur="doneEditing(items,'itemEditing')" autofocus />
                         
                         <button ng-if="!items.isItemDeleted" type="button"  style="float: right;" class="btn btn-success btn-circle"   ng-click="addNewItem(opIndex)">  <span class="glyphicon glyphicon-plus"></span></button>
                         <button ng-if="!items.isItemDeleted" type="button"  style="float: right;" class="btn btn-danger btn-circle"   ng-click="deleteItem(opIndex)">  <span class="glyphicon glyphicon-minus"></span></button>
                       </td> 
                      <td ng-style="Requirement.isDeleted && {'background-color': '#f2dede'} || Requirement.isNewRequirement && {'background-color': '#dff0d8'}" 
                      rowspan="{{Requirement.effectsLength}}" ng-if="Requirement.PC!=''">
                          <span  ng-hide="Requirement.pcEditing" ng-click="editItem(Requirement,'pcEditing')">{{Requirement.PC}}</span>
                          <input ng-show="Requirement.pcEditing" ng-model="Requirement.PC" ng-blur="doneEditing(Requirement,'pcEditing')" autofocus />
                          <button ng-if="!Requirement.isDeleted" type="button"  style="float: right;" class="btn btn-success btn-circle"   ng-click="addNewRequirement(opIndex,$index,Requirement)">  <span class="glyphicon glyphicon-plus"></span></button>
                          <button ng-if="!Requirement.isDeleted" type="button"  style="float: right;" class="btn btn-danger btn-circle"   ng-click="deleteRequirement(items.opid,opIndex,Requirement.pcid,Requirement.fmid,$index)">  <span class="glyphicon glyphicon-minus"></span></button>
                      </td>
                       <td  ng-style="Requirement.isDeleted && {'background-color': '#f2dede'} || Requirement.isNewRequirement && {'background-color': '#dff0d8'}" 
                       rowspan="{{Requirement.effectsLength}}"  ng-if="Requirement.FM!=''"> 
                          <span  ng-hide="Requirement.fmEditing" ng-click="editItem(Requirement,'fmEditing')">{{Requirement.FM}}</span>
                          <input ng-show="Requirement.fmEditing" ng-model="Requirement.FM" ng-blur="doneEditing(Requirement,'fmEditing')" autofocus />
                          <button ng-if="!Requirement.isDeleted" type="button"  style="float: right;" class="btn btn-success btn-circle"   ng-click="addNewRequirement(opIndex,$index,Requirement)">  <span class="glyphicon glyphicon-plus"></span></button>
                          <button ng-if="!Requirement.isDeleted" type="button"  style="float: right;" class="btn btn-danger btn-circle"   ng-click="deleteRequirement(items.opid,opIndex,Requirement.pcid,Requirement.fmid,$index)">  <span class="glyphicon glyphicon-minus"></span></button>
                      </td>
                       <td ng-style="Requirement.isDeleted && {'background-color': '#f2dede'} || Requirement.isEffectsDeleted && {'background-color': '#f2dede'} 
                       || Requirement.isNewRequirement && {'background-color': '#dff0d8'} || Requirement.isNewEffect && {'background-color': '#dff0d8'} ">
                             <span  ng-hide="Requirement.effectEditing" ng-click="editItem(Requirement,'effectEditing')">{{Requirement.effect}}</span>
                             <input ng-show="Requirement.effectEditing" ng-model="Requirement.effect" ng-blur="doneEditing(Requirement,'effectEditing')" autofocus />
                             <button ng-if="!Requirement.isDeleted && !Requirement.isEffectsDeleted" type="button" style="float: right;" class="btn btn-primary btn-circle" ng-click="addNewEffect(items.opid,opIndex,Requirement.pcid,Requirement.fmid,$index)"> <span class="glyphicon glyphicon-plus"></span></button>
                             <button ng-if="!Requirement.isDeleted && !Requirement.isEffectsDeleted" type="button" style="float: right;" class="btn btn-danger btn-circle"  ng-click="deleteEffect(opIndex,$index)">  <span class="glyphicon glyphicon-minus"></span></button>
                      </td>
            </tr>
        </tbody>    
        
        
 </table>
 </div>
  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
 <script src=" https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
 <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-hotkeys/1.7.0/hotkeys.min.js"></script>
 <script src="https://rawgit.com/Blitzen/Angular-Chronicle/master/chronicle.js"></script>
       
   
</body>
</html>
 
var app = angular.module('app', [
    'Chronicle',
    'cfp.hotkeys'
  ])
app.controller('demoController', [
  '$scope','Chronicle','hotkeys','dataService',
  function ($scope,Chronicle,hotkeys,dataService) {
      begin();
      
      
     function begin(){
           $scope.opid = 1;
           $scope.reqid = 3;
           $scope.itemsArr = [{
            'opid': '1',
            'operation': 'opt des..',
            'Requirements': [
              {'pcid': '1','fmid': '1', 'PC': 'PC1','FM': 'FM1','effect': 'Potential Effects 111....', 'effectsLength': '4' },
              { 'pcid': '1','fmid': '1', 'PC': '',  'FM': '', 'effect': 'Potential Effects 222....'},
              {'pcid': '1','fmid': '1',  'PC': '',  'FM': '','effect': 'Potential Effects 333....' },
              {'pcid': '1', 'fmid': '1', 'PC': '','FM': '','effect': 'Potential Effects 123....'  },
              {'pcid': '2','fmid': '2','PC': 'PC2', 'FM': 'FM2','effect': 'Potential Effects 444....','effectsLength': '3'},
              { 'pcid': '2',  'fmid': '2','PC': '', 'FM': '','effect': 'Potential Effects 555....' },
              {'pcid': '2','fmid': '2',  'PC': '',  'FM': '', 'effect': 'Potential Effects 666....' },
              {'pcid': '3', 'fmid': '3', 'PC': 'PC3','FM': 'FM3','effect': 'Potential Effects 777....','effectsLength': '3' },
              {'pcid': '3', 'fmid': '3',  'PC': '',  'FM': '', 'effect': 'Potential Effects 888....' },
              { 'pcid': '3','fmid': '3', 'PC': '',  'FM': '','effect': 'Potential Effects 999....'}
            ]
      }];
       
       $scope.limit = 5;
       dataService.getData().then(function (result) {
           console.log("loading done...!!!",result.data);
           $scope.itemsArr = result.data;
            redoUndo();
       });  
        
       
   } 
   
    
    function redoUndo(){
          //redo undo functionality
        $scope.canUndo = false;
        $scope.canRedo = false;
        //Creation of chronicle object
        $scope.numChronicle = Chronicle.record('itemsArr', $scope);
        $scope.canUndoRedo = function(){
            $scope.canUndo = $scope.numChronicle.canUndo();
            $scope.canRedo = $scope.numChronicle.canRedo();
        };
        $scope.numChronicle.addOnAdjustFunction($scope.canUndoRedo);
        $scope.numChronicle.addOnUndoFunction($scope.canUndoRedo);
        $scope.numChronicle.addOnRedoFunction($scope.canUndoRedo);
        
        $scope.undo = function(){
            $scope.numChronicle.undo()
        };
        $scope.redo = function(){
            $scope.numChronicle.redo()
        };
        
        hotkeys.add({
            combo: 'ctrl+z',
            description: 'undo',
            callback: function() {
              $scope.numChronicle.undo();
            }
        });
        
        hotkeys.add({
            combo: 'ctrl+y',
            description: 'redo',
            callback: function() {
              $scope.numChronicle.redo();
            }
        });
    }
    
    
      
    $scope.increaseLimit = function(){
        $scope.limit += 10;
        console.log("limit :=",$scope.limit)
    }
    
    $scope.addNewItem = function (opIndex) {
      $scope.opid++;
      var newOperation = {
          'opid': $scope.opid,
          'operation': '<new operation>',
          'Requirements': [{
              'pcid': $scope.reqid,
              'fmid': $scope.reqid,
              'PC': '<New PC>',
              'FM': '<New FM>',
              'effect': '<New Effect>',
              'effectsLength': '1',
              'isNewRequirement': true,
              'isNewEffect': true
            }]
        };
      $scope.itemsArr.splice(parseInt(opIndex) + 1, 0, newOperation);//.push(newOperation);
    };
    $scope.addNewRequirement = function (opIndex,requirementId,equirementObj) {
      $scope.reqid++;
      var newRequirement = {
          'pcid': $scope.reqid,
          'fmid': $scope.reqid,
          'PC': '<New PC>',
          'FM': '<New FM>',
          'effect': '<New Effect>',
          'effectsLength': '1',
          'isNewRequirement': true,
          'isNewEffect': true
        };
      $scope.itemsArr[opIndex].Requirements.splice(parseInt(requirementId) + parseInt(equirementObj.effectsLength), 0, newRequirement); //.push(newRequirement);
    };
    $scope.addNewEffect = function (opid, opIndex, pcid, fmid, requirementId) {
      angular.forEach($scope.itemsArr[opIndex].Requirements, function (obj, index) {
        if (obj.pcid == pcid && obj.fmid == fmid && obj.effectsLength != undefined) {
          $scope.itemsArr[opIndex].Requirements[index].effectsLength = parseInt(obj.effectsLength) + 1;
        }
      });
      var newRequirement = {
          'pcid': pcid,
          'fmid': fmid,
          'PC': '',
          'FM': '',
          'effect': '<New Effect>',
          'isNewEffect': true
        };
      $scope.itemsArr[opIndex].Requirements.splice(parseInt(requirementId) + 1, 0, newRequirement);
    };
    $scope.deleteRequirement = function (opid, opIndex, pcid, fmid, requirementId) {
      //console.log(opid,opIndex,pcid,fmid, requirementId)
      angular.forEach($scope.itemsArr[opIndex].Requirements, function (obj, index) {
        if (obj.pcid == pcid && obj.fmid == fmid) {
          $scope.itemsArr[opIndex].Requirements[index].isDeleted = true;
        }
      });
    };
    $scope.deleteEffect = function (opIndex, requirementId) {
      $scope.itemsArr[opIndex].Requirements[requirementId].isEffectsDeleted = true;
    };
    $scope.deleteItem = function (opIndex) {
      $scope.itemsArr[opIndex].isItemDeleted = true;
      angular.forEach($scope.itemsArr[opIndex].Requirements, function (obj, index) {
        $scope.itemsArr[opIndex].Requirements[index].isDeleted = true;
      });
    };
    $scope.editItem = function (item, prop) {
      if (!item.isDeleted && !item.isItemDeleted)
        item[prop] = true;
    };
    $scope.doneEditing = function (item, prop) {
      item[prop] = false;  //dong some background ajax calling for persistence...
    };
    
    
   
  }
]);
app.directive('scrolly', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            var raw = element[0];
            console.log('loading directive');
                
            element.bind('scroll', function () {
                console.log('in scroll');
                console.log(raw.scrollTop + raw.offsetHeight);
                console.log(raw.scrollHeight);
                if (raw.scrollTop + raw.offsetHeight > raw.scrollHeight) {
                    scope.$apply(attrs.scrolly);
                }
            });
        }
    };
});
app.factory("dataService", function($q) {
    return {
        getData:getData
    }
    function getData(){
        var deferred = $q.defer();
        var itemsArr =[];
        var datasize = 50;
        //poor performance when data is large 
       //var datasize = 5000;
        console.log("start...");
        for(var i=1;i<=datasize;i++){
            var tempObj ={};
            tempObj.opid = i;
            tempObj.operation = 'opt des..'+i;
            tempObj.Requirements = [
            {'pcid': '1','fmid': '1', 'PC': 'PC1','FM': 'FM1','effect': 'Potential Effects 111....', 'effectsLength': '4' },
            { 'pcid': '1','fmid': '1', 'PC': '',  'FM': '', 'effect': 'Potential Effects 222....'},
            {'pcid': '1','fmid': '1',  'PC': '',  'FM': '','effect': 'Potential Effects 333....' },
            {'pcid': '1', 'fmid': '1', 'PC': '','FM': '','effect': 'Potential Effects 123....'  },
            {'pcid': '2','fmid': '2','PC': 'PC2', 'FM': 'FM2','effect': 'Potential Effects 444....','effectsLength': '3'},
            { 'pcid': '2',  'fmid': '2','PC': '', 'FM': '','effect': 'Potential Effects 555....' },
            {'pcid': '2','fmid': '2',  'PC': '',  'FM': '', 'effect': 'Potential Effects 666....' },
            {'pcid': '3', 'fmid': '3', 'PC': 'PC3','FM': 'FM3','effect': 'Potential Effects 777....','effectsLength': '3' },
            {'pcid': '3', 'fmid': '3',  'PC': '',  'FM': '', 'effect': 'Potential Effects 888....' },
            { 'pcid': '3','fmid': '3', 'PC': '',  'FM': '','effect': 'Potential Effects 999....'}
          ]
            itemsArr.push(tempObj);
            
        }
        deferred.resolve({
            data: itemsArr
        });
        return deferred.promise;
    }
});
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
anonymouspro
0viewers