Skip to content

Commit 7bfc5af

Browse files
committed
refactor(json-editor): Enhance JSON change tracking and validation synchronization
Signed-off-by: Giovanni Magliocchetti <[email protected]>
1 parent b03f939 commit 7bfc5af

File tree

2 files changed

+35
-21
lines changed

2 files changed

+35
-21
lines changed

packages/survey-creator-core/src/components/tabs/json-editor-plugin.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ export abstract class JsonEditorBaseModel extends Base {
3737
this.isJSONChanged = false;
3838
}
3939
protected onTextChanged(): void {
40-
// Mark that JSON has changed
40+
// Mark that JSON text has been modified. This flag serves two purposes:
41+
// 1. Triggers the error validation timeout (processErrors) for immediate user feedback
42+
// 2. Indicates to deactivate() or syncJsonEditorText() that validation is needed
43+
// Note: This does NOT mean the JSON is valid - validation occurs later before sync
4144
this.isJSONChanged = true;
4245

4346
if (this.jsonEditorChangedTimeoutId !== -1) {

packages/survey-creator-core/src/creator-base.ts

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3301,44 +3301,55 @@ export class SurveyCreatorModel
33013301
if (!!this.getSurveyJSONTextCallback) {
33023302
return this.getSurveyJSONTextCallback().text;
33033303
}
3304-
3305-
// If we're on the JSON editor tab, get the text directly from the plugin
3306-
// This is necessary because the JSON editor only syncs text on deactivate, which causes
3307-
// issues when trying to save while still on the JSON tab
3308-
if (this.activeTab === "json") {
3309-
const jsonPlugin = this.getPlugin("json");
3310-
if (
3311-
jsonPlugin &&
3312-
(jsonPlugin as any).model &&
3313-
(jsonPlugin as any).model.text
3314-
) {
3315-
return (jsonPlugin as any).model.text;
3316-
}
3317-
}
3318-
33193304
return this.getSurveyTextFromDesigner();
33203305
}
33213306
public set text(value: string) {
33223307
this.changeText(value, true);
33233308
}
33243309

33253310
/**
3326-
* Force synchronization of JSON editor text to the creator.
3327-
* This should be called before operations that need the latest JSON text,
3328-
* such as saving or validation, when the JSON editor tab is active.
3311+
* Synchronizes JSON editor text to the creator with validation.
3312+
* This method should be called before operations that need the latest JSON text,
3313+
* such as saving, when the JSON editor tab is active.
3314+
*
3315+
* @returns `true` if synchronization succeeded (JSON is valid) or no sync was needed,
3316+
* `false` if JSON validation failed (indicates errors that must be fixed)
3317+
*
3318+
* Example usage:
3319+
* ```typescript
3320+
* if (!creator.syncJsonEditorText()) {
3321+
* // Show error: "Please fix JSON errors before saving"
3322+
* return;
3323+
* }
3324+
* // Proceed with save - JSON is validated and synced
3325+
* const json = creator.text;
3326+
* ```
33293327
*/
3330-
public syncJsonEditorText(): void {
3328+
public syncJsonEditorText(): boolean {
33313329
if (this.activeTab === "json") {
33323330
const jsonPlugin = this.getPlugin("json") as any;
33333331
if (jsonPlugin?.model?.isJSONChanged && !jsonPlugin.model.readOnly) {
3332+
// Use the same validation logic as tab switching (deactivate)
3333+
// This ensures we only sync valid JSON to maintain data integrity
3334+
const canDeactivate = jsonPlugin.defaultAllowingDeactivate();
3335+
3336+
// undefined = JSON is syntactically invalid (cannot parse)
3337+
// false = JSON has validation errors
3338+
// true = JSON is valid and can be synced
3339+
if (canDeactivate !== true) {
3340+
return false; // Validation failed, do not sync
3341+
}
3342+
3343+
// Validation passed - safe to sync the JSON
33343344
const jsonText = jsonPlugin.model.text;
33353345
if (jsonText) {
3336-
// Update the creator's text without triggering the usual change flow
33373346
this.changeText(jsonText, false, true);
33383347
jsonPlugin.model.isJSONChanged = false;
33393348
}
33403349
}
33413350
}
3351+
// Return true if not on JSON tab or no changes (safe to proceed)
3352+
return true;
33423353
}
33433354

33443355
public getSurveyJSON(): any {

0 commit comments

Comments
 (0)