Click to Edit Directive for AngularJS

by yoorek

HTML

<div ng-controller="LocationFormCtrl">
    <h2>Editors</h2>
    <div class="field">
        <strong>State:</strong>
        <div click-to-edit="location.state"></div>
    </div>
    <div class="field">
        <strong>City:</strong>
        <div click-to-edit="location.city"></div>
    </div>
    <div class="field">
        <strong>Neighbourhood:</strong>
        <div click-to-edit="location.neighbourhood"></div>
    </div>
    <h2>Values</h2>
    <p><strong>State:</strong> {{location.state}}</p>
    <p><strong>City:</strong> {{location.city}}</p>
    <p><strong>Neighbourhood:</strong> {{location.neighbourhood}}</p>
</div>

CSS

body {
    font-family: "HelveticNeue", sans-serif;
    font-size: 14px;
    padding: 20px;
}

h2 {
    color: #999;
    margin-top: 0;
}

.field {
    margin-bottom: 1em;
}

.click-to-edit {
    display: inline-block;
}

JavaScript

app = angular.module("formDemo", []);

app.directive("clickToEdit", function() {
    var editorTemplate = '<div class="click-to-edit">' +
        '<div ng-hide="view.editorEnabled">' +
            '{{value}} ' +
            '<a ng-click="enableEditor()">Edit</a>' +
        '</div>' +
        '<div ng-show="view.editorEnabled">' +
            '<input ng-model="view.editableValue">' +
            '<a href="#" ng-click="save()">Save</a>' +
            ' or ' +
            '<a ng-click="disableEditor()">cancel</a>.' +
        '</div>' +
    '</div>';

    return {
        restrict: "A",
        replace: true,
        template: editorTemplate,
        scope: {
            value: "=clickToEdit",
        },
        controller: function($scope) {
            $scope.view = {
                editableValue: $scope.value,
                editorEnabled: false
            };

            $scope.enableEditor = function() {
                $scope.view.editorEnabled = true;
                $scope.view.editableValue = $scope.value;
            };

            $scope.disableEditor = function() {
                $scope.view.editorEnabled = false;
            };

            $scope.save = function() {
                $scope.value = $scope.view.editableValue;
                $scope.disableEditor();
            };
        }
    };
});

app.controller("LocationFormCtrl", function($scope) {
    $scope.location = {
        state: "California",
        city: "San Francisco",
        neighbourhood: "Alamo Square"
    };
});

angular.element(document).ready(function() {
    angular.bootstrap(document, ["formDemo"]);
});