cancel
Showing results for 
Search instead for 
Did you mean: 

External form rendering : Form properties values listing

fredg
Champ in-the-making
Champ in-the-making
Hi all,

I’m working on a workaround to migrate from jpdl outgoing transitions to BPMN 2 (human task + Exclusive gateway)

My need:

* Provide a form display; give user a choice to decide next step (outgoing sequence flow).
* Choice must be "by design" embedded in process. (using Activiti Eclipse Designer)

Reading this forum I saw that the way to do is using a process like this: a usertask followed by an exclusive gateway.


My solution:

* UserTask : add some form properties, and use them for the following Exclusive gateway evaluation.
Example:

    <formProperties id="step1" name=" step1" type="enum" value="TaskA,TaskB" readable="true" />
    <formProperties id="step2" name=" step2" type="string" value="TaskA,TaskB" readable="true" />
* List those values using List<FormProperty> formService.getTaskFormData(task.getId()).getFormProperties()

Unfortunately, List<FormProperty> is always empty and I can't get any of them, so I’m unable to provide my user a choice.


I would like to access a form property default value, in my case "TaskA,TaskB"
The user choice (TaskA or TaskB) with then be added to a variable so the gateway can take a decision.

Can someone explain why FormProperty.getValue() is always null ?


Activiti 5.6, postgres 9, spring 3.x

Here is code :


   ProcessInstance processInstance = null;
        try {
            /**
             * You must define "initiator" on StartEvent node
             * FIXME Thead safe ?
             */
            this.identityService.setAuthenticatedUserId("ofred");
            processInstance = this.runtimeService.startProcessInstanceByKey("testGateway",
                            null,
                            new HashMap<String, Object>());
        } finally {
            this.identityService.setAuthenticatedUserId(null);
        }
        assertFalse(processInstance.isEnded());
        //Step 1 : we should wait on usertask1
        Task task = this.taskService.createTaskQuery()
            .processInstanceId(processInstance.getId())
            .singleResult();
        assertEquals("User Task", task.getName());
        //FORM
        Object o = this.formService.getRenderedTaskForm(task.getId());
        assertNull(o);
        /**
         * Get list of available user choice : pseudo out going transitions
         * Process definition must be readable="true"
         * ENUM types not yet supported see http://jira.codehaus.org/browse/ACT-882 as java enum (and sucks in designer)
         */
        StartFormData startformData = this.formService.getStartFormData(processInstance.getProcessDefinitionId());
        assertNotNull(startformData);
        assertEquals(0, startformData.getFormProperties().size());
        /**
         * Only readable="true" will be visible
         */
        TaskFormData formData = this.formService.getTaskFormData(task.getId());
        List<FormProperty> data = formData.getFormProperties();
        assertNotNull(data);
        assertTrue(data.size() > 0);//FIXME fails !!
        for (FormProperty prop : data) {
            String id = prop.getId();
            String value = prop.getValue();
        }
11 REPLIES 11

frederikherema1
Star Contributor
Star Contributor
Not sure if I understand what you're trying to do, my best shot:

You should fill in the FormProperty values yourself, and submit the form-properties to the formService, so the task is completed with the values you specified. Internally, the values you filled in (or set in code on the FormProperty objects) will be made available as process-variables. These can be used in expressions in your gateway afterwards.

fredg
Champ in-the-making
Champ in-the-making
Thanks, I think my post is not clear, i'm a step before submiting using formService, i'm displaying the form to submit.

Imagine a usertask having many outgoing transitions (sequence flow) and a user can choose to follow only one of them.
This is what i want to do.
(This can be done in jbpm; but seems impossible in BPMN 2 http://forums.activiti.org/en/viewtopic.php?f=6&t=1279)

So i try to implement the jbarrez right way to do : (see from post)
"The right way to do it, is using a combination of task + exclusive gateway"

I have a usertask, followed by an exclusive gateway (then some more but doesn't matter).
The gateway is looking for a variable, with some expected values

Ex :

if ${userChoiceFlow=='pathA'} then move on to TaskA
if ${userChoiceFlow=='pathB'} then move on to TaskB

I'm looking for a solution to show on my own task rendering form : "pathA" or "pathB" so user can choose one.


I try to use Form Properties to store my expected values (some other solution ?) inside process definition :

<bpmn2:UserTask …>
<formProperties id="step1" name="step1" type="string" value="pathA,pathB" readable="true" />
</bpmn2:UserTask>


Now in java :

When the user task is active, how can I get default values defined in the process ?
This is BEFORE submit, I just want to retrieve the value="pathA,pathB" to display on my form.

I would expect the following code shows value="pathA,pathB" when id="step1", but it's always null (property is found by id).

for (FormProperty prop : formService.getTaskFormData(task.getId())) {
    String id = prop.getId();
    String value = prop.getValue();
}
I've also check vars :

        Map<String, Object> v1 = runtimeService.getVariables(processInstance.getId());
        Map<String, Object> v2 = runtimeService.getVariablesLocal(task.getExecutionId());
        Map<String, Object> v3 = taskService.getVariables(task.getId());
        Map<String, Object> v4 = taskService.getVariablesLocal(task.getId());
But they're all empty.

What's the point ?

Regards,

ronald_van_kuij
Champ on-the-rise
Champ on-the-rise
defining them is not the same giving them a value… If not explicitly set, they are just not there….

frederikherema1
Star Contributor
Star Contributor
Check out the org.activiti.engine.impl.form.EnumFormType. You should do a getInformation("values") to get the possible values defined in your process-definition

/**
* @author Tom Baeyens
*/
public class EnumFormType extends AbstractFormType {

  protected Map<String, String> values;

  public EnumFormType(Map<String, String> values) {
    this.values = values;
  }

  public String getName() {
    return "enum";
  }


How do you get access to the EnumFormType?
I'm trying to get access to the form values for a task.
This works - but I don't want to be so intimate with you guys (nothing personal).
<code>
TaskFormData tfd = processEngine.getFormService().getTaskFormData(ti.getId());
   Task task = tfd.getTask();

   // this is an internal class and probably should not be using it, but I was
   // unable to get the form values any other way.
   if(task instanceof TaskEntity) {

    TaskEntity taskEntity = (TaskEntity) task;
    TaskDefinition taskDefinition = taskEntity.getTaskDefinition();
    TaskFormHandler tfh = taskDefinition.getTaskFormHandler();
    if(tfh instanceof DefaultTaskFormHandler) {
     DefaultTaskFormHandler defaultTaskFormHandler = (DefaultTaskFormHandler) tfh;
     List<FormPropertyHandler> formPropertyHandlers = defaultTaskFormHandler.getFormPropertyHandlers();
     if(formPropertyHandlers != null && !formPropertyHandlers.isEmpty()) {
      for(FormPropertyHandler fph : formPropertyHandlers) {
       if(fph.getType() != null) {
        if(fph.getType() instanceof EnumFormType) {
         EnumFormType enumFormType = (EnumFormType) fph.getType();
         // obviously we are way out in the weeds here.
         Object o = enumFormType.getInformation("values");
         if(o != null) {
          if(o instanceof LinkedHashMap) {
           // here's the data i need
           // example {complete=force complete, retry=retry}
           LinkedHashMap<String, String> map = (LinkedHashMap) o;
           transitions.addAll(map.keySet());
          }
         }
        }
       }
      }
     }
    }
   }
</code>

fredg
Champ in-the-making
Champ in-the-making
Thank you for answers.

Unfortunately, neither EnumFormType.getInformation("values") nor StringFormType.xxx() are filled with default values provided in process xml definition.
I've tried all methods & debug mode to browse objects.

For EnumFormType so far I understood I will need to manually add something like (example from user-guide):

<activiti:formProperty id="direction" type="enum">
      <activiti:value id="left" name="Go Left" />
      <activiti:value id="right" name="Go Right" />
      <activiti:value id="up" name="Go Up" />
      <activiti:value id="down" name="Go Down" />
</activiti:formProperty>

in my  xx.bpmn20.xml process because Eclipse Designer doesn’t do it from the xx.activiti file. In this case EnumFormType.getInformation("values") works but this is not user friendly… and I can’t choose this solution (manual update after WYSIWYG designed process)

For information, Eclipse Designer generates no <activiti:value> tags
(some jira opened see see http://forums.activiti.org/en/viewtopic.php?f=6&t=2110&hilit=formProperty+enum😞

<activiti:formProperty id="step2" name="step2" type="enum" variable="TaskA,TaskB" required="false" readable="true" writable="true"></activiti:formProperty>
That's why I wanna try using StringFormType, but value's empty too…


Anyway with your answer & Ronald one I’ve found than the .activiti process:

    <formProperties id="step1" name="step1" type="string" value="TaskA,TaskB" readable="true"/>
    <formProperties id="step2" name="step2" type="enum" value="TaskA,TaskB" readable="true"/>

is translated to bpmn20.xml :

<activiti:formProperty id="step1" name="step1" type="string" variable="TaskA,TaskB" required="false" readable="true" writable="false"></activiti:formProperty>
        <activiti:formProperty id="step2" name="step2" type="enum" variable="TaskA,TaskB" required="false" readable="true" writable="false"></activiti:formProperty>

So you’re right I’m not setting value just declaring it, due to issue in the designer?


So far another solution to workaround the multi-outgoing transition in BPMN2 ? (using Designer only)

frederikherema1
Star Contributor
Star Contributor
Yes, looks like designer issue than. Can you give a clear explaination and file a JIRA issue?

hmandic
Champ in-the-making
Champ in-the-making
I'm having the same problem, so I didn't start a new topic.
Is this fixed by now? Or will it be in the near future?

trademak
Star Contributor
Star Contributor
Should be fixed yes. Let us know if you are still experiencing issues.

Best regards,