67 Contributor Interface: Customizing Asset Forms

This chapter discusses customizations that you can apply to asset forms in the WebCenter Sites Contributor interface. It also provides a step-by-step example for building a single-valued and multi-valued attribute editor for some of the supported data types.

This chapter contains the following topics:

67.1 Overview of Asset Forms Customization

You can perform two types of customizations on asset forms in the Contributor interface. One, you can modify the header of an asset form. The other is, you can either customize an existing attribute editor, as explained in Section 18.3, "Customizing Attribute Editors," or you can build a custom attribute editor for the data types supported by WebCenter Sites, as described in Section 67.3, "Building an Attribute Editor."

Note:

Unlike other components of the Contributor interface, asset forms are not in the Contributor framework. Therefore, requests for asset forms are not processed by the UI Controller.

67.2 Modifying the Header of Asset Forms

You can modify the header of any asset form by creating a custom assettype-specific element in the OpenMarket/Xcelerate/AssetType/<AssetTypeName>/ directory. You can include additional stylesheets or JavaScript code instead of modifying the body of the HTML pages. The name of the element must be Header.

67.3 Building an Attribute Editor

You can customize the look and feel of some of the existing ready-to-use attribute editors, as described in Section 18.3, "Customizing Attribute Editors." You can also create a custom attribute editor for the data types supported in WebCenter Sites.

This section describes how to build a custom attribute editor that supports a single value of data type text, string, integer, or money. This section also provides pointers and sample code for implementing a multi-valued attribute editor for the same data types.

Note:

If you want to create a custom attribute editor for the blob or asset data type, you can base your implementation on the UPLOADER attribute editor for the blob type and the PICKASSET attribute editor for the asset data type.

Steps for building an attribute editor are the following:

67.3.1 Creating a Dojo Widget and its Template

This section describes how to create a Dojo widget to handle a single value of data type text, string, integer, or money.

This section contains the following topics:

67.3.1.1 Create a Template for the Dojo Widget

To create an HTML template for the Dojo widget:

  1. In your WebCenter Sites installation directory, navigate to the <context_root>/js/ directory.

  2. Create a new directory structure under the js directory as follows: extensions/dijit/templates.

  3. In the <context_root>/js/extensions/dijit/templates directory, create an HTML template file and give it a meaningful name. For example: MyWidget.html

  4. In the HTML template file, define the look and feel of the new Dojo widget. The content of this HTML template would look similar to this:

    <div>
       <div>
           <input type="text" dojoAttachPoint='inputNode'
            name='${name}'size='60' class='valueInputNode'>
           </input>
       </div>
    </div>
    

    If you use the above code for the template, then the input node will take the input from the end user and the value of the input node will be maintained in the Dojo widget which you will create in Section 67.3.1.2, "Creating a Dojo Widget."

  5. Save your template file.

  6. Continue to Section 67.3.1.2, "Creating a Dojo Widget."

67.3.1.2 Creating a Dojo Widget

To create a Dojo widget:

  1. Navigate to the js/extensions/dijit directory of the WebCenter Sites installation.

  2. Create a dojo widget, for example, MyWidget.js (see Example 67-1) by implementing the following mandatory functions:

    • _setValueAttr: This setter method sets the value of the attribute.

    • _getValueAttr: This getter method gets the attribute value.

    • isValid: This method runs validations to see if the given value is valid or not.

    • focus: This sets the focus on the attribute editor.

    • onChange: This method is called whenever the user updates the value of the attribute.

    • onBlur: This method updates the widget when the attribute value is entered by the user. An update will be triggered when the user selects another field.

    Example 67-1 Sample Code for a Dojo Widget

    dojo.provide('extensions.dijit.MyWidget');
    dojo.require('dijit._Widget');
    dojo.require('dijit._Templated');
    dojo.declare('extensions.dijit.MyWidget', [dijit._Widget, dijit._Templated], {
      //string.
      //The value of the attribute.
      value: '',
      //int
      //The Attribute editor's MAXALLOWEDCHARS should be assigned to this variable.
      //maxAllowedLength: 15,
      //string
      //   This variable is required only for single valued instance.
      //   The server should recieve information from input element with this name.
      name: '',
      //HTMLElement
      //   This stores the cached template of the widget's representation.
      templateString: dojo.cache('extensions.dijit', 'templates/MyWidget.html'),
      //string
      //   This class will be applied to the top div of widget.
      //   It will help in managing css well.
      baseClass: 'MyWidget',
      postCreate: function() {
          var self = this;
          // Do not allow typing characters more than allowed length.
             dojo.connect(this.inputNode, 'onkeypress', function(e) {
             if (this.value.length >= self.maxAllowedLength && e.keyCode !=
                 dojo.keys.BACKSPACE) 
             e.preventDefault();
          });
    },
    // Start -  Mandatory functions
    _setValueAttr: function(value) {
        //  summary:
        //     Set the value to 'value' attribute and input node
        if (value === undefined || !this._isValid(value)) return;
        this.value = value;
        this._setInputNode(value);
    },
    _getValueAttr: function() {
       // summary:
       //Get the latest value and return it.
       return this.value;
    },
    _isValid: function(newVal) {
       //summary:
       //Verify if the given value is as per the expectation or not.
       if (newVal.length > this.maxAllowedLength) {
       return false;
    }
       return true;
    },
       focus: function() {
       //summary:
       //Set the focus to the representation node i.e. input node here.
       if (typeof this.inputNode.focus === 'function')
       this.inputNode.focus();
    },
    onBlur: function() {
       //summary:
       //Custom selected browser event when the value should be updated
       //Any activity which leads to value change should update 
       //the widget value as well.
       this.updateValue();
    },
    _onChange: function(newValue) {
       //summary:
       //Internal onChange method
       this.onChange(newValue);
    },
    onChange: function(newValue) {
       //summary:
       //A public hook for onChange.
    },
       // End -  Mandatory functions
       // Extra functions used in Mandatory functions
    _setInputNode: function(value) {
      //summary:
      //Sets the value to input node.
      this.inputNode.value = value;
    },
    updateValue: function() {
      //summary:
      //Validate the newly entered value and if it is successful 
      //then update widget's value.
      var newVal = this.inputNode.value;
      if (!this._isValid(newVal)) return;
      if (this.value != newVal)
      this._onChange(newVal);
      this.set('value', newVal);
    }
    });
    

    Note:

    For information about creating Dojo widgets, see the Dojo documentation at http://dojotoolkit.org/.

  3. In the js/extensions/themes/directory, create a CSS (for example, MyWidget.css) for this widget. You can use the following code in the CSS file, or write your own code:

    .fw .MyWidget .valueInputNode {
    color: blue;
    }
    
  4. In the js/extensions/themes/directory, update the UI.css with an import statement for the Dojo widget's CSS. For example, @import url("MyWidget.css");

  5. Save your work.

  6. Continue to Section 67.3.2, "Defining the Attribute Editor as a Presentation Object."

67.3.2 Defining the Attribute Editor as a Presentation Object

This section describes how to define input tags (presentation objects) for flex attributes. It also describes how to assign arguments that the input tags can pass from the attribute editor to the display elements.

To define the attribute editor:

  1. In your WebCenter Sites installation, navigate to the Sites\11gR1\Sites\11.1.1.6.1\presentationobject.dtd file.

  2. In the presentationobject.dtd file, do the following;

    1. Add a new tag (presentation object) to the list in the <!ELEMENT PRESENTATIONOBJECT …> statement. In this example, the new tag is named MYATTREDITOR.

      In the following line, MYATTREDITOR is your custom attribute editor whose name matches the name of the element you will create in Section 67.3.3, "Creating the Attribute Editor Element." All other tags are ready-to-use attribute editors.

      <!ELEMENT PRESENTATIONOBJECT (TEXTFIELD | TEXTAREA | PULLDOWN | RADIOBUTTONS | CHECKBOXES | PICKFROMTREE | EWEBEDITPRO | REMEMBER |
      PICKASSET | FIELDCOPIER | DATEPICKER | IMAGEPICKER | REALOBJECT | 
      CKEDITOR | DATEPICKER | IMAGEPICKER | REALOBJECT | CKEDITOR | FCKEDITOR | UPLOAD | MAGEEDITOR | RENDERFLASH | PICKORDERASSET | TYPEAHEAD | UPLOADER |
      MYATTREDITOR)>
      
    2. Add an <!ELEMENT … > section that defines the new tag (presentation object) and the arguments it takes. This new tag includes elements that supply the logic behind the format and behavior of the attribute when it is displayed on a form. Ensure that MAXALLOWEDCHARS is marked as a required attribute.

      <!ELEMENT MYATTREDITOR ANY>
      <!ATTLIST MYATTREDITOR MAXALLOWEDCHARS CDATA #REQUIRED>
      <!ATTLIST MYATTREDITOR MAXVALUES CDATA #IMPLIED>
      
    3. Save and close the presentationobject.dtd file.

  3. Continue to Section 67.3.3, "Creating the Attribute Editor Element."

67.3.3 Creating the Attribute Editor Element

This section describes how to create an element that displays an "edit" view of an attribute (single-valued) when it appears in a "New" or "Edit" form. This element must be located in the OpenMarket/Gator/AttributeTypes directory in the ElementCatalog table. The element name must exactly match the name of the tag you defined in Section 67.3.2, "Defining the Attribute Editor as a Presentation Object," so that it can be invoked by the tag (in this example, MYATTREDITOR).

  1. Navigate to the OpenMarket/Gator/AttributeTypes directory in your ElementCatalog.

  2. Create an attribute element for your new editor (in this example, MYATTREDITOR.jsp. See Example 67-2.) Ensure that the name of this element matches the tag name you defined in the presentationobject.dtd file (Section 67.3.2, "Defining the Attribute Editor as a Presentation Object").

  3. To prevent the default rendering of the attribute editor, set the doDefaultDisplay variable to no.

  4. To display the attribute name, call the element OpenMarket/Gator/FlexibleAssets/Common/DisplayAttributeName. The code is:

    <ics:callelement
      element="OpenMarket/Gator/FlexibleAssets/Common/DisplayAttributeName"/>
    
  5. To render the widget, call the element OpenMarket/Gator/AttributeTypes/CustomTextAttributeEditor by using the following parameters:

    If you use the code given in Example 67-2, then the single-valued attribute editor would look like the editor in Figure 67-1.

    Figure 67-1 Single-Valued Attribute Editor

    Description of Figure 67-1 follows
    Description of "Figure 67-1 Single-Valued Attribute Editor"

    Note:

    In Example 67-2, the following core logic is implemented to render the single-valued attribute using the new attribute editor:

    <ics:if condition='<%= "no".equals(ics.GetVar("MultiValueEntry")) %>'>
    <ics:then>
         <div dojoType='<%= ics.GetVar("editorName") %>'
         name='<%= ics.GetVar("cs_SingleInputName") %>'
         value='<%= attributeValue %>'
         >
         </div>
    </ics:then>
    

    The name that is coded in the element must be ics.GetVar("cs_SingleInputName") to ensure that the input node in the Dojo template will have the same name. The input node value will be sent to the server for saving the attribute.

    Example 67-2 Sample Single-Valued Attribute Editor (MYATTREDITOR)

    <%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld" %>
    <%@ taglib prefix="ics" uri="futuretense_cs/ics.tld" %>
    <%@ taglib prefix="satellite" uri="futuretense_cs/satellite.tld" %>
    <%//
    // OpenMarket/Gator/AttributeTypes/MYATTREDITOR
    //
    // INPUT
    //
    // OUTPUT
    //%>
    <%@ page import="COM.FutureTense.Interfaces.FTValList" %>
    <%@ page import="COM.FutureTense.Interfaces.ICS" %>
    <%@ page import="COM.FutureTense.Interfaces.IList" %>
    <%@ page import="COM.FutureTense.Interfaces.Utilities" %>
    <%@ page import="COM.FutureTense.Util.ftErrors" %>
    <%@ page import="COM.FutureTense.Util.ftMessage"%>
    <cs:ftcs>
    <ics:setvar name="doDefaultDisplay" value="no" />
    <script>
         dojo.require('extensions.dijit.MyWidget');
    </script>
    <link href="<%=ics.GetVar("cs_imagedir")%>/../js/extensions/themes/MyWidget.css"
         rel="stylesheet" type="text/css"/>
    <%
    FTValList args = new FTValList();
    args.setValString("NAME", ics.GetVar("PresInst"));
    args.setValString("ATTRIBUTE", "MAXALLOWEDCHARS");
    args.setValString("VARNAME", "MAXALLOWEDCHARS");
    ics.runTag("presentation.getprimaryattributevalue", args);
    args.setValString("NAME", ics.GetVar("PresInst"));
    args.setValString("ATTRIBUTE", "MAXVALUES");
    args.setValString("VARNAME", "MAXVALUES");
    ics.runTag("presentation.getprimaryattributevalue", args);
    String maximumValues = ics.GetVar("MAXVALUES");
    maximumValues = null == maximumValues ? "-1" : maximumValues;
    String editorParams = "{ maxAllowedLength: " 
         + ics.GetVar("MAXALLOWEDCHARS") + " }";
    %>
    <tr>
    <ics:callelement
      element="OpenMarket/Gator/FlexibleAssets/Common/DisplayAttributeName"/>
        <td></td>
        <td>
        <ics:callelement
          element="OpenMarket/Gator/AttributeTypes/CustomTextAttributeEditor">
             <ics:argument name="editorName" value="extensions.dijit.MyWidget" />
             <ics:argument name="editorParams" value='<%= editorParams %>' />
             <ics:argument name="maximumValues" value="<%= maximumValues %>" />
    </ics:callelement>
        </td>
     </tr>
    </cs:ftcs>
    
  6. Continue to Section 67.3.4, "Creating the Attribute Editor."

67.3.4 Creating the Attribute Editor

This section describes how to create an attribute editor asset to make it available to content contributors on their content management sites. This asset will support the input types you defined in Section 67.3.3, "Creating the Attribute Editor Element," for example, check boxes, radio options, and drop-down lists. The developer selects this editor when creating or modifying the attribute.

  1. Log in to the Admin interface of your site.

  2. On the New page, under the Name column, click New Attribute Editor.

  3. In the Name field, enter a meaningful name for your editor. For example, MyAttrEditor.

  4. In the XML box, enter the XML code for your attribute editor. Ensure that the name of the attribute editor in this code is exactly the same as the element name. For example:

    <?XML VERSION="1.0"?> 
    <!DOCTYPE PRESENTATIONOBJECT >
    <PRESENTATIONOBJECT NAME="MYATTREDITOR">
    <MYATTREDITOR MAXALLOWEDCHARS="10"> </MYATTREDITOR> </PRESENTATIONOBJECT>
    
  5. In the Attribute Type box, accept the appropriate value(s).

  6. Click the Save icon.

    The attribute editor similar to the editor in Figure 67-2 is created for your site.

    Figure 67-2 Sample Attribute Editor for a Site

    Description of Figure 67-2 follows
    Description of "Figure 67-2 Sample Attribute Editor for a Site"

  7. Continue to Section 67.3.5, "Implementing a Multi-Valued Attribute Editor."

67.3.5 Implementing a Multi-Valued Attribute Editor

In Section 67.3.3, "Creating the Attribute Editor Element," Example 67-2 shows the implementation for a single-valued attribute editor. To implement a multi-valued attribute editor for text, integer, string, or money data types, you can write code similar to the code in Example 67-3.

Example 67-3 Sample Multi-Valued Attribute Editor (CustomTextAttributeEditor)

<%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld" %>
<%@ taglib prefix="ics" uri="futuretense_cs/ics.tld" %>
<%@ taglib prefix="satellite" uri="futuretense_cs/satellite.tld" %>
<%//
// OpenMarket/Gator/AttributeTypes/CustomTextAttributeEditor
//
// INPUT
//
// OUTPUT
//%>
<%@ page import="COM.FutureTense.Interfaces.FTValList" %>
<%@ page import="COM.FutureTense.Interfaces.ICS" %>
<%@ page import="COM.FutureTense.Interfaces.IList" %>
<%@ page import="COM.FutureTense.Interfaces.Utilities" %>
<%@ page import="COM.FutureTense.Util.ftErrors" %>
<%@ page import="COM.FutureTense.Util.ftMessage"%>
<cs:ftcs>
<%
IList attributeValueList = ics.GetList("AttrValueList", false);
boolean hasValues = null != attributeValueList && attributeValueList.hasData();
String attributeValue = hasValues ? attributeValueList.getValue("value") : "";
%>
<ics:if condition='<%= "no".equals(ics.GetVar("MultiValueEntry")) %>'>
<ics:then>
       <div dojoType='<%= ics.GetVar("editorName") %>'
            name='<%= ics.GetVar("cs_SingleInputName") %>'
            value='<%= attributeValue %>'
       >
       </div>
</ics:then>
<ics:else>
<ics:callelement
  element="OpenMarket/Gator/AttributeTypes/RenderMultiValuedTextEditor">
    <ics:argument name="editorName" 
      value='<%= ics.GetVar("editorName") %>' />
    <ics:argument name="editorParams" 
      value='<%= ics.GetVar("editorParams") %>' />
    <ics:argument name="multiple" 
      value="true" />
    <ics:argument name="maximumValues" 
      value='<%= ics.GetVar("maximumValues") %>' />
</ics:callelement>
</ics:else>
</ics:if>
</cs:ftcs>

If the code in Example 67-3 is used, then the multi-valued attribute editor will look similar to the editor in Figure 67-3.

Figure 67-3 Multi-Valued Attribute Editor

Description of Figure 67-3 follows
Description of "Figure 67-3 Multi-Valued Attribute Editor"

Note the following points about Example 67-3:

  • You can instantiate a multi-valued widget, which uses a single-valued widget to render multi-valued representations.

  • The MultiValueEntry variable with the no value indicates that the attribute editor renders a single value. Changing the variable value to yes will enable the attribute editor to render multiple values.

  • You can implement a multi-valued widget that accepts values in the JSON object or in any other format.

  • For a multi-valued attribute editor, the RenderMultiValuedTextEditor element creates hidden input nodes required for Save logic. The value of each node is sent to the server.

  • The multi-valued widget is rendered by calling the OpenMarket/Gator/AttributeTypes/RenderMultiValuedTextEditor element using the following code in Example 67-3:

    <ics:else>
      <ics:callelement
        element="OpenMarket/Gator/AttributeTypes/RenderMultiValuedTextEditor">
              <ics:argument name="editorName" 
               value='<%= ics.GetVar("editorName") %>' />
              <ics:argument name="editorParams" 
               value='<%= ics.GetVar("editorParams") %>' />
              <ics:argument name="multiple" 
               value="true" />
              <ics:argument name="maximumValues" 
                value='<%= ics.GetVar("maximumValues") %>' />
         </ics:callelement>
    </ics:else>
    </ics:if>
    

If you want to create a custom attribute editor for the blob or asset data type, you can base your implementation on the UPLOADER attribute editor for the blob type and the PICKASSET attribute editor for the asset data type.