Saving additional data to a custom react-flow node

1k Views Asked by At

I want to save additional data for the custom node, I used this article for creating a custom node using additional data.

Custom node:

import { useState } from 'react';
import { Handle, Position } from 'react-flow-renderer';
import { Modal } from "react-bootstrap";
import {  Form } from 'react-bootstrap';
import { triggerLimitationType } from "../../../enums/triggerLimitationType";
import _ from 'lodash';
import i18next from "../../../i18n";

function CustomNode({ data }) {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
const defaultValues = { type: 0 };
const [formData, setFormData] = useState(defaultValues);
const handleChange = event => {
    const name = event.target.name;
    const value = event.target.value;
    setFormData(values => ({ ...values, [name]: value }))
    data.attribute = formData;
}

return (
    <row>
        <div onDoubleClick={handleShow}>
            <Handle type="target" position={Position.Top} />
            <div className="node-icon" >
                <i className="feather icon-skip-back"></i>
            </div>
            <Handle type="source" position={Position.Bottom} id="b" />
        </div>

        {show && (
            <Modal show={show} onHide={handleClose} className="right fade">
                <Modal.Header closeButton>
                    <Modal.Title>{i18next.t("Trigger")} : {i18next.t("VisitorReturn")}      </Modal.Title>
                </Modal.Header>

                <Modal.Body>
                    <Form.Group >
                        <Form.Label>Type</Form.Label>
                        <Form.Control required as="select" placeholder="Enter Name" value={formData.type} name="type" onChange={handleChange} >
                            {_.map(triggerLimitationType, (value, key) => (
                                <option value={value} key={value}>{key}</option>
                            ))}
                        </Form.Control>
                        <Form.Control.Feedback type="invalid">Please choose a type.</Form.Control.Feedback>
                    </Form.Group>
                </Modal.Body>
            </Modal>
        )}
    </row>
  );
 }

export default CustomNode;

Created node:

 const onDrop = (event) => {
    event.preventDefault();

    const reactFlowBounds = reactFlowWrapper.current.getBoundingClientRect();
    const type = event.dataTransfer.getData("type");
  
    const position = reactFlowInstance.project({
        x: event.clientX - reactFlowBounds.left,
        y: event.clientY - reactFlowBounds.top
    });
    console.log("event", event.dataTransfer);
    const newNode = {
        id: getId(),
        position,
        type: type,
        data: {
            label: `${type} node`, attribute: {
                type: 0
            } }
    };
    // setElements((es) => es.concat(newNode));
    setElements([...elements, newNode]);
    // onSave();
    dispatch(updateElements(newNode));
    console.log("ONDROP", elements);
};

But when I set the value for an attribute, I get the error: "attribute" is read-only.

1

There are 1 best solutions below

0
On

I have added onDragStart event to the custom node .Inside the onDragStart function set the desired key and value like

    const onDragStart = (event: any, nodeType: any, node: any) => {
        event.dataTransfer.setData('name', node);
    };

In the onDrop function you can access this name like this

     event.dataTransfer.getData('name')