Skip to content

Commit

Permalink
Fix for Bug #6618 (#6628)
Browse files Browse the repository at this point in the history
* Fix for Bug #6618

This Commit fixes Bug #6618. It is a little bit more complicated than
using one tiddler to store the new value for a field. Because the
following can happen:

* The user types "not-a-date" into the field value of a simple text field.
* The user now selects a field name that uses a HTML5 date editor. The
  Editor will show no date because the value cannot be parsed.
* The user saves the tiddler by clicking the checkmark.

Now the date-field contains the value "not-a-date" but the user was not
aware that this will be added. The edit control showed no date (because
the value was invalid) and the user assumed the field was empty and
won't be added to the tiddler.

To prevent this, every kind of field editor gets its own storage tiddler.
Its name is derived from the SHA256-hash of the name of the tiddler that
is returned by the Field Editor Cascade. That way every editor in the
cascade is only seeing its input. As long as the default setup (with one
default editor) is used, everything works like in 5.2.1.

This commit also fixes the bug that the after adding a field the
field-type input box was not focused again.

* Update Documentation for Field Editor Cascade

The fix for bug #6618 makes the handling of the tiddler backing the edit
operation much more complicated. See previous commit "Fix for Bug #6618"
for more details.
  • Loading branch information
FlashSystems committed May 14, 2022
1 parent 775c7f0 commit e9405ac
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 19 deletions.
11 changes: 7 additions & 4 deletions core/ui/EditTemplate.tid
@@ -1,18 +1,21 @@
title: $:/core/ui/EditTemplate

\define delete-edittemplate-state-tiddlers() <$action-deletetiddler $filter="[<newFieldNameTiddler>] [<newFieldValueTiddler>] [<newFieldNameInputTiddler>] [<newFieldNameSelectionTiddler>] [<newTagNameTiddler>] [<newTagNameInputTiddler>] [<newTagNameSelectionTiddler>] [<typeInputTiddler>] [<typeSelectionTiddler>]"/>
\define delete-edittemplate-state-tiddlers() <$action-deletetiddler $filter="[<newFieldNameTiddler>] [prefix<newFieldValueTiddlerPrefix>] [<newFieldNameInputTiddler>] [<newFieldNameSelectionTiddler>] [<newTagNameTiddler>] [<newTagNameInputTiddler>] [<newTagNameSelectionTiddler>] [<typeInputTiddler>] [<typeSelectionTiddler>]"/>

\define get-field-value-tiddler-filter() [subfilter<get-field-editor-filter>sha256[16]addprefix[/]addprefix<newFieldValueTiddlerPrefix>]
\define get-field-editor-filter() [<newFieldNameTiddler>get[text]else[]] :cascade[all[shadows+tiddlers]tag[$:/tags/FieldEditorFilter]!is[draft]get[text]] :and[!is[blank]else{$:/core/ui/EditTemplate/fieldEditor/default}]

\define save-tiddler-actions()
\whitespace trim
<$action-sendmessage $message="tm-add-tag" $param={{{ [<newTagNameTiddler>get[text]] }}}/>
<$action-sendmessage $message="tm-add-field" $name={{{ [<newFieldNameTiddler>get[text]] }}} $value={{{ [<newFieldNameTiddler>get[text]] :map[<newFieldValueTiddler>get<currentTiddler>] }}}/>
<$action-sendmessage $message="tm-add-field" $name={{{ [<newFieldNameTiddler>get[text]] }}} $value={{{ [<newFieldNameTiddler>get[text]] :map[subfilter<get-field-value-tiddler-filter>get[text]] }}}/>
<<delete-edittemplate-state-tiddlers>>
<$action-sendmessage $message="tm-save-tiddler"/>
\end

\define cancel-delete-tiddler-actions(message)
\whitespace trim
<<delete-edittemplate-state-tiddlers>>
<<delete-edittemplate-state-tiddlers>>
<$action-sendmessage $message="tm-$message$-tiddler"/>
\end

Expand All @@ -26,7 +29,7 @@ title: $:/core/ui/EditTemplate
storyTiddler=<<currentTiddler>>
newTagNameTiddler=<<qualify "$:/temp/NewTagName">>
newFieldNameTiddler=<<qualify "$:/temp/NewFieldName">>
newFieldValueTiddler=<<qualify "$:/temp/NewFieldValue">>
newFieldValueTiddlerPrefix=<<qualify "$:/temp/NewFieldValue">>
newFieldNameInputTiddler=<<qualify "$:/temp/NewFieldName/input">>
newFieldNameSelectionTiddler=<<qualify "$:/temp/NewFieldName/selected-item">>
newTagNameInputTiddler=<<qualify "$:/temp/NewTagName/input">>
Expand Down
2 changes: 1 addition & 1 deletion core/ui/EditTemplate/fieldEditor-default.tid
@@ -1,3 +1,3 @@
title: $:/core/ui/EditTemplate/fieldEditor/default

<$edit-text tiddler=<<currentTiddler>> field=<<currentField>> default="" class="tc-edit-texteditor tc-edit-fieldeditor" placeholder={{$:/language/EditTemplate/Fields/Add/Value/Placeholder}} tabindex={{$:/config/EditTabIndex}} cancelPopups="yes"/>
<$edit-text tiddler=<<currentTiddler>> field=<<currentField>> tag="input" default="" class="tc-edit-texteditor tc-edit-fieldeditor" placeholder={{$:/language/EditTemplate/Fields/Add/Value/Placeholder}} tabindex={{$:/config/EditTabIndex}} cancelPopups="yes"/>
14 changes: 6 additions & 8 deletions core/ui/EditTemplate/fields.tid
Expand Up @@ -16,8 +16,8 @@ $:/config/EditTemplateFields/Visibility/$(currentField)$

\define new-field-actions()
\whitespace trim
<$action-sendmessage $message="tm-add-field" $name={{{ [<newFieldNameTiddler>get[text]] }}} $value={{{ [<newFieldNameTiddler>get[text]] :map[<newFieldValueTiddler>get<currentTiddler>] }}}/>
<$action-deletetiddler $filter="[<newFieldNameTiddler>] [<newFieldValueTiddler>] [<storeTitle>] [<searchListState>]"/>
<$action-sendmessage $message="tm-add-field" $name={{{ [<newFieldNameTiddler>get[text]] }}} $value={{{ [<newFieldNameTiddler>get[text]] :map[subfilter<get-field-value-tiddler-filter>get[text]] }}}/>
<$action-deletetiddler $filter="[<newFieldNameTiddler>] [prefix<newFieldValueTiddlerPrefix>] [<storeTitle>] [<searchListState>]"/>
<$action-sendmessage $message="tm-focus-selector" $param=<<current-tiddler-new-field-selector>>/>
\end

Expand Down Expand Up @@ -51,8 +51,8 @@ $:/config/EditTemplateFields/Visibility/$(currentField)$
<$button tooltip=<<lingo Fields/Add/Button/Hint>>>
<$action-sendmessage $message="tm-add-field"
$name=<<name>>
$value={{{ [<newFieldValueTiddler>get<name>] }}}/>
<$action-deletetiddler $filter="[<newFieldNameTiddler>] [<newFieldValueTiddler>] [<storeTitle>] [<searchListState>]"/>
$value={{{ [subfilter<get-field-value-tiddler-filter>get[text]] }}}/>
<$action-deletetiddler $filter="[<newFieldNameTiddler>] [prefix<newFieldValueTiddlerPrefix>] [<storeTitle>] [<searchListState>]"/>
<<lingo Fields/Add/Button>>
</$button>
</$reveal>
Expand Down Expand Up @@ -135,13 +135,11 @@ $value={{{ [<newFieldValueTiddler>get<name>] }}}/>
</div>
</$reveal>
</div>
<$let currentTiddler=<<newFieldValueTiddler>> currentField={{{ [<newFieldNameTiddler>get[text]] }}}>
<$let currentTiddlerCSSescaped={{{ [<currentTiddler>escapecss[]] }}} currentTiddler={{{ [subfilter<get-field-value-tiddler-filter>] }}} currentField="text" currentFieldName={{{ [<newFieldNameTiddler>get[text]] }}}>
<span class="tc-edit-field-add-value tc-small-gap-right">
<$set name="currentTiddlerCSSescaped" value={{{ [<currentTiddler>escapecss[]] }}}>
<$keyboard key="((add-field))" actions=<<new-field-actions>>>
<$transclude tiddler={{{ [<currentField>] :cascade[all[shadows+tiddlers]tag[$:/tags/FieldEditorFilter]!is[draft]get[text]] :and[!is[blank]else{$:/core/ui/EditTemplate/fieldEditor/default}] }}} />
<$transclude tiddler={{{ [subfilter<get-field-editor-filter>] }}} />
</$keyboard>
</$set>
</span>
<span class="tc-edit-field-add-button">
<$macrocall $name="new-field"/>
Expand Down
@@ -1,24 +1,30 @@
created: 20220305183700000
modified: 20220305183700000
modified: 20220413165500000
tags: Concepts
title: Customizing EditTemplate field rendering
type: text/vnd.tiddlywiki

When editing a tiddler the [[EditTemplate|$:/core/ui/EditTemplate/fields]] normally renders fields as simple input boxes. To modify this behaviour, the [[cascade mechanism|Cascades]] can be used. Via the [[Field Editor Cascade|Field Editor Cascade]] the name of the tiddler used for rendering the field editor can be specified. The content of this tiddler is transcluded to represent the content of the field.

To modify the appearance of all fields whose name ends with `-date` create a new tiddler and add the `$:/tags/FieldEditorFilter` tag to it. Add a `list-before` field and assign the value `$:/config/FieldEditorFilters/default`. Now you have to put the filter for the cascade into the tiddler's text field: `[regexp[-date$]then[$:/config/EditTemplateFields/Templates/dates]]`. This will transclude the tiddler named `$:/config/EditTemplateFields/Templates/dates` to render the input elements for all fields with names matching the regular expression.
To modify the appearance of all fields whose name ends with `-date` create a new tiddler and add the `$:/tags/FieldEditorFilter` tag to it. Add a `list-before` field and assign the value `$:/config/FieldEditorFilters/default`. Now you have to put the filter for the cascade into the tiddler's text field: `[suffix[-date]then[$:/config/EditTemplateFields/Templates/dates]]`. This will transclude the tiddler named `$:/config/EditTemplateFields/Templates/dates` to render the input elements for all fields with names matching the regular expression.

The variables `currentTiddler` and `currentField` are set to pass information about the tiddler and field that are edited to the transcluded tiddler.
The variables `currentTiddler`, `currentField` and `currentFieldName` are set to pass information about the tiddler and field that are edited to the transcluded tiddler.

|`currentTiddler`|The tiddler that must be used to store the field value.|
|`currentField`|The field within the `currentTiddler` that must be used to store the field name. This is an opaque value hat may contain any field name (even `text`), use `currentFieldName` to make decisions based on the actual name of the currently edited field.|
|`currentFieldName`|The name of the currently edited field.|

For example, a tiddler containing the following WikiText would render the field as an HTML input element of the type `date`. This will show a date picker for the fields on all modern browsers:

```
<$edit-text tiddler=<<currentTiddler>> field=<<currentField>> type="date" class="tc-edit-texteditor tc-edit-fieldeditor" placeholder="Set your date" tabindex={{$:/config/EditTabIndex}} cancelPopups="yes"/>
<$edit-text tiddler=<<currentTiddler>> field=<<currentField>> tag="input" type="date" class="tc-edit-texteditor tc-edit-fieldeditor" placeholder="Set your date" tabindex={{$:/config/EditTabIndex}} cancelPopups="yes"/>
```

<<.warning "The `currentField` variable will be set to `text` for new fields. Make sure that your editor will handle this correctly. For example, by setting the `tag` attribute on the EditTextWidget. If you want to know the name of the currently edited/added field, use the `currentFieldName` variable.">>

The `tabindex` and `cancelPopups` attributes make sure the HTML input element behaves exactly the default elements provided by TiddlyWiki.

Not only the `EditTextWidget` can be used. A tiddler containing the following WikiText will render the field as a drop-down-list that allows the user to select the name of a tiddler. The name of the selected tiddler will be stored in the field.
Not only the EditTextWidget can be used. A tiddler containing the following WikiText will render the field as a drop-down-list that allows the user to select the name of a tiddler. The name of the selected tiddler will be stored in the field.

```
<$select tiddler=<<currentTiddler>> field=<<currentField>> class="tc-edit-texteditor tc-edit-fieldeditor" cancelPopups="yes">
Expand All @@ -28,4 +34,14 @@ Not only the `EditTextWidget` can be used. A tiddler containing the following Wi
</$select>
```

The classes `tc-edit-texteditor` and `tc-edit-fieldeditor` should be used to style the `input` and `select` elements to match the theme of the TiddlyWiki installation.
The classes `tc-edit-texteditor` and `tc-edit-fieldeditor` should be used to style the `input` and `select` elements to match the theme of the TiddlyWiki installation.

! Persistence of values when creating fields

When using multiple field editors for creating fields within the [[EditTemplate|$:/core/ui/EditTemplate/fields]], every field editor tiddler returned by the [[Field Editor Cascade|Field Editor Cascade]] gets its own storage tiddler. This is done to prevent problems with incompatible values when the user is switching between fields governed by different field editors.

!! Example

There is a cascade that returns a special field editor for all fields starting with the string "my-". All other fields use the default field editor.
If you type a new value into the "field value" input box and select any field not starting with "my-", the value will be kept.
If you switch to a field, that starts with "my-", the "field value" input field will be empty again because a new type of field editor is used. If you now type a value and switch to another field starting with "my-" the value will be kept. If you switch to a field that does not start with "my-" the previously typed value (that was stored for the default editor) will reappear.

0 comments on commit e9405ac

Please sign in to comment.