In my gojs code, I have a Group
setup such that deletable: false
. This was done so that we can ask the user for confirmation before deleting the group.
Now that deletable
is false, Group
s are no longer removed from a diagram when calling diagram.commandHandler.cutSelection()
I’m thinking there are two paths forward:
- Either I set
deletable: true
and find some way to asynchronously request confirmation from the consuming code before deleting a group, or…
- I override
cutSelection
in some way so that the parts are deleted
The latter would be more straightforward, and I believe I can just directly call diagram.removeParts(arrayOfGroups);
after calling cutSelection
.
Are there downsides to that approach? Or is there a better approach to be taken?
Here’s one way to prevent interactive deletion of groups, without setting Group.deletable to false:
class CustomCommandHandler extends go.CommandHandler {
constructor(init) {
super();
if (init) Object.assign(this, init);
}
deleteSelection() {
let s = "";
this.diagram.selection.each(p => {
if (p instanceof go.Group) {
s += `${p.data.text} (key: ${p.key}) `;
}
})
if (s !== "") {
// Ask asynchronously if OK to delete -- if answer is no, there's nothing to do.
console.log("ask if OK to delete group(s): " + s);
// But if answer is yes, do the deletion by calling CommandHandler.deleteSelection,
// or if the selection might have changed, Diagram.removeParts in a transaction.
} else {
super.deleteSelection();
}
}
}
Install by replacing the standard Diagram.commandHandler:
new go.Diagram(. . ., {
commandHandler: new CustomCommandHandler(),
. . .
})
Oh, that’s better. Thank you
Actually, it is a bad idea to use a call to CommandHandler.canDeleteSelection as an indication of the intent of the user to delete the selected Parts. Any number of buttons might be calling that predicate just to see if it’s possible to delete (in order to show or enable or disable or hide the button), and they need to be able to decide that without giving any suggestion that the user actually wants to delete.
Instead, one has to override CommandHanderl.deleteSelection, because that is the one place where we know that the user wants to delete the selection. If the decision to actually remove some Parts cannot happen synchronously, then this method must not actually do the removal, but wait for the decision to be made and (if yes) then do the removal later within a transaction.
Sorry for my mixup. I have updated the code above.
FYI, CommandHandler.deleteSelection is called not only by doKeyDown for the Delete
and Backspace
keys, but also by the cutSelection command and by the default context menu’s “Delete” button. And there are lots of calls to canDeleteSelection and deleteSelection throughout the samples.