Skip to content

Commit

Permalink
Fixed #4889 - The 'Cannot read properties of undefined (reading 'valu…
Browse files Browse the repository at this point in the history
…e')' exception is thrown when using the Ctrl+Z to reset a calculated field name to the initial value
  • Loading branch information
tsv2013 committed Nov 20, 2023
1 parent fd89b6f commit d4dd1a5
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 6 deletions.
13 changes: 10 additions & 3 deletions packages/survey-creator-core/src/creator-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3005,7 +3005,8 @@ export class CreatorBase extends Base
rootNode.removeEventListener("keydown", this.onKeyDownHandler);
}
}
protected onKeyDownHandler = (event: KeyboardEvent) => {
public findSuitableShortcuts(event: KeyboardEvent): IKeyboardShortcut[] {
const shortcuts: IKeyboardShortcut[] = [];
const availableShortcuts = Object.keys(this.shortcuts || {})
.map((key) => this.shortcuts[key])
.filter((shortcut: IKeyboardShortcut) => !shortcut.affectedTab || shortcut.affectedTab === this.activeTab);
Expand All @@ -3017,8 +3018,14 @@ export class CreatorBase extends Base
if (!!hotKey.ctrlKey !== !!event.ctrlKey) return;
if (!!hotKey.shiftKey !== !!event.shiftKey) return;
if (hotKey.keyCode !== event.keyCode) return;
if ((hotKey.keyCode < 48 || hotKey.keyCode == 89 || hotKey.keyCode == 90) && isTextInput(event.target)) return;
shortcut.execute(this.selectElement);
shortcuts.push(shortcut);
});
return shortcuts;
}
protected onKeyDownHandler = (event: KeyboardEvent) => {
this.findSuitableShortcuts(event).forEach((shortcut: IKeyboardShortcut) => {
if ((event.keyCode < 48 || event.keyCode == 89 || event.keyCode == 90) && isTextInput(event.target)) return;
shortcut.execute(this.selectedElement);
});
}
private shortcuts: { [index: string]: IKeyboardShortcut } = {};
Expand Down
19 changes: 17 additions & 2 deletions packages/survey-creator-core/src/property-grid/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1342,8 +1342,23 @@ export abstract class PropertyGridEditorStringBase extends PropertyGridEditor {
return json;
}
public onCreated(obj: Base, question: Question, prop: JsonObjectProperty, options: ISurveyCreatorOptions) {
question.disableNativeUndoRedo = true;
if(prop.name === "title") {
if (question instanceof QuestionTextBase) {
question.onKeyDownPreprocess = (event: KeyboardEvent) => {
if ((event.ctrlKey || event.metaKey) && [89, 90].indexOf(event.keyCode) !== -1) {
if (question.isInputTextUpdate) {
(options as any).findSuitableShortcuts(event).forEach((shortcut: any) => {
shortcut.execute((options as any).selectedElement);
});
event.preventDefault();
} else if ((event.target as HTMLInputElement).value == question.value) {
(options as any).findSuitableShortcuts(event).forEach((shortcut: any) => {
shortcut.execute((options as any).selectedElement);
});
}
}
}
}
if (prop.name === "title") {
question.allowSpaceAsAnswer = true;
}
if(question.getType() == "textwithreset" || question.getType() == "commentwithreset") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import { PropertyGridEditorMatrixRateValues } from "../../src/property-grid/matr
import { editorLocalization } from "../../src/editorLocalization";
import { SurveyQuestionEditorDefinition } from "../../src/question-editor/definition";
import { PropertyGridModelTester, findSetupAction } from "./property-grid.base";
import { CreatorTester } from "../creator-tester";

test("Check property grid survey options", () => {
const oldValue = Serializer.findProperty(
Expand Down Expand Up @@ -2879,4 +2880,79 @@ test("Allow to enter one space into question title #4416", () => {
const propertyGrid2 = new PropertyGridModelTester(question);
const titleQuestion2 = <QuestionMatrixDynamicModel>(propertyGrid2.survey.getQuestionByName("title"));
expect(titleQuestion2.value).toBe(" ");
});
});

test("Test event prevent default on typing text update mode, fix undo/redo #4889", () => {
const testInput = document.createElement("input");
const fakeInput = document.createElement("input");
document.body.appendChild(testInput);
document.body.appendChild(fakeInput);

const question = new QuestionTextModel("q");
const creator = new CreatorTester();
creator.registerShortcut("undo_test", {
name: "undo",
affectedTab: "designer",
hotKey: {
ctrlKey: true,
keyCode: 90,
},
macOsHotkey: {
keyCode: 90,
},
execute: () => { log += "->undo"; }
});
creator.registerShortcut("redo_test", {
name: "redo",
affectedTab: "designer",
hotKey: {
ctrlKey: true,
keyCode: 89,
},
macOsHotkey: {
keyCode: 89,
},
execute: () => { log += "->redo"; }
});
let propertyGrid = new PropertyGridModelTester(question, creator);
let questionName_RequiredOnBlur = propertyGrid.survey.getQuestionByName("name");
let questionTitle_OnTyping = propertyGrid.survey.getQuestionByName("title");

const eventCtrlZ = {
target: testInput,
keyCode: 90,
ctrlKey: true,
preventDefault: () => { log += "->preventDefaultZ"; }
};
const eventCtrlY = {
target: testInput,
keyCode: 89,
ctrlKey: true,
preventDefault: () => { log += "->preventDefaultY"; }
};

let log = "";
questionName_RequiredOnBlur.onKeyDown(eventCtrlZ);
expect(log).toBe(""); //, "text ctrl+Z for required property - call built-in undo

questionName_RequiredOnBlur.onKeyDown(eventCtrlY);
expect(log).toBe(""); //, "text ctrl+Y" for required property - call built-in redo

testInput.value = questionName_RequiredOnBlur.value;

questionName_RequiredOnBlur.onKeyDown(eventCtrlZ);
expect(log).toBe("->undo"); //, "text ctrl+Z for required property - call creator undo, built-in undo will do nothing for the save values

questionName_RequiredOnBlur.onKeyDown(eventCtrlY);
expect(log).toBe("->undo->redo"); //, "text ctrl+Y" for required property - call creator redo, built-in undo will do nothing for the save values

questionTitle_OnTyping.onKeyDown(eventCtrlZ);
expect(log).toBe("->undo->redo->undo->preventDefaultZ"); //, "comment ctrl+Z" for onTyping property

questionTitle_OnTyping.onKeyDown(eventCtrlY);
expect(log).toBe("->undo->redo->undo->preventDefaultZ->redo->preventDefaultY"); //, "comment ctrl+Y" for onTyping property

testInput.remove();
fakeInput.remove();
});

0 comments on commit d4dd1a5

Please sign in to comment.