CMB2 new repeatable WYSIWYG fields not initializing
CMB2 is great for adding your own fields (custom meta boxes) to WordPress.
When implementing a repeater group with a (WP tinyMCE) WYSIWYG editor I ran into an issue with adding a new group. The new WYSIWYG wouldn’t load (initialize properly). Only after saving the form in WordPress. At the time of writing this issue doesn’t seem to be fixed yet. I did find a patch by Arkytn which fixes this issue.
Example code
Example php code in function.php to create a repeater group with a title field and a WYSIWYG field:
(replace status201 with your own prefix)
/** * Get the bootstrap (when including cmb2 inside your theme)! If using the plugin from wordpress.org, REMOVE THIS! */ if ( file_exists( dirname( __FILE__ ) . '/cmb2/init.php' ) ) { require_once dirname( __FILE__ ) . '/cmb2/init.php'; } elseif ( file_exists( dirname( __FILE__ ) . '/CMB2/init.php' ) ) { require_once dirname( __FILE__ ) . '/CMB2/init.php'; } add_action( 'cmb2_admin_init', 'status201_register_repeatable_group_field_metabox' ); /** * Hook in and add a metabox to demonstrate repeatable grouped fields with a WYSIWYG */ function status201_register_repeatable_group_field_metabox() { $prefix = 'status201_group_'; /** * Repeatable Field Groups */ $cmb_group = new_cmb2_box( array( 'id' => $prefix . 'metabox', 'title' => __( 'Content accordeon', 'cmb2' ), 'object_types' => array( 'page', ), ) ); // $group_field_id is the field id string, so in this case: $prefix . 'subcontent' $group_field_id = $cmb_group->add_field( array( 'id' => $prefix . 'subcontent', 'type' => 'group', 'description' => __( 'Voeg subcontent (titel en tekstveld paren) toe', 'cmb2' ), 'options' => array( 'group_title' => __( 'Subcontent {#}', 'cmb2' ), // {#} gets replaced by row number 'add_button' => __( 'Nieuwe subcontent toevoegen', 'cmb2' ), 'remove_button' => __( 'Verwijder', 'cmb2' ), 'sortable' => true, // beta // 'closed' => true, // true to have the groups closed by default ), ) ); /** * Group fields works the same, except ids only need * to be unique to the group. Prefix is not needed. * * The parent field's id needs to be passed as the first argument. */ $cmb_group->add_group_field( $group_field_id, array( 'name' => __( 'Titel', 'cmb2' ), 'id' => 'title', 'type' => 'text', // 'repeatable' => true, // Repeatable fields are supported w/in repeatable groups (for most types) ) ); $cmb_group->add_group_field( $group_field_id, array( 'name' => __( 'Content', 'cmb2' ), 'description' => __( 'Vrije tekst', 'cmb2' ), 'id' => 'content', 'type' => 'wysiwyg', 'options' => array( 'textarea_rows' => 5, ), ) ); }
The example code to get the values in the frontend:
(Again, replace status201 with your own prefix)
$entries = get_post_meta( get_the_ID(), 'status201_group_' . 'subcontent', true ); foreach ( (array) $entries as $key => $entry ) { if ( isset( $entry['title'] ) ) $title = esc_html( $entry['title'] ); if ( isset( $entry['content'] ) ) $content = $entry['content']; // Output the values if ( !empty($title) ) echo '<h2>'.$title.'</h2>'; if ( !empty($content) ) echo wpauotp($content); // wpautop to have paragraph tags! }
The patches to fix this issue
We only have to change some code inside includes/cmb2.js
(and minified into includes/cmb2.min.js
).
Find this line (inside the if ( isEditor ) {
check):
newID = newID ? oldID.replace( 'zx'+ prevNum, 'zx'+ cmb.idNumber ) : '';
And replace it with this:
newID = newID ? oldID.replace( '_'+ prevNum, '_'+ cmb.idNumber ) : '';
Further down, find this code:
if ( typeof( tinyMCEPreInit.qtInit[ id ] ) === 'undefined' ) { var newQTS = jQuery.extend( {}, tinyMCEPreInit.qtInit[ old ] ); for ( _prop in newQTS ) { if ( 'string' === typeof( newQTS[_prop] ) ) { newQTS[_prop] = newQTS[_prop].replace( new RegExp( old, 'g' ), id ); } } tinyMCEPreInit.qtInit[ id ] = newQTS; } tinyMCE.init({ id : tinyMCEPreInit.mceInit[ id ], });
And replace it with this:
if ( typeof( tinyMCEPreInit.qtInit[ id ] ) === 'undefined' ) { tinyMCEPreInit.qtInit[id] = $.extend( {}, tinyMCEPreInit.qtInit[ old ] ); tinyMCEPreInit.qtInit[id].id = id; //Remove cloned toolbar $('#qt_'+id+'_toolbar').remove(); // make the editor area visible $('#'+id).addClass('wp-editor-area').show(); // initialize quicktags new QTags(id); QTags._buttonsInit(); } switchEditors.go(id, tinyMCEPreInit.mceInit[id].mode); tinymce.init(tinyMCEPreInit.mceInit[id]);
Download the patched JS files
Download the patched cmb2.js and cmb2.min.js. (for version 2.2.2.1)