Learn how Scrivito CMS can help you deliver amazing digital experiences
See Scrivito CMS in action

Using and Defining Editors

Using and Defining Editors

Using the JavaScript API, Scrivito's user interface can be extended to make custom editing tools available.

Quick start

Whenever an attribute of a CMS object is rendered using a Scrivito tag helper such as scrivito_tag, the attribute becomes editable in the user interface, i.e. on the page on which it is rendered in editing mode. Several attribute types exist, each of which requires a specialized editing facility that allows users to alter attribute values of that individual type. A date value needs different treatment than a string value.

Scrivito already includes standard editors for all attribute types. They are part of the scrivito_editors gem and are automatically made available through the predefined default editor. The scrivito_editors gem is automatically included after adding the scrivito gem to your Rails application.

Even though Scrivito comes with editors for all attribute types, they may sometimes not adequately cover specific use cases. For example, how a number should be edited depends on what the number stands for. Is it a color, a column width, a distance? To let users change such values using an editor tailored to the specific use case, a callback can be provided, scrivito.select_editor, that lets you specify when to use a special editor, like so:

scrivito.on("load", function() { scrivito.select_editor(function(element, editor) { // Use a special editor but only for the "column_width" attribute. if ($(element).attr("data-scrivito-field-name") === "column_width") { editor.use("slider"); } }); });

Making editors available to users

In the moment a user attempts to edit an attribute value, the user interface executes the scrivito.select_editor callback, passing to it the DOM element concerned plus an editor object. You can use this callback to specify the editor to use or to disable editing, depending on the context, e.g. the CSS class or the attribute name:

scrivito.on("load", function() { scrivito.select_editor(function(element, editor) { // No editing inside '.my_special_area'. if ($(element).is(".my_special_area *")) { // Do not use any editor, i.e. the attribute is not editable. editor.disable(); } // Use a special editor but only for the "language" attribute. if ($(element).attr("data-scrivito-field-name") === "language") { editor.use("special_editor"); } // Also, make a couple of non-default/3rd-party editors available. // The first one capable of handling the element is used. editor.use("medium"); editor.use("fancy-enum"); editor.use("cool-tags"); }); });

If the select_editor callback specifies an editor to use, the UI checks whether it exists and, if it does, calls its can_edit method to determine whether the editor is suitable for editing the field. If it is, the UI activates the editor by calling its activate method. The select_editor callback is always executed after all callbacks set in scrivito.on("content") (which might have manipulated the DOM) are done.

If several editors are made available for use with an attribute (as in the example above), only the first one capable of editing its value is activated. If the callback does not specify an editor to use, or the ones specified cannot handle the attribute, the default editor is used as a fallback.

Call the disable method of an editor to completely prevent the field from being edited, regardless of any subsequent calls to use.

For the best control over the editors to use as well as regulated fallback mechanisms, please use scrivito.select_editor wherever possible. In case you cannot specify an editor by means of the JavaScript API, you can still use the :editor option of the scrivito_tag helper:

<!-- app/views/balloon_widget/show.html.erb --> <%= scrivito_tag :div, widget, :color, {class: 'balloon-color'}, editor: :balloon %>

Note that using the helper option for a field causes the logic implemented in scrivito.select_editor to be circumvented for this field.

Defining a custom editor

Scrivito's JavaScript API lets you define and select custom editors programmatically as attribute values are accessed in editing mode. A custom editor can be specified using the define_editor method, passing to it the editor name and the editor definition consisting of two callbacks, can_edit and activate:
scrivito.define_editor("editor_name", { can_edit: function(element) { // 1. Check whether the editor is suitable for editing // the field of the element. }, activate: function(element) { // 2. Activate the editor. } });

The UI calls can_edit to determine whether the editor is capable of editing the given element. If the callback returns a truthy value or is missing, activate is called to activate the editor. If the callback returns a falsy value or raises an error then the editor is not activated for this field.

If activate raises an error, the error is logged, but the UI continues to work normally.

Here is a full example of a simple custom editor for an enum field whose values are “yes” and “no”:

scrivito.on("load", function() { scrivito.define_editor("my_enum_editor", { can_edit: function(element) { return $(element).is("[data-scrivito-field-type=enum]"); }, activate: function(element) { element = $(element); element.on("change", function() { element.scrivito("save", element.is(":checked") ? "yes" : "no"); }); } }); });