Proper way to implement TinyMCE

Proper way to implement TinyMCE

shovon-choudhuryshovon-choudhury Posts: 15Questions: 3Answers: 0

We are trying to integrate TinyMCE into datatables Editor. TinyMCE seems to load but it is not showing saved data for that certain field. Additionally we are trying to get the switch to source view toolbar working. Is there any proper documentation on that?
here is the scripts we are loading:

<!-- Scripts -->
  <script src="{{ asset('js/dashboard.js') }}"></script>
  <script>
    jQuery(function() {
        //Global X-CSRF-TOKEN setup for ajax
        $.ajaxSetup({
            headers: {
                "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
            },
        });
    });
  </script>
  <script src="{{ asset('js/settings/ckeditor-default-config.js') }}"></script>
  <script src="{{ asset('js/settings/datatables-default-config.js') }}"></script>
  <script src="{{ asset('vendor/tinymce/tinymce.js') }}"></script>
  <script src="{{ asset('vendor/tinymce/plugins/code/plugin.min.js') }}"></script>
  <script src="{{ asset('vendor/editor/dataTables.editor.min.js') }}"></script>
  <script src="{{ asset('vendor/editor/editor.bootstrap4.min.js') }}"></script>
  <script src="{{ asset('vendor/editor/editor.ckeditor5.js') }}"></script>
  <script src="{{ asset('vendor/unitegallery/js/unitegallery.min.js') }}"></script>
  <script src="{{ asset('vendor/unitegallery/themes/tiles/ug-theme-tiles.js') }}"></script>
  <script src="{{ asset('vendor/unitegallery/themes/grid/ug-theme-grid.js') }}"></script>
  <script src="{{ asset('vendor/unitegallery/themes/video/ug-theme-video.js') }}"></script>
  <script src="{{ asset('vendor/unitegallery/themes/slider/ug-theme-slider.js') }}"></script>
  <script src="{{ asset('vendor/unitegallery/themes/carousel/ug-theme-carousel.js') }}"></script>
  <script src="{{ asset('vendor/editor/editor.tinymce.js') }}"></script>

here is how we are using the field type:

                       {
                label: "Article content",
                name: "articles.fulltext",
                type: "tinymce",
            },

Any help is appropriated.

Answers

  • allanallan Posts: 62,099Questions: 1Answers: 10,183 Site admin

    Happy to take a look at a test case showing the issue.

    Allan

  • koniahinkoniahin Posts: 186Questions: 39Answers: 7

    Shovon and I worked on our example that you have access to. Sign in under your account and visit:

    https://www.smokeymo.xyz/bin/tinymce

    select id, title, `fulltext` from articles where id=674;
    +-----+---------+---------------------+
    | id  | title   | fulltext            |
    +-----+---------+---------------------+
    | 674 | TinyMCE | <p>asdfasdfsadfasdfasdfasdfasdfasdf</p> |
    +-----+---------+---------------------+
    1 row in set (0.001 sec)
    

    Here is a curiosity. When you make a change in the Article content (tinymce) field then click either Update or Save/Close it seems to save but it is appending what is already in the field. What you see above is 2 saves.

    Also, after you click to save it visually clears the field and you cannot view whatever you just saved, making you think you errored.

    You reload the page and it shows no text visually but an SQL query indicates otherwise.

      {
        label: "Article content",
        name: "articles.fulltext",
        type: "tinymce", /* minimum required for  default */
        /* disabled extras
        tinymce: {
            plugins: "code",
            toolbar: "undo redo | bold italic | alignleft aligncenter alignright | code",
            height: 400
        },
        type: 'textarea',
        */
      },
    
  • allanallan Posts: 62,099Questions: 1Answers: 10,183 Site admin

    Thanks for the link!

    Could you replace the create function in the editor.tinymce.js plug-in with the following please?:

        create: function ( conf ) {
            var that = this;
            conf._safeId = DataTable.Editor.safeId( conf.id );
     
            conf._input = $('<div><textarea id="'+conf._safeId+'"></textarea></div>');
     
            // Because tinyMCE uses an editable iframe, we need to destroy and
            // recreate it on every display of the input
            this
                .on( 'open.tinymceInit-'+conf._safeId, function () {
                    tinymce.init( $.extend( true, {
                        selector: '#'+conf._safeId,
                        setup: function (editor) {
                            editor.on('init', function (e) {
                                if ( conf._initSetVal ) {
                                    editor.setContent( conf._initSetVal );
                                    conf._initSetVal = null;
                                }
                            });
                            
                            that.bubblePosition();
                        }
                    }, conf.opts ) );
                } )
                .on( 'close.tinymceInit-'+conf._safeId, function () {
                    var editor = tinymce.get( conf._safeId );
    
                    if ( editor ) {
                        editor.destroy();
                    }
    
                    conf._initSetVal = null;
                    conf._input.find('textarea').val('');
                } );
     
            return conf._input;
        },
    

    Hopefully that should do the trick.

    Allan

  • koniahinkoniahin Posts: 186Questions: 39Answers: 7

    Shovon updated the code. It has gotten us one step closer, two to do. What we now see is that when we access the page we can add some text but if we click to Update, the field empties. See the video:

    https://vimeo.com/823064471
    password = tinymce

    Reloading the page reveals that what we entered saved.

    The second need is to get Tools or Source Code added to the toolbar.

    That will get us really close to Karma.

  • allanallan Posts: 62,099Questions: 1Answers: 10,183 Site admin
    edited May 2023

    Hi,

    Have you managed to resolve the issue? I've just tried it and it appears to work okay.

    1. Click a cell under the "Edit content" column
    2. Editor pops up with the TinyMCE editor filled in with the current value
    3. Edit that value
    4. Click update - submits successfully
    5. Click the same cell again
    6. TinyMCE filled with the updated value is shown in the form
    7. Edit that value
    8. Click update - submits successfully

    I can then repeat as much as I want.

    Regarding the code plug-in. Change:

    tinymce: {
      plugins: "code",
    

    in the Editor setup for the field, to be:

    opts: {
      plugins: "code",
    

    As noted here the options to pass to TinyMCE should be in the opts object.

    Allan

  • koniahinkoniahin Posts: 186Questions: 39Answers: 7

    Shovon added the option to add code and that worked - we are 66% there thank you.

    Editing however is still failing. Okay there are 2 different ways to edit text. We need to add a button to the 'Edit content' method so that it opens with 2 options to save. Should be:

    1) Update - update saves but keeps the window open. This is performing like Save and Close (wrong, our bad)
    2) Save and close - updates and closes like what you see.

    However, to see the issue either 1) click on the tiny edit icon in the second column or 2) highlight the row and click on the Edit button up top. That will open the full editing form with the correct options.

  • koniahinkoniahin Posts: 186Questions: 39Answers: 7

    That might have been confusing. To see how Update should work click on the tiny edit icon or highlight the row and click on the Edit button above.

    In that view the Update button works to save all fields without closing the page which is where we see the problem.

  • allanallan Posts: 62,099Questions: 1Answers: 10,183 Site admin

    Thanks for the clarification - I think I see the issue. The "Update" button's code is:

              this.submit();
              //editor.close();
              table.row(target, {
                page: 'current'
              }).select();
              editor.edit(table.rows({
                selected: true
              }).indexes());
    

    However, the submit() method has async operation. So this code is triggering an edit action before the previous form has submitted. Then the submit does happen and the form closes - i.e. it all happens out of sequence.

    Try this instead:

    this.submit(function () {
      editor.edit(
        table.rows({selected: true}).indexes()
      );
    });
    

    That will trigger the next edit after the current one has completed its submission.

    Since you are keeping the editor window open, I think it will also need an update to the TinyMCE plug-in's create function to this:

        create: function ( conf ) {
            var that = this;
            conf._safeId = DataTable.Editor.safeId( conf.id );
     
            conf._input = $('<div><textarea id="'+conf._safeId+'"></textarea></div>');
     
            // Because tinyMCE uses an editable iframe, we need to destroy and
            // recreate it on every display of the input
            this
                .on( 'open.tinymceInit-'+conf._safeId, function () {
                    var editor = tinymce.get( conf._safeId );
    
                    if (editor) {
                        if ( conf._initSetVal ) {
                            editor.setContent( conf._initSetVal );
                            conf._initSetVal = null;
                        }
                    }
                    else {
                        tinymce.init( $.extend( true, {
                            selector: '#'+conf._safeId,
                            setup: function (editor) {
                                editor.on('init', function (e) {
                                    if ( conf._initSetVal ) {
                                        editor.setContent( conf._initSetVal );
                                        conf._initSetVal = null;
                                    }
                                });
                                
                                that.bubblePosition();
                            }
                        }, conf.opts ) );
                    }
                } )
                .on( 'close.tinymceInit-'+conf._safeId, function () {
                    var editor = tinymce.get( conf._safeId );
    
                    if ( editor ) {
                        editor.destroy();
                    }
    
                    conf._initSetVal = null;
                    conf._input.find('textarea').val('');
                } );
     
            return conf._input;
        },
    

    Allan

  • koniahinkoniahin Posts: 186Questions: 39Answers: 7

    Shovon incorporated the latest changes. We are still seeing the problem.

    Select the row
    Click on the Edit button above
    Click in the tinyMCE text field
    Click Update

    I have identified a second issue on this form- if you need a separate post, I can do that.

    If you click on the font-awesome Edit icon (2nd column) and click Update it blanks out the form. Clicking Update a second time returns the error:

    foreach() argument must be of type array|object, null given

  • allanallan Posts: 62,099Questions: 1Answers: 10,183 Site admin

    Could you try using the latest plug-in from here please? I think the issue is with the iframe TinyMCE uses being removed and then reinserted back into the document.

    Allan

  • rmeetinrmeetin Posts: 100Questions: 24Answers: 1

    We installed the latest plugin. Thank you Allan but this has not helped with Update.

  • allanallan Posts: 62,099Questions: 1Answers: 10,183 Site admin
    edited May 2023

    This is painful - sorry. It worked locally for me, I'm not clear on why is isn't for you.

    Can you include the TinyMCE integration for Editor directly from here - i.e. use that URL as your src for the -tag script`? That way I can tweak things and try to understand why it isn't working in your app.

    Allan

  • rmeetinrmeetin Posts: 100Questions: 24Answers: 1

    Shovon took care of this. Over...

  • allanallan Posts: 62,099Questions: 1Answers: 10,183 Site admin

    Thanks. The link from before is redirecting to https://www.smokeymo.xyz/email/verify now though?

    Allan

  • rmeetinrmeetin Posts: 100Questions: 24Answers: 1

    Oops - we were working on the users table and registration system. I manually updated your profile adding a verification date:

    | 10 | Allan | allan@datatables.net | 2023-05-17 14:40:09 |

  • allanallan Posts: 62,099Questions: 1Answers: 10,183 Site admin

    That was two hours of debugging "fun". Anyway, that's it fixed now :). You might need to ctrl-f5 your browser on your page to make sure you get the latest version of the Javascript file. You'll also want to copy that dev code to your own file, as I periodically clean out my dev directory.

    Regards,
    Allan

  • rmeetinrmeetin Posts: 100Questions: 24Answers: 1

    Thanks but I get confused. Please point me to the source of the most recent file version for editor.tinymce.js. If I know the line or character count that will help.

  • allanallan Posts: 62,099Questions: 1Answers: 10,183 Site admin

    http://datatables.net/dev/editor.tinymce.js . 156 lines in the file (including two empty lines at the end).

    Allan

  • rmeetinrmeetin Posts: 100Questions: 24Answers: 1
    edited May 2023

    Allan, thanks for the effort. I double-checked and unfortunately it is still not working. I verified with Shovon; in order for you to check the status all you need to do is access is sign in and access the TinyMCE test form from the dashboard. Click on the inline Edit button in the table, not the Edit button above. Make a change and click Update, then Update again.

    The way it is set up we don't need to recompile anything. Looking at page source you will see:

    <script src="https://datatables.net/dev/editor.tinymce.js"></script>

    Here's where we are. Shovon has an alternate kludgey solution which works, but not as smooth. We would like to see the clean solution but if it's too much we can live with door number 2.

  • allanallan Posts: 62,099Questions: 1Answers: 10,183 Site admin

    One thing I noticed was that in the update button does:

    editor.submit();
    editor.edit(...);
    

    The submit action is async - you should trigger the edit action in a callback:

    editor.submit(function () {
      editor.edit(...);
    });
    

    Allan

  • rmeetinrmeetin Posts: 100Questions: 24Answers: 1

    Shovon tried that earlier and it did not help. He enabled his hack fix to get it to mostly work.

Sign In or Register to comment.