Creating Custom Dialog Fields with JavaScript
Magnolia authors use a special interface to manage page data, called dialog. A dialog is a pop-up, featuring a set of fields to add and edit content in Magnolia’s WYSIWYG editor. Besides offering many field types out of the box, Magnolia allows developers to create custom field types using JavaScript and file-based configuration.
To define dialogs developers use data modeling, specifying each field type. Below is a simple example of a dialog, consisting of two tabs: text and image. The text tab allows authors to define a headline and text. Headline is a text field and text is a rich text field:
Dialog Fields
The available field types in Magnolia are likely to cover your project needs, but likely is not always. Hence, we enable developers to define custom dialog fields.
Previously, you had to get your hands dirty with Java to create custom fields. This isn’t ideal for two reasons.
Many template developers are not familiar with Java.
Each Java module requires a deployment and restart of all Magnolia instances.
JavaScript Dialog Fields
This challenge can easily be overcome with the help of one module, JavaScript Dialog Fields. This extension enables the file-based configuration of custom dialogs fields using Magnolia Light Development. Now, developers can create custom dialog fields of type javascriptField though simple YAML configuration.
The javascriptField field type loads an HTML file in an iframe. The iframe communicates with Magnolia through a set of predefined messages.
To better understand how to use the module, let’s build a color picker dialog field.
Start by creating the dialog definition colorField.yaml:
form:
implementationClass: info.magnolia.ui.javascript.form.FormViewWithChangeListener
properties:
colorField:
label: Color field
$type: javascriptField
fieldScript: /ui-framework-javascript-examples/webresources/colorField.html
height: 40
The form uses the new field type javascriptField and fieldScript points to the HTML file to load in the iframe. Height defines the iframe’s height rendered by Magnolia.
colorField.yaml has to be placed in an existing or new Light Module.
Next, create a minimal page with one input field called colorField.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
</head>
<body>
<input id="input" type="color" />
<script>
let input = document.getElementById('input');
let correlationId;
input.addEventListener('change', function () {
parent.window.postMessage({ action: 'changeValue', correlationId, value: input.value }, '*');
});
window.addEventListener(
'message',
function (event) {
if (event.data.action === 'init') {
correlationId = event.data.correlationId;
input.value = event.data.state.value || event.data.state.defaultValue || '';
}
},
false
);
</script>
</body>
</html>
The communication between Magnolia and the iframe happens via JavaScript messages. All messages have an action parameter allowing you to influence the page behavior.
As you can see, the page is listening for a message with an init action, which Magnolia sends when it fully loaded the iframe. With init action we get the correlationId that prevents mixing up messages between the different javascriptField fields.
We also get the current value of the field inside the state object as well as its defaultValue if specified in the dialog definition.
The page also observes changes to the input field and triggers a message to its Magnolia parent window with three parameters:
changeValue as action
correlationId from init action
value as new value from input
After referencing the dialog in a page or component definition you should see the new colorField when editing content.
Low-code development
Simplify and speed up development with Magnolia using file-based configuration.
More Features
Field Validation
javascriptField can use regular Magnolia validators to check field values. If an invalid value was entered into the field, the page would receive an errorMessage as action.
emailField:
label: Email field
$type: javascriptField
fieldScript: /ui-framework-javascript-examples/webresources/emailField.html
height: 40
validators:
email:
$type: emailValidator
errorMessage: Please enter a valid email address
Parameters Object
You can also pass various parameters to your iframe, for example, a background color.
withParameters:
label: With parameters
$type: javascriptField
fieldScript: /ui-framework-javascript-examples/webresources/withParameters.html
height: 40
parameters:
background: blue
Do you remember the init action message we listened to in the color picker example? Data passed to the withParameters.html iframe will be extended with the parameters object.
{
action: 'init';
correlationId: '550';
formFields: [];
height: '40.0px';
parameters: {
background: 'blue';
}
}
This allows us to access parameters using:
event.data.state.parameters.background
Conditional Forms
Changes to any of the dialog fields trigger a change action updating the formFields object.
event.data.state.formFields
The formFields object contains the current values of all dialog fields. By continuously updating javascriptField with all current values, you are able to build conditional forms.
This functionality could, for example, be used for product and color choosers. Users can choose from a different set of colors for product A than for product B.
Availability
The JavaScript Dialog Fields module is available in the Magnolia Marketplace. For a set of examples covering all action types take a look at the Light Module ui-framework-javascript-examples.
Now feel free to try the new field type in your project.