Question

I'm working with Activiti workflows in Alfresco Share and I need to add a header common to all the user task forms in a workflow. This header would be a set of read-only properties (fields) displaying context workflow information at the top of all the user task forms in the workflow. For example, in client management workflows, the header may show the client name and surnames, the client file code, etc., displaying each value in a read-only text box or label.

Is there a simple way to add a set of information fields (and populate them as well) to all the user task forms in a workflow? I know it's possible to create a new aspect containing the desired properties, but how could I add that aspect at runtime to my task types and set their property values via JavaScript when needed? Currently, each user task in the workflow has its own custom type (i.e. form) in a workflow model definition (XML file), except for some "standard" review tasks, which are using "wf:activitiReviewTask" as form key. The set of read-only information fields should appear in all the forms, including the standard review task forms.

I want to achieve something like this (see red square):

Task form with information fields

Thanks for your help in advance.

UPDATE 1

I have no experience with form templates. Since my forms are very simple, I just used a few model definitions (aspects & types) and some Share custom configuration combined to design them. The information I wish to display in the header can be easily retrieved from JavaScript code, since it's stored in several workflow context variables. This is what I had in mind, not tested yet, please tell me if it's a workable idea. If not, could you provide an example of how to do it using form templates?

mynsModel.xml

<aspect name="myns:customerTaskHeader">
    <title>Customer task header</title>
    <properties>
        <property name="myns:customerName">
            <title>Name</title>
            <type>d:text</type>
        </property>
        <property name="myns:customerSurname">
            <title>Surname</title>
            <type>d:text</type>
        </property>         
    </properties>
</aspect>

workflowModel.xml

<type name="wf:customerDelivery">
    <title>Delivery to customer</title>
    <parent>bpm:workflowTask</parent>
    <properties>
        <property name="wf:customerDeliveryType">
            <title>Delivery type</title>
            <type>d:text</type>         
        </property>
        <property name="wf:customerDeliveryStatus">
            <title>Signed</title>
            <type>d:boolean</type>                  
        </property>
    </properties>
    <mandatory-aspects>
        <aspect>myns:customerTaskHeader</aspect>
    </mandatory-aspects>    
</type>

share-config-custom.xml

<config evaluator="task-type" condition="wf:customerDelivery">
    <forms>
        <form>
            <field-visibility>
                <show id="myns:customerName" />
                <show id="myns:customerSurname" />
                <show id="packageItems" />
                <show id="wf:customerDeliveryType" />
                <show id="wf:customerDeliveryStatus" />
                <show id="bpm:comment" />   
                <show id="transitions" />
            </field-visibility>
            <appearance>
                <set id="" appearance="title" label-id="workflow.set.general" />
                <set id="items" appearance="title" label-id="workflow.set.items" />
                <set id="response" appearance="title" labelid="workflow.set.response" />
                <field id="bpm:comment" labelid="workflow.field.message">
                    <control template="/org/alfresco/components/form/controls/textarea.ftl">
                        <control-param name="style">width: 95%</control-param>
                    </control>
                </field>
                <field id="packageItems" set="items" />
                <field id="transitions" set="response" />
                <field id="myns:customerName" read-only="true">
                    <control template="/org/alfresco/components/form/controls/info.ftl" />
                </field>
                <field id="myns:customerSurname" read-only="true">
                    <control template="/org/alfresco/components/form/controls/info.ftl" />
                </field>
            </appearance>
        </form>
    </forms>
</config>

Some drawbacks I see in this (possible) workaround:

  1. All the task type definitions must include the customerTaskHeader aspect. The problem is that many user tasks in the workflow have a built-in type, not a custom one. It would be nice to be able to add the aspect with all the required values to the task type at runtime by JavaScript code, but this is probably not possible.
  2. I need a different custom config evaluator for each task type in share-config-custom.xml. Same problem.
  3. I find it quite cumbersome to use and hard to maintain. Moreover, correct me if I'm wrong, I cannot see a simple way to set values to the header fields of all the task forms in the workflow. I think I should add a "create" event listener to every user task, with the following code:

[JavaScript Code]

    var customerName = execution.getVariable('customerName');
    var customerSurname = execution.getVariable('customerSurname');
    task.setVariable('myns_customerName', customerName);
    task.setVariable('myns_customerSurname', customerSurname);
Was it helpful?

Solution

It is pretty easy to define a custom form template, as documented on http://wiki.alfresco.com/wiki/Forms. As part of that template, you can display any information you need to before you start rendering the fields themselves. You could even create a common 'include' template if you need to show this in multiple form templates.

The question is exactly what information you wish to display in the header, and where is that information stored? That will impact how you need to retrieve it for display to the user.

If you the properties you need are available on the task item, then it is easy to retrieve them through the form field values. They can then then be rendered straight into the output HTML.

What I suspect is more likely however, from your question, is that the values are stored somewhere else and must be retrieved from there prior to display. In that case, you would need to implement a client-side function (or component) using the standard Share pattern, and modify your form template so that the HTML it generates causes that code to be run when loaded by the browser.

Within that component, you can make XHR calls out to, say, the repository API, to retrieve the property values, and then update the HTML page using a callback function to populate the data for user display.

As an example of something similar, see the task owner.ftl field template provided by Share

<#if field.value?? && field.value?length &gt; 0>
...
<script type="text/javascript">//<![CDATA[
YAHOO.util.Event.onContentReady("${fieldHtmlId}", function ()
{
   YAHOO.util.Dom.get("${fieldHtmlId}").innerHTML = Alfresco.util.userProfileLink("${userName}", "${fullName}", "", ${disableLink?string});
}, this);
//]]></script>
</#if>

Here the client-side function uses Alfresco.util.userProfileLink, but you could implement your own function which uses Alfresco.util.Ajax.jsonGet() or similar to retrieve the data and then populate it using YAHOO.util.Dom functions.

But as I say, the exact method depends on where your data is and how you need to display it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top