AngularJS: Inline editable table

Inline editing table data with cancel/undo (using ng-include)

by Ganesh

HTML

<div ng-app="demo" ng-controller="Ctrl">
    <table>
        <thead>
            <th>Name</th>
            <th>Age</th>
            <th></th>
        </thead>
        <tbody>
            <tr ng-repeat="contact in model.contacts" ng-include="getTemplate(contact)">
            </tr>
        </tbody>
    </table>
    
    <script type="text/ng-template" id="display">
        <td>{{contact.name}}</td>
        <td>{{contact.age}}</td>
        <td>
            <button ng-click="editContact(contact)">Edit</button>
        </td>
    </script>
    <script type="text/ng-template" id="edit">
        <td><input type="text" ng-model="model.selected.name" /></td>
        <td><input type="text" ng-model="model.selected.age" /></td>
        <td>
            <button ng-click="saveContact($index)">Save</button>
            <button ng-click="reset()">Cancel</button>
        </td>
    </script>
</div>

JavaScript

var demo = angular.module("demo", []);

demo.controller("Ctrl",

function Ctrl($scope) {
    $scope.model = {
        contacts: [{
            id: 1,
            name: "Ben",
            age: 28
        }, {
            id: 2,
            name: "Sally",
            age: 24
        }, {
            id: 3,
            name: "John",
            age: 32
        }, {
            id: 4,
            name: "Jane",
            age: 40
        }],
        selected: {}
    };

    // gets the template to ng-include for a table row / item
    $scope.getTemplate = function (contact) {
        if (contact.id === $scope.model.selected.id) return 'edit';
        else return 'display';
    };

    $scope.editContact = function (contact) {
        $scope.model.selected = angular.copy(contact);
    };

    $scope.saveContact = function (idx) {
        console.log("Saving contact");
        $scope.model.contacts[idx] = angular.copy($scope.model.selected);
        $scope.reset();
    };

    $scope.reset = function () {
        $scope.model.selected = {};
    };
});