12.1.1. Defining a Custom User Interface

Engineering Knowledge Manager

Administration Guide | Chapter 12: Defining Custom Dialogs, Wizards and Applications | 12.1. Defining Custom Dialog Boxes |

12.1. Defining Custom Dialog Boxes |  | 12.1.2. Defining Dialog Box Steps and Variables
Prev |  | Next

### 12.1.1. Defining a Custom User Interface

EKM's user interface is designed using web technologies such as XHTML and JSF. You can utilize these technologies when you want to define a custom user interface such as a dialog box or wizard that can open when an action, process template, job template, or custom application is invoked.

- XHTML: Dialog boxes are defined using XHTML syntax. See XHTML Files for details.

- JSF: Java Server Faces (JSF) is a new standard for developing web-based applications. It introduces tags that can be used in XHTML files. These tags can be used to provide complex user interface components (such as calendar, tree, and so on) that are not directly supported by HTML. Some components have built-in AJAX support to increase user interface responsiveness and interactivity. In addition, these tags are used to bind the values specified in the user interface to some variables defined in the back-end. This binding enables JSF to automatically fill the values of the variables with user inputs when the form is submitted. The tags that can be used depend on the JSF component libraries loaded by the system. EKM uses the following JSF component libraries: MyFaces Core, Tomahawk, and RichFaces. Refer to http://myfaces.apache.org/ for more information on MyFaces and Tomahawk libraries. Refer to http://www.jboss.org/richfaces for more information on the RichFaces libraries.

  Note:

  - If you use custom applications and JSF validation tags, you need to provide a label so that the validation protocols can apply a proper error message to the custom application. In the example that follows, the error message is missing the label of the field that has an invalid entry.

    Figure 12.1: A Faulty Error Message in a Custom Application

  - Variable names used in a custom application should always be a valid java identifier. For example, a variable cannot have a name that is a reserved word such as "boolean".

If you are new to XHTML, CSS, JavaScript and JSF, then it may feel a little overwhelming to understand all of the technologies and languages at first. Indeed, the possibilities offered by these technologies are very extensive making them both powerful and complex. However, if you have a basic understanding of HTML, the documentation and examples provided in this chapter will enable you to create a basic user interface.

#### 12.1.1.1. XHTML Files

XHTML files are XML files that support all of the tags (for example, `div`, `span`, `table`, `br`, `img`, and so on) and attributes (for example, `style`, `class`, and so on) of HTML. This syntax enables you to have complete freedom when designing the layout and presentation of a dialog box. You can create tables, use different font styles and sizes, embed custom images, and so on. If needed, you can also utilize CSS to specify styles for user interface components and JavaScript to provide dynamic behavior.

All of the `XHTML` files that you create must have the .xhtml file extension and contain the following:

- header

- body

- footer

Sample XHTML Code for a Custom Dialog Box contains a full listing for an XHTML file for a sample custom dialog box. Figure 12.2: Sample Custom Dialog Box shows how the dialog box is displayed in the EKM user interface. The file defines common user interface components and can be used as a template to define any custom dialog box.

##### Header

An `XHTML` must start with the header:

    <html xmlns="http://www.w3.org/1999/xhtml"
    	xmlns:f="http://java.sun.com/jsf/core"
    	xmlns:h="http://java.sun.com/jsf/html"
    	xmlns:t="http://myfaces.apache.org/tomahawk"
    	xmlns:ui="http://java.sun.com/jsf/facelets"
    	xmlns:rich="http://richfaces.org/rich"
    	xmlns:a4j="http://richfaces.org/a4j"
    	xmlns:ing="http://www.ansys.com/ingress/spdm">

##### Body

In between the header and footer, you may insert any HTML or JSF tag in the `XHTML` file to define the user interface components. See User Interface Components for details.

##### Footer

An `XHTML` must end with the footer:

    </ui:component>
    </body>
    </html>

#### 12.1.1.2. Sample XHTML Code for a Custom Dialog Box

The sample XHTML code shown below defines a custom dialog box that is displayed in the EKM user interface as Figure 12.2: Sample Custom Dialog Box.

The dialog box uses common user interface components such as check boxes, selection lists, and so on that can be used as a template when you define any custom dialog box. The variables for the dialog box are defined in a separate initialization macro named `init` that EKM uses to create the dialog box.

Figure 12.2: Sample Custom Dialog Box

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:t="http://myfaces.apache.org/tomahawk"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:ing="http://www.ansys.com/ingress/spdm"
      xmlns:a4j="https://ajax4jsf.dev.java.net/ajax"
      xmlns:rich="http://richfaces.org/rich">

    <body>

    <ui:component>
      <div style="text-align: center; font-size: large">
      Sample Dialog<br/>
      <span style="color: red">For Displaying Common UI Components</span>
      </div>
      <div style="padding-top: 10px; padding-bottom: 10px; width: 100%">
      <table>
        <tr>
          <td>File upload:</td>
          <td>
            <t:inputFileUpload size="60" value="#{custom.vars.file.value}"/>
          </td>
        </tr>
        <tr>
          <td>Reference selection:</td>
          <td>
            <ing:inputCustomReference size="60" referenceVar="reference"/>
          </td>
        </tr>
      </table>
      </div>
      <table>
        <tr>
          <td><h:graphicImage value="#{custom.url}/tank.jpg" /></td>
          <td>
          <table style="padding-left: 10px; width: 250px">
            <tr>
              <td>String Entry:</td>
              <td>
                <h:inputText value="#{custom.vars.string.value}" />
              </td>
            </tr>
            <tr>
              <td>Integer Entry:</td>
              <td>
                <h:inputText value="#{custom.vars.integer.value}">
                  <f:validateLongRange minimum="0" maximum="10"/>
                </h:inputText>
              </td>
            </tr>
            <tr>
              <td>Real Entry:</td>
              <td>
                <h:inputText value="#{custom.vars.real.value}" />
              </td>
            </tr>
            <tr>
              <td>Date:</td>
              <td>
                <rich:calendar value="#{custom.vars.date.value}"
                  datePattern="MMM d, yyyy HH:mm"
                  enableManualInput="true" />
              </td>
            </tr>
            <tr>
              <td>Check box:</td>
              <td>
                <h:selectBooleanCheckbox value="#{custom.vars.boolean.value}" />
              </td>
            </tr>
            <tr>
              <td>Radio buttons:</td>
              <td>
                <h:selectOneRadio value="#{custom.vars.radio.value}"
                                  layout="lineDirection">
                  <f:selectItem itemValue="Radio 1"/>
                  <f:selectItem itemValue="Radio 2"/>
                </h:selectOneRadio>
              </td>
            </tr>
            <tr>
              <td>Select menu:</td>
              <td>
                <h:selectOneMenu value="#{custom.vars.menu.value}">
                  <f:selectItems value="#{custom.vars.menu.optionItems}"/>
                </h:selectOneMenu>
              </td>
            </tr>
            <tr>
              <td>List box:</td>
              <td>
                <h:selectManyListbox value="#{custom.vars.listBox.value}">
                  <f:selectItem itemValue="List Option 1"/>
                  <f:selectItem itemValue="List Option 2"/>
                  <f:selectItem itemValue="List Option 3"/>
                </h:selectManyListbox>
              </td>
            </tr>
          </table>
          </td>
        </tr>
      </table>
    </ui:component>

    </body>
    </html>

#### 12.1.1.3. User Interface Components

This section defines syntax for common user interface components for a custom dialog box that are defined in the body of the XHTML file. Refer to Sample XHTML Code for a Custom Dialog Box for the full listing of the XHTML file that generates the sample dialog box shown in Figure 12.2: Sample Custom Dialog Box.

##### 12.1.1.3.1. Layout and Style

You can define the layout and style of a dialog box using any HTML tag and attributes. For the example dialog box (Figure 12.2: Sample Custom Dialog Box) the label at the top of the dialog box is defined using the plain HTML code fragment:

    <div style="text-align: center; font-size: large">
      Sample Dialog<br/>
      <span style="color: red">For Displaying Common UI Components</span>
    </div>

You can also use an HTML table to display an image and other controls, side by side.

##### 12.1.1.3.2. Embedded Images

The `graphicImage` component can be used to embed an image in an interface. The `value` attribute specifies the path of the image file. You must specify `#{custom.url}/` at the start. This will make sure that the path starts with the location of the expanded resource archive in the custom resources folder. After that, you need to specify the relative path of the image in the resource archive.

    <h:graphicImage value="#{custom.url}/tank.jpg" />

For the sample dialog box (Figure 12.2: Sample Custom Dialog Box), tank.jpg is at the top-level of the resources folder, so the full path becomes: `#{custom.url}/tank.jpg`.

If you want to display an image that resides in the EKM repository, see Linked Images.

##### 12.1.1.3.3. Linked Images

The `image` component can be used to display an image that resides in the EKM repository. You can include this component by adding the `<ing:image>` tag to the markup. If doing so, you must ensure that the `ing` namespace is defined in the XHTML file.

This component can have the following attributes:

`path`: specifies the path of the image file. It can be a JSF EL expression such as `#{custom.vars.imagePath}`, or an absolute value such as `/Data/Shared Data/image.gif`.
`style`: can be used to define a style for the image. For example, you may want to display a colored border around it, as shown in the sample below.

    <ing:image path="/Data/Shared Data/test.gif" style="border:1px solid green"/>

##### 12.1.1.3.4. Object Links

The `objectLink` component can be used to display a link to an object in the EKM repository. Clicking on the link displays the object in its default view. You can include this component by adding the `<ing:objectLink>` tag to the markup.

This component can have the following attributes:

`path`: specifies the path of the object. It can be a JSF EL expression such as `#{custom.vars.path}`, or an absolute value such as `/Data/Shared Data`.
`style`: can be used to define a style for the link.
`styleClass`: refers the CSS class to be applied to link.
`value​`: can be used to specify the link text. If not specified, the object name is used for the link text, with the object path shown in a tooltip.

    <ing:objectLink path="/Data/Shared Data" styleClass="facesCommandLink" value="Click here for Shared Data"/>

##### 12.1.1.3.5. User Inputs

Except for a reference selection, all elements that capture user inputs must have a `value` attribute. This attribute points to the value of the variable defined in the initialization script that stores the user input. The common syntax to specify the value is: `#{custom.vars.varName.value}`, where `varName` is the name of the variable defined in the initialization script. In this case the name of the variable is `string`.

###### String Input

The `inputText` component can be used to define a text box for capturing string input in a dialog box, as shown in the following code fragment:

    <h:inputText value="#{custom.vars.string.value}" />

Except for a reference selection, all elements that capture user inputs must have a `value` attribute. This attribute points to the value of the variable, defined in the initialization script, that stores the user input. The common syntax to specify the value is:`#{custom.vars.varName.value}`, where `varName` is the name of the variable defined in the initialization script. In this case the name of the variable is `string`.

###### Integer Input

The `inputText` component can be used to define a text box for capturing integer input in a dialog box, as shown in the following code fragment:

    <h:inputText value="#{custom.vars.integer.value}">
      <f:validateLongRange minimum="0" maximum="10"/>
    </h:inputText>

The `value` attribute must point to a variable of type long in the initialization script. In this case, the name of the variable is `integer`. If required, you can also specify `minimum` and/or `maximum` values for the integer as shown above with the `f:validateLongRange` tag. This is optional and if it’s not specified, the integer will not have any minimum or maximum value.

###### Real Number Input

The `inputText` component can be used to define a text box for capturing real number input in a dialog box, as shown in the following code fragment:

    <h:inputText value="#{custom.vars.real.value}" />

The `value` attribute must point to a variable of type `double` in the initialization script. In this case the name of the variable is `real`. If required, you can also specify `minimum` and/or `maximum` values for the real number as shown above for integer inputs. This is optional and if it is not specified, the real number will not have any minimum or maximum value.

###### Date Input

The `rich:calendar` component can be used to define a text box for capturing date and time input in a dialog box, as shown in the following code fragment:

    <rich:calendar value="#{custom.vars.date.value}"
        datePattern="MMM d, yyyy HH:mm"
    enableManualInput="true" />

The `value` attribute must point to a variable of type `Date` in the initialization script. In this case the name of the variable is `date`. The `datePattern` attribute specifies the format in which the date will be displayed or entered manually. The `enableManualAttribute` specifies whether manual date input is allowed or not. Refer to the RichFaces documentation for information about this component and to learn about additional attributes.

###### File Upload

The `inputFileUpload` component can be used to define a browse feature for selecting a file to upload to EKM, as shown in the following code fragment:

    <t:inputFileUpload size="60" value="#{custom.vars.file.value}"/>

The `value` attribute must point to a variable of type `VARIABLE_TYPE_FILE` in the initialization script. In this case the name of the variable is `file`.

###### Multi-File Upload

The `multiFileUpload` component can be used to add a browse feature for selecting multiple files to upload to EKM, as shown in the following code fragment:

    <ing:multiFileUpload id="mfu1" value="#{custom.dialog.vars['uploadDir'].value}"/>

The value attribute must point to an empty variable of type VARIABLE_TYPE_STRING defined in the initialization script.

This component uploads files to a directory within the EKM temp directory. The name of the directory is written into the empty dialog variable passed to the component. When a user clicks the submit button in the dialog box, a script needs to be called to copy the files from this directory to the repository.

Sample files that illustrate this component's usage can be found in the following folder: `EKM_HOME\examples\conf\customTypes\multiFileUpload`.

To see the example:

1. Begin workspace configuration. Upload the custom type file (MultiFileUpload.type.xml) to the Configuration\Custom Types folder, then apply or accept the configuration. This custom type has a custom Edit > Multi File Upload action assigned to it.

2. Copy the custom interface (multi-upload-ui.xhtml) to your custom resources folder. This is a dialog box that will be launched when the custom Edit > Multi File Upload action is selected. By default, the path of the custom resources folder is `EKM_HOME/conf/resources`. For more information see Specifying the Custom User Interface Folder (<customResourcesPath>).

3. Upload the input.mfu file to the repository, which is a file of the custom MultiFileUpload type.

4. With the input.mfu file selected, select the custom Edit > Multi File Upload action.

   The custom dialog box (with a multi-file upload component) is launched:

###### Reference Selection

The `inputCustomReference` component can be used to add a browse feature to the interface so that you can reference another object in EKM, as shown in the following code fragment:

    <ing:inputCustomReference size="60" referenceVar="reference"/>

The `referenceVar` attribute specifies the name of the reference variable defined in the dialog box’s macro. In this case the name of the variable is `reference`. You can control the size of the text box using size or width attributes.

###### Selection from Repository

The `browseRepository` component can be used to add a browse feature for selecting an object in the EKM repository. The following example shows the code you might use to select a folder for output files:

    <ing:browseRepository value="#{custom.vars.outputFolder}" width="99%" id="outputFolder" />

This component accepts the following arguments:

- (required) `value`: A binding dialog variable that determines the value of the component

- (optional) `width`: The width of the browse popup window

- (optional) `height`: The height of the browse popup window

- (optional) `render`: A comma-separated list of ids which will be rendered when the popup window is dismissed

- (optional) `onFileSelection`: Client-side code to be executed when the popup window is dismissed

###### Selection from Working Directory

The `browseWorkingDirectory` component can be used to add a browse feature for selecting files from a job's working directory. For example:

    <ing:browseWorkingDirectory id="inputFile" value="#{custom.vars.inputFile}" width="300px"
    render="inputFileDiv" onFileSelection="updateJobName(); enableSubmitButton();"/>

This component accepts the following arguments:

- (required) `value`: A binding dialog variable that determines the value of the component

- (optional) `width`: The width of the browse popup window

- (optional) `height`: The height of the browse popup window

- (optional) `render`: A comma-separated list of ids which will be rendered when the popup window is dismissed

- (optional) `onFileSelection`: Client-side code to be executed when the popup window is dismissed

##### 12.1.1.3.6. Check Boxes

The `selectBooleanCheckbox` setting can be used to define a check box in a dialog box, as shown in the following code fragment:

    <h:selectBooleanCheckbox value="#{custom.vars.boolean.value}" />

The `value` attribute must point to a `boolean` variable in the initialization script. For the example dialog box (Figure 12.2: Sample Custom Dialog Box) the name of the variable is `boolean`.

##### 12.1.1.3.7. Radio Buttons

The `selectoneRadio` setting can be used to define a radio button group in a dialog box, as shown in the following code fragment:

    <h:selectOneRadio value="#{custom.vars.radio.value}"
     layout="lineDirection">
        <f:selectItem itemValue="Radio 1"/>
        <f:selectItem itemValue="Radio 2"/>
    </h:selectOneRadio>

The `value` must point to a `string` variable defined in the initialization script. For the example dialog box (Figure 12.2: Sample Custom Dialog Box), the name of the variable is `radio`. The `layout` attribute specifies whether radio buttons are displayed horizontally (using the `lineDirection` value) or vertically (using the `pageDirection` value). The options for the radio button are specified using the `f:selectItem` tags as shown above. Instead, you can use the `f:selectItems` tag to specify the variable options in the dialog box’s macro. See Selection Menu for an example of the `f:selectItems` tag.

##### 12.1.1.3.8. Selection Menu

You can define a selection menu or drop-down list in a dialog box using the `selectOneMenu` setting. The `value` attribute must point to a string variable defined in the dialog box’s script. The common syntax for specifying the `value` is `#{custom.vars.varName.optionItems}`, where `varName` is the name of the variable. The options for the menu can be specified as either `f:selectItems` or `f:selectItem`. If you are using `f:selectItems`, the `value` attribute must point to the options defined for the variable in the dialog box’s macro.

    <h:selectOneMenu value="#{custom.vars.menu.value}">
        <f:selectItems value="#{custom.vars.menu.optionItems}"/>
    </h:selectOneMenu>

In this case the name of the variable is `menu`.

##### 12.1.1.3.9. List Box

A list box can be defined using the `selectManyListbox` setting.

    <h:selectManyListbox value="#{custom.vars.listBox.value}">
        <f:selectItem itemValue="List Option 1"/>
        <f:selectItem itemValue="List Option 2"/>
        <f:selectItem itemValue="List Option 3"/>
    </h:selectManyListbox>

The `value` attribute must point to a string variable defined in the initialization script. In this case the name of the variable is `listBox`. If the variable is defined as multi-valued, the list box will allow multiple selections. Otherwise only a single selection is allowed. The options for the list box are specified using the `f:selectItem` tags as shown above. Instead of this, you can use `f:selectItems` tag to specify the variable options for the dialog box’s macro. See Selection Menu for an example of the `f:selectItems` tag.

#### 12.1.1.4. Invoking Methods from UI Components

You can use `#{custom.dialog}` to retrieve the current information from a view associated with a custom application or process, and then invoke an API method such as `executeMacro` directly from the XHTML components. For example, `#{custom.dialog.executeMacro('<macro name>')}` can be used as an action for a `commandLink` or `commandButton` component. For job templates you can use `#{custom.executeMacro('<macro name>')}` to execute a macro.

In the example below, when a user clicks an Update command link next to an input box, the macro `testMacro` (specified in the script) is executed. This macro updates the value of the variable `testString`. After the macro is executed, the input box is rendered again to display the updated value, `New Value`.

    <h:inputText value="#{custom.vars.testString.value}" id="inputText"/>
        <a4j:commandLink id="testLink" action="#{custom.dialog.executeMacro('testMacro')}"
        render="inputText" value="Update"/>
    <h:inputText class="submitXMLData" value="#{custom.dialog.vars.xmlData.value}" style="display:none"/>

The `testMacro` definition is as follows:

    def testMacro(dialog):
        dialog.getVar("testString").setValue("New value")

In the case where a macro returns a URL string (as described in Example: Launching a URL from a Macro), the URL will be fired by the browser on completion of the macro.

Contains proprietary and confidential information of ANSYS, Inc. and its subsidiaries and affiliates.

Prev | Up / Contents | Next

Release 18.2 - © ANSYS, Inc. All rights reserved.