Custom List element in XML, Similar to FormData


#1

Hello,

I am adding custom properties to elements. This is required so my back-end can parse the XML with a correct hierarchy. I managed to create them as an extension on existing elements with the XML as following:

    <bpmn2:serviceTask id="Task_08atnyy" camunda:type="external" camunda:topic="runscript" camunda:runscript="CreateInvoice">

The runscript type only becomes available when the selected topic equals “runscript”, so this worked out pretty well.

Now, when selecting the CreateInvoice-Runscript, certain variables are needed to execute it. When creating the model, values are to be given to these. For example, an InvoiceNumber.

It is very likely that several variables need a value. To link this to the corresponding element, a list of variables is needed. When adding Form-Fields to a Start-Event, the list of fields look like this:

ExtensionElements supports this, but using it lets the user add and remove elements.

I have tried to replicate the functionality and syntax of camunda:formData with the list of camunda:formFields in it, but i have not been able to… Tried assigning values hardcoded but even then i do not see any result in the exported XML. If i can achieve this in a basic way, i can figure out the rest, but i need a little bit of help.

Where i am now

  • Duplicated some code from the FormProps

  • Hardcoding values into the variables

  • Using Formdata, its certain that this can be used to achieve it.
    (I have tried like a million things, so i have no idea how far i’ve wandered off…):

                  entryFactory.textField({
                  id: variabledata.name + "variablevalue1",
                  label: 'Variable value',
                  modelProperty: 'id',
                  prefix: 'FormField',
    
                  get: function (element, node) {
                      var bo = getBusinessObject(element);
                      return {FormField: bo.get('camunda:FormField')};
                  },
    
                  set: function (element, values, node) {
                      var bo = getBusinessObject(element);
                      var commands = [];
                      var formData = elementHelper.createElement('camunda:FormData', {fields: [], businesskey: scriptname}, bo, bpmnFactory);
                      commands.push(cmdHelper.updateBusinessObject(element, bo, {FormData: formData}));
                      var field = elementHelper.createElement('camunda:FormField', {id: variabledata.name}, formData, bpmnFactory);
                      if (typeof formData.fields !== 'undefined') {
                          commands.push(cmdHelper.addElementsTolist(element, formData, 'fields', [field]));
                      } else {
                          commands.push(cmdHelper.updateBusinessObject(element, formData, {
                              fields: [field]
                          }));
                      }
    

Looking forward to replies!

Cheers, Revlyn


#2

You are on the right track already. We use lists of extension elements for execution listeners, input/output mappings and so on. You can simply take a look at how these are implemented and copy build your component the same way.


#3

I cant figure it out, the reason for this is that the context from which i am trying to achieve it is different than the context from which, for example, FormProps is initialized… I need to send back commands created by the CmdHelper, but the context from which i am working requires entries. Tried a lot of things to work around this but no succes…

The input field out of which the list of elements will exist need to be initiated after a specific RunScript is selected. the box that controls adding and removing these elements is not needed. But the list that lies underneath it is.

I am missing out a lot on the documentation… Is there any way the structure and methods ,along with what they do and expect, can be clarified a bit more? Maybe some additional documentation or something like this that can help me a bit further?

Cheers, Revlyn


#4

I totally agree with you, there’s not enough documentation given the complexity of the properties panel which makes it hard for people to get started. We’d like to improve that in the future.


#5

I will just keep trying, and i’ll let you know when i succeeded. Eventually i’ll figure it out.


#6

I am working with the extensionElements, and im almost there. My current problem:

How can i create initial form-fields in an Extension Element without beinig forced to click the add-button that triggers the event?

At the moment, i added 3 options to my extensionElement. An array of initialvalues, a method which controls how these are set and a boolean which controls whether its the first initalization.

var createInitialElements = options.createInitialExtensionElements;           
var initialValues = options.initialValues;
var initialized = false;

//In the set-attribute of the returnvalue of the modules.exports
commands.push(createInitialElements(element, extensionElements, initialValues, node));

FormProps

In my FormProps, when creating the entry, i define the array-values and method logic:

var formFieldsEntry = extensionElements(element, bpmnFactory, {
        id: 'form-fields',
        label: 'Variables',
        modelProperty: 'id',
        prefix: 'FormField',
        createInitialExtensionElements: function (element, extensionElements, values) {
        var bo = getBusinessObject(element), commands = [];

        if (!extensionElements) {
            extensionElements = elementHelper.createElement('bpmn:ExtensionElements', {values: []}, bo, bpmnFactory);
            commands.push(cmdHelper.updateProperties(element, {extensionElements: extensionElements}));
        }

        var formData = extensionElements.values[0];
        var fields = [];
        var arrayLength = values.length;
        for (var i = 0; i < arrayLength; i++) {
            fields.push(elementHelper.createElement('camunda:FormField', {id: values[i]}, formData, bpmnFactory));
        }
        if (!formData) {
            formData = elementHelper.createElement('camunda:FormData', {fields: fields}, extensionElements, bpmnFactory);
            commands.push(cmdHelper.addAndRemoveElementsFromList(
                    element,
                    extensionElements,
                    'values',
                    'extensionElements',
                    [formData],
                    []
                    ));
        }
        return commands;
    },       
    initialValues: ["test1", "test2"],
                    [formData],
                    []
                    ));
        }
        return commands;
    },       
    initialValues: ["test1", "test2"],

When selecting a certain script, i need the FormTab to be created along with the initialValues. So, i need to trigger the function of creating a Form-Field, but the problem is that the trigger happens from the add-button, which is not created yet until the complete group of entries is returned and created.

So right now, when the FormTab is created its empty like:

When i click “Add” it looks like:

What i need is for the variables to be created without needing to click the plus. How can i do this?

Cheers, Revlyn


#7

Having initial properties for your elements is possible through either using default element templates or implementing the behavior in bpmn-js.