ng-repeat moves dom elements around, which breaks a ckeditor because it doesn't support having it's dom elements moved

StackOverflow https://stackoverflow.com/questions/23435655

  •  14-07-2023
  •  | 
  •  

Question

I'm trying have an ng-repeat which contains divs that include a CKEDITOR instance. The list is sortable by a few different properties. However, when the list is resorted, the CKEDITORs break because they don't support being moved around in the DOM. The only solution I can think of is to destroy the CKEDITOR instance before sort, and recreate them after. Is there any events on ng-repeat that can accomplish this?

plunkr here: http://plnkr.co/edit/tGnTdzvRl7xhEX7zYq4c?p=preview

Was it helpful?

Solution

Was able to get this fixed eventually. Pretty easy now that I think about, but took me 3 days to realize it. Instead of trying to listen for events on ng-repeat, catch the event that is causing the data to be modified. For me, it was jquery UI sortable (angular directive.) In the controller add $scope.$broadcast('unbind-ckeditor') before the change, and then $scope.$broadcast('rebind-ckeditor') after it. In your angularjs directive for ckeditor, call scope.$on('unbind-ckeditor', function() {instance.destroy /* instance is your ckeditor instance*/}); and then reload it in the rebind. Hope this helps someone.

Edit: Make sure the $on('unbind-ckeditor'... is only added to the scope once, or multiple sorts will throw exceptions.

OTHER TIPS

The solution for me:

  1. use divArea and not iframe, this will work with ng-repeat when the list changed.

  2. using other textarea (hidden) and monitoring it as the ng-sortable+ckeditor broke the order of CKEditors.

in ng-sortable (who make the change in the list) I was added this code:

$rootScope.$broadcast('rebind-ckeditor'); console.log("rebind")

and in CKEDITOR directive:

 scope.$on('rebind-ckeditor', function () {

    if (jQuery(element).data("loaded")) { 
         console.log("rebind");
         CKEDITOR.instances[element[0].id].destroy(); 
          jQuery(element).data("loaded", null); 
          element[0].value = $("textarea", element.parent())[1].value; // update manualy from the hidden textarea 
          onLoad();  //recreate CKE after textarea changed.
}
                })
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top