How can I use bpmn-js the on local .bpmn files?

Hello,

I am new to Camunda and bpmn io. In the last couple of weeks I watched the tutorials and did the walkthoughts of Camunda and bpmn io and this week I am taking the step to start a project of my own.

What do I want: view the munsterprocess generated by the Camunda modeler of the Camunda tutorial in the browser using bpmn io. I’ve added the munsterprocess.bpmn file in the attachment.

So I looked up the bpmn-js-example and tried the following code and it’s works on my machine.

var diagramUrl = 'the cdn link';
var bpmnViewer = new BpmnJS({
  container: '#canvas'
});

function openDiagram(bpmnXML) {
  bpmnViewer.importXML(bpmnXML, function (err) {
    if (err) {
      return console.error('could not import BPMN 2.0 diagram', err);
    }
    var canvas = bpmnViewer.get('canvas');
    canvas.zoom('fit-viewport');
  });
}

$.get(diagramUrl, openDiagram, 'text');

The problem is that I am not sure what I need to put in the diagramUrl variabel for local use. At first I tried var diagramUrl='mylocalpathtomunsterprocess'. But this didn’t work. I got the missing start tag error. I took a look on the forum and found a solution. What I understood from the solution on that topic was that I should not use a musterprocess filepath, but the content of the munsterprocess bpmn file. (as a user I am not allowed to post more than two links so I can post the topic.

So I tried this:

var diagramUrl = '<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1dnct9u" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.6.0">
  <bpmn:process id="WatchMunster" name="Watch Munster" isExecutable="true">
    <bpmn:startEvent id="StartEvent_1">
      <bpmn:outgoing>SequenceFlow_0ocryyj</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:sequenceFlow id="SequenceFlow_0ocryyj" sourceRef="StartEvent_1" targetRef="Task_0j0l1xx" />
    <bpmn:userTask id="Task_0j0l1xx" name="Pick a team">
      <bpmn:incoming>SequenceFlow_0ocryyj</bpmn:incoming>
      <bpmn:outgoing>SequenceFlow_1w9vdhq</bpmn:outgoing>
    </bpmn:userTask>
    <bpmn:exclusiveGateway id="ExclusiveGateway_14tt7lf" name="What team did you pick?">
      <bpmn:incoming>SequenceFlow_1w9vdhq</bpmn:incoming>
      <bpmn:outgoing>SequenceFlow_0y07g4u</bpmn:outgoing>
      <bpmn:outgoing>SequenceFlow_0mh0s07</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:sequenceFlow id="SequenceFlow_1w9vdhq" sourceRef="Task_0j0l1xx" targetRef="ExclusiveGateway_14tt7lf" />
    <bpmn:sequenceFlow id="SequenceFlow_0y07g4u" name="Preussen Munster" sourceRef="ExclusiveGateway_14tt7lf" targetRef="Task_0boabwh">
      <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">#{teamName == 'Preussen Munster'}</bpmn:conditionExpression>
    </bpmn:sequenceFlow>
    <bpmn:endEvent id="EndEvent_08prxfb">
      <bpmn:incoming>SequenceFlow_0mh0s07</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="SequenceFlow_0mh0s07" sourceRef="ExclusiveGateway_14tt7lf" targetRef="EndEvent_08prxfb" />
    <bpmn:endEvent id="EndEvent_1dx5p1w">
      <bpmn:incoming>SequenceFlow_1ul5s9w</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="SequenceFlow_1ul5s9w" sourceRef="Task_0boabwh" targetRef="EndEvent_1dx5p1w" />
    <bpmn:userTask id="Task_0boabwh" name="Watch game with Niall">
      <bpmn:incoming>SequenceFlow_0y07g4u</bpmn:incoming>
      <bpmn:outgoing>SequenceFlow_1ul5s9w</bpmn:outgoing>
    </bpmn:userTask>
  </bpmn:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="WatchMunster">
      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
        <dc:Bounds x="179" y="209" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="SequenceFlow_0ocryyj_di" bpmnElement="SequenceFlow_0ocryyj">
        <di:waypoint x="215" y="227" />
        <di:waypoint x="270" y="227" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="UserTask_1jzbdpy_di" bpmnElement="Task_0j0l1xx">
        <dc:Bounds x="270" y="187" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="ExclusiveGateway_14tt7lf_di" bpmnElement="ExclusiveGateway_14tt7lf" isMarkerVisible="true">
        <dc:Bounds x="505" y="202" width="50" height="50" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="495" y="259" width="70" height="27" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="SequenceFlow_1w9vdhq_di" bpmnElement="SequenceFlow_1w9vdhq">
        <di:waypoint x="370" y="227" />
        <di:waypoint x="505" y="227" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="SequenceFlow_0y07g4u_di" bpmnElement="SequenceFlow_0y07g4u">
        <di:waypoint x="530" y="202" />
        <di:waypoint x="530" y="120" />
        <di:waypoint x="690" y="120" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="587" y="89" width="47" height="27" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="EndEvent_08prxfb_di" bpmnElement="EndEvent_08prxfb">
        <dc:Bounds x="852" y="209" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="SequenceFlow_0mh0s07_di" bpmnElement="SequenceFlow_0mh0s07">
        <di:waypoint x="555" y="227" />
        <di:waypoint x="852" y="227" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="EndEvent_1dx5p1w_di" bpmnElement="EndEvent_1dx5p1w">
        <dc:Bounds x="932" y="102" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="SequenceFlow_1ul5s9w_di" bpmnElement="SequenceFlow_1ul5s9w">
        <di:waypoint x="790" y="120" />
        <di:waypoint x="932" y="120" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="UserTask_1mgour3_di" bpmnElement="Task_0boabwh">
        <dc:Bounds x="690" y="80" width="100" height="80" />
      </bpmndi:BPMNShape>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>
';
var bpmnViewer = new BpmnJS({
  container: '#canvas'
});

function openDiagram(bpmnXML) {
  bpmnViewer.importXML(bpmnXML, function (err) {
    if (err) {
      return console.error('could not import BPMN 2.0 diagram', err);
    }
    var canvas = bpmnViewer.get('canvas');
    canvas.zoom('fit-viewport');
  });
}

$.get(diagramUrl, openDiagram, 'text');

I am sure this is not the way to go, but I am not really sure how to solve this.

munsterprocess.bpmn (4.7 KB)

For open bpmn file from local

1- Put Html input element with file type

<input type="file" accept="text/bpmn" name="txt_localFile" id="txt_localFile" onchange="openLocalDiagram(event, openBpmnDiagram)" style="visibility: hidden; display: none;" />

2- Call this code in button click

$('input[type="file"][id="txt_localFile"]').click();

3- Open file function

let _openLocalDiagram = function (event, openCallback) {        
        var input = event.target;
        var reader = new FileReader();
        reader.onload = function () {
            if (openCallback && typeof openCallback === 'function') {
                openCallback(reader.result);
            }

            console.log('end load diagram from local');
        };
        reader.readAsText(input.files[0]);  

        var fileNameSpan = $('span[id="bpmnFileName"]');
        fileNameSpan.html(input.files[0]['name'].split('.')[0]);        
    };

4- Open bpmn diagram callback

let _openBpmnDiagram = function (xml) {
        modeler.importXML(xml, function (error) {
            if (error) {
                return;
            }

            var canvas = modeler.get('canvas');

            canvas.zoom('fit-viewport');

            /* ********************************************************************************* */
            /* Override modeler canvas scroll to new object */
            canvas.scroll({ dx: +52, dy: -0 }); /* not important if you use large screen */
            /* ********************************************************************************* */            
        });
    };

@Hadi_Jami is this also possible without a Html input element?

@teletobbie Without Html input, you need call browser open dialog API in JavaScript, It’s maybe hard or not successful in any browser like old IE or Chrome.

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API is your friend.

You can do it without input element if you somehow how a local “webserver” or similar to access your filesystem via fetch-request like phillippfromme is suggesting.
this is basically what i have done in this tool: https://github.com/38leinaD/bpmn-diff
The bpmn-io webapp is embeeded in a java application that is hosting a small webserver; in specific, the local files are exposed via Rest resources.

cheers,
daniel