Follow these instructions to build your custom editor:

  1. Load dependencies using the requireJS library

    For example:

    Discover/config/import/editors/custom/StringEditor/editor.js

    JavaScript libraries are resolved relative to the following path mappings:

    JavaScript modules provided by the framework must be loaded according to the JavaScript documentation installed with Tools and Frameworks.

    define(["app/xmgr/view/editors/Editor",
     "core/TemplateEngine",
     "template!editors/custom/StringEditor/editor.html"
    function(Editor, TemplateEngine, EditorTemplate) {
    }
    }

    In addition to editor.js, if a custom editor depends on any other custom JavaScript extensions, then these extensions can be resolved within editor.js using the relative paths from the current editor context or the paths relative to the editors folder. For example, if a custom editor needs three more JavaScript extensions that are available at these locations:

    The editor.js references them like in the following example:

    define(["app/xmgr/view/editors/Editor",
     "core/TemplateEngine",
     "template!editors/custom/StringEditor/editor.html",
     "editors/MediaEditor",editors/MediaEditor/model/Image"],
     function(Editor, TemplateEngine, EditorTemplate, MediaEditor,Image) {
    });
    
                                    (OR)
    
    define(["app/xmgr/view/editors/Editor",
     "core/TemplateEngine",
     "template!editors/custom/StringEditor/editor.html",
     "editors/MediaEditor",./model/Image"],
     function(Editor, TemplateEngine, EditorTemplate, MediaEditor,Image) {
    });

  2. The custom editor must extend the base Editor class.

    According to the JavaScript module pattern, to extend the Editor, the custom editor must define a constructor method with Configuration as a parameter and invoke the super class constructor. You must create an Editor object using a prototypical instance and copy this Editor prototype to the custom editor prototype. For example:

    ...
    var StringEditor = function(pConfig) {
        var self = this;
        Editor.call(self, pConfig);
    };
    StringEditor.prototype = Object.create(Editor.prototype);
    ...
  3. Optional. Override the initialize() life cycle method to implement any additional parsing that is specific to the custom editor.

    For example, ChoiceEditor would have an array of choices. In this case, parse the cartridge template and populate choices under the initialize method. If overridden, this method should explicitly call the Editor::initialize() super class method.

    ...
    ChoiceEditor.prototype.initialize = function(pTemplateConfig, pContentItem) {
        var self = this;
        //Populate choices from the pTemplateConfig object
        Editor.prototype.initialize.call(self, pTemplateConfig);
    };
    ...
  4. Optional. Override the editorReady() life cycle method to implement any additional manipulations regarding a property or properties within which an editor works.

  5. Define an editor.html template. In the following example, Discover/config/import/editors/custom/StringEditor/editor.html uses ojInputText, the Oracle JET component, and oj-flex, the default Oracle JET responsive layout. To ensure uniqueness generate a unique ID for each of the editor form controls.

    <!-- Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. -->
    <div class="oj-flex">
        <!-- To ensure uniqueness, generated unique id for label and input tags. -->
        <!-- Example: Generated Id will be in the format editor_<number> -->
        <div class="oj-flex-item customLabel customEditorLabel">
            <label data-bind="attr:{for: editorId}"><span data-bind="text : labelText"/></label>
        </div>
        <div class="oj-flex-item editorInput">
            <!-- invalidComponentTracker is required in case of any validation needed for editor. So if an editor has validations defined, then
              add  invalidComponentTracker: $parents[3].tracker as a property of ojComponent-->
            <input title="" data-bind="attr : {'id': editorId ,'aria-label' : editorBundle.getMessage('editor.aria.label')}, ojComponent: { component: 'ojInputText', value : property().value , disabled : !isEnabled() || isReadOnly(),
                                                                             help :{definition :helpText},
                                                                             rootAttributes: {style:'max-width:68.5rem'},
                                                                             displayOptions: {messages: 'inline'},
                                                                             optionChange: handleInputKey.bind($data),
                                                                             validators : [
                                                                             {
                                                                                type : 'regExp',
                                                                                options : {
                                                                                            pattern : requiredPattern
                                                                                          }
                                                                             }
                                                                             ],
                                                                             invalidComponentTracker: $parents[3].tracker
                                                                             }"/><br>
            <span data-bind="text: bottomLabel" class="bottomLabel"></span>
        </div>
        </div>
    </div>
    
  6. Once a template is defined, it can be loaded using the TemplateEngine JavaScript module provided by the framework.

    In the following example, Discover/config/import/editors/custom/StringEditor/editor.js, the template can be loaded by specifying a path relative to the editors folder. The template can also be resolved by specifying a path relative to editor.js, for example, require("template!./editor.html").

    var TemplateEngine  = require("core/TemplateEngine");
    ...
    var TEMPLATE_TEXT = require("template!editors/custom/StringEditor/editor.html");
    ...
    var StringEditor = function(pConfig) {
       var self = this;
       ...
       self.template(TemplateEngine.addSource(TEMPLATE_TEXT));
    }
    ...
  7. Define a _.json with an ecr:type of editor. If you need a configuration for this editor, that can be defined in the config property. See the following example of Discover/config/import/editors/custom/StringEditor/_.json:

    {
      "ecr:type": "editor",
        "config":{
          "pattern":"[A-Za-z0-9_]{5,}"
       }
    }
  8. If you need to define a custom CSS for your editor, place at the following location: <app dir>/editors/custom/<editor name>/css/<name>.css file.

  9. If you created a custom CSS in the previous step, add a link to the CSS in your custom editor. For example:

    <link rel="stylesheet" href="sites/Discover/editors/custom/StringEditor/css/styles.css"/>
    <div class="oj-flex">
     <div class="editorLabel">
            <label data-bind="attr:{for: uniqueId}"><span data-bind="text : labelText"/></label>
        </div>
        <div class="editorInput">
    <input>
    </div>
    <div>

Here is an example of the completed editor.js for the String Editor used in the previous topics:

// Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
define(["app/xmgr/view/editors/Editor", "core/TemplateEngine", "template!editors/custom/StringEditor/editor.html", "ojs/ojcomponents", "ojs/ojknockout", "ojs/ojinputtext"], function (Editor, TemplateEngine, EditorTemplate) {
  "use strict";

  var TOOL_TIP = "tooltip";

  /**
   * @alias StringEditor
   * @classdesc Special Editor for editing properties whose value is a String.
   * Editor allows values only those which are in a specific pattern.
   * This pattern can be configured using a regular expression in editor's
   * configuration file i.e. _.json.
   * @extends app/xmgr/view/editors/Editor
   * @constructor
   */
  var StringEditor = function (pConfig) {
    var self = this;
    Editor.call(self, pConfig);
    /**
     * Pattern allowed to enter through editor. Default is null.
     * @type {null}
     */
    self.requiredPattern = pConfig.editorConfig.pattern;

    self.template(TemplateEngine.addSource(EditorTemplate));
  };

  StringEditor.prototype = Object.create(Editor.prototype);

  /**
   * This method initializes the editor instance. This should not be called explicitly,
   * as framework internally calls the same as part of editor's life cycle.
   * Should call initialize method of it's super class, passing the configuration object.
   * Will override this method to instantiate and initialize any custom controllers,
   * subscribe for any custom notifications etc.
   * @param pTemplateConfig Configuration object that holds configuration specified in cartridge template for this editor.
   * @param pContentItem ContentItem object which has the property that this editor works with.
   */
  StringEditor.prototype.initialize = function (pTemplateConfig, pContentItem) {
    var self = this;
    pTemplateConfig[TOOL_TIP] = self.editorBundle.getMessage("tooltip.information", self.requiredPattern);
    Editor.prototype.initialize.call(this, pTemplateConfig, pContentItem);
  };

  /**
   * This method binds the property object, whose value will be edited through this editor.
   * This should not be called explicitly, as framework internally calls the same as part of
   * editor's life cycle. Based on the type that you give for a property in cartridge template,
   * framework wraps property in an appropriate property class :
   * Allowed types are String, Boolean, Item, List, ContentItem, ContentItemList. Corresponding to these types framework wraps property using
   * StringProperty, BooleanProperty, JSONProperty (for both Item and List), ContentItemProperty, ContentItemListProperty.
   * Can override this method, if there is a need to a wrap property in a custom extension to the Property API.
   * For example in case of NumericStepperEditor, StringProperty can be wrapped using NumberProperty in editorReady.
   * If overridden, should call editorReady method of it's super class, passing the property object.
   */
  StringEditor.prototype.editorReady = function (pProperty) {
    var self = this;
    Editor.prototype.editorReady.call(self, pProperty);
  };

  return StringEditor;

});


Copyright © Legal Notices