Remove overlay when removing element

Hello,

my problem is I dont know how to delete an overlay, if a user removes the corresponding element from the diagram.
I am adding an overlay if a user sets an attribute on a specific element (cp:EvidenceGateway -> Attribute “evidence-level”). If it is set to [A,B,C,D,E,F] it should display an overlay to the selected element with the selected value.

My code how I add the overlay:

 eventBus.on('element.changed', function (event) {

    console.log(event);
    console.log("add");

    var element = event.element,
        bo = element.businessObject;

    if (isAny(bo, ['cp:Task', 'cp:EvidenceGateway']) && element.type != "label") {

        if (evidenceLevel.includes(bo.get('evidence-level').toUpperCase())) {
            bo.set('evidence-level', bo.get('evidence-level').toUpperCase());

            overlays.clear({element: element});

            var overlay_id = overlays.add(element, {
                position: {
                    top: -20,
                    left: element.width - 10,
                },
                html: $('<div class="cp-evidence-marker">').text(bo.get('evidence-level'))
            });

        } else {
            overlays.remove({element: element});
            bo.set('evidence-level', '');
        }

    }
});

I tried to hook into eventBus.on(‘shape.deleted’)… But after that event gets fired, the element.changed event will be fired too. Is there a way to recognize, that a user has deleted the particular element in the “element.changed” listener function? Or is there a way to delete an overlay if the corresponding element gets deleted?

Thank you for your help.
mfuesslin

Overlays should be automatically removed on element deletion. Do you experience a different behavior?

Yes. I think the problem is, that the element.changed event gets also fired if the particular element was removed. In that case i cannot check if the intent of element.changed is a modification or removal…

I fixed it now. It is weird because the only thing I changed is, that I pass “element.id” to overlays.add() and overlays.remove() instead of “element”.

eventBus.on('element.changed', 100, function (event) {

    var element = event.element,
        bo = element.businessObject;
    
    if (isAny(bo, ['cp:Task', 'cp:EvidenceGateway']) && element.type != "label") {

        if (evidenceLevel.includes(bo.get('evidence-level').toUpperCase())) {
            bo.set('evidence-level', bo.get('evidence-level').toUpperCase());


            try {
                var overlay_id = overlays.add(element.id, {
                    position: {
                        top: -20,
                        left: element.width - 10
                    },
                    html: $('<div class="cp-evidence-marker">').text(bo.get('evidence-level'))
                });
            } catch(e) {
                // this will break if element was removed... No one knows how to properly do that.
            }

        } else {
            overlays.remove({element: element.id});
            bo.set('evidence-level', '');
        }

    }
});

I had a similar problem. When you call

overlays.remove(overlayId);

It removes the object from the DOM and when you try to include the object HTML again it doesn’t exist anymore. I don’t know the best solution but I change to create a new object every time instead of using jquery.

overlayId = overlays.add(element.id, {
        html: `<select id="js-select-task" name="tasks">
                <option value=""></option>
                <option value="task1">TASK 1</option>
                <option value="task2">TASK 2</option>
                <option value="task3">TASK 3</option>
                <option value="task4">TASK 4</option>
              </select>`
      ,
        position: {
          right: 100,
          bottom: 50
        }
      });

instead of

var overlayId = overlays.add(element.id, {
        html: $('#js-select-task'),
        position: {
          right: 100,
          bottom: 50
        }
      });

I found another solution.
First I create the code html like this

  <div id='parent-js-select-task'>        
          <select id="js-select-task" name="tasks">
                <option value=""></option>
                <option value="task1">TASK 1</option>
                <option value="task2">TASK 2</option>
                <option value="task3">TASK 3</option>
                <option value="task4">TASK 4</option>
              </select>
</div>

and before call the remove method I called this

 $("#js-select-task").detach().appendTo("#parent-js-select-task");