[11]深入浅出工作开源框架Camunda:部署HTML表单

Camunda不仅仅支持类似于JSON格式的表单,也支持HTML格式的表单。支持Camunda JSON表单格式比较简单,比如类似下面的表达。

{
  "schemaVersion": 2,
  "components": [
    {
      "label": "Text Field",
      "type": "textfield",
      "id": "Field_0kpmyne",
      "key": "field_1kjqk1b"
    },
    {
      "label": "Number",
      "type": "number",
      "id": "Field_1pp63a0",
      "key": "field_1iy0fgh"
    },
    {
      "label": "Checkbox",
      "type": "checkbox",
      "id": "Field_09m9mbv",
      "key": "field_1iufp4h"
    },
    {
      "values": [
        {
          "label": "Value",
          "value": "value"
        }
      ],
      "label": "Radio",
      "type": "radio",
      "id": "Field_0tanpr2",
      "key": "field_0wz7jwp"
    },
    {
      "values": [
        {
          "label": "Value",
          "value": "value"
        }
      ],
      "label": "Select",
      "type": "select",
      "id": "Field_0uvqqg4",
      "key": "field_0vwokcn"
    },
    {
      "text": "# Text",
      "type": "text",
      "id": "Field_1mmwz20"
    },
    {
      "action": "submit",
      "label": "Button",
      "type": "button",
      "id": "Field_1kwxmg4",
      "key": "field_184exnw"
    }
  ],
  "type": "default",
  "id": "Form_1kmjw6v"
}

其UI视图如下:
在这里插入图片描述
那么如果需要部署一个带表单的应用,且是独立部署,不是把流程和html表单嵌入到Java应用里面应该如何做呢?
比如下面的流程和表单。
在这里插入图片描述
其流程文件(loanApproval.bpmn)源码如下:

<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="_r7y_gEa-EeO5NO3lqhkDkg" targetNamespace="http://camunda.org/examples" exporter="Camunda Modeler" exporterVersion="4.11.1" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
  <bpmn2:process id="embeddedFormsQuickstart" name="Embedded Forms Quickstart" isExecutable="true">
    <bpmn2:startEvent id="StartEvent_1" name="Loan Request&#10;Received" camunda:formKey="embedded:deployment:start-form.html">
      <bpmn2:outgoing>SequenceFlow_1</bpmn2:outgoing>
    </bpmn2:startEvent>
    <bpmn2:sequenceFlow id="SequenceFlow_1" sourceRef="StartEvent_1" targetRef="UserTask_1" />
    <bpmn2:endEvent id="EndEvent_1" name="Done">
      <bpmn2:incoming>SequenceFlow_3</bpmn2:incoming>
    </bpmn2:endEvent>
    <bpmn2:userTask id="UserTask_1" name="Approve Request" camunda:formKey="embedded:deployment:task-form.html" camunda:assignee="demo">
      <bpmn2:incoming>SequenceFlow_1</bpmn2:incoming>
      <bpmn2:outgoing>SequenceFlow_3</bpmn2:outgoing>
    </bpmn2:userTask>
    <bpmn2:sequenceFlow id="SequenceFlow_3" sourceRef="UserTask_1" targetRef="EndEvent_1" />
  </bpmn2:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="embeddedFormsQuickstart">
      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_3" bpmnElement="SequenceFlow_3" sourceElement="_BPMNShape_UserTask_3" targetElement="_BPMNShape_EndEvent_8">
        <di:waypoint x="398" y="118" />
        <di:waypoint x="460" y="118" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="533" y="268" width="0" height="0" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_1" bpmnElement="SequenceFlow_1" sourceElement="_BPMNShape_StartEvent_3" targetElement="_BPMNShape_UserTask_3">
        <di:waypoint x="212" y="118" />
        <di:waypoint x="298" y="118" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="347" y="268" width="0" height="0" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_3" bpmnElement="StartEvent_1">
        <dc:Bounds x="176" y="100" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="160" y="136" width="69" height="27" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="_BPMNShape_EndEvent_8" bpmnElement="EndEvent_1">
        <dc:Bounds x="460" y="100" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="465" y="136" width="27" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="_BPMNShape_UserTask_3" bpmnElement="UserTask_1">
        <dc:Bounds x="298" y="78" width="100" height="80" />
      </bpmndi:BPMNShape>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn2:definitions>

其有两个表单,启动的节点(Load Request Recevied)和用户任务(Approve Request)。
其分别关联了下面的表单:
(1)开始节点的表单(start-form.html)

<h3>Embedded Forms Quickstart</h3>
<form role="form"
      name="variablesForm">

  <div class="row">

    <div class="col-xs-6">
      <h2>Loan Data</h2>

      <!-- Loan Type -->
      <div class="form-group">
        <label for="selectLoanType">Type of the loan</label>
        <div class="controls">
          <!--select box -->
          <select id="selectLoanType"
                  required
                  class="form-control"
                  name="loanType"
                  cam-variable-name="loanType"
                  cam-variable-type="String"
                  ng-change="calculateLoan()">
            <option value="mortage" checked>Mortage Loan (5%)</option>
            <option value="cashAdvance">Cash Advance (10%)</option>
          </select>
        </div>

        <!-- Custom validation message for select box -->
        <p ng-if="variablesForm.loanType.$invalid" style="color: red">
          Please select a loan type.
        </p>
      </div>

      <!-- Loan Amount -->
      <div class="form-group">
        <label for="inputLoanAmount">Amount</label>
        <div class="controls">
          <input id="inputLoanAmount"
                 required
                 class="form-control"
                 cam-variable-type="Double"
                 cam-variable-name="loanAmount"
                 min="1000"
                 ng-change="calculateLoan()"
                 name="loanAmount"
                 type="number"/>
        </div>
      </div>

      <!-- Runtime in Years -->
      <div class="form-group">
        <label for="inputLoanRuntime">Runtime (Years)</label>
        <div class="controls">
          <input id="inputLoanRuntime"
                 required
                 class="form-control"
                 cam-variable-type="Double"
                 cam-variable-name="loanRuntime"
                 min="2" max="30"
                 ng-change="calculateLoan()"
                 name="loanRuntime"
                 type="number"/>
        </div>
      </div>

      <!-- calculate monthly payment -->
      Projected monthly payment:
      <p ng-if="monthlyPayment" class="alert alert-success">
        {{monthlyPayment}}€ at {{interest}}% interest rate.
      </p>

      <p ng-if="!monthlyPayment" class="alert alert-danger">
        Invalid selection.
      </p>

      <!-- The following code demonstrates use of custom scripting.

            The 'cam-script' directive makes sure the the script is loaded and can bind to the angular $scope for the form.

            Access to form fields is provided through $scope.variablesForm.
         -->
      <script cam-script type="text/form-script">
      $scope.calculateLoan = function() {
        var form = $scope.variablesForm;

        if(!form.loanType.$valid || !form.loanAmount.$valid || !form.loanRuntime.$valid) {
          $scope.monthlyPayment = undefined;

        } else {

          var loanAmount = form.loanAmount.$modelValue;
          var years = form.loanRuntime.$modelValue;
          var loanType = form.loanType.$modelValue;
          var interestRate = 0;

          if(loanType == "mortage") {
            interestRate = 0.05;
          } else if(loanType == "cashAdvance") {
            interestRate = 0.10;
          }

          $scope.interest = 100 * interestRate;

          // calculate monthly payment using special formula provided by Bobby G
          $scope.monthlyPayment = Math.round((loanAmount * ((Math.pow((1+interestRate),years)*interestRate) / (Math.pow((1+interestRate),years)-1))) * (1/12));

        }
      }

      </script>

    </div>

    <div class="col-xs-6">
      <h2>Contact Data</h2>

      <!-- Gender -->
      <div class="form-group">
        <label for="gender">Gender</label>
        <div class="controls">

          <!--select box -->
          <select id="gender"
                  class="form-control"
                  cam-variable-name="gender"
                  cam-variable-type="String"
                  ng-change="calculateLoan()">
            <option value="m" checked>Mr.</option>
            <option value="f">Mrs.</option>
          </select>

        </div>
      </div>

      <!-- Firstname -->
      <div class="form-group">
        <label for="inputFirstname">First Name</label>
        <div class="controls">
          <input id="inputFirstname"
                 class="form-control"
                 required
                 type="text"
                 cam-variable-name="firstname"
                 cam-variable-type="String"
                 placeholder="John"
                 ng-minlength="2"
                 ng-maxlength="20"/>
        </div>
      </div>

      <!-- Lastname -->
      <div class="form-group">
        <label for="inputLastname">Last Name</label>
        <div class="controls">
          <input id="inputLastname"
                 class="form-control"
                 required
                 type="text"
                 cam-variable-name="lastname"
                 cam-variable-type="String"
                 placeholder="Doe"
                 ng-minlength="2"
                 ng-maxlength="20"/>
        </div>
      </div>

      <!-- Email -->
      <div class="form-group">
        <label for="inputEmail">Email</label>
        <div class="controls">
          <input id="inputEmail"
                 class="form-control"
                 required
                 type="text"
                 cam-variable-name="email"
                 cam-variable-type="String"
                 placeholder="john.doe@camunda.org"
                 ng-minlength="2"
                 ng-maxlength="40"/>
        </div>
      </div>

      <!-- Address -->
      <div class="form-group">
        <label for="inputAddress">Address</label>
        <div class="controls">
        <textarea id="inputAddress"
                  class="form-control"
                  cam-variable-name="address"
                  cam-variable-type="String"
                  rows="4"></textarea>
        </div>
      </div>

    </div>

  </div>
</form>

(2)用户任务节点的表单(task-form.html)

<form role="form" name="form">
  <script cam-script type="text/form-script">
    camForm.on('form-loaded', function() {
      camForm.variableManager.fetchVariable('loanType');
      camForm.variableManager.fetchVariable('loanAmount');
      camForm.variableManager.fetchVariable('loanRuntime');
      camForm.variableManager.fetchVariable('gender');
      camForm.variableManager.fetchVariable('firstname');
      camForm.variableManager.fetchVariable('lastname');
      camForm.variableManager.fetchVariable('address');
      camForm.variableManager.fetchVariable('email');
    });
    camForm.on('variables-restored', function() {
      $scope.loanType = camForm.variableManager.variableValue('loanType');
      $scope.loanAmount = camForm.variableManager.variableValue('loanAmount');
      $scope.loanRuntime = camForm.variableManager.variableValue('loanRuntime');
      $scope.gender = camForm.variableManager.variableValue('gender');
      $scope.firstname = camForm.variableManager.variableValue('firstname');
      $scope.lastname = camForm.variableManager.variableValue('lastname');
      $scope.address = camForm.variableManager.variableValue('address');
      $scope.email = camForm.variableManager.variableValue('email');
      console.log("setting variables to scope");
    });
  </script>
  <h2>Request Summary</h2>

  <table>

    <tr>
      <td>Type of the loan:</td>
      <td>{{ loanType }}</td>
    </tr>

    <tr>
      <td>Amount:</td>
      <td>{{loanAmount}}</td>
    </tr>

    <tr>
      <td>Runtime (Years):</td>
      <td>{{loanRuntime}}</td>
    </tr>

  </table>

  <h2>Contact Data:</h2>

  <address>
    <strong>
      <span ng-if="gender == 'f'">Mrs.</span>
      <span ng-if="gender == 'm'">Mr.</span>
      {{firstname}} {{lastname}}
    </strong><br>
    {{address}}<br>
    <a href="mailto:{{email}}">{{email}}</a>
  </address>

  <h2>Approval</h2>

  Do you approve this request?

  <div class="form-group">
    <input type="checkbox" cam-variable-name="approved" cam-variable-type="Boolean"/>
  </div>
</form>

那么,其是如何在流程里面关联html表单的呢?以开始节点为例,
在 Forms的Type选择,“Embedded Or External Task Forms”
Form Key 输入: embedded:deployment:start-form.html
在这里插入图片描述
用户任务节点类似。

关联后,就可以通过Camunda modeler直接进行部署~

部署成功后效果如下:
1)启动节点
在这里插入图片描述

  1. 用户任务节点

在这里插入图片描述
部署成功,且能直接执行~

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值