#StackBounty: #tinymce #visual-editor #media-modal Adding image to visual editor popup for shortcode with wp.media and wp.mce: changing…

Bounty: 100

tl;dr: Why does using media manager popup within a TinyMCE popup cause duplications of shortcodes? Is it my code or just the way life is?

I’ve written a small plugin to create a visual editor button and popup that inserts a shortcode representing a "media object": image to right, text to left.

enter image description here

In the visual editor you click the button,

enter image description here

fill in the text in the popup,

enter image description here

choose the image

enter image description here

enter image description here

and hurrah:

enter image description here

The shortcode is correctly inserted into the editor, and the media view renders it nicely. (This is a reduced case for this question. The full popup has a heap of options.)

The only problem I have is if I want to edit the object and change the image.

If I edit the text, things are fine. If I change the image, then the whole thing inserts a second shortcode instead of replacing the first.

enter image description here

enter image description here

I suspect that clicking the Select Image button on the popup is changing the underlying insertion point or selection in the main editor, but I can’t for the life of me see how I can fix it.

Here’s my editor view JavaScript, taken from all the work done on shortcode popups by DT Baker a few years ago and still almost the only source of info on the Internet for this.

/* global tinyMCE */
(function($){
    var media = wp.media, shortcode_string = 'media_object';
    wp.mce = wp.mce || {};
    wp.mce.media_object = {
        shortcode_data: {},
        template: media.template( 'editor-media-object' ),
        getContent: function() {
            var options = this.shortcode.attrs.named;
            options.innercontent = this.shortcode.content;
            return this.template(options);
        },
        View: { // before WP 4.2:
            template: media.template( 'editor-media-object' ),
            postID: $('#post_ID').val(),
            initialize: function( options ) {
                this.shortcode = options.shortcode;
                wp.mce.media_object.shortcode_data = this.shortcode;
            },
            getHtml: function() {
                var options = this.shortcode.attrs.named;
                options.innercontent = this.shortcode.content;
                return this.template(options);
            }
        },
        edit: function( data ) {
            var shortcode_data = wp.shortcode.next(shortcode_string, data);
            var values = shortcode_data.shortcode.attrs.named;
            // var StrippedString = shortcode_data.shortcode.content.replace(/(<([^>]+)>)/ig,"");
            var StrippedString = shortcode_data.shortcode.content.replace(/(<p[^>]+?>|<p>|</p>|<br>|</br>|<br/>|<br />)/img, "");
            values.innercontent = StrippedString;
            // values.innercontent = shortcode_data.shortcode.content;
            values.imagehtml = '<img src="' + values.image_url + '" class="wp-image-' + values.image_id + '" width=120 height=120 style="max-width: 120px; max-height: 120px;" />';
            wp.mce.media_object.popupwindow(tinyMCE.activeEditor, values);
        },
        // this is called from our tinymce plugin, also can call from our "edit" function above
        // wp.mce.boutique_banner.popupwindow(tinyMCE.activeEditor, "bird");
        popupwindow: function(editor, values, onsubmit_callback){
            values = values || [];
            if(typeof onsubmit_callback !== 'function'){
                onsubmit_callback = function( e ) {
                    // Insert content when the window form is submitted (this also replaces during edit, handy!)
                    var args = {
                            tag     : shortcode_string,
                            //type    : e.data.innercontent.length ? 'closed' : 'single',
                            content : e.data.innercontent,
                            type    : 'closed',
                            //type    : 'single',
                            //content : '',
                            attrs : {
                                image_id    : e.data.image_id,
                                image_url   : e.data.image_url,
                                
                                
                            }
                        };
                    editor.insertContent( wp.shortcode.string( args ) );
                };
            }
            editor.windowManager.open( {
                title: 'Media Object',
                    body: [
                    
                    {
                        type: 'textbox',
                        name: 'innercontent',
                        multiline: true,
                        minWidth: 500,
                        minHeight: 100,
                        label: 'Main Text',
                        value: values.innercontent
                    },
                    
                    
                    {
                        type: 'textbox',
                        name: 'image_url',
                        label: 'Image',
                        id: 'my-image-box',
                        value: values.image_url
                    },
                    {
                        type: 'textbox',
                        name: 'imagehtml',
                        label: '',
                        id: 'my-image-box-html',
                        hidden: true,
                        value: values.imagehtml
                    },
                    {
                        type: 'textbox',
                        name: 'image_id',
                        label: '',
                        id: 'my-image-box-id',
                        hidden: true,
                        value: values.image_id
                    },
                    
{
                    type   : 'container',
                    minWidth: 120,
                    minHeight: 120,
                    
                    name   : 'container',
                    label  : ' ',
                    id: 'my-image-container',
                    html   : values.imagehtml
                },
                
                    {
                        type: 'button',
                        name: 'selectimage',
                        text: 'Select Image',
                        onclick: function() {
                            window.mb = window.mb || {};

                            window.mb.frame = wp.media({
                                frame: 'post',
                                state: 'insert',
                                library : {
                                    type : 'image'
                                },
                                multiple: false
                            });

                            window.mb.frame.on('insert', function() {
                                var json = window.mb.frame.state().get('selection').first().toJSON();

                                if (0 > jQuery.trim(json.url.length)) {
                                    return;
                                }
console.log(json);
                                jQuery('#my-image-box-id').val(json.id);
                                jQuery('#my-image-box').val(json.sizes.medium.url);
                                //jQuery('#my-image-container').prepend('<img src="' + json.url + '" />');
                                jQuery('#my-image-container-body').empty().prepend('<img src="' + json.sizes.medium.url + '" width=120 height=120 style="max-width: 120px; max-height: 120px;" />');
                                imagehtml = '<img src="' + json.sizes.medium.url + '" class="wp-image-' + json.id + '" />';
                                jQuery('#my-image-box-html').val(imagehtml);
                            });

                            window.mb.frame.open();
                        }
                    }],
                onsubmit: onsubmit_callback
            } );
        }
    };
    wp.mce.views.register( shortcode_string, wp.mce.media_object );
}(jQuery));


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.