diff --git a/demo/tiddlers/MyExampleTask.tid b/demo/tiddlers/MyExampleTask.tid index 4e6a0b1..eeea4b7 100644 --- a/demo/tiddlers/MyExampleTask.tid +++ b/demo/tiddlers/MyExampleTask.tid @@ -4,4 +4,9 @@ modified: 20230218103716732 modifier: 林一二 tags: Task ColorAndCounter title: MyExampleTask -type: text/vnd.tiddlywiki \ No newline at end of file +type: text/vnd.tiddlywiki + +<$button> + Update complete counter + <$action-setfield tiddler=<> completedCount="1" /> + \ No newline at end of file diff --git a/src/widgets/supertag-form/index.ts b/src/widgets/supertag-form/index.ts index 2f3e026..7a5bec8 100644 --- a/src/widgets/supertag-form/index.ts +++ b/src/widgets/supertag-form/index.ts @@ -1,23 +1,18 @@ import type { IChangedTiddlers } from 'tiddlywiki'; -import * as JSONEditor from '@json-editor/json-editor'; +import type * as JSONEditor from '@json-editor/json-editor'; import 'spectre.css/dist/spectre.min.css'; import 'spectre.css/dist/spectre-icons.css'; import 'spectre.css/dist/spectre-exp.css'; import './style.css'; import { widget as Widget } from '$:/core/modules/widgets/widget.js'; -import { getSuperTagTraits } from '../utils/getTraits'; -import { mergeSchema } from '../utils/mergeSchema'; +import { initEditor } from './initEditor'; class SupertagFormWidget extends Widget { - editor?: JSONEditor.JSONEditor; + editor?: JSONEditor.JSONEditor; containerElement?: HTMLDivElement; errorValidatorInfoElement?: HTMLSpanElement; currentTiddlerTitle?: string; - refresh(_changedTiddlers: IChangedTiddlers): boolean { - return false; - } - /** * Lifecycle method: Render this widget into the DOM */ @@ -39,22 +34,25 @@ class SupertagFormWidget extends Widget { this.domNodes.push(containerElement); // eslint-disable-next-line unicorn/prefer-dom-node-append parent.appendChild(containerElement); - const superTags = getSuperTagTraits(currentTiddlerTitle); - const tiddlerFields = $tw.wiki.getTiddler(currentTiddlerTitle)?.fields ?? {}; - if (superTags.length === 0) return; - const fullSchema = mergeSchema(superTags); - this.editor = new JSONEditor.JSONEditor(editorElement, { - schema: fullSchema, - theme: 'spectre', - iconlib: 'spectre', - disable_edit_json: true, - form_name_root: 'SuperTag', - startval: tiddlerFields, - no_additional_properties: true, - use_default_values: true, - }); - this.editor.on('change', this.formOnChange); + this.editor = initEditor(currentTiddlerTitle, editorElement); + this.editor?.on('change', this.formOnChange); + } + } + + public refresh(changedTiddlers: IChangedTiddlers): boolean { + if (this.currentTiddlerTitle === undefined) return false; + const changedAttributes = this.computeAttributes(); + if ($tw.utils.count(changedAttributes) > 0 || changedTiddlers[this.currentTiddlerTitle] !== undefined) { + this.refreshSelf(); + return true; } + return false; + } + + public refreshSelf() { + if (this.currentTiddlerTitle === undefined || this.editor === undefined) return; + const tiddlerFields = $tw.wiki.getTiddler(this.currentTiddlerTitle)?.fields ?? ({} as Record); + this.editor.setValue(tiddlerFields); } private readonly formOnChange = () => { @@ -67,8 +65,17 @@ class SupertagFormWidget extends Widget { this.errorValidatorInfoElement.className = 'label label-warning'; this.errorValidatorInfoElement.textContent = 'Form not valid'; } else { - const tiddlerFields = $tw.wiki.getTiddler(this.currentTiddlerTitle)?.fields ?? {}; - $tw.wiki.addTiddler({ ...tiddlerFields, ...latestFormValue, title: this.currentTiddlerTitle }); + const tiddlerFields = $tw.wiki.getTiddler(this.currentTiddlerTitle)?.fields ?? ({} as Record); + + let hasChange = false; + Object.keys(latestFormValue).forEach((key) => { + if (tiddlerFields[key] !== latestFormValue[key]) { + hasChange = true; + } + }); + if (hasChange) { + $tw.wiki.addTiddler({ ...tiddlerFields, ...latestFormValue, title: this.currentTiddlerTitle }); + } } } }; diff --git a/src/widgets/supertag-form/initEditor.ts b/src/widgets/supertag-form/initEditor.ts new file mode 100644 index 0000000..92fa990 --- /dev/null +++ b/src/widgets/supertag-form/initEditor.ts @@ -0,0 +1,20 @@ +import * as JSONEditor from '@json-editor/json-editor'; +import { getSuperTagTraits } from '../utils/getTraits'; +import { mergeSchema } from '../utils/mergeSchema'; + +export function initEditor(currentTiddlerTitle: string, editorElement: HTMLDivElement): JSONEditor.JSONEditor | undefined { + const superTags = getSuperTagTraits(currentTiddlerTitle); + const tiddlerFields = $tw.wiki.getTiddler(currentTiddlerTitle)?.fields ?? {}; + if (superTags.length === 0) return; + const fullSchema = mergeSchema(superTags); + return new JSONEditor.JSONEditor(editorElement, { + schema: fullSchema, + theme: 'spectre', + iconlib: 'spectre', + disable_edit_json: true, + form_name_root: 'SuperTag', + startval: tiddlerFields, + no_additional_properties: true, + use_default_values: true, + }); +}