简体   繁体   中英

How to handle variable number of process variables in Camunda

I'm new to Camunda and didn't find any tutorial or reference explaining how to achieve the following:

When starting a process I want the user to add as many items as he likes to an invoice. On the next user task all those items and their quantity should be printed to somebody approving the data.

I don't understand yet how to get this 1:n relationship between a process and its variables working. Do I need to start subprocesses for each item? Or do I have to use a custom Java object? If so, how can I map form elements to such an object from within the Tasklist?

I got it working with the help of the links provided by Thorben.

The trick is to use JSON process variables to store more complex data structures. I initialize such lists in my "Start Event". This can be done either in a form or in my case in a Listener:

execution.setVariable("items", Variables.objectValue(Arrays.asList(dummyItem)).serializationDataFormat("application/json").create());

Note that I added a dummyItem, as an empty list would lose its type information during serialization.

Next in my custom form I load this list and can add/remove items. Using the camForm callbacks one can persist the list.

<form role="form" name="form">
    <script cam-script type="text/form-script">
    /*<![CDATA[*/
    $scope.items = [];

    $scope.addItem = function() {
        $scope.items.push({name: '', count: 0, price: 0.0});
    };

    $scope.removeItem = function(index) {
        $scope.items.splice(index, 1);
    };

    camForm.on('form-loaded', function() {
        camForm.variableManager.fetchVariable('items');
    });

    // variables-fetched is not working with "saved" forms, so we need to use variables-restored, which gets called after variables-fetched
    camForm.on('variables-restored', function() {
        $scope.items = camForm.variableManager.variableValue('items');
    });

    camForm.on('store', function() {
        camForm.variableManager.variableValue('items', $scope.items);
    });
    /*]]>*/
    </script>


    <table class="table">
        <thead>
            <tr><th>Name</th><th>Count</th><th>Price</th><th></th></tr>
        </thead>
        <tbody>
            <tr ng-repeat="i in items">
                <td><input type="text" ng-model="i.name"/></td>
                <td><input type="number" ng-model="i.count"/></td>
                <td><input type="number" ng-model="i.price"/></td>
                <td>
                    <button class="btn btn-default" ng-click="removeItem($index)">
                        <span class="glyphicon glyphicon-minus"></span>
                    </button>
                </td>
            </tr>
        </tbody>
        <tfoot>
            <tr>
                <td colspan="4">
                    <button class="btn btn-default" ng-click="addItem()">
                        <span class="glyphicon glyphicon-plus"></span>
                    </button>
                </td>
            </tr>
        </tfoot>
    </table>

</form>

Two things aren't working yet:

  • Field validation, eg for number fields
  • The dirty flag used on the "save" button doesn't get updated, when adding/removing rows

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM