<!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%"> </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">×</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>