I wasn’t able to directly add a repeating field (with let’s say a + button) but I was able to create a 2 step process whereby the end-user can use a numeric field to set the number of repeatable areas on the next screen:
Step 1 – Select Shortcode
Step 2 – Shortcode Builder Step 1/2
Step 3 – Shortcode Builder Step 2/2
Step 4 – Shortcode Output into WYSIWYG Editor
Code:
(function() {
tinymce.PluginManager.add('shortcode_mce_button', function( editor, url ) {
editor.addButton( 'shortcode_mce_button', {
tooltip: 'Add custom shortcode',
image: '/wp-content/plugins/wdst-shortcodes/public/images/shortcodes.gif',
type: 'menubutton',
menu: [
{
text: 'accordion',
onclick: function() {
editor.execCommand('accordion_shortcode_mce_button_popup','',{
type: 'default',
accordionclass: '',
numberofitems: '2',
});
}
},
]
});
var accordion_tag = 'accordion'; //Add to the accordion shortcode naming; in our case accordion works fine.
//add accordion popup
editor.addCommand('accordion_shortcode_mce_button_popup', function(ui, v) {
//setup defaults
var type="default";
if (v.type)
type = v.type;
var accordionclass="";
if (v.accordionclass)
accordionclass = v.accordionclass;
var numberofitems="";
if (v.numberofitems)
numberofitems = v.numberofitems;
//open the popup
editor.windowManager.open( {
title: 'Accordion Shortcode Builder (Step 1 of 2)',
classes: 'items-panel',
body: [
{//add type select
type: 'listbox',
name: 'type',
label: 'Type',
value: type,
minWidth:300,
'values': [
{text: 'Default', value: 'default'},
],
tooltip: 'Select the type of accordion you want.'
},
{//add class input
type: 'textbox',
name: 'accordionclass',
label: 'Class',
value: accordionclass,
minWidth:300,
tooltip: 'Add custom classes to the accordion wrapper.'
},
{//add class input
type: 'textbox',
name: 'numberofitems',
label: 'Number of Items',
value: numberofitems,
minWidth:300,
tooltip: 'Set the number of accordion items needed.'
},
],
onsubmit: function(e) { // when the ok button is clicked
var finaltype = e.data.type;
var finalclass = e.data.accordionclass;
var totalitems = e.data.numberofitems;
var generalFormItems = [];
for(var i = 1; i <= totalitems; i++)
{
generalFormItems.push(
{
title: 'Accordion-Item '+i,
name:'item'+i,
type: 'form',
items:[
{
label: 'Accordion-Item ' +i,
name: 'itemhtml'+i,
type: 'container',
minWidth:300
},
{
label: 'Title',
name: String('title'+i),
type: 'textbox',
minWidth:300,
tooltip: 'Leave blank for none.'
},
{
label: 'Content',
name: 'content'+i,
multiline: true,
type: 'textbox',
minWidth:300
}]
})
}
win = editor.windowManager.open({
autoScroll: true,
minWidth: 600,
resizable: true,
classes: 'largemce-panel',
title: 'Insert Accordion-Items (Step 2 of 2)',
body: generalFormItems,
onsubmit: function( e ) { // when the ok button is clicked
//start the shortcode tag
var accordion_str="<p>[" + accordion_tag + ' type="'+finaltype+'" class="'+finalclass+'"]</p>';
for(var i = 1; i <= totalitems; i++) {
var gettitle = String('e.data.title' + i);
var title = eval(gettitle);
var getcontent = String('e.data.content' + i);
var content = eval(getcontent);
accordion_str += '<p>[' + accordion_tag + '-header]';
accordion_str += '[' + accordion_tag + '-title]' + title + '[/' + accordion_tag + '-title]';
accordion_str += '[/' + accordion_tag + '-header]</p>';
accordion_str += '<p>[' + accordion_tag + '-content]' + content + '[/' + accordion_tag + '-content]</p>';
}
//start the shortcode tag
accordion_str += '<p>[/' + accordion_tag + ']</p>';
//insert shortcode to TinyMCE
editor.insertContent( accordion_str );
}
});
}
});
});
});
})();
Additional Notes:
On the second option screen, I used the autoScroll parameter to create a scrollbar but in WordPress, this conflicts with their TinyMCE styles so I had to add the ‘classes’ parameter to set a class on this window and then use css to fix the display issues.
/*Fix Accordion Window scroll effect*/
.mce-largemce-panel {
top: 22% !important;
max-height: 500px !important;
}
.mce-largemce-panel .mce-reset {
height: 500px !important;;
overflow: auto !important;
margin-left: -16px !important;
margin-right: -16px !important;
}
.mce-largemce-panel .mce-window-head {
margin-left: 16px !important;
margin-right: 16px !important;
}
.mce-largemce-panel .mce-foot {
margin-left: 15px !important;
}
I also used some jquery validation on the number field on the first pop-up window. It’s not the prettiest code, and I’m sure someone else could find a better way to target this window, but this is what I am currently using to validate that a number has been input.
$(document).on('keyup', '.mce-items-panel .mce-reset .mce-container-body .mce-last .mce-container-body .mce-last .mce-container-body input.mce-last', function(event) {
var v = this.value;
if($.isNumeric(v) === false) {
//chop off the last char entered
this.value = this.value.slice(0,-1);
}
});
So, this just about covers everything. If there are any further updates, I’ll post those at that time. Hopefully this will atleast help some people who need a repeating field solution and can improve upon what I have shown here.