akatov / angular-contenteditable

angular model for the "contenteditable" attribute
http://akatov.github.io/angular-contenteditable/
MIT License
176 stars 55 forks source link

IE10 contenteditable div not bound to ng-model #11

Open solidspark opened 11 years ago

solidspark commented 11 years ago

Simply put, IE10 isn't updating the model when the contenteditable div is edited. The template code in question is:

<div class="profile-label" ng-model="item.label" contenteditable="true"></div>
<div class="profile-description" ng-model="item.description" contenteditable="true"></div>

edit: After further testing, it's just IE10.

solidspark commented 11 years ago

After some research, IE10/11 never fire the input event for a contenteditable element.

$element.bind('input', function(e) { ...

listens for this particular event.

See: http://connect.microsoft.com/IE/feedback/details/794285/ie10-11-input-event-does-not-fire-on-div-with-contenteditable-set

akatov commented 11 years ago

does it fire any events?

solidspark commented 11 years ago

I haven't looked into what events it does fire, it requires dirty hacks:

function fix_onChange_editable_elements()
{
  var tags = document.querySelectorAll('[contenteditable=true][onChange]');//(requires FF 3.1+, Safari 3.1+, IE8+)
  for (var i=tags.length-1; i>=0; i--) if (typeof(tags[i].onblur)!='function')
  {
    tags[i].onfocus = function()
    {
      this.data_orig=this.innerHTML;
    };
    tags[i].onblur = function()
    {
      if (this.innerHTML != this.data_orig)
        this.onchange();
      delete this.data_orig;
    };
  }
}
Narretz commented 10 years ago

A trivial workaround is to bind keyup , cut and paste additionally to input. This makes it work with keyboard input, but it doesn't work for context menu pasting / cutting. These work after you put the scope.$apply in a timeout with zero delay. (html() reports the wrong content, although the model binding seems to be delayed some of the time, not completely broken)

Biggest problem is that it seems difficult to use either input or the other events, since it's hard to test the features. Might resort to browser sniffing for this.

Narretz commented 10 years ago

Another problem is that the lack of input does not prevent backspace from going back in the browser history (does not always happen). Listening to backspace and e.stopPropagation() fix this.

Narretz commented 10 years ago

angular's basic input directives use changeand a timeout for browsers that don't have input, (instead of binding to keyup) and browser / feature sniffing + additional binds to get around edge cases. Actually makes me wonder why contenteditable model binding hasn't been included yet, since a lot of code must be duplicated, escpecially from private services $browser and $sniffer. https://github.com/angular/angular.js/blob/master/src/ng/directive/input.js

quanghoc commented 10 years ago

So is there any good fix / workaround for IE at this point? Not having this to work in IE 11 is somewhat a big blocker for me to use this.

bettysteger commented 9 years ago

So is there now any good fix / workaround for IE 10 / 11 at this point?

I just used the keyup event additionally..

ghost commented 9 years ago

A late +1

2 years after the initial report, angular has been upgrade to 1.4.6, IE is now version but still the same problem...

soferio commented 8 years ago

+1 from me. I am currently trying to see if there is any other way to use contenteditable and angular which might work with IE. Has anyone found a method? (There is something promising here: http://gaboesquivel.com/blog/2014/in-place-editing-with-contenteditable-and-angularjs/; and perhaps here: http://fdietz.github.io/recipes-with-angular-js/common-user-interface-patterns/editing-text-in-place-using-html5-content-editable.html).

I have now checked the latter recipe and it works on IE!