TinyMCE 4 – Multi-line labels in popup dialogs

Adding an explanatory text label to a TinyMCE pop-up can be a great way of helping your users find their way around your custom dialogs. Unfortunately you might struggle if you can’t keep your instructions short.

If you’re writing a custom TinyMCE plugin which includes a popup dialog you might want to add some explanatory text to guide your users on how to use it. This is pretty easy to do by adding a label control:-

editor.windowManager.open({
    title: 'A simple popup',
    body: [{type: 'label',
            name: 'someHelpText',
            text: "Here's some kinda lengthy help text to " +
                  "explain how to use this popup and what you need " +
                  "to type in the field below"},
           {type: 'textbox',
            name: 'someField',
            size: 20,
            label: 'A field'}]
});

Unfortunately this doesn’t look great in the user’s browser, especially if they’re using a narrow window:-

 

TinyMCE Popup Label (1/5)

 

TInyMCE clearly won’t help us out by automatically balancing the layout for us. Unfortunately it doesn’t make it easy for us to balance it ourselves either.

Automatic label wrapping

The documentation for the Window class does reveal width and height properties we can set. Constraining the size of the pop-up would seem logical:-

editor.windowManager.open({
    title: 'A simple popup',
    width: 340,
    height: 140,
    body: [{type: 'label',
            name: 'someHelpText',
            text: "Here's some kinda lengthy help text to explain " +
                  "how to use this popup and what you need to " +
                  "type in the field below"},
           {type: 'textbox',
            name: 'someField',
            size: 20,
            label: 'A field'}],
});

And this does indeed constrain the size of the popup. Unfortunately it doesn’t constrain the size of the fields it contains:-

 

TinyMCE Popup Label (2/5)

 

Reviewing the label documentation again reveals a few potentially useful properties, multiline in particular looks promising, though it fails to deliver (at least initially) as does the height property. Setting the height via the style property does at least allow us to increase the depth of the control.

editor.windowManager.open({
    title: 'A simple popup',
    width: 340,
    height: 140,
    body: [{type: 'label',
            name: 'someHelpText',
            multiline: true,
            style: 'height: 50px',
            text: "Here's some kinda lengthy help text to explain " +
                  "how to use this popup and what you need to " +
                  "type in the field below"},
           {type: 'textbox',
            name: 'someField',
            size: 20,
            label: 'A field'}],
});

Unfortunately the extra depth doesn’t get filled up with our text:-

 

TinyMCE popup labels (3/5)

 

Having a shufti at the runtime properties the controls via an HTML browser shows that the width of both the label and the field are being set to use the full space required by the widest control – in this case the label. Trying to set narrow widths via the style properties has no affect on the text box and only causes the label to become horizontally scrollable.

Manual label wrapping

Patient plodding through the other CSS properties and the other TinyMCE layout managers available for popups might eventually yield a good solution, though I haven’t got there yet. If you’re anything like me at this point a workaround is looking preferable to a hard won ‘right answer’. Fortunately, since the pop-up can be set to a fixed width and the label text is also static, breaking the label up ourselves with new-lines would work just as well. The label is rendered as an HTML label element, so adding some <br/> tags to its content ought to be enough:-

editor.windowManager.open({
    title: 'A simple popup',
    width: 340,
    height: 140,
    body: [{type: 'label',
            name: 'someHelpText',
            multiline: true,
            style: 'height: 50px;',
            text: "Here's some kinda lengthy help text to explain<br/>"+
                  "how to use this popup and what you need to<br/>" +
                  "type in the field below"},
           {type: 'textbox',
            name: 'someField',
            size: 20,
            label: 'A field'}],
});

Alas, TinyMCE is one step ahead of us again:-

 

TinyMCE Popup Labels (4/5)

 

The content provided in the text property is scrubbed for HTML special characters before being rendered so our <br/> is displayed as just that rather than as an HTML element. The alternative of using \n newlines doesn’t work either.

This time though we do have a way around it. Instead of setting our content in the text property we can assign it to the control in the onPostRender function:-

editor.windowManager.open({
    title: 'A simple popup', 
    width: 340,
    height: 140,
    body: [{type: 'label',
            name: 'someHelpText',
            multiline: true,
            style: 'height: 50px',
            text: "",
            onPostRender : function() {
                this.getEl().innerHTML =
                   "Here's some kinda lengthy help text to explain<br/>"+
                   "how to use this popup and what you need to<br/>" + 
                   "type in the field below";}},
           {type: 'textbox',
            name: 'someField',
            size: 20,
            label: 'A field'}],
});

Not only does this finally oblige us with a multi-line label, but since the default layout for the dialog has been calculated with an empty label it sorts out the width of our text field too:-

 

TinyMCE Popup Labels (5/5)

 

Sure, it’s not a very elegant solution, but it does get the job done and sometimes that’s enough.

After all, we’ve all got better things to do with our time!

 

4 responses to “TinyMCE 4 – Multi-line labels in popup dialogs

  1. And how can I get user’s input?

    • TinyMCE’s toJSON function is a pretty nifty way of getting all the field values on a pop-up form. For example, the following onSubmit function for the above dialog will display an alert box showing the user’s input into the field:-

      onSubmit : function() {
      alert(this.toJSON().someField);
      }

  2. Thanks for this time-saving post. I found myself in a slightly different situation where I had to update the text inside a label (which needs lines to wrap) dynamically in a callback for a mouseover event on another widget. I’m using the jQuery friendly version of TinyMCE, which gives you an alternative to having to call getEl().innerHTML on the label widget. Instead, I put an id attribute on my label (via the id property) and then set the innerHtml inside the mouseover callback with a jQuery selector: $(“#labelId”).html(…).

    The result is the same although I thought it was worth mentioning the alternative approach.

  3. Hi,

    I was looking on how to create more complex dialogs. But the TinyMCE documentation isn’t very helpful. So I went ahead and wrote an article listing the different widgets and containers layout available: http://makina-corpus.com/blog/metier/2016/how-to-create-a-custom-dialog-in-tinymce-4

    Hope it will helps

Leave a Reply to devsumo Cancel reply

Your email address will not be published. Required fields are marked *