Skip to content
This repository has been archived by the owner on Sep 8, 2020. It is now read-only.

angular-ui/ui-tinymce setup method in tinymceOptions breaks model binding #112

Closed
polojko opened this issue Dec 17, 2014 · 20 comments
Closed

Comments

@polojko
Copy link

polojko commented Dec 17, 2014

I want to add a custom button to the tinymce toolbar, and added a setup function to tinymceOptions as discribed in the docs:

$scope.tinymceOptions = {
setup: function (editor) {
editor.addButton('myMethod', { //myCode }
},
//more options
}

<textarea ui-tinymce="tinymceOptions" ng-model="model.content"></textarea>

Adding the setup function breaks the binding with the model. Content added to the editor is not synced to the model and vice-versa.

Are there known issues with this approach? If so, what would be the other way to add custom buttons, without breaking binding?

Tnx;

@Ireland999
Copy link

你好,在这方面我也有很多疑问,不知道怎么去获取textarea中的内容的

@coltonmccormack
Copy link

I too can confirm that model bind breaks when using a setup object.

@Ireland999
Copy link

我在使用汉化插件时遇到一个问题,使用了汉化插件在angularjs的controller里无法获得textarea中的值

@jonahlau
Copy link

I confirm the same issue when including a "setup" object in the editor options passed to the directive

@coltonmccormack
Copy link

Ok, I think I see the issue. The plugin works by utilizing the 'setup' property in the options to setup hooks for various TinyMCE events and then call angular internal functions when they are encountered.
Code:

 // Update model when calling setContent (such as from the source editor popup)
          setup: function (ed) {
            var args;
            ed.on('init', function(args) {
              ngModel.$render();
              ngModel.$setPristine();
            });
            // Update model on button click
            ed.on('ExecCommand', function (e) {
              ed.save();
              updateView();
            });
            // Update model on keypress
            ed.on('KeyUp', function (e) {
              ed.save();
              updateView();
            });
            // Update model on change, i.e. copy/pasted text, plugins altering content
            ed.on('SetContent', function (e) {
              if (!e.initial && ngModel.$viewValue !== e.content) {
                ed.save();
                updateView();
              }
            });
            ed.on('blur', function(e) {
                elm.blur();
            });
            // Update model when an object has been resized (table, image)
            ed.on('ObjectResized', function (e) {
              ed.save();
              updateView();
            });
            if (configSetup) {
              configSetup(ed);
            }
          },
          mode: 'exact',
          elements: attrs.id
        };

Whenever we make our own 'setup' functions this code gets overwritten with the angular.extend function angular.extend(options, uiTinymceConfig, expression); thus wiping out all of that lovely event-driven code.

I suspect that copying the setup function above into your tinymce config object will make things 'work normally'. You would then be able to modify it to suit your own needs. Note, this will mean that if the setup function gets changed in the plugin at a future date you will not see the change as yours is overwriting it. The 'proper' way would probably be to extend the setup function with whatever setup function defined in the config. If someone wants to write a PR for that I'm sure it would be appreciated.

@Ireland999
Copy link

编辑器在保存中文的时候出现中文乱码要怎么解决?

@joshuakon
Copy link

this (copying the code @thatguyyoulove posted into my tinymceOptions object) doesn't work for me. the attrs object isn't defined. if I remove the mode and elements items, the editor doesn't load.
Can anyone point me at a good way of creating a plugin instead?

@helmutkian
Copy link

If you do not need to handle events that occur before the 'init' event, then until the issue with setup is resolved, you could use init_instance_callback instead.

So replace

{
   // ...
   setup: function (ed) {
       ed
         .on('init', function () { alert('init!'); })
         .on('blur', function () { alert('blurred!'); });
   }
}

with

{
   // ...
   init_instance_callback: function (ed) {
       alert('init!');
       ed.on('blur', function () { alert('blurred!'); });
   }
}

@minutephp
Copy link

This seems to work for now:

inside tinymce.js

if (expression.custom_setup) {
    scope.$eval(function () {
          expression.custom_setup(ed)
     });
     delete expression.custom_setup;
}

inside your_code.js

$scope.tinymceOptions = {
//...
custom_setup: function(editor) { /* setup */ }
}

@daynejones
Copy link

Can confirm this is an issue for me as well.

@coltonmccormack
Copy link

This was resolved with ae37bb9, however the tagging is currently messed up and version 0.0.5 does not currently resolve to the correct version 0.0.5 tag.

Recommendation is to download the .zip of the real v.0.0.5 and use that in the interim.
https://github.com/angular-ui/ui-tinymce/archive/v0.0.5.zip

@rbecheras
Copy link
Contributor

Ok @thatguyyoulove it cool, but why there is no new tag 0.0.6 tag ?
This issue is important !

@coltonmccormack
Copy link

Comment on #127 to get support for having it fixed please.

@wesleycho
Copy link
Contributor

I believe this is now fixed - I have removed the broken 0.0.5 tag and released 0.0.6.

I do however think that the api is a little awkward for extending the setup function - I am open to any ideas on a better way to extend the logic in the existing callbacks, in the event the user wants custom behavior to happen, if it is desired. If anyone is interested, feel free to open a new issue on this.

@webdev67
Copy link

It still happens. Using the init_instance_callback as @helmutkian suggested does not work if you are adding a new button . It works for the context menu surprisingly..

@webdev67
Copy link

Just FYI - i solved the issue of not being able to add the button via creating a new plugin - and injecting that in the tinymce options. I also passed the $rootScope, $scope and other angular requirements to the plugin via this.PluginManager.$rootScope = $rootScope from within the init_instance_callback function in the $scope.tinymceOptions in the controller.

@asanthoshkumar
Copy link

Take the @mangreen code, It fixed couple of issues for me.

  1. Allows me to add custom button.
  2. When inline=true two way binding not works without this fix for me.

@andreyluiz
Copy link

Not only in this case. In my approach I need to do stuff in the init. And I can't setup this because the entire model binding is lost (setup function extends over the original one in the directive).

@deeg
Copy link
Contributor

deeg commented Oct 12, 2015

Will a new version be put out with the fix by @mangreen?

@yaegerbomb
Copy link

Since updating to the latest version of Tiny I had to do the following to get my angular buttons to work:

$scope.tinymceOptions = {
external_plugins: { "custom-button": "/scripts/libraries/ui-tiny/plugin.js" }
init_instance_callback: function (ed) {
ed.$scope = $scope;
},
toolbar: "custom-plugin"
}

In the plugin.js folder it was just a normal ed.addButton function.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests