Elfayer Elfayer - 3 months ago 63x
AngularJS Question

Contenteditable with ng-model doesn't work

I'm trying to store the value of a

to my JS code. But I can't find out why
doesn't work in this case.

<div ng-app="Demo" ng-controller="main">
<input ng-model="inputValue"></input>
<div>{{inputValue}}</div> // Works fine with an input
<div contenteditable="true" ng-model="contentValue"></div>
<div>{{contentValue}}</div> // Doesn't work with a contenteditable

Is there a workaround to do that ?

See : JSFiddle

Note: I'm creating a Text editor, so the user should see the result, while I'm storing the HTML behind it. (ie. user see: "This is an example !", while I store:
This is an <b>example</b> !


contenteditable tag will not work directly with angular's ng-model because the way contenteditable rerender the dom element on every change.

You have to wrap it with a custom directive for that:


angular.module('customControl', ['ngSanitize']).
directive('contenteditable', ['$sce', function($sce) {
  return {
    restrict: 'A', // only activate on element attribute
    require: '?ngModel', // get a hold of NgModelController
    link: function(scope, element, attrs, ngModel) {
      if (!ngModel) return; // do nothing if no ng-model

      // Specify how UI should be updated
      ngModel.$render = function() {
        element.html($sce.getTrustedHtml(ngModel.$viewValue || ''));

      // Listen for change events to enable binding
      element.on('blur keyup change', function() {
      read(); // initialize

      // Write data to the model
      function read() {
        var html = element.html();
        // When we clear the content editable the browser leaves a <br> behind
        // If strip-br attribute is provided then we strip this out
        if ( attrs.stripBr && html == '<br>' ) {
          html = '';


<form name="myForm">
 <div contenteditable
      name="myWidget" ng-model="userContent"
      required>Change me!</div>
  <span ng-show="myForm.myWidget.$error.required">Required!</span>
 <textarea ng-model="userContent"></textarea>

Source it from the original docs