Edit Next TextBlock when Hitting Tab & Change Textarea to Match the Size of the TextBlock

I have two questions:

  1. Is it possible to use tab to move to the next textblock when editing text? For example in the image below, I want to start editing the word VARCHAR after hitting tab. Hitting tab again would move to the next row and first column. Finally, when in the last row and column, hitting tab would move to the first row and column.

  2. In the image above, is it possible to have the editing textarea match the size of the textblock behind it? UPDATE: I realize that this was being set by my CSS. I made the change; however, I am wondering how to have it match the background. For example, how do you get it to be blue when editing GROUP and the lighter blue when editing a field.

Thanks in advance for any help.

If you want to customize the in-place text editor, I suggest that you read GoJS HTML Interaction -- Northwoods Software and HTMLInfo Text Editor and especially https://gojs.net/latest/extensions/TextEditor.js, where you can see how the editor is defined and how it is styled.

My first question is what I need the most help with. Any ideas how to address my first question?

For the second question, I have looked through those documents and am still struggling. the textEditor is just slightly off from where I want it so I am trying to modify the top and left styles. I tried (I have also tried doStart and canStart):

fileDiagram.toolManager.textEditingTool.doActivate = function() {
	textEditor = this.defaultTextEditor.mainElement;
	textEditor.style.left = (parseInt(textEditor.style.left, 10) + 4) + "px";
	textEditor.style.top = (parseInt(textEditor.style.top, 10) + 1) + "px";
	return go.TextEditingTool.prototype.doActivate.call(this);

However, this doesn’t change before loading the texteditor. How do I change it before loading the textEditor? Do I need to change the textEditor.js file?

I also need a dynamic background based on the textBlock. I know how to change the background for everything but I want this to be more dynamic depending on the background of the textblock.

You can see how keyboard input is handled in that extensions/TextEditor.js file. In fact it already handles the TAB key – you just need to do some additional work to start editing another TextBlock. I can’t help you decide which one (if any) to start editing next, but once you have that TextBlock you could call CommandHandler.editTextBlock from within a setTimeout function.

Okay thank you. I was able to adjust the location using the TextEditior extension.

You say you can’t help me decide which textblock to start editing next which is fine, but how would I even find any blocks to edit. For example, with the following code, what would I add in place of /***** textblock *****/:

fileDiagram.commandHandler.doKeyDown = function() {
	var e = fileDiagram.lastInput;
	if (e.key == '	') { // tab key
		fileDiagram.CommandHandler.editTextBlock(/***** textblock *****/);

You’ll have to walk the visual tree to look for other TextBlocks.

Use GraphObject.panel to get the containing Panel, use Panel.elt to get a particular element of a Panel or Panel.elements to iterate over all of them.

Sweet! It worked.

Here is my modified code of https://gojs.net/latest/extensions/TextEditor.js for anyone who is looking to do the same in the future:

textarea.addEventListener('keydown', function(e) {
	var tool = TextEditor.tool;
	if (tool.textBlock === null) return;
	var keynum = e.which;

	// checks if the enter key is pressed and accepts the text
	if (keynum === 13) {
		if (tool.textBlock.isMultiline === false) e.preventDefault();
	// checks if the tab key is pressed and toggles forward through all the text blocks
	} else if (keynum === 9) {
		var initialTextObject = "", finalTextObject = "", textObject = "", tempTextObject = "";
		var diagram = tool.diagram;
		var fields = tool.textBlock.panel.part.findObject("FIELDS");
		var foundBlock = false;
		var index = 0;
		// checks if the shift key is pressed at the same time and cycles in reverse
		if (e.shiftKey) {
			fields.elements.each(function(field) {
				if (index == fields.elements.count - 1) {
					finalTextObject = field.findObject("DATATYPE");
					if (textObject == "") textObject = finalTextObject;
				if (tool.textBlock == field.findObject("DATATYPE")) {
					textObject = field.findObject("FIELD");
				} else if (tool.textBlock == field.findObject("FIELD")) {
					textObject = tempTextObject;
				} else {
					tempTextObject = field.findObject("DATATYPE");
				index += 1;

		// cycles forward
		} else {
			fields.elements.each(function(field) {
				if (index == 0) {
					initialTextObject = field.findObject("FIELD");
				if (tool.textBlock == field.findObject("FIELD")) {
					textObject = field.findObject("DATATYPE");

				} else if (tool.textBlock == field.findObject("DATATYPE")) {
					foundBlock = true;
					if (index == fields.elements.count - 1) {
						textObject = initialTextObject;
						foundBlock = false;
				} else if (foundBlock) {
					textObject = field.findObject("FIELD");
					foundBlock = false;
				index += 1;
		if (textObject != "") diagram.commandHandler.editTextBlock(textObject);

	// cancels the editing if the escape key is pressed
	} else if (keynum === 27) {
		if (tool.diagram !== null) tool.diagram.doFocus();
}, false);

…and here is an example of what I am cycling through:

Thank you!