AngularJS Example:
HTML
<div ng-app="svgContentEditable" ng-controller="DemoCtrl">
<h2>Demo for SVG Text Directive for Angular!</h2>
<p>Just click on the <i>{{foo}}</i> below and change it to whatever you like!</p>
<svg ng-attr-height="{{graph.height}}" ng-attr-width="{{graph.width}}">
<circle cx="60" cy="70" r="50" />
<circle cx="90" cy="18" r="10" />
<text x="20" y="70" fill="red" ng-model="foo" content-editable>{{foo}}</text>
</svg><br />
This was posted <a href="http://stackoverflow.com/questions/27074096/" target="_blank">here</a> on Stack Overflow. If you have any questions you can drop me a comment there - thanks!
</div>
CSS
</style> <!-- Ugly Hack due to jsFiddle issue: http://goo.gl/BUfGZ -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.min.js"></script>
<style>
JavaScript
angular.module('svgContentEditable', [])
.controller('DemoCtrl', ['$scope', function($scope)
{
$scope.graph = {'width': 150, 'height': 150};
$scope.foo = 'bar';
}])
.directive('contentEditable', function($document, $compile, $sce)
{
function link(scope, element, attrs, ngModel)
{
if (!ngModel) return; // do nothing if no ng-model
var container = document.createElement('div');
// Specify how UI should be updated
ngModel.$render = function() {
element.html($sce.getTrustedHtml(ngModel.$viewValue || ''));
};
container.innerHTML = element.text();
container.value = container.innerHTML;
container.style.position = 'absolute';
container.style.left = element.prop('offsetLeft') + 'px';
container.style.top = element.prop('offsetTop') + 'px';
container.style.color = attrs.fill || '';
container.contentEditable = 'true';
container.style.display = 'none';
container.setAttribute('ng-model', attrs.ngModel);
var $container = $compile(container)(scope);
var body = $document.find('body').eq(0);
body.append($container);
$container.on('blur keyup change', function() {
scope.$evalAsync(read);
});
// Write data to the model
function read() {
var html = $container.html();
ngModel.$setViewValue(html);
}
//read(); // initialize
element.on('mouseover', function(event)
{
event.preventDefault();
container.style.display='inline';
});
}
return {
require: '?ngModel',
link: link
};
});;