Let's look at how to create a modal window on the example of a simple plugin which user presses the button will open a modal window with a form.
Here is the code for this plugin:
(function($R)
{
$R.add('plugin', 'myplugin', {
init: function(app)
{
// define app
this.app = app;
// define services
this.toolbar = app.toolbar;
},
start: function()
{
// create the button data
var buttonData = {
title: 'My plugin',
api: 'plugin.myplugin.open'
};
// create the button
var $button = this.toolbar.addButton('myplugin', buttonData);
},
open: function()
{
// open the modal
}
});
})(Redactor);
Now you need to add the body of the modal window to the properties of the plugin. To do this, we define the object modals
, and inside we specify the modal window variable, by whose name we will open this window. This variable can contain any HTML code. But as a rule, it will be a form with a set of fields.
(function($R)
{
$R.add('plugin', 'myplugin', {
modals: {
// this is variable with modal HTML body
'mymodal': '<form action="">'
+ '<div class="form-item">'
+ '<label>Please, type some text</label>'
+ '<textarea name="text" style="height: 200px;"></textarea>'
+ '</div>'
+ '</form>'
},
init: function(app)
{
this.app = app;
this.toolbar = app.toolbar;
},
start: function()
{
var buttonData = {
title: 'My plugin',
api: 'plugin.myplugin.open'
};
var $button = this.toolbar.addButton('myplugin', buttonData);
},
open: function()
{
// open the modal
}
});
})(Redactor);
By the way, you can specify several variables with modal windows, if your plugin should work with different windows. Like this:
(function($R)
{
$R.add('plugin', 'myplugin', {
modals: {
// this is variable with modal HTML body
'mymodal-1': '<form action="">'
+ '<div class="form-item">'
+ '<label>Please, type some text</label>'
+ '<textarea name="text" style="height: 200px;"></textarea>'
+ '</div>'
+ '</form>',
'mymodal-2': '<form action="">'
+ '<div class="form-item">'
+ '<label>Text</label>'
+ '<input type="text" name="text">'
+ '</div>'
+ '</form>'
},
// ... plugin code ...
});
})(Redactor);
Let's write the code for opening the modal window in the open
method of our plugin:
open: function()
{
var options = {
title: 'My modal', // the modal title
name: 'mymodal', // the modal variable in modals object
commands: {
cancel: { title: 'Cancel' } // the cancel button in the modal
}
};
// open the modal with API
this.app.api('module.modal.build', options);
}
Now when the button is pressed in the toolbar, our plugin will open the modal window. Full example:
(function($R)
{
$R.add('plugin', 'myplugin', {
modals: {
'mymodal': '<form action="">'
+ '<div class="form-item">'
+ '<label>Please, type some text</label>'
+ '<textarea name="text" style="height: 200px;"></textarea>'
+ '</div>'
+ '</form>'
},
init: function(app)
{
this.app = app;
this.toolbar = app.toolbar;
},
start: function()
{
var buttonData = {
title: 'My plugin',
api: 'plugin.myplugin.open'
};
var $button = this.toolbar.addButton('myplugin', buttonData);
},
open: function()
{
var options = {
title: 'My modal', // the modal title
name: 'mymodal', // the modal variable in modals object
commands: {
cancel: { title: 'Cancel' } // the cancel button in the modal
}
};
// open the modal with API
this.app.api('module.modal.build', options);
}
});
})(Redactor);
When opening the modal window, we specified an object with options, let's look at all the possible options for calling the modal window.
String
String
String
String
600px
String
false
, that means auto-height, you can set like 500px
.Object
String
commands
object that will be called when the enter key is pressed in the form of a modal window (see full description below)Let's see all the options in action:
open: function()
{
var options = {
title: 'My modal',
name: 'mymodal',
width: '500px',
height: '400px',
handle: 'insert',
commands: {
insert: { title: 'Insert' },
cancel: { title: 'Cancel' }
}
};
this.app.api('module.modal.build', options);
}
In this example, the modal window named mymodal
will be opened with a width of 500px and a fixed height of 400px. In the modal window there will be two buttons:
cancel
button that closes the modal window and calls the cancel
callback of the modal window on closing.insert
button, which calls the callback of the modal window insert
when pressed. Also in the handle
option this command is specified, which means when you press enter key on the form, this command will also be called.The modal window commands, which are the same buttons that will be in the footer, are set using the commands
object in the window's call options.
commands: {
insert: { title: 'Insert' },
cancel: { title: 'Cancel' }
}
Each command has a name and its own object with the properties of the button. In properties, you can specify the type of the button, for example: danger
, which will make the button red. This is useful for deletion actions.
commands: {
insert: { title: 'Insert' },
remove: { title: 'Delete', type: 'danger' },
cancel: { title: 'Cancel' }
}
Modal windows when opening and closing trigger common callbacks, regardless of which window is open or closed. See this in more detail in modal callbacks.
Also, each modal window calls its callbacks, tied to the modal window name and specified in the window's call options. Consider all the callbacks, for example, for this window call:
open: function()
{
var options = {
title: 'My modal',
name: 'mymodal',
handle: 'insert',
commands: {
insert: { title: 'Insert' },
cancel: { title: 'Cancel' }
}
};
this.app.api('module.modal.build', options);
}
Here are some callbacks that can be caught in your plugin by the name of this window:
(function($R)
{
$R.add('plugin', 'myplugin', {
modals: {
'mymodal': '<form action="">'
+ '<div class="form-item">'
+ '<label>Please, type some text</label>'
+ '<textarea name="text" style="height: 200px;"></textarea>'
+ '</div>'
+ '</form>'
},
init: function(app)
{
this.app = app;
this.toolbar = app.toolbar;
},
// messages
onmodal: {
mymodal: {
open: function($modal, $form)
{
},
opened: function($modal, $form)
{
},
close: function($modal, $form)
{
},
closed: function($modal, $form)
{
},
cancel: function($modal, $form)
{
},
insert: function($modal, $form)
{
}
}
},
start: function()
{
var buttonData = {
title: 'Myplugin',
api: 'plugin.myplugin.open'
};
var $button = this.toolbar.addButton('myplugin', buttonData);
},
open: function()
{
var options = {
title: 'My modal',
name: 'mymodal',
handle: 'insert',
commands: {
insert: { title: 'Insert' },
cancel: { title: 'Cancel' }
}
};
this.app.api('module.modal.build', options);
}
});
})(Redactor);
In the example, we specify the interception of messages from the modal windows through the onmodal
object and in it we specify the name of the variable mymodal
of our window.
The example shows a list of all possible messages/callbacks of this window, automatically called open
, opened
, close
, closed
and those messages that will be called when the buttons in the modal window are clicked: cancel
, insert
.
Each callback/message has the modal window object, and the form object as arguments (if the form is in the body of the modal window).
Create the life in our callbacks/messages of the modal window.
For example, let's set the data in the form of the modal window and put the focus in the form field.
// messages
onmodal: {
mymodal: {
open: function($modal, $form)
{
$form.setData({ text: 'Ok, it is my text.' });
},
opened: function($modal, $form)
{
$form.getField('text').focus();
}
}
}
To work with the form, we used Modal Form API.
Now let's see how the modal window can respond to commands, get data from the form, and close the window.
// messages
onmodal: {
mymodal: {
insert: function($modal, $form)
{
var data = $form.getData();
this._insert(data);
}
}
}
In this example, when the Insert
button is pressed in the modal window, the command triggers callback/message and inside we can use Modal Form API to get the data from the form and send them to the _insert
plugin method. Let's look at the possible code for this method:
_insert: function(data)
{
// close the modal
this.app.api('module.modal.close');
// check the data
if (data.text.trim() === '') return;
// insert data with Insertion Service
this.insertion.insertText(data.text);
}
Plugins have a service for translating values into different languages, including modal windows. To do this, define the lang
service when initializing the plugin and set the values for the translation.
translations: {
en: {
"myplugin": "My Plugin",
"myplugin-label": "Please, type some text"
}
},
init: function(app)
{
// define app
this.app = app;
// define lang service
this.lang = app.lang;
// define other services
this.toolbar = app.toolbar;
this.insertion = app.insertion;
}
Now call the lang service to specify the values.
// public
start: function()
{
// create the button data
var buttonData = {
title: this.lang.get('myplugin'),
api: 'plugin.myplugin.open'
};
// create the button
var $button = this.toolbar.addButton('myplugin', buttonData);
},
open: function()
{
var options = {
title: this.lang.get('myplugin'),
width: '600px',
name: 'mymodal',
handle: 'insert',
commands: {
insert: { title: this.lang.get('insert') },
cancel: { title: this.lang.get('cancel') }
}
};
this.app.api('module.modal.build', options);
}
You can specify language variables using the double #
character in the HTML body of the window, for example:
modals: {
'mymodal': '<form action="">'
+ '<div class="form-item">'
+ '<label>##! myplugin-label ##</label>'
+ '<textarea name="text" style="height: 200px;"></textarea>'
+ '</div>'
+ '</form>'
}
In this case, the language variable myplugin-label
will be automatically replaced with the value when the modal window is opened.
Look at the full example: how to create a plugin with modal window.