AngularJS inplace edit.

HTML

<div ng-app="inplaceTest">
 
    <script type="text/ng-template" id="editable-template.html">
        <div class="panel">
            <span class="c1" ng-hide="editorEnabled" ng-click="enableEditor();">{{model | default:defaultVal}}</span>
            <input ng-show="editorEnabled" ng-model="editModel" ng-required ui-keypress="{13: 'finishedEdit()'}" ui-event="{'blur': 'finishedEdit()'}"/> 
        </div>        
    </script>  
    
    <div ng-controller="MyCtrl">
         <h1>
             <editable model="heading" default-val="{{defaultText}}"></editable>
         <h1>
        <p><span>Heading: {{heading}}</span></p>
    </div>  
</div>

CSS

</style> <!-- Ugly Hack due to jsFiddle issue: http://goo.gl/BUfGZ --> 
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/foundation/4.1.6/css/foundation.min.css"> 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script> 
<script src="https://rawgithub.com/angular-ui/angular-ui/master/build/angular-ui.js"></script> 
<style>

JavaScript

var app = angular.module('inplaceTest', ['ui']);

//Include angular-ui dependency in resources on the side and as 'ui'
app.directive('editable', function () {
    return {
        restrict: 'E',
        replace: true,
        templateUrl: 'editable-template.html',
        scope: {
            model: '=',
            defaultVal: '@'
        },
        // The linking function will add behavior to the template
        link: function (scope, element, attrs) {
            scope.editorEnabled = false;

            scope.finishedEdit = function ($event) {
                scope.model = angular.copy(scope.editModel);
                scope.editorEnabled = false;
                if ($event != null) {
                    $event.preventDefault();
                }
            };

            scope.enableEditor = function () {
                scope.editModel = angular.copy(scope.model);
                scope.editorEnabled = true;
                // The element enable needs focus and we wait for milliseconds before allowing focus on it.
                setTimeout(function () {
                    element.find('input')[0].focus();
                });
            };
        }
    }
});

app.controller('MyCtrl', function ($scope) {
    $scope.defaultText = "Here is some default text";
});

app.filter('default', function () {
    return function (input, value) {
        return out = input != null && input != undefined && (input != "" || angular.isNumber(input)) ? input : value || '';
    }
});