Implementing a Custom Element

Working With Scripts and Forms 11-5 When you remove a script, you are simply removing it from the site, not deleting from the content server. Figure 11–6 Remove from Site Icon

11.3 Custom Element Forms

A custom element is a user-defined element. In addition to the other elements WYSIWYG, text only, image only, static list, dynamic list, the custom element provides one way to extend Site Studio to suit individual business needs. Custom elements are created when the other elements are not as suitable. Custom elements are full HTML files that reside within an IFRAME in the Contributor form. A custom element must use an API and implement several callbacks to function correctly as a Site Studio element. A custom element form is designed to work with a custom element, which you add to a contribution region like any other element. The custom element form is unique in that it can be used to create a custom interface that contributors use to add various types of content to a Web site. You might, for example, create a custom form that queries the content server for a certain file type, enables users to select one of those files, and returns the user to the Contributor. Or, you might create a form that provides a text box that contributors use to copy and paste source code or formatted text to a web page. The form can be a generic browser-based form that collects arbitrary information from the user and returns a value to the host in this case, Contributor. This section includes the following topics: ■ Implementing a Custom Element on page 11-5 ■ Backward Compatibility and Upgrading on page 11-12 ■ Sample Custom Elements on page 11-13

11.3.1 Implementing a Custom Element

In order for a custom element to function properly in a Contributor form, a custom element must use an API and implement a hand-full of callbacks. The following notes highlight the ElementAPI and its methods for creating custom elements. Important: If you upgrade a Site Studio site from a version before 10gR3 10.1.3.3.3, you must manually update any custom elements in the site. See Backward Compatibility and Upgrading on page 11-12. Note: The path URL to a custom element must be in the same domain as the Contributor form. This is so that the Contributor form and the custom element can communicate without violating cross-domain scripting rules. 11-6 Oracle Fusion Middleware Users Guide for Site Studio Designer ElementAPI The ElementAPI object is a JavaScript object explicitly loaded into the custom element page that facilitates communication between the Contributor form and the custom element. The ElementAPI provides methods for custom elements to communicate to the Contributor from, and a callback mechanism for the Contributor form to pass notifications to the custom element. Loading the ElementAPI JavaScript Object Before the ElementAPI and its supporting libraries can be used, the ElementAPI must first be loaded into the custom element page. After the ElementAPI is loaded, the custom element should continue with page initialization and notify the Contributor form that the custom element is loaded and ready to go. DOCTYPE html PUBLIC -W3CDTD XHTML 1.0 StrictEN http:www.w3.orgTRxhtml1DTDxhtml1-strict.dtd html xmlns=http:www.w3.org1999xhtml head titleSimple Custom Elementtitle style type=textcss { padding: 0; margin: 0; } body { font-size: 10pt; font-family: Tahoma; } container { height: 150px; overflow: auto; width: 100; text-align: center; align: center;} content { width: 99; } style script type=textjavascript var Custom = {}; Custom.originalData = null; Custom.Initialize = function { Set callback methods for the Contributor Form to send notifications to this Element. ElementAPI.SetCallbackGetElementContent, functioncallback { callbackCustom.GetData; }; ElementAPI.SetCallbackActivateElement, functioncallback{ IDcontent.focus; callback; }; ElementAPI.SetCallbackCanCloseElement, functioncallback{ callback{canClose: true}; }; ElementAPI.SetCallbackShow, functioncallback{ callback; }; ElementAPI.SetCallbackHide, functioncallback{ callback; }; ElementAPI.SetCallbackIsDirty, function { return { isDirty: Custom.originalData == Custom.GetData }; }; Set the height of the Custom Element forms host. var height = ElementAPI.GetElementCount == 1 ? 100 : 150px; var flags = ElementAPI.GetElementConfigPropertyflags || {}; var config = ElementAPI.GetElementConfiguration || {}; if flags.canSetHeight config.height config.height.length 0 { height = config.height; Working With Scripts and Forms 11-7 } height = ElementAPI.SetHostHeightheight; Get the default content stored within the data file. IDcontent.value = Custom.GetDefaultData; Add base styles WCM.DHTML.AddStyleSheet{path: WCM.path + .basewcm.base.css, context: window}; Add a resize handler for when the window is resized. var ResizeHandler = function { WCM.DHTML.SetStylecontainer, height, WCM.DHTML.GetViewportHeight + px; WCM.DHTML.SetStylecontainer, width, WCM.DHTML.GetViewportWidth + px; }; ResizeHandler; WCM.DHTML.AddWindowResizeEventwindow, ResizeHandler; Immediately store the original data as a baseline for the IsDirty comparison. Custom.originalData = Custom.GetData; Let the Contributor Form know this Custom Element is ready. required ElementAPI.Ready; }; Custom.GetDefaultData = function { return ElementAPI.GetDefaultData .replacepreg, .replace\preg, .replacelt;g, .replacegt;g, || Some default content.; }; Custom.GetData = function { return pre + IDcontent.value.replaceg, lt;.replaceg, gt; + pre; }; try { Tell the Contributor Form to load the Custom Element dependent JavaScript libraries. required PARAMETERS 1st parameter: The context window in which the form loads the Custom Element dependent JavaScript libraries into. 2nd parameter: A user defined function pointer for the Contributor Form to call when initialization is complete. window.top.WCM.InitializeCustomElementwindow, Custom.Initialize; catche { } script head body div id=container div id=titleSimple Custom Elementdiv 11-8 Oracle Fusion Middleware Users Guide for Site Studio Designer divtextarea id=content rows=5textareadiv div body html Communication from Contributor Form to Custom Element The Contributor form communicates with a custom element by executing functions implemented by the custom element. As part of the initialization process, a custom element must register these functions by passing their function pointers to the Contributor form. The table below lists the functions that can be registered with the Contributor form. None of these functions must be implemented by the custom element; however, a few of them are required if the intention is to collect and save data from a Contributor user. Furthermore, all of these functions except the IsDirty function, when executed, pass a callback function pointer to execute when the task is complete. This enables asynchronous communication if a custom element must perform an asynchronous task during execution. Note: The code example loads the ElementAPI and notifies the Contributor form that it is loaded and ready. It does not, however, collect or save data. Function Signature Description CanCloseElementcallback; The Contributor form executes this method when the Contributor user performs an update. The implementation of the function should calculate whether the custom element can be safely closed. For instance, if the data does not pass validation, then the custom element should indicate that it cannot be closed. GetElementContentcallback; The Contributor form executes this method when the Contributor user performs an update. The implementation of the function should pass back string content to be saved. Hidecallback; The Contributor form executes this method whenever the form performs a DHTML task that overlays an HTML element over the custom element. For instance, this method is executed when the Metadata tab is activated and the Contributor elements are obscured. This method was introduced specifically for the Ephox-based elements, because Java applets always have top z-index. All other elements HTML-based elements can ignore this method. Showcallback; The Contributor form executes this method whenever the form performs a DHTML task that removes an overlay that makes custom element reappear. This method was introduced specifically for the Ephox-based elements because Java applets always have top z-index. All other elements HTML-based elements can ignore this method. IsDirty; The Contributor form executes this method whenever the form popup is being closed without updating. The custom element should calculate whether unsaved changes exist so that the Contributor user can be notified if there are unsaved changes. Working With Scripts and Forms 11-9 The following is a JavaScript code snippet of how a custom element can register functions with the Contributor form: function CanCloseElementcallback { No data validation in this sample - just pass back a true value. callback{canClose: true}; Here is an example of passing a false value callback{canClose: false, reason: Failed validation. Use only lowercase letters.}; } function GetElementContentcallback { Pass back some sample content for demo purposes. callbackThis is my Custom Element Content.; } function Showcallback { Just handle this notification by executing the callback. callback; } function Hidecallback { Just handle this notification by executing the callback. callback; } function IsDirty { This Custom Element is never dirty - so pass a false value. return {isDirty: false}; } Set callback methods for the Contributor Form to send notifications to this Element. ElementAPI.SetCallbackCanCloseElement, CanCloseElement; ElementAPI.SetCallbackGetElementContent, GetElementContent; ElementAPI.SetCallbackShow, Show; ElementAPI.SetCallbackHide, Hide; ElementAPI.SetCallbackIsDirty, IsDirty; Communication From Custom Element to Contributor Form A custom element initiates communication with the Contributor form by using the ElementAPI JavaScript object. The following is a list of available ElementAPI methods. Function Signature Description ElementAPI.GetDefaultData; Retrieves the default content stored in the data file. ElementAPI.GetSearchResultsoptions; Displays the Oracle Content Servers Get Search Results page. ElementAPI.GetQueryTextoptions; Displays the Get Query Text UI. ElementAPI.CaptureQueryoptions; Displays the Oracle Content Servers Capture Query page. 11-10 Oracle Fusion Middleware Users Guide for Site Studio Designer ElementAPI Dependent Scripts When the ElementAPI is loaded into the custom element page, so are the ElementAPI dependent scripts. These scripts contain most of the JavaScript WCM library and is also available for custom element authors to use. The following script files are loaded into a custom element: ■ wcm.js ■ .basewcm.dhtml.js ■ .basewcm.get.js ■ .basewcm.http.js ■ .basewcm.popup.js ■ .sitestudiowcm.contentserver.popup.js ■ .formelementswcm.elementapi.js ■ .sitestudioelementswcm.sitestudio.elementapi.js ■ .sitestudiowcm.idc.js ■ .formelementselementwcm.element.js ■ .formelementscustomwcm.custom.js Example of a Source-Mode Type of Custom Element The following simple custom element example saves content entered into a TEXTAREA by Contributor users, and displays it directly in the layout. DOCTYPE html PUBLIC -W3CDTD XHTML 1.0 StrictEN http:www.w3.orgTRxhtml1DTDxhtml1-strict.dtd html xmlns=http:www.w3.org1999xhtml head titleSimple Custom Elementtitle style type=textcss { padding: 0; margin: 0; } body { font-size: 10pt; font-family: Tahoma; } container { ElementAPI.GetHyperlinkoptions; Displays the Hyperlink Wizard UI. ElementAPI.FocusFormoptions; Focuses the parent window thereby blurring the Element window. ElementAPI.SetHostHeightheight; Sets the height of the Elements containing IFRAME. ElementAPI.SetRequiredIndicatorisRequired; Toggles the Required graphic indicator in the Contributor Form UI. ElementAPI.GetSiteoptions; Displays the Choose Website picker UI. ElementAPI.GetSectionoptions; Displays the Choose Website Section picker UI. ElementAPI.GetColoroptions; Displays the Color picker UI. ElementAPI.GetFontoptions; Displays the Get Font picker UI. Function Signature Description Working With Scripts and Forms 11-11 height: 150px; overflow: auto; width: 100; text-align: left; align: left; padding: 7px; } .controls { border: 1px solid B9B9B4; border-top-color: DDDDD8; border-bottom-color: 797975; vertical-align: middle; font-family: tahoma,verdana,arial,helvetica,sans-serif; font-size: 100; 11px Normal font-color: 000; } style script type=textjavascript var Custom = {}; Custom.originalData = null; Custom.Initialize = function { ElementAPI.SetCallbackGetElementContent, functioncallback { callbackCustom.GetData; }; ElementAPI.SetCallbackActivateElement, functioncallback{ IDcontent.focus; callback; }; ElementAPI.SetCallbackCanCloseElement, functioncallback{ callback{canClose: true}; }; ElementAPI.SetCallbackShow, functioncallback{ callback; }; ElementAPI.SetCallbackHide, functioncallback{ callback; }; ElementAPI.SetCallbackIsDirty, function { return { isDirty: Custom.originalData == Custom.GetData }; }; var height = ElementAPI.GetElementCount == 1 ? 100 : 150px; var flags = ElementAPI.GetElementConfigPropertyflags || {}; var config = ElementAPI.GetElementConfiguration || {}; if flags.canSetHeight config.height config.height.length 0 { height = config.height; } height = ElementAPI.SetHostHeightheight; IDinput-value.value = ElementAPI.GetDefaultData; WCM.DHTML.AddStyleSheet{path: WCM.path + .basewcm.base.css, context: window}; var ResizeHandler = function { var viewPortWidth = WCM.DHTML.GetViewportWidth; var viewPortHeight = WCM.DHTML.GetViewportHeight; 11-12 Oracle Fusion Middleware Users Guide for Site Studio Designer WCM.DHTML.SetStylecontainer, height, viewPortHeight + px; WCM.DHTML.SetStylecontainer, width, viewPortWidth + px; WCM.DHTML.SetStyleinput-value, height, viewPortHeight - 15 + px; WCM.DHTML.SetStyleinput-value, width, viewPortWidth - WCM.IS_IE ? 15 : 15 + px; }; ResizeHandler; WCM.DHTML.AddWindowResizeEventwindow, ResizeHandler; Custom.originalData = Custom.GetData; ElementAPI.Ready; }; Custom.GetData = function { return IDinput-value.value; }; try { window.top.WCM.InitializeCustomElementwindow, Custom.Initialize; } catche { } script head body div id=container nowrap textarea id=input-value class=controls type=text title=URLtextarea div body html

11.3.2 Backward Compatibility and Upgrading