Skip to main content
Previous sectionNext section

Including Custom Features in a Workflow

This chapter describes how to include custom features in a workflow. It includes the following topics:

Extending the Standard Task Form

Each task has an associated task form that displays (at a minimum) a standard set of items, as follows:

  • The read-only TaskId, Owner, %Subject and %Message properties of the task

  • The Accept button (when the task is unassigned)

  • The Relinquish and Save buttons (when the task is assigned)

To add additional buttons (which are visible only when the task is assigned), provide a comma-separated list of button names in the %Actions property of the task request.

To add additional editable values (which are visible only when the task is assigned), set one of the following properties in the task request object:

  • %FormFields — Provides a list of fields for the task form to display.

    The task request and response objects have a %FormFields property. Upon making the call to a task request, set the %FormFields value to a comma-delimited list of the fields that you want to display on the task form. For now, these are all assumed to be simple string values (if you need more control, use a form template).

  • %FormTemplate — Identifies a file that defines the HTML form template to be displayed.

    The task request and response objects have a %FormTemplate property. Upon making the call to a task request, set the %FormTemplate value to the name of a CSP file that defines a form to be displayed. This CSP page should only define the form and contents: it should not have HTML, HEAD, or BODY sections. The CSP page can overload certain JavaScript Event methods. When this form is processed, the variable %task is the current task response object.

If you use %FormFields or %FormTemplate, you can specify default values to be shown in the fields. To do so, specify the %FormValues property of the task request object. This property is an array of strings, subscripted by field name. Use the array interface to add values to the property.

When the Workflow Engine processes a task, it makes a copy of all the form-related properties from the task request into the task response, including the array collection %FormValues. As fields in the form acquire new values, the Workflow Engine keeps updating the values in the %FormValues collection of the task response object.

Forms always display the current values in the %FormValues collection. This allows dynamic operation of forms within a specific task: by modifying the values of the form-related properties, the task response callback methods can influence how form processing takes place. The %FormValues collection of the task response object is available to the original caller when the final task response is sent back to it.

Using a Custom Task Form

It is possible to display a custom form to a user for a workflow task. The steps are as follows:

  1. Create an HTML template file that defines the contents of the customized form.

  2. Set the %FormTemplate property of the task request object to the name of this CSP page. For example, the <call> statement sending the task request to the workflow operation would contain:

    <assign property='callrequest.%FormTemplate'
            value='"MyForm.csp"'
            action='set' />
    Copy code to clipboard
  3. Set the %FormFields property of the task request object to a comma-delimited list of field names. This is the list of fields that will be defined for the form. For example:

    <assign property='callrequest.%FormFields'
            value='"Details,CustomerName"'
            action='set' />
    Copy code to clipboard
  4. If you wish to provide initial values for the form fields, set the corresponding element (that is,. the array key is the name of the field) of the %FormValues collection property of the task request object to the desired value. For example:

    <assign property='callrequest.%FormValues'
            value='request.CustomerName'
            action='set'
            key='"CustomerName"' />
    Copy code to clipboard

As described in previous sections, whenever a workflow user reviews a task that he or she currently owns, the system displays a the associated task form. By default, this form is automatically generated using the fields defined by the values in the %FormFields property of the task request object. The calling business process provides these values. However, there is a way to use a custom-designed template instead of this generated form.

A workflow form template defines a block of HTML that is injected into the standard task form. This HTML block can include any number of form fields; these fields will be automatically submitted and processed by the Workflow Engine whenever a user performs an action on the workflow task. The HTML contained in a template file is not a complete HTML document; it is simply the HTML needed to display the custom portion of the form. Specifically, the resulting HTML generated by the task form looks like this:

<html>
  <body>
    <form>
      —TEMPLATE CONTENTS INJECTED HERE—
    </form>
  </body>
</html>
Copy code to clipboard

The following template defines an HTML table that displays two HTML input controls: a text box and a select (combobox). The names of the controls correspond to the fields defined by the %FormFields property. This example also uses a server-side expression to get the initial value for the Details property. The %task variable is always pre-set to the current task response object:

<!— workflow template —>
<table>
  <tr>
    <td>Details:</td>
    <td>
      <input type="text"
             name="Details"
             value="#(%task.%FormValues.GetAt("Details"))#">
    </td>
  </tr>
  <tr>
    <td>Company:</td>
    <td>
      <select name="CustomerName">
        <option value="ABC Corp">ABC Corp</option>
        <option value="XYZ Corp">XYZ Corp</option>
      </select>
    </td>
  </tr>
</table>
Copy code to clipboard

In addition to HTML, the workflow template file can contain the following, optional, Javascript callback functions:

  • onLoad() — called when the workflow form is loaded into the browser.

  • onAction() — called when the user clicks on one of the action buttons displayed by the form.

To add these callbacks to a workflow template file, simply place the function definition within a <script> tag in the template file; for example:

<script language="JavaScript">
        function onLoad(form)
        {
                // form is the workflow form object
                return true;
        }

        function onAction(form,action)
        {
                // form is the workflow form object
                // action is a string containing the user's action
                // returning false will cancel this action
                return true;
        }
        </script>
Copy code to clipboard

Customizing the Task Distribution Strategy

The task distribution strategy is specified in the task response class. To implement a custom task distribution strategy, do the following:

  • Create a subclass of EnsLib.Workflow.TaskResponse and override its OnNewTask() callback method (and possibly other methods). The first subsection provides details on the options.

  • Make sure to invoke the custom task response class. This is discussed in the second subsection.

Creating a Custom Task Response Class

When you create a subclass of EnsLib.Workflow.TaskResponse, you override its OnNewTask() callback method (and possibly other methods). The following is a list of the callback methods that you can override:

  • OnAction() — Called when a user selects an action from the worklist form. Typically this marks the end of a task.

  • OnAssign() — Called when a user requests ownership of a task associated with it. Typically this method performs the assignment.

  • OnCancel() — Called when a task is cancelled, for example when it times out.

  • OnFormSubmit() — Called when the task form associated with this task is submitted.

  • OnNewTask() — Called when a new task is received by the Workflow Engine. Typically this method associates the task with members of the current role.

  • OnRelinquish() — Called when a user requests giving up ownership of a task associated with it. Typically this method unassigns the task and then sends the task back to others in the role.

  • OnRoleChange() — Called when a user or role definition associated with this task is changed, for example when the list of users within a role changes.

EnsLib.Workflow.TaskResponse callback methods control the distribution of tasks by calling a number of API methods defined in the Workflow Engine (EnsLib.Workflow.Engine).

The following is a list of the class methods in EnsLib.Workflow.Engine that you can use when you override the callbacks listed previously.

  1. AssignTask() — Assign a task to a specific user.

  2. CompleteTask() — Mark a task as Completed and return the response to the caller.

  3. FindLeastBusyUser() — Return the name of the “least busy” user. This is the user with the fewest assigned tasks in the system.

  4. SendTask() — Send a task to a specific user.

  5. SendTaskToAll() — Send a task to all users in the current role.

  6. SendTaskToTitle() — Send a task to one or more users with the given title in the current role.

  7. SendTaskToTop() — Send a task to the top n users in the current role, according to their respective ranking in the role.

  8. UnassignTask() — Remove task assignment.

For details on these methods, see the InterSystems Class Reference.

Invoking the Custom Task Response Class

A task request message has class parameter (RESPONSECLASSNAME) that specifies which response class to use. You can override this by setting the %TaskHandler property of the request class.

This means that you have two ways to cause the task request to use the desired task response:

  • Optionally create a subclass of EnsLib.Workflow.TaskRequest and override its RESPONSECLASSNAME parameter to equal the name of your custom task response class. For example:

    Class MyApp.MyWorkflowRequest Extends EnsLib.Workflow.TaskRequest
    {
    
    Parameter RESPONSECLASSNAME = "MyApp.MyWorkflowResponse";
    
    }
    Copy code to clipboard

    Then use this message class in the appropriate parts of the workflow process.

  • In the workflow process, when making the call to the workflow operation, set the value of the %TaskHandler property of the request instance so that it gives the name of the desired task response class name. For example:

     set callrequest.%TaskHandler="MyApp.MyWorkflowResponse"
    Copy code to clipboard