Prevent Palette Node Drag

Hello, I’ve been looking and looking through all existing Posts and can’t find my desired solution.

I need to allow a Palette Node to be copied onto the Diagram once. Once it exists in the Diagram we want lock it (prevent drag) in the Palette and change its color to a disabled grey color. We can remove the Node but we do not want to remove it, we want to disable it. We could prevent the copying but we don’t want to, we want to prevent the DRAG from starting after a COPY.

If the user deletes the copied Node from the Diagram, the Palette Node becomes enabled once again and so on etc.

We are already changing its color, but I can’t figure out the nodeDataArray Node prop that needs to be set to false to prevent its drag.

Thank you!

I think you want to set or bind Part.copyable to false.

Thank you, that didn’t work though…

nodeDataArray.forEach((node: any, i: number) => {
			if (node.category === goJsCategory.ImportNode) {
				const index = templatePaletteData.findIndex(
					(el: any) => el.text === node.text
				);
				paletteData[index].fill = '#ccc';
				paletteData[index].copyable = false;
			}
		});

What are those variables and when do you execute that code?

If those Arrays are of node data objects in a Model, you have to call Model.set in order to make any data property changes.

How do I call Model.set within this context? I’ve never had to call this method before… the code block I’m working in is currently in a useEffect hook, and the ReactDiagram implementation is in a child component so, I’m not sure how I’d get to the Model instance so I could call the method…

nodeDataArray is the ReactDiagram Array for the prop nodeDataArray.

<ReactDiagram nodeDataArray={nodeDataArray} />

paletteData is the ReactPalette Array for the prop nodeDataArray.

<ReactPalette nodeDataArray={paletteData} />

Here’s the entire useEffect code block

useEffect(() => {
		// If initial run, declare Ghost and Empty nodes
		const nodeDataArray = diagramData?.nodeDataArray?.length
			? diagramData?.nodeDataArray
			: [ghostNode, emptyNode];

		// Stringify and parse to deep copy so it can modify object
		const paletteData = JSON.parse(JSON.stringify(templatePaletteData));

		// Iterate to find existing Import Nodes, change its fill color
		nodeDataArray.forEach((node: any, i: number) => {
			if (node.category === goJsCategory.ImportNode) {
				const index = paletteData.findIndex(
					(el: any) => el.text === node.text
				);
				paletteData[index].fill = '#ccc';
				paletteData[index].copyable = false;
			}
		});

		goJsTemplatesStateRef.current = {
			selectedTemplateNode,
			diagramData: {
				linkDataArray: diagramData?.linkDataArray,
				nodeDataArray,
			},
			editingTemplate,
			templatePaletteData: paletteData,
			selectedDocletTypeNode,
		};

		// Force Render Cycle
		forceRenderCycle(Date.now());
	}, [
		diagramData,
		editingTemplate,
		templatePaletteData,
		selectedDocletTypeNode,
		selectedTemplateNode,
	]);

You hadn’t mentioned React before. If I understand you correctly, you are modifying some data that has not yet been passed to the Diagram component, so that is OK – you are not modifying data in use by the Diagram or its Model.

Do your Node template(s) in the Palette have bindings like this?

new go.Binding("copyable")