Possibility of appending Service Task instead of Task by clicking the start element


#1

If I click the “start”-element in the bpmn editor, I can choose different append actions.
Is there an option to replace the default normal task against a service task?

What I tried is:

  • Adding a eventhandler for “shape.added”
  • Use modeler.get(‘modeling’).updateProperties and set the type to “bpmn:ServiceTask” if the given element is from type “bpmn:Task”

but then I become an error:
"illegal invocation in or phase (action: element.updateProperties)

I can change the type in the eventhandler for “element.changed” but then I need to click out of the element and jump in again to see the changes. I want to see the changes directly.


#2

Hi @qingshu

Please share a running / prototypical example that clearly shows what you’re trying to achieve, what is working and what is not.

Use our existing starter projects to quickly hack it or share your existing, partial solution on GitHub. Provide the necessary pointers that allow us to quickly understand where you got stuck.

This way we may be able to help you in a constructive manner.

Thanks :heart:


#3

Thanks for your response.

example

Instead of adding a normal “Task”, we want to add a “ServiceTask” by default.

I tried to change the type of the “Task” to a “ServiceTask” after adding the “Task” shape, what not worked.
But actually I found some examples to modify the editor, so may the better solution would be to modify the editor instead of change the element type after the shape was added!?

Unfortunately I can`t use git at this Moment, but I hope my codesnippets would help to understand.
If not, let me know and i will find a solution to share the full code.
My index.js was build with npm and grunt. I dont know If this is best practise, cause as you can see I need a wrapper object to call modeler methods in the index.html, but it works fine.

index.html

<!DOCTYPE HTML>
<html>
	<head>
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta charset="UTF-8" />
		<title>Test</title>
		
		<link rel="stylesheet" href="css/diagram-js.css" />
		<link rel="stylesheet" href="vendor/bpmn-font/css/bpmn-embedded.css" />
		<link rel="stylesheet" href="css/app.css" />
	</head>
	<body onload="BPMNImpl.openDiagram('');">
		<div id="js-drop-zone">	
			<div class="canvas" id="js-canvas" style="height: 500px;">
			</div>
		</div>	
	
		<script>
			var BPMNImpl = {
				mModeler : undefined,
				setModeler : function(  pModeler ) {
					mModeler = pModeler;
				},
				openDiagram: function(xml) {
					mModeler.openDiagram(xml);
				},
				registerEventHandler : function( pEvent, pFunction ) {
					mModeler.registerEvent( pEvent, pFunction );
				},
				changeToServiceTask : function ( pElement ) {
					mModeler.changeToServiceTask(pElement);
				}	
			}
		</script>
		
		<script src="index.js"></script>
		
		<script>
			function handler(event, pElement) {
				console.log("Handler called.");
				if (pElement.element !== undefined && pElement.element.type === "bpmn:Task" ) {
					// Here we become an error.
					BPMNImpl.changeToServiceTask(pElement);
				}
			}

			function handler2( event, pElement ) {
				console.log("Handler2 called.");
				if (pElement.element !== undefined && pElement.element.type === "bpmn:Task" ) {
					// This works! But I need to click out of the element and then click the element again
					// it does not change direct.
					//BPMNImpl.changeToServiceTask(pElement);
				}
			}

			BPMNImpl.registerEventHandler( "element.click", handler );
			BPMNImpl.registerEventHandler( "shape.added", handler );
			BPMNImpl.registerEventHandler( "element.changed", handler2 );
			
		</script>
	</body>
</html>

index.js - snipped of the my “compiled” version with grunt. at the end your code follows and is not displayed…
based on bpmn-js 1.0.1

(function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()({1:[function(require,module,exports){
'use strict';

var MyModeler = {
		
		initialDiagram : '<?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:di="http://www.omg.org/spec/DD/20100524/DI" ' +
					                    'xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" ' +
					                    'xmlns:camunda="http://camunda.org/schema/1.0/bpmn" ' +
					                    'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
					                    'id="Definitions_1" ' +
					                    'targetNamespace="http://bpmn.io/schema/bpmn" >' +                   
					    '<bpmn:process id="Process_1" isExecutable="true">' +
					      '<bpmn:startEvent id="StartEvent_1"/>' +
					    '</bpmn:process>' +
					    '<bpmndi:BPMNDiagram id="BPMNDiagram_1">' +
					      '<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">' +
					        '<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">' +
					          '<dc:Bounds height="36.0" width="36.0" x="173.0" y="102.0"/>' +
					        '</bpmndi:BPMNShape>' +
					      '</bpmndi:BPMNPlane>' +
					    '</bpmndi:BPMNDiagram>' +
					  '</bpmn:definitions>',

		openDiagram : function( pXML ) {
			console.log("Open Diagram: " + pXML);
			if ( pXML === undefined || pXML === "" ) {
				pXML = MyModeler.initialDiagram;
			}
			modeler.importXML( pXML, function( err ) {
				if ( err ) {
					$( '#js-drop-zone' ).removeClass( 'with-diagram' ).addClass( 'with-error' );
					$( '#js-drop-zone' ).find('.error pre').text( err.message );
					console.error( err );
				} else {
					console.log("Diagram loaded");
					$('#js-drop-zone').removeClass( 'with-error' ).addClass( 'with-diagram' );
				}
			});
		},

		changeToServiceTask : function( pElement ) {
			pElement.element.type = "bpmn:ServiceTask";
			var elementRegistry = modeler.get( 'elementRegistry' );
			var elementRegistryEntry = elementRegistry.get( pElement.element.id );
			modeler.get( 'modeling' ).updateProperties( elementRegistryEntry, { type: "bpmn:ServiceTask" } );
		},

		registerEvent : function( event, handler ) {
			var eventBus = modeler.get( 'eventBus' );
			eventBus.on( event, handler );
		}
};

var $ = require( 'jquery' ),
BpmnModeler = require( 'bpmn-js/lib/Modeler' );

try {
	BPMNImpl.setModeler( MyModeler );
}
catch ( err ) {
	console.error( "Error setting Modeler: " + err );
}

var modeler = new BpmnModeler( {
	container: $( '#js-canvas' ), 
	moddleExtensions: {
		camunda: require('camunda-bpmn-moddle/resources/camunda')
	}
	} );
},{"bpmn-js/lib/Modeler":2,"camunda-bpmn-moddle/resources/camunda":114,"jquery":295}],2:[function
....

This is the error, I get If I drop/add a “Task” to the diagram.
error


#4

So first of all the error message illegal invocation in <execute> or <revert> phase means that you tried to execute a command while another command was being executed/reverted. You can only execute additional commands before or after these phases. Read more about it in the CommandStack.

The solution in you case would be to change the type of shape that is being created through using the palette and the context pad.