angular-ui / ui-tinymce

AngularUI wrapper for TinyMCE
MIT License
488 stars 371 forks source link

Pass ng-repeat item ID to tinymceOptions at init #283

Closed bartonsprings closed 7 years ago

bartonsprings commented 7 years ago

I have run into an issue. Here is my scenario:

  1. Tinymce editor is inside a ng-repeat. For example, lets say item in items
  2. The textarea ng-model is bound to item.Body property of the item
  3. I need to post a URL based on onclick event for a specific button. But the url string depends on the item.ID inside that item object
  4. How do I get this item.ID inside the tinymceOptions so I can use it. Or for that matter, any property of that item object which this editor belongs to in the ng-repeat iterations?

I am stuck not able to understand if this is a limitation or some workaround to setup tinymceOptions during init. Also, if that ID changes later then I need to get the latest ID. It would have been very easy if tinymceOptions was passed as an function with user defined callbacks or parameters. But since it is just an object, I have no way to pass any information at init. HELP!

ghost commented 7 years ago

I'm not sure if this will help you but I was hitting a similar brick wall. In the end I just added my own attribute to the directive tag and then grabbed it back from the event when it fired.

I haven't updated my workaround to deal with any ID changes but hopefully this approach might have some relevance to your issue.

vm.tinymceStandard = { setup: function(e) {

            e.on('blur', function () {
                dataToSend = {
                    page:'home',
                    section: e.bodyElement.attributes.modelID.nodeValue,
                    content: e.bodyElement.innerHTML
                };

                cmsFactory.save(dataToSend)
                .success(function(){});

            });
        },
        selector: 'div.editable',
        themes: 'inlite',
        height: 500,
        inline: true
    };
bartonsprings commented 7 years ago

Thank you @leighmillard ! You pointed me in the right direction. I built up on your direction and did it this way.

HTML Markup: <textarea class="its-editor" ui-tinymce="tinymceOptions" ng-model="item.Body" data-section="{{item.itemID}}" </textarea>

As you can see that I am defining a new attribute "data-section" here. Reasoning for using the data-* attribute is that we can also pass any type of data other than just string. In my case, we are not supporting anything below IE9. So pretty much all browsers we want to support support this data-* attribute.

Now I read this in the controller inside the tinymceOptions during setup but specifically on the custom button click in toolbar.

Also, I am using the getElement() call of the tinymce editor inside the 'onclick' event. Now I have full control over the model properties and done partially in angular way.

Controller:

$scope.tinymceOptions = {
               selector: "textarea",
               skin_url: '/resources/less/tinymce',
               menubar: '',
               min_height: 250,
               autoresize_on_init: true,
               autoresize_min_height: 250,
               elementpath: false,
               setup: function (editor) {
                   var itemId = null;
                   var element = null;

                   editor.addButton('myButton', {
                       text: '',
                       tooltip: 'My Button',
                       icon: 'someIcon',
                       onclick: function () {

                           // Get the element object (the textarea of tinymce)
                           element = angular.element(editor.getElement())[0];
                           itemId = element.attributes['data-section'].value;
  ......

Hope this also helps others.