Field type plug-ins

When creating a web-app with Editor you might have a form which requires a specialised, unique, form control that is not available in Editor's built-in field types. Catering for every possible field type in Editor's core would be impossible, so only the most common field types are made available by the core.

To provide the ability of using other field types, Editor makes it easy to extend the capabilities of the library by providing a plug-in architecture for field types (in fact, the built-in types are really plug-ins which also use this architecture!).

Plug-in interface

Field type plug-ins for Editor are objects which have a specific structure and are added to the DataTable.ext.editorFields object.

The object that you add to editorFields must provide the following three functions:

  • create - called when the field is initialised, and the HTML for the control is created.
    • Function with the following signature:
    • Parameter 1: The field's configuration object (field-options)
    • Returns: The jQuery instance or the DOM node to append to the Editor form for the input. Can be null if no DOM element is required.
  • get - get the value of the field.
    • Function with the following signature:
    • Parameter 1: The field's configuration object (field-options)
    • Returns: The field value.
  • set - set the value of the field.
    • Function with the following signature:
    • Parameter 1: The field's configuration object (field-options)
    • Parameter 2: The value to set the field to.
    • Returns: None

Optionally the following functions may also be given for use with the Editor public API:

  • canReturnSubmit (since 1.6) - When the field has focus, can the return key submit the form. This can be used for fields where a return key press and be used to selected items, insert newlines or any other field specific operation. If the return key means nothing to the field, the function should return true allowing the form to be submitted. This function is executed at the time when the return key is pressed.
    • Function with the following signature:
    • Parameter 1: The field's configuration object (field-options)
    • Parameter 2: The node upon which the return key was triggered (node)
    • Returns: true if return will submit the form, and false if not.
  • disable - disable the field from user interaction.
    • Function with the following signature:
    • Parameter 1: The field's configuration object (field-options)
    • Returns: None
  • destroy - (since 1.6) - Called if the field is removed from the form (clear()) or the Editor instance is destroyed (destroy()). Provides the opportunity to clean up any event handlers that the field defined, to ensure there are no memory leaks.
    • Function with the following signature:
    • Parameter 1: The field's configuration object (field-options)
    • Returns: None
  • enable - enable the field for user interaction.
    • Function with the following signature:
    • Parameter 1: The field's configuration object (field-options)
    • Returns: None
  • errorMessage (since 1.6) - If Editor needs to display an error message for the field, this method will be called. It can be used to display a validation error message in a floating panel if the field input uses one. For example this is used in the datetime input, where the floating panel might otherwise cover the error message.
    • Function with the following signature:
    • Parameter 1: Error message to display. Will be falsy if no error is to be shown.
    • Returns: None
  • input - Obtain the element that the end user enters data into - this is typically a input, select, textarea or similar element. Editor will automatically find those three elements itself if this method is not supplied.
    • Function with the following signature:
    • Parameter 1: The field's configuration object (field-options)
    • Returns: None
  • owns - Used for inline and bubble editing - this method is executed when Editor detects a click event outside of the items being edited, allowing a check to be performed to see if the element clicked upon is owned by the editing field or not. This is useful for complex field types which can show extra information attached to the document's body.
    • Function with the following signature:
    • Parameter 1: The field's configuration object (field-options)
    • Parameter 2: The DOM node that was clicked upon.
    • Returns: boolean - true if the element is owned by the field (i.e. the editing will not be terminated), or false if it is not (editing will be terminated).

Each of these functions, when executed, is run in the Editor instance's scope - i.e. the this parameter is your Editor instance, allowing you to access the API methods and events if required.

Furthermore, the field object that is always passed in as the first parameter to these functions holds information about the configuration of the field input. This ensures that at any time you can access information about the field that is being worked with (a single field type can be used for multiple field instances) and store information unique to that field if required (for example a reference to the DOM elements used for the field type, so they can be referred to at later date - i.e. in the get / set functions).

Custom methods

Additional methods can be added to your field type beyond the six default methods above and will be accessible as editor.field(...).myMethod() through the fields() method. This can be very useful for cases where your field has additional options that can be called through the API such as updating the list of the available data for the field.

Custom methods have a similar function signature as the default methods, with the field object field-options) always being passed in as the first parameter, and any arguments given to the custom method's API call being appended after it.

Template structure

Field type plug-ins should use the following basic structure - note how the object that is used to hold the plug-ins is created if it does not already exist - Editor will use this object when it is loaded, allowing the load order of the files to be more flexible.

(function ($, DataTable) {

if ( ! DataTable.ext.editorFields ) {
    DataTable.ext.editorFields = {};
}

var Editor = DataTable.Editor;

DataTable.ext.editorFields.myFieldType = {
    create: function ( conf ) {
        ...
    },

    get: function ( conf ) {
        ...
    },

    set: function ( conf, val ) {
        ...
    }
};

})(jQuery, jQuery.fn.dataTable);

All that is required now is to fill in the functions!

Field creation

The create method is run when the field is added to the Editor instance, either using the fields option or add() API method. This method is used to set up the HTML for the field and attach any events that are required.

Keep in mind also that you have full access to the Editor API inside this method, so you can attach listeners for the events that Editor can trigger using the on() method. This can be useful, for example, to perform actions when the Editor form is first shown (open).

The following example uses two button elements which are set up to act as a toggle:

create: function ( conf ) {
    var that = this;

    conf._enabled = true;
    conf._input = $( 
        '<div id="'+Editor.safeId( conf.id )+'">'+
            '<button type="button" class="inputButton" value="0">To do</button>'+
            '<button type="button" class="inputButton" value="1">Done</button>'+
        '</div>');

    $('button.inputButton', conf._input).click( function () {
        if ( conf._enabled ) {
            that.set( conf.name, $(this).attr('value') );
        }

        return false;
    } );

    return conf._input;
},

Line-by-line:

  • Line 2 - Save the execution scope of the function so we can call the API methods when required by jQuery events
  • Line 4 - Attach a private flag to the conf object for the field enabled state (used in the enable and disable functions). Attaching it to the conf object means that this parameter is unique to this field instance.
  • Lines 5-9 - Create the HTML for the field type - in this case two buttons. Again we save the node to the conf object so we can reference it again later (in the get and set functions). Note that DataTable.Editor.safeId is used to create an ID which is easy to use - this is not required, but it can be useful if you wish to access elements by their ID.
  • Lines 11-17 - Attach a jQuery click event to each of the buttons that calls the Editor set() API method to set the value of the field (this will call the set function defined in our plug-in here). The code also checks that the field is enabled (_enabled) before the action is performed - the _enabled) flag is set by the enable and disable methods (see below).
  • Line 19 - Return the DOM node to be placed into the HTML form for the user to interact with.

Get and set

The get and set methods of our plug-in do exactly what you would expect and either get the value of the field (directly from the HTML, or from Javascript data store if one is used), or set the value of the field, updating the display as required to show the end user the value of the field.

Continuing the toggle button example above, the button that represents the currently selected value has the selected class attached to it (CSS can be used to visually identify the selected button).

In the case of the get function for this toggle field type simply use a jQuery selector to get the value attribute. For the set we simply remove the selected class from the buttons and then apply it to the required button, based on the value given to set:

get: function ( conf ) {
    return $('button.selected', conf._input).attr('value');
},

set: function ( conf, val ) {
    $('button.selected', conf._input).removeClass( 'selected' );
    $('button.inputButton[value='+val+']', conf._input).addClass('selected');
},

Enable and disable

The enable and disable functions are optional, however, in this example we'll illustrate their use. If you have no intention of using the field enable and disable functionality of Editor, then these functions aren't necessary. However, if you are creating a distributable plug-in for Editor, then including these functions is a good idea, in case someone else does use this functionality, or you yourself do so in future.

As you would expect, the enable and disable functions simply allow or disallow user interaction with the field.

Continuing the toggle field type example from above, a flag is attached to the field configuration object called _enabled. This is a simple boolean value that can be used to check if the field should allow user interaction or not, and the enable and disable functions can simply set that value. A class name is also added to the field when disabled to allow CSS to visually represent the disabled state:

enable: function ( conf ) {
    conf._enabled = true;
    $(conf._input).removeClass( 'disabled' );
},

disable: function ( conf ) {
    conf._enabled = false;
    $(conf._input).addClass( 'disabled' );
}

Bringing it together

To use the constructed field type now, simply set the type option of the field configuration object when using fields or add().

The example constructed here is available in the Editor examples.