nikku / bpmn-js-copy-paste-example

An example how to copy and paste between multiple instances of bpmn-js
5 stars 0 forks source link
bpmn-js modeler

bpmn-js-copy-paste-example

CI

This example shows how to copy and paste elements programatically using bpmn-js.

pasted screenshot

Features

How it works

You need the BPMN Modeler to use copy and paste.

Copy

To copy an element, specify it via its elementId. From that point on, we'll use only APIs the BPMN modeler provides:

// element to be copied
var elementId = ...;

var clipboard = modeler.get('clipboard'),
    copyPaste = modeler.get('copyPaste'),
    elementRegistry = modeler.get('elementRegistry');

// get element to be copied
var element = elementRegistry.get(elementId);

// copy!
copyPaste.copy(element);

// retrieve clipboard contents
var copied = clipboard.get();

// persist in local storage, encoded as json
localStorage.setItem('bpmnClipboard', JSON.stringify(copied));

Paste

To paste an element we need to specify the target, as well as the location where the element needs to be pasted:

// to be pasted onto...
var targetId = ...;
var position = ...;

var clipboard = modeler.get('clipboard'),
    copyPaste = modeler.get('copyPaste'),
    elementRegistry = modeler.get('elementRegistry'),
    moddle = modeler.get('moddle');

// retrieve from local storage
var serializedCopy = localStorage.getItem('bpmnClipboard');

// parse tree, reinstantiating contained objects
var parsedCopy = JSON.parse(serializedCopy, createReviver(moddle));

// put into clipboard
clipboard.set(parsedCopy);

// paste tree directly
copyPaste.paste({
  element: elementRegistry.get(targetId),
  point: position
});

// alternatively paste using two-step pasting
copyPaste.paste();

The Paste Catch

During JSON parsing of the serialized copy tree, we use a reviver function to re-construct model types:

function createReviver(moddle) {

  var elCache = {};

  /**
   * The actual reviewer that creates model instances
   * for elements with a $type attribute.
   *
   * Elements with ids will be re-used, if already
   * created.
   *
   * @param  {String} key
   * @param  {Object} object
   *
   * @return {Object} actual element
   */
  return function(key, object) {

    if (typeof object === 'object' && typeof object.$type === 'string') {

      var objectId = object.id;

      if (objectId && elCache[objectId]) {
        return elCache[objectId];
      }

      var type = object.$type;
      var attrs = Object.assign({}, object);

      delete attrs.$type;

      var newEl = moddle.create(type, attrs);

      if (objectId) {
        elCache[objectId] = newEl;
      }

      return newEl;
    }

    return object;
  };
}

Checkout the full example here.

Run the Example

# install dependencies
npm install

# run in browser
npm run dev

Open multiple instances of the test site and copy/paste across.

License

MIT

:heart: