<!DOCTYPE html>
<html>

  <head>
    <link data-require="bootstrap@*" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
    <script data-require="jquery@*" data-semver="2.1.1" src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
    <script data-require="bootstrap@*" data-semver="3.0.0" src="//maxcdn.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
    <script data-require="angular.js@1.2.16" data-semver="1.2.16" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
    <script data-require="ui-bootstrap@0.11.2" data-semver="0.11.2" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.11.2/ui-bootstrap.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
    <script src="modal.directive.js"></script>
    <script src="person-modal.directive.js"></script>
    <script src="person.controller.js"></script>
  </head>

  <body ng-app="app">
    <div ng-controller="PersonController as vm">
      <a href="" class="btn btn-primary btn-xs" ng-click="vm.addPerson(); vm.showModal = true;">Add person</a>
      <table class="table table-striped table-hover" style="margin-bottom:10px;">
        <thead>
          <tr>
            <th style="width:30%">Firstname</th>
            <th style="width:30%">Lastname</th>
            <th style="width:10%">&nbsp;</th>
          </tr>
        </thead>
        <tbody ng-cloak>
          <tr ng-repeat="person in vm.people">
            <td>{{person.Firstname}}</td>
            <td>{{person.Lastname}}</td>
            <td>
    					<a href="" ng-click="vm.selectedPerson = person; vm.showModal = true">Edit</a>
    					<a href="" ng-click="vm.deletePerson(person)">Delete</a>
    				</td>
          </tr>
        </tbody>
      </table>
      
      <modal visible="vm.showModal" on-hide="vm.selectedPerson = {}">
        <person-modal one-way-bind-person="vm.selectedPerson" on-save="vm.savePerson"></person-modal>
      </modal>
    </div>
  </body>

</html>
(function(){
  'use strict'
  
  angular.module('app', ['ui.bootstrap']);
}())
/* Styles go here */

(function () {
	'use strict';
	
	angular
        .module('app')
        .controller('PersonController', PersonController);
        
  function PersonController() {
    
    var vm = this;
		vm.showModal = false;
    vm.people = [];
		vm.selectedPerson = {};
		vm.addPerson = addPerson;
		vm.savePerson = savePerson;
		vm.deletePerson = deletePerson;
    
    function addPerson() {
			var person = {};
		  person.Firstname = '';
      person.Lastname = '';

			vm.selectedPerson = person;
		}

		function savePerson(person) {
      angular.copy(person, vm.selectedPerson);

      var shouldAdd = true;

      for(var k = 0; k < vm.people.length; ++k){
        if(vm.people[k].Firstname == vm.selectedPerson.Firstname){
          shouldAdd = false;
          break;
        }
      }

			if (shouldAdd) {
				vm.people.push(vm.selectedPerson);
			}

			vm.showModal = false;
		}

		function deletePerson(person) {
				var index = vm.people.indexOf(person);
				vm.people.splice(index, 1);
		}
    
    activate();
    
    function activate() {
      var person1 = {};
      person1.Firstname = 'person1 fn';
      person1.Lastname = 'person1 ln';
      
      var person2 = {};
      person2.Firstname = 'person2 fn';
      person2.Lastname = 'person2 ln';
      
      vm.people.push(person1);
      vm.people.push(person2);
    }
  }
}())
(function () {
	'use strict';

	angular
        .module('app')
        .directive('modal', modal);

	function modal() {

		var directive = {
			restrict: 'E',
			replace: true,
			transclude: true,
			scope: {
				visible: '=',
				onShow: '&',
				onHide: '&'
			},
			template: '<div class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true" ng-transclude></div>',
			link: link
		};

		return directive;

		function link(scope, element, attrs) {
			$(element).modal({
				show: false
			});

			$(element).on('shown.bs.modal', function () {
				scope.$apply(function () {
					scope.visible = true;
				});
			});

			$(element).on('shown.bs.modal', function () {
				scope.$apply(function () {
					scope.onShow();
				});
			});

			$(element).on('hidden.bs.modal', function () {
				scope.$apply(function () {
					scope.visible = false;
				});
			});

			$(element).on('hidden.bs.modal', function () {
				scope.$apply(function () {
					scope.onHide({temp:'test'});
				});
			});

			scope.$watch(
			  function () {
			    return scope.visible;
			  }, 
			  function (value) { 
			    if (value === true) { 
			      $(element).modal('show');
			    } else { 
			      $(element).modal('hide'); 
			    }
			  });
		}
	}
})();
(function() {
  'use strict';

  angular
    .module('app')
    .directive('personModal', personModal);

  function personModal() {

    var directive = {
      replace: true,
      restrict: 'E',
      scope: {
        oneWayBindPerson: '=',
        onSave: '&'
      },
      templateUrl: 'person-modal.directive.html',
      link: link
    };

    return directive;

    function link(scope, element, attrs) {
      // we are watching for a reference change only(if you need to watch for the properties of the object or if you pass in an array, then use $watchCollection)
      scope.$watch(function parentValueWatch() {
        return scope.oneWayBindPerson;
      }, function onParentValueChange(newParentValue) {
        scope.person = angular.copy(newParentValue);
      });
    }
  }
})();
<div class="modal-dialog">
	<div class="modal-content">
		<div class="modal-header">
			<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
			<h4 class="modal-title">Save person</h4>
		</div>
		<div class="modal-body">
			<div class="form-group">
				<label class="control-label" for="inputValue">Firstname:</label>
				<input class="form-control input-sm" type="text" placeholder="Firstname" ng-model="person.Firstname" />
			</div>

			<div class="form-group">
				<label class="control-label" for="inputValue">Lastname:</label>
				<input class="form-control input-sm" type="text" placeholder="Lastname" ng-model="person.Lastname" />
			</div>
		</div>
		<div class="modal-footer">
			<button type="button" class="btn btn-primary" ng-click="onSave()(person)">OK</button>
			<button type="button" class="btn btn-warning" data-dismiss="modal">Cancel</button>
		</div>
	</div>
</div>