<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.2.17" data-semver="1.2.17" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="appName" ng-controller="TestCtrl">
<h1>cmEditableText Sample</h1>
<p cm-editable-text ng-model="testValue"></p>
<p cm-editable-text ng-model="testValue"></p>
</body>
</html>
(function () {
'use strict';
angular.module('appName', function(){});
angular.module('appName').controller('TestCtrl', function ($scope) {
$scope.testValue = 'double click me!';
});
angular.module('appName').directive('cmEditableText', function () {
return {
restrict : 'A',
require : '^ngModel',
link : function(scope, element, attrs, ngModel) {
ngModel.$render = function() {
element.html(ngModel.$viewValue);
};
element.on('dblclick', function() {
var clickTarget = angular.element(this);
var EDITING_PROP = 'editing';
if ( !clickTarget.hasClass(EDITING_PROP) ) {
clickTarget.addClass(EDITING_PROP);
clickTarget.html('<input type="text" value="' + ngModel.$viewValue + '" />');
var inputElement = clickTarget.children();
inputElement.on('focus', function() {
inputElement.on('blur', function() {
var inputValue = inputElement.val() || this.defaultValue;
clickTarget.removeClass(EDITING_PROP).text(inputValue);
inputElement.off();
scope.$apply(function() {
ngModel.$setViewValue(inputValue);
});
});
});
inputElement[0].focus();
}
});
var destroyWatcher = scope.$on('$destroy', function () {
if ( angular.equals(destroyWatcher, null) ) {
return;
}
element.off();
destroyWatcher();
destroyWatcher = null;
});
}
};
});
}());
/* Styles go here */
p {
color: red;
font-weight: bold;
}