How do You Copy, Cut, and Paste Items in Nodes?

I am wondering how to copy, cut, and paste items in nodes rather than the nodes or links themselves. Essentially, I am looking to replace console.log("copy"); and console.log("cut"); in the code below. Then I would need to figure out how to paste them and am not sure where to begin here:

// finds all selected attributes or fields
function findAllSelectedFields() {
	var fields = [];
	for (var nit = fileDiagram.nodes; nit.next(); ) {
		var node = nit.value;
		var table = node.findObject("FIELDS");
		if (table) {
			for (var iit = table.elements; iit.next(); ) {
				var fieldPanel = iit.value;
				if (fieldPanel.background !== "transparent") fields.push(fieldPanel);
			}
		}
	}
	return fields;
}

// function to copy selected fields
function copyFields(fields) {
	console.log("copy");
}

// function to cut selected fields
function cutFields(fields) {
	console.log("cut");
}

// handles copying
fileDiagram.commandHandler.copySelection = function() {
	var fields = findAllSelectedFields();
	if (fields.length > 0) {  
		copyFields(fields);
	} else {
		x = 0;
		y = 0;
		go.CommandHandler.prototype.copySelection.call(fileDiagram.commandHandler);
	}
};

// handles cutting
fileDiagram.commandHandler.cutSelection = function() {
	var fields = findAllSelectedFields();
	if (fields.length > 0) {  
		cutFields(fields);
	} else {
		x = 0;
		y = 0;
		go.CommandHandler.prototype.cutSelection.call(fileDiagram.commandHandler);
	}
};

I imagine you want to do something along these lines (I did this based on the Selectable Fields sample, which I imagine you adapted from):

myDiagram.commandHandler.copySelection = function() {
  var items = findAllSelectedItems();
  if (items.length > 0) {  // if there are any selected items, save them to a clipboard
    myDiagram.commandHandler._itemClipboard = items;
  } else {  // otherwise just copy nodes and/or links, as usual
    go.CommandHandler.prototype.copySelection.call(myDiagram.commandHandler);
  }
}

myDiagram.commandHandler.pasteSelection = function() {
  var itemClipboard = myDiagram.commandHandler._itemClipboard;
  var pasteTarget = myDiagram.selection.first();  // assumes a single node is selected, may need to be changed
  if (itemClipboard && itemClipboard.length > 0 && pasteTarget instanceof go.Node) {
    myDiagram.startTransaction("paste items");
    for (var i = 0; i < itemClipboard.length; i++) {
      var panel = itemClipboard[i];
      var itemdata = panel.data;
      var fields = pasteTarget.data.fields;
      myDiagram.model.addArrayItem(fields, itemdata);  // add the copied panel's data to the selected node's fields
    }
    myDiagram.commitTransaction("paste items");
  } else {  // otherwise just paste nodes and/or links, as usual
    go.CommandHandler.prototype.pasteSelection.call(myDiagram.commandHandler);
  }
}

Cut should just work since it a basically a copy combined with a delete. You probably also want to override canCopySelection and canPasteSelection to check the conditions. This could be improved to only store the copied panel’s data instead of the whole panel, but I’ll leave that to you.

Sweet! This worked. I had to change this:

if (items.length > 0) {  // if there are any selected items, save them to a clipboard
  myDiagram.commandHandler._itemClipboard = items;			 
} else {  // otherwise just paste nodes and/or links, as usual
  go.CommandHandler.prototype.copySelection.call(myDiagram.commandHandler);
}

…to the following. This is so that I could copy items without having copied a node first and then resetting the copy so I could copy nodes again:

if (items.length > 0) {  // if there are any selected items, save them to a clipboard
  myDiagram.commandHandler._itemClipboard = items;			 
  go.CommandHandler.prototype.copySelection.call(myDiagram.commandHandler);
} else {  // otherwise just paste nodes and/or links, as usual
  myDiagram.commandHandler._itemClipboard = null;
  go.CommandHandler.prototype.copySelection.call(myDiagram.commandHandler);
}