React Diagram - Restrict Operations
The Diagram UI component raises the requestEditOperation event every time a user attempts an edit operation. This article contains code samples that demonstrate how to use this event's parameters to prohibit individual edit operations and customize a shape collection in the toolbox and context toolbox.
Refer to the following section for more information on the requestEditOperation event's parameters: Prohibit Individual Operations.
Prohibit Creating Loops
The example below demonstrates how to prevent users from connecting a shape to itself:
- import React from 'react';
- import Diagram from 'devextreme-react/diagram';
- class App extends React.Component {
- constructor(props) {
- super(props);
- this.diagramRef = React.createRef();
- this.onRequestEditOperation = this.onRequestEditOperation.bind(this);
- }
- onRequestEditOperation(e) {
- if (e.operation === 'changeConnection')
- if (e.args.connector && e.args.connector.fromId === e.args.connector.toId)
- e.allowed = false;
- }
- render() {
- return (
- <Diagram id="diagram" ref={this.diagramRef} onRequestEditOperation={this.onRequestEditOperation}>
- </Diagram>
- );
- }
- }
- export default App;
Prohibit Adding Shapes Twice
The example below demonstrates how to prevent users from adding more than one shape of each type to a chart:
- import React from 'react';
- import Diagram, { ContextToolbox,} from 'devextreme-react/diagram';
- var currentShapeId;
- class App extends React.Component {
- constructor(props) {
- super(props);
- this.diagramRef = React.createRef();
- this.onRequestEditOperation = this.onRequestEditOperation.bind(this);
- }
- onRequestEditOperation(e) {
- if (e.operation === 'addShape') {
- // Gets types of shapes the chart contains
- var itemsTypes = e.component.getItems().filter(function(item) {
- return (item.itemType === "shape") && (item.id !== e.args.shape.id);
- }).map(a => a.type);
- // Cancels the operation if the chart contains a shape with the same type as the shape that is about to be added
- if (itemsTypes.indexOf(e.args.shape.type) !== -1) {
- e.allowed = false;
- return;
- }
- }
- }
- render() {
- return (
- <Diagram id="diagram" ref={this.diagramRef} onRequestEditOperation={this.onRequestEditOperation} >
- </Diagram>
- );
- }
- }
- export default App;
See Also
Remove Shapes from Toolboxes
In the example below, the Diagram component updates the shape collection in the toolbox and context toolbox as follows:
- Removes a shape from these toolboxes after a user adds it to a chart
- Returns a shape to these toolboxes after a user deletes it from a chart
- import React from 'react';
- import Diagram from 'devextreme-react/diagram';
- var shapeCount;
- class App extends React.Component {
- constructor(props) {
- super(props);
- this.diagramRef = React.createRef();
- this.onRequestEditOperation = this.onRequestEditOperation.bind(this);
- this.onOptionChanged = this.onOptionChanged.bind(this);
- }
- onOptionChanged(e) {
- // Detects changes of the Diagram model
- if (e.name === "hasChanges" && e.value) {
- e.component.option("hasChanges", false);
- var currentShapeCount = e.component.getItems().filter(function(item) {
- return (item.itemType ==="shape")
- }).length;
- // Updates the toolbox and context toolbox if a shape was added or deleted
- if (this.shapeCount !== currentShapeCount) {
- this.shapeCount = currentShapeCount;
- window.setTimeout(function() {
- e.component.updateToolbox();
- }, 0);
- }
- }
- }
- onRequestEditOperation(e) {
- if (e.operation === "addShapeFromToolbox") {
- e.component.getItems().forEach(function(item) {
- // Removes a shape from the toolboxes if the chart contains a shape of this type
- if (item.itemType === "shape" && item.type === e.args.shapeType)
- e.allowed = false;
- });
- }
- }
- render() {
- return (
- <Diagram id="diagram" ref={this.diagramRef} onRequestEditOperation={this.onRequestEditOperation} onOptionChanged={this.onOptionChanged}>
- </Diagram>
- );
- }
- }
- export default App;
See Also
Prohibit Moving Shapes Between Containers
The example below demonstrates how to prevent users from moving a shape from one container to another:
- import React from 'react';
- import Diagram, from 'devextreme-react/diagram';
- var containerIds = {};
- class App extends React.Component {
- constructor(props) {
- super(props);
- this.diagramRef = React.createRef();
- this.onRequestEditOperation = this.onRequestEditOperation.bind(this);
- this.onSelectionChanged = this.onSelectionChanged.bind(this);
- }
- onRequestEditOperation(e) {
- if (e.operation === "moveShape")
- // Cancels the operation if a user moves a shape outside its container.
- if (containerIds[e.args.shape.id] !== e.args.shape.containerId)
- e.allowed = false;
- }
- onSelectionChanged(e) {
- e.component.getItems().forEach(item => {containerIds[item.id] = item.containerId;});
- }
- render() {
- return (
- <Diagram id="diagram" ref={this.diagramRef} onRequestEditOperation={this.onRequestEditOperation} onSelectionChanged={this.onSelectionChanged}>
- </Diagram>
- );
- }
- }
- export default App;
Customize Shape Collection in the Context Toolbox
The following example demonstrates how to hide shapes in the context toolbox depending on the connector's start node type:
- import React from 'react';
- import Diagram, { ContextToolbox,} from 'devextreme-react/diagram';
- var currentShapeId;
- class App extends React.Component {
- constructor(props) {
- super(props);
- this.diagramRef = React.createRef();
- this.onRequestEditOperation = this.onRequestEditOperation.bind(this);
- }
- onRequestEditOperation(e) {
- if (e.operation === 'changeConnection' && e.args.connector)
- // Gets the connector's start node identifier
- this.currentShapeId = e.args.connector.fromId;
- if (e.operation === 'addShapeFromToolbox') {
- // Gets the connector's start node type
- var currentShape = e.component.getItemById(this.currentShapeId);
- if (e.args.shapeType === 'terminator')
- // If the connector's start node type is "decision"
- if (currentShape && currentShape.type === 'decision')
- // Hides the "terminator" shape in the context toolbox
- e.allowed = false;
- }
- }
- render() {
- return (
- <Diagram id="diagram" ref={this.diagramRef} onRequestEditOperation={this.onRequestEditOperation} >
- <ContextToolbox shapeIconsPerRow={3} width={100} shapes={['process', 'decision', 'terminator']}>
- </ContextToolbox>
- </Diagram>
- );
- }
- }
- export default App;
If you have technical questions, please create a support ticket in the DevExpress Support Center.