Cmb2: Make WYSIWYG / TinyMCE / Editor field repeatable?

Created on 26 Mar 2015  Â·  58Comments  Â·  Source: CMB2/CMB2

Hi there,

I know this has been asked a couple of times, I just hope you didn't give up on this. I think it's very important for CMB2. To me it's pretty much the only thing that's missing. Apart from this, being a CMB2 user and having tried many other frameworks, you da best.

Keep up the great work.
NB: I'd be willing to pay for this feature. A lot.

All 58 comments

We haven't given up and we/I get asked very frequently. It's just a matter of getting the time. CMB2 is a (heavily used) side project for us, so we work on it when we can, and repeatable wysiwyg is at the top of the feature list roadmap.

Thanks a lot for taking the time to answer!

Just in case this helps, I have a repeatable group with a WYSIWYG editor as a field within that group and it works perfectly.

function register_metabox() {
        $prefix = '_repeatable_editor_';

        $cmb_showcase = new_cmb2_box( array(
            'id'            => $prefix . 'metabox',
            'title'         => __( 'Repeatable Editor', 'cmb2' ),
            'object_types'  => array( 'page' ), // Post type
            'context'       => 'normal',
            'priority'      => 'high',
            'show_names'    => true, // Show field names on the left
            //'cmb_styles'    => false, // false to disable the CMB stylesheet
        ) );

        // Repeatable group
        $group_showcase = $cmb_showcase->add_field( array(
            'id'          => $prefix . 'sections',
            'type'        => 'group',
            'options'     => array(
                'group_title'   => __( 'Editor', 'cmb2' ) . ' {#}', // {#} gets replaced by row number
                'add_button'    => __( 'Add another Editor', 'cmb2' ),
                'remove_button' => __( 'Remove Editor', 'cmb2' ),
                'sortable'      => true, // beta
            ),
        ) );

        // Main editor
        $cmb_showcase->add_group_field( $group_showcase, array(
            'name'    => __( 'Content', 'cmb2' ),
            'id'      => 'content',
            'type'    => 'wysiwyg',
            'options' => array( 'textarea_rows' => 8, ),
        ) );
    }

    add_action( 'cmb2_init', 'register_metabox' );

@adchsm does your new editor instantiate ok when you add it? I get a blank ckeditor tinyMCE (dur) area when clicking Add another Editor, like this:

screen shot 2015-04-15 at 10 06 06 am

If I save the post and refresh it works fine, however. But ideally the tinyMCE instance would work immediately after duplicating.

(Edit: I see it does work fine if you are in Text mode instead of Visual.)

Yeah it works all ok for me. I can add multiple editors without the need to save/update. This is on WordPress 4.0 + 4.1

@adchsm Interesting. I wonder if it has to do with using Bedrock/Sage and/or using CMB2 as a plugin?

It works fine if I'm editing in Text mode, but if it's set to Visual, the freshly-added editor is always broken.

Are you using it as a plugin? I've built it into the theme.

@adchsm yeah, I have CMB2 in mu-plugins using Bedrock's composer.json so I can easily keep it updated.

Well, as long as I know it works for you duplicating editors in Visual mode, then it's something I need to track down on my own install. Thanks for the feedback.

Fwiw, I downloaded a fresh Wordpress 4.1.1 install, copied CMB2 into the twentyfifteen theme directory, and just added this to functions.php:

require get_template_directory() . '/lib/CMB2/init.php';
function register_metabox() {
        $prefix = '_repeatable_editor_';

        $cmb_showcase = new_cmb2_box( array(
            'id'            => $prefix . 'metabox',
            'title'         => __( 'Repeatable Editor', 'cmb2' ),
            'object_types'  => array( 'page' ), // Post type
            'context'       => 'normal',
            'priority'      => 'high',
            'show_names'    => true, // Show field names on the left
            //'cmb_styles'    => false, // false to disable the CMB stylesheet
        ) );

        // Repeatable group
        $group_showcase = $cmb_showcase->add_field( array(
            'id'          => $prefix . 'sections',
            'type'        => 'group',
            'options'     => array(
                'group_title'   => __( 'Editor', 'cmb2' ) . ' {#}', // {#} gets replaced by row number
                'add_button'    => __( 'Add another Editor', 'cmb2' ),
                'remove_button' => __( 'Remove Editor', 'cmb2' ),
                'sortable'      => true, // beta
            ),
        ) );

        // Main editor
        $cmb_showcase->add_group_field( $group_showcase, array(
            'name'    => __( 'Content', 'cmb2' ),
            'id'      => 'content',
            'type'    => 'wysiwyg',
            'options' => array( 'textarea_rows' => 8, ),
        ) );
    }

    add_action( 'cmb2_init', 'register_metabox' );

...and it still behaves the same. I also realized that the Text mode isn't actually working, it was just showing the textarea, but the quickbar buttons don't work.

cmb2-wysiwyg

I've seen this feature work in other frameworks (but they weren't as good as CMB2).

I hope CMB2 will be maintained in the future (I'm going to poke the author again and he's going to think that I'm a really annoying person, sorry for that).

@jtsternberg we need you.

:+1:

@adchsm @natebeaty - did you manage to get anything working. I wonder if there is a way to get this to work (or any other plugin with repeatable wysiwyg)

+1 for this feature, it would be very useful.

I wasn't able to get it fully working. Right now you have to add a new block with some content (either switching to Text and typing in the wysiwyg area, or adding some content to another field in the new repeatable block) and save, then you can edit with the fully instantiated tinymce area in the new block.

I also ran into a problem with the move-up and move-down buttons, as they don't support swapping wysiwyg areas.

@natebeaty do you have a patch or code for your fixes ? what you have sounds much better than anything else.

@sandys I am using default code. You can do basic repeatable wysiwyg fields, but the post just has to be saved before tinymce inits properly for editing in Visual mode.

I looked into adjusting cmb.js to support the up/down arrows w/ wysiwyg areas, but my quick fixes didn't work and I don't have much time to work on this right now.

I wonder if there is a way to get this to work (or any other plugin with repeatable wysiwyg)

@sandys You can take a look at C7 Form Builder. Being able to repeat any field (including editor and group field) is one of the features available.

And, if anyone willing to implement repeatable editor fields in CMB, feel free to borrow code from my plugin.

I started to debug this but ran out of time. The issue seems to reside in cmb2.js. Here's what I determined:

  1. Something causes the cmb.neweditor_id object values 'id' and 'old' to remain IDENTICAL. This means when cmb.afterRowInsert tries to init TinyMCE, it's pointing to the old one. But this alone doesn't resolve the "canvas undefined", which seems to be related to quicktags.
  2. Then when I also add:
    quicktags( tinyMCEPreInit.qtInit[ id ] ); QTags._buttonsInit();
    The "canvas undefined" goes away, but the wysiwyg is still not initialized.
  3. But then, if you toggle the tabs (Visual | Text), they both initialize. But the Text view, where QuickTags binds, is duplicated.

So this _seems_ very fixable. Wish I could keep at it. Cheers and long live CMB2! Thanks a lot.

I needed to hove a reapeatable group with a wisiwig field too, and all my custom field were already managed by cmb2 so I coulnd't change to something else without changing everything, so I manage something (not really clean i agree) with an other jquery plugin for wisiwig textarea. I post it here so maybe it can help until the feature exist in cmb2.
The pluggin is trumbowygeditor, it's a really simple jquery pluggin for wisiwig.
So I change my wisiwig fields in cmb2 for textareas.
I create a js file that i load in my admin as well as the js and css files of trumbowygeditor.
I initialize trumbowygeditor for all the textareas in the repeatables blocks (you can easily find the appropriate selector looking for the classes in the code).
Here there will be 2 problems, when you sort the groups, as well as with tinymce, the wisiwig fields will stay in place, so it's why I chose this pluggin, it has a function that can close the wisiwig, so i target the click event on the "move up" and "move down" arrows, to close all the trumbowygeditors during the order switch, the with a setTimeout, I re-initialise them.
The second problem is when you add a new Group, it will simply duplicate the html of the previous group, so it won't initialise trumbowygeditors on the new field.
So I target the click event on the cmb-add-group-row, then I clone the textarea, I empty the cell with all the non-working html, and I initialise again the trumbowygeditor pluggin on this field.
I tell you, it's more a temporary tricky hack than a real solution, but it do the job until we find better.
If someone is interesting in it, I can give him the code.
Hope it'll help someone

@dnsJunior cool workaround, I was looking to fix this for a while now, would it be possible to have a look at your code.

Thanks,
Hugo

Related: #26, #356

Thanks for the amazing plugin @jtsternberg but in the meantime it would be great for me to implement @dnsJunior temporary fix.

Thanks in advance.

I've been having a look at this today to see if I can manage to at least get the editors working in groups.

I implemented the steps that @wilrevehl talked about and fixed the tinymce.init call. The settings were being passed through to the 'id' element but I think that's incorrect (I'm by no means a TinyMCE expert though - so correct me if I'm wrong).

Anyway, this has got me as far as the TinyMCE area now initialising but for some reason it is hidden so it looks as though it hasn't initialised even though that isn't the case. If you run this code, you'll notice that the element with a class of mce-tinymce mce-container mce-panel has a display: none; inline which is causing it to be hidden.

This change has also caused the tabs from letting you switch editors.

I forked the repository and you can find the changes I made at: https://github.com/0Neji/CMB2/commit/0ad6616786ebbb8ed1206a413b02c5b16e1de7a4

Obviously, still miles away from an actual fix but I thought it might be a good idea to post it to see if it gives anyone else more ideas etc.

I'll try to find more time to look again but hopefully this helps someone!

You all might try testing this branch: https://github.com/WebDevStudios/CMB2/tree/repeat-wysiwyg

wysiwyg is working in repeat groups, but only when adding groups. Removing groups is not working yet.

Ah, interesting - I'll check that out. Thanks!

Well! After a couple of days trying to get various methods to work with minimal fuss and hacking (for sorting and adding steps) and that works with existing textarea fields, I have implemented a button activated popup dialog for wysiwyg editing of textareas (using Trumbowyg that @dnsJunior recommended, but you could use any).

It has only two steps.

First add an _after_field_ setting containing the button html, to any textarea fields it is required on. e.g.

  array(
      'id'   => 'field-step-description',
      'name' => __('Step Description', 'pizazzwp-code'),
      'type' => 'textarea',
      'after_field' => '<p><div class="button wysiwyg-editor">wysiwyg</div></p>',
  ),

And secondly, the javascript:

(function ( $ )
{
  "use strict";
  jQuery( function ()
  {

    jQuery('.cmb2-wrap'  ).on( 'click', '.button.wysiwyg-editor',function ()
    {
      popEditor(this);
      //  return false; // Need this if your button is a <button>
    } );

    function popEditor( t )
    {
      var theSource = jQuery( t ).closest( '.cmb-td' ).find( '.cmb2_textarea' );
      var title = jQuery( t ).closest( '.postbox.cmb-row' ).find( 'h3.cmb-group-title' ).text();
      jQuery( '<div id="editor"></div>' ).dialog( {
        modal: true,
        width: 500,
        title: title + ' description',
        open: function ( event, ui )
        {
          jQuery( '#editor' ).html( '<textarea class="theeditor">' + jQuery( theSource ).val() + '</textarea>' );
          jQuery( '.theeditor' ).trumbowyg( {
            semantic: true,
            fullscreenable: false
          } );
        },
        close: function ( event, ui )
        {
          var theEditor = jQuery( '.theeditor' );
          jQuery( theSource ).val( theEditor.val() );
          theEditor.trumbowyg( 'destroy' );
          jQuery( '#editor' ).dialog( 'destroy' );
        }
      } );
    }
  } );

}( jQuery ));

(yes, for readability, I prefer to explicitly write jQuery, not $ )

And some screenshots:

image

image

If anyone can improve on this code or the implementation, please do!

@jtsternberg just tried your https://github.com/WebDevStudios/CMB2/tree/repeat-wysiwyg branch and it does initialize TinyMCE fields when adding a new block, but it acts strangely if there are more than one wysiwyg field in the block. It saves the content of the _last_ wysiwyg block as the content for the first one, and the rest of them are left blank. (Along similar lines, it won't save the new block at all unless the last wysiwyg area has content.)

repeat-wys

@jtsternberg I switched to the branch from this pull request and it worked for me, resolving the issues I mention above: https://github.com/WebDevStudios/CMB2/pull/431

Although you still can't reorder blocks with wysiwyg fields unless you switch to Text mode, it at least fixes the issue of adding new blocks.

Will this be added in the latest CMB2 plugin? It's making a blank line if you're in visual mode.

@natebeaty I also switched to the branch from the pull request and it also resolves the issues for me.

Not really sure whether this feature is really needed. Multiple instance of TinyMCE will be a burden to the browser performance. Before saving the Repeatable Group with WYSIWYG field, no matter how may instance of TinyMCE, firefox reserved up to 150mb physical memory, after saving the field, and reload the page with 5 TinyMCE instance, my firefox memory used up to 2gb of memory :((

@nonsensecreativity Well, that's interesting. What does it do with something like 5 instances? Does it crash?

@spwebguy it didn't crash, just turn really slow and lagging. all of the 5 instances only containing 1 paragraph of lorem ipsum text. Not sure it's firefox issue or not, haven't tested on other browser yet.

Yeah, this is still a problem for me. I often need to have wysiwyg in repeatable group field, but I don't want to limit cmb2 to the branch mentioned in this thread. I would definitely vote to have it as a feature.

I have submitted a pull request that fixes this issue.

@johnsonpaul1014 thanks.

Hi, not sure it’s the best to write here or open a new ticket…
I’ve noticed a bug when comboing WYSIWYG and the action of sorting (moving up or down a sortable item). When textarea ›WYSISYG is set as “visual” sorting does not work on this field. It sorts all other fields but not the WYSIWYGged one (= big mess). As I switch to “text”, it sorts correctly.
Running WP 4.5.2 and CMB2 plugin 2.2.1.
Thanks

@synthview I noticed that also: https://github.com/WebDevStudios/CMB2/issues/264#issuecomment-107667612 ... just told client to switch to text mode before sorting, but that's obviously not a great solution.

@synthview WYSIWYG in repeatable groups is not supported. That's why this thread exists. Or are you referring to a different branch?

well, in my case it seems to almost work, just I have to create a new group & save the (custom) post to make it load. BTW I’ve disabled the main content (the_content) form my posts

I've got a new PR that could use testing, but should make wysiwyg in repeatable groups work as expected. For all interested, please review/test!

Just found this patched version of the included .js which worked perfectly for me:
http://dev201.nl/cmb2-new-repeatable-wysiwyg-fields-not-initializing/

@madebymartin Thanks, working perfectly for me, too.

@madebymartin Thanks, it works, but only for init and saving. Sorting doesn't work.
@jtsternberg Do I correctly understand, that to test your PR I need to use trunk branch?

@slaFFik yes, it is now part of the trunk branch.

@jtsternberg Tested, seems to be working fine.
Sorting, adding new group, editing, saving - no problem.
Are there any estimates when it may become available for general public?

I'm working on finalizing some bits for the REST API, so once that's good to go, I'll be pushing an update.

Excited!

Just use trunk as is and carry on :)

Already changed in composer.json version to dev-trunk :)
But this is possible only during hard development, not when the product is released.

Thank you all for your input and contributions. wywiwyg field-types should now work correctly in repeatable groups.

From the changelog:

  • Make wysiwyg editors work in the repeatable groups context. A standard repeatable (non-group) wysiwyg field is not supported (but will possibly be included in a future update). Props @johnsonpaul1014 (#26, #99, #260, #264, #356, #431, #462, #657, #693).

This works smoothly but any pre code disappears in the CMB2 wysiwyg editor. In the visual editor, I add the html with > etc., and put a pre around it, just like in the regular visual editor and save then it's gone. If I do the same in just the text editor, it is fine as long as I don't switch back. Very odd.

@carasmo I would suggest adding your own 'sanitization_cb' (and possibly 'escape_cb').

Hi, all. While the functionality of a repeating group with a WYSIWYG field works, has anybody solved the problem with it becoming very laggy when there are numerous editors in the page? Some people reported that it's laggy when you have 5 editors. Our team can have upwards of 15 or 20 or more groups, which causes there to be that many editors in the page. I've been trying to figure out a way to get the editors to lazy load, but haven't had a lot of success. Any ideas on how to solve the lagginess issue?

@cooms13 your dilemma is exactly why it took so long for me to implement this feature. But we had a generous PR come in, so we got it in. I think if you're looking to do something like you are, unfortunately your best bet is going to be something custom-made until we have a better solution in core. You can also look through the available resources to see if there is anything that could help.

@jtsternberg Thanks for your response. Are you saying that the PR that you integrated solves the problem of the page getting laggy when there are lots of editors?

I believe the PR was already merged, and composed what we have now. However, that means that your usecase is still a bit on the heavy side for the topic.

@cooms13 @tw2113 is right. I meant, I didn't want to necessarily tackle the problem by throwing a ton of editor instances on the page, but the solution that came in is better than not being able to use wysiwyg fields in groups at all, so this is what we have for now.

One possible solution, we switch to a single editor instance when over X number of groups, and have an edit button next to the textarea which opens the content in a modal w/ that editor instance.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tw2113 picture tw2113  Â·  8Comments

noquierouser picture noquierouser  Â·  8Comments

stabilimenta picture stabilimenta  Â·  8Comments

bomsn picture bomsn  Â·  5Comments

GaryJones picture GaryJones  Â·  3Comments