mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-27 03:57:21 +00:00
Keyboard-driven dropdown inputs (#4725)
* Add shortcut descriptions to Misc.multids * Update framed.js * Update simple.js * Add inputActions and refreshTitle to factory.js * Add inputActions and refreshTitle to edit.js * Update DefaultSearchResultList.tid * Update search.tid * Update ShortcutInfo.multids * Update shortcuts.multids * Create keyboard-driven-input.tid * Update tag-picker.tid * Create keyboard-driven-input_Macro.tid * Update EditTextWidget.tid * Update EditWidget.tid * Update engine.js * Update base.tid * Use primaryListFilter, secondaryListFilter, primaryList and secondaryList * Update tag-picker.tid * Update search.tid * Update DefaultSearchResultList.tid * Update keyboard-driven-input_Macro.tid * Fix typo udpate -> update * Update framed.js
This commit is contained in:
parent
d505eeb269
commit
0d2df34c58
@ -62,6 +62,11 @@ OfficialPluginLibrary: Official ~TiddlyWiki Plugin Library
|
|||||||
OfficialPluginLibrary/Hint: The official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team.
|
OfficialPluginLibrary/Hint: The official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team.
|
||||||
PluginReloadWarning: Please save {{$:/core/ui/Buttons/save-wiki}} and reload {{$:/core/ui/Buttons/refresh}} to allow changes to ~JavaScript plugins to take effect
|
PluginReloadWarning: Please save {{$:/core/ui/Buttons/save-wiki}} and reload {{$:/core/ui/Buttons/refresh}} to allow changes to ~JavaScript plugins to take effect
|
||||||
RecentChanges/DateFormat: DDth MMM YYYY
|
RecentChanges/DateFormat: DDth MMM YYYY
|
||||||
|
Shortcuts/Input/Accept/Hint: Accept the selected item
|
||||||
|
Shortcuts/Input/AcceptVariant/Hint: Accept the selected item (variant)
|
||||||
|
Shortcuts/Input/Cancel/Hint: Clear the input field
|
||||||
|
Shortcuts/Input/Down/Hint: Select the next item
|
||||||
|
Shortcuts/Input/Up/Hint: Select the previous item
|
||||||
SystemTiddler/Tooltip: This is a system tiddler
|
SystemTiddler/Tooltip: This is a system tiddler
|
||||||
SystemTiddlers/Include/Prompt: Include system tiddlers
|
SystemTiddlers/Include/Prompt: Include system tiddlers
|
||||||
TagManager/Colour/Heading: Colour
|
TagManager/Colour/Heading: Colour
|
||||||
|
@ -81,7 +81,7 @@ function FramedEngine(options) {
|
|||||||
{name: "click",handlerObject: this,handlerMethod: "handleClickEvent"},
|
{name: "click",handlerObject: this,handlerMethod: "handleClickEvent"},
|
||||||
{name: "input",handlerObject: this,handlerMethod: "handleInputEvent"},
|
{name: "input",handlerObject: this,handlerMethod: "handleInputEvent"},
|
||||||
{name: "keydown",handlerObject: this.widget,handlerMethod: "handleKeydownEvent"},
|
{name: "keydown",handlerObject: this.widget,handlerMethod: "handleKeydownEvent"},
|
||||||
{name: "focus",handlerObject: this,handlerMethod: "handleFocusEvent"},
|
{name: "focus",handlerObject: this,handlerMethod: "handleFocusEvent"}
|
||||||
]);
|
]);
|
||||||
// Insert the element into the DOM
|
// Insert the element into the DOM
|
||||||
this.iframeDoc.body.appendChild(this.domNode);
|
this.iframeDoc.body.appendChild(this.domNode);
|
||||||
@ -108,13 +108,20 @@ Set the text of the engine if it doesn't currently have focus
|
|||||||
FramedEngine.prototype.setText = function(text,type) {
|
FramedEngine.prototype.setText = function(text,type) {
|
||||||
if(!this.domNode.isTiddlyWikiFakeDom) {
|
if(!this.domNode.isTiddlyWikiFakeDom) {
|
||||||
if(this.domNode.ownerDocument.activeElement !== this.domNode) {
|
if(this.domNode.ownerDocument.activeElement !== this.domNode) {
|
||||||
this.domNode.value = text;
|
this.updateDomNodeText(text);
|
||||||
}
|
}
|
||||||
// Fix the height if needed
|
// Fix the height if needed
|
||||||
this.fixHeight();
|
this.fixHeight();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Update the DomNode with the new text
|
||||||
|
*/
|
||||||
|
FramedEngine.prototype.updateDomNodeText = function(text) {
|
||||||
|
this.domNode.value = text;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get the text of the engine
|
Get the text of the engine
|
||||||
*/
|
*/
|
||||||
@ -177,6 +184,9 @@ Handle a dom "input" event which occurs when the text has changed
|
|||||||
FramedEngine.prototype.handleInputEvent = function(event) {
|
FramedEngine.prototype.handleInputEvent = function(event) {
|
||||||
this.widget.saveChanges(this.getText());
|
this.widget.saveChanges(this.getText());
|
||||||
this.fixHeight();
|
this.fixHeight();
|
||||||
|
if(this.widget.editInputActions) {
|
||||||
|
this.widget.invokeActionString(this.widget.editInputActions);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -68,13 +68,20 @@ Set the text of the engine if it doesn't currently have focus
|
|||||||
SimpleEngine.prototype.setText = function(text,type) {
|
SimpleEngine.prototype.setText = function(text,type) {
|
||||||
if(!this.domNode.isTiddlyWikiFakeDom) {
|
if(!this.domNode.isTiddlyWikiFakeDom) {
|
||||||
if(this.domNode.ownerDocument.activeElement !== this.domNode || text === "") {
|
if(this.domNode.ownerDocument.activeElement !== this.domNode || text === "") {
|
||||||
this.domNode.value = text;
|
this.updateDomNodeText(text);
|
||||||
}
|
}
|
||||||
// Fix the height if needed
|
// Fix the height if needed
|
||||||
this.fixHeight();
|
this.fixHeight();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Update the DomNode with the new text
|
||||||
|
*/
|
||||||
|
SimpleEngine.prototype.updateDomNodeText = function(text) {
|
||||||
|
this.domNode.value = text;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get the text of the engine
|
Get the text of the engine
|
||||||
*/
|
*/
|
||||||
@ -115,6 +122,9 @@ Handle a dom "input" event which occurs when the text has changed
|
|||||||
SimpleEngine.prototype.handleInputEvent = function(event) {
|
SimpleEngine.prototype.handleInputEvent = function(event) {
|
||||||
this.widget.saveChanges(this.getText());
|
this.widget.saveChanges(this.getText());
|
||||||
this.fixHeight();
|
this.fixHeight();
|
||||||
|
if(this.widget.editInputActions) {
|
||||||
|
this.widget.invokeActionString(this.widget.editInputActions);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -178,6 +178,8 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
|
|||||||
this.editFocus = this.getAttribute("focus");
|
this.editFocus = this.getAttribute("focus");
|
||||||
this.editTabIndex = this.getAttribute("tabindex");
|
this.editTabIndex = this.getAttribute("tabindex");
|
||||||
this.editCancelPopups = this.getAttribute("cancelPopups","") === "yes";
|
this.editCancelPopups = this.getAttribute("cancelPopups","") === "yes";
|
||||||
|
this.editInputActions = this.getAttribute("inputActions");
|
||||||
|
this.editRefreshTitle = this.getAttribute("refreshTitle");
|
||||||
// Get the default editor element tag and type
|
// Get the default editor element tag and type
|
||||||
var tag,type;
|
var tag,type;
|
||||||
if(this.editField === "text") {
|
if(this.editField === "text") {
|
||||||
@ -209,9 +211,11 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
|
|||||||
EditTextWidget.prototype.refresh = function(changedTiddlers) {
|
EditTextWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
var changedAttributes = this.computeAttributes();
|
var changedAttributes = this.computeAttributes();
|
||||||
// Completely rerender if any of our attributes have changed
|
// Completely rerender if any of our attributes have changed
|
||||||
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.cancelPopups || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE]) {
|
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes["default"] || changedAttributes["class"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE]) {
|
||||||
this.refreshSelf();
|
this.refreshSelf();
|
||||||
return true;
|
return true;
|
||||||
|
} else if (changedTiddlers[this.editRefreshTitle]) {
|
||||||
|
this.engine.updateDomNodeText(this.getEditInfo().value);
|
||||||
} else if(changedTiddlers[this.editTitle]) {
|
} else if(changedTiddlers[this.editTitle]) {
|
||||||
var editInfo = this.getEditInfo();
|
var editInfo = this.getEditInfo();
|
||||||
this.updateEditor(editInfo.value,editInfo.type);
|
this.updateEditor(editInfo.value,editInfo.type);
|
||||||
|
@ -49,6 +49,8 @@ EditWidget.prototype.execute = function() {
|
|||||||
this.editTabIndex = this.getAttribute("tabindex");
|
this.editTabIndex = this.getAttribute("tabindex");
|
||||||
this.editFocus = this.getAttribute("focus","");
|
this.editFocus = this.getAttribute("focus","");
|
||||||
this.editCancelPopups = this.getAttribute("cancelPopups","");
|
this.editCancelPopups = this.getAttribute("cancelPopups","");
|
||||||
|
this.editInputActions = this.getAttribute("inputActions");
|
||||||
|
this.editRefreshTitle = this.getAttribute("refreshTitle");
|
||||||
// Choose the appropriate edit widget
|
// Choose the appropriate edit widget
|
||||||
this.editorType = this.getEditorType();
|
this.editorType = this.getEditorType();
|
||||||
// Make the child widgets
|
// Make the child widgets
|
||||||
@ -87,7 +89,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
|
|||||||
EditWidget.prototype.refresh = function(changedTiddlers) {
|
EditWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
var changedAttributes = this.computeAttributes();
|
var changedAttributes = this.computeAttributes();
|
||||||
// Refresh if an attribute has changed, or the type associated with the target tiddler has changed
|
// Refresh if an attribute has changed, or the type associated with the target tiddler has changed
|
||||||
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tabindex || changedAttributes.cancelPopups || (changedTiddlers[this.editTitle] && this.getEditorType() !== this.editorType)) {
|
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || (changedTiddlers[this.editTitle] && this.getEditorType() !== this.editorType)) {
|
||||||
this.refreshSelf();
|
this.refreshSelf();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -5,11 +5,19 @@ caption: {{$:/language/Search/DefaultResults/Caption}}
|
|||||||
\define searchResultList()
|
\define searchResultList()
|
||||||
//<small>{{$:/language/Search/Matches/Title}}</small>//
|
//<small>{{$:/language/Search/Matches/Title}}</small>//
|
||||||
|
|
||||||
<$list filter="[!is[system]search:title{$(searchTiddler)$}sort[title]limit[250]]" template="$:/core/ui/ListItemTemplate"/>
|
<$list filter="[!is[system]search:title{$(searchTiddler)$}sort[title]limit[250]]">
|
||||||
|
<span class={{{[<currentTiddler>addsuffix[-primaryList]] -[<searchListState>get[text]] +[then[]else[tc-list-item-selected]] }}}>
|
||||||
|
<$transclude tiddler="$:/core/ui/ListItemTemplate"/>
|
||||||
|
</span>
|
||||||
|
</$list>
|
||||||
|
|
||||||
//<small>{{$:/language/Search/Matches/All}}</small>//
|
//<small>{{$:/language/Search/Matches/All}}</small>//
|
||||||
|
|
||||||
<$list filter="[!is[system]search{$(searchTiddler)$}sort[title]limit[250]]" template="$:/core/ui/ListItemTemplate"/>
|
<$list filter="[!is[system]search{$(searchTiddler)$}sort[title]limit[250]]">
|
||||||
|
<span class={{{[<currentTiddler>addsuffix[-secondaryList]] -[<searchListState>get[text]] +[then[]else[tc-list-item-selected]] }}}>
|
||||||
|
<$transclude tiddler="$:/core/ui/ListItemTemplate"/>
|
||||||
|
</span>
|
||||||
|
</$list>
|
||||||
|
|
||||||
\end
|
\end
|
||||||
<<searchResultList>>
|
<<searchResultList>>
|
||||||
|
@ -2,25 +2,12 @@ title: $:/core/ui/SideBarSegments/search
|
|||||||
tags: $:/tags/SideBarSegment
|
tags: $:/tags/SideBarSegment
|
||||||
|
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
<div class="tc-sidebar-lists tc-sidebar-search">
|
|
||||||
|
|
||||||
<$set name="searchTiddler" value="$:/temp/search">
|
\define count-popup-button()
|
||||||
<div class="tc-search">
|
\whitespace trim
|
||||||
<$edit-text tiddler="$:/temp/search" type="search" tag="input" focus={{$:/config/Search/AutoFocus}} focusPopup=<<qualify "$:/state/popup/search-dropdown">> class="tc-popup-handle" cancelPopups="yes"/>
|
|
||||||
<$reveal state="$:/temp/search" type="nomatch" text="">
|
|
||||||
<$button tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class="tc-btn-invisible">
|
|
||||||
<$action-setfield $tiddler="$:/temp/advancedsearch" text={{$:/temp/search}}/>
|
|
||||||
<$action-setfield $tiddler="$:/temp/search" text=""/>
|
|
||||||
<$action-navigate $to="$:/AdvancedSearch"/>
|
|
||||||
{{$:/core/images/advanced-search-button}}
|
|
||||||
</$button>
|
|
||||||
<$button class="tc-btn-invisible">
|
|
||||||
<$action-setfield $tiddler="$:/temp/search" text="" />
|
|
||||||
{{$:/core/images/close-button}}
|
|
||||||
</$button>
|
|
||||||
<$button popup=<<qualify "$:/state/popup/search-dropdown">> class="tc-btn-invisible">
|
<$button popup=<<qualify "$:/state/popup/search-dropdown">> class="tc-btn-invisible">
|
||||||
{{$:/core/images/down-arrow}}
|
{{$:/core/images/down-arrow}}
|
||||||
<$list filter="[{$:/temp/search}minlength{$:/config/Search/MinLength}limit[1]]" variable="listItem">
|
<$list filter="[{$(searchTiddler)$}minlength{$:/config/Search/MinLength}limit[1]]" variable="listItem">
|
||||||
<$set name="searchTerm" value={{{ [<searchTiddler>get[text]] }}}>
|
<$set name="searchTerm" value={{{ [<searchTiddler>get[text]] }}}>
|
||||||
<$set name="resultCount" value="""<$count filter="[!is[system]search<searchTerm>]"/>""">
|
<$set name="resultCount" value="""<$count filter="[!is[system]search<searchTerm>]"/>""">
|
||||||
{{$:/language/Search/Matches}}
|
{{$:/language/Search/Matches}}
|
||||||
@ -28,28 +15,65 @@ tags: $:/tags/SideBarSegment
|
|||||||
</$set>
|
</$set>
|
||||||
</$list>
|
</$list>
|
||||||
</$button>
|
</$button>
|
||||||
|
\end
|
||||||
|
|
||||||
|
\define search-results-list()
|
||||||
|
\whitespace trim
|
||||||
|
<$list filter="[{$(searchTiddler)$}minlength{$:/config/Search/MinLength}limit[1]]" emptyMessage="""<div class="tc-search-results">{{$:/language/Search/Search/TooShort}}</div>""" variable="listItem">
|
||||||
|
|
||||||
|
{{$:/core/ui/SearchResults}}
|
||||||
|
|
||||||
|
</$list>
|
||||||
|
\end
|
||||||
|
|
||||||
|
\define delete-state-tiddlers() <$action-deletetiddler $filter="[[$:/temp/search]] [<searchTiddler>] [<searchListState>]"/>
|
||||||
|
|
||||||
|
\define cancel-search-actions() <$action-deletetiddler $filter="[<__storeTitle__>] [<__tiddler__>] [<__selectionStateTitle__>]"/>
|
||||||
|
|
||||||
|
\define input-accept-actions() <$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/>
|
||||||
|
|
||||||
|
\define input-accept-variant-actions() <$action-sendmessage $message="tm-edit-tiddler" $param={{{ [<__tiddler__>get[text]] }}}/>
|
||||||
|
|
||||||
|
<div class="tc-sidebar-lists tc-sidebar-search">
|
||||||
|
|
||||||
|
<$vars searchTiddler="$:/temp/search/input" searchListState=<<qualify "$:/state/search-list/selected-item">> titleSearchFilter="[!is[system]search:title<userInput>sort[title]limit[250]]" allSearchFilter="[!is[system]search<userInput>sort[title]limit[250]]">
|
||||||
|
<div class="tc-search">
|
||||||
|
<$macrocall $name="keyboard-driven-input" tiddler="$:/temp/search" storeTitle=<<searchTiddler>>
|
||||||
|
selectionStateTitle=<<searchListState>> refreshTitle="$:/temp/search/refresh" type="search"
|
||||||
|
tag="input" focus={{$:/config/Search/AutoFocus}} focusPopup=<<qualify "$:/state/popup/search-dropdown">>
|
||||||
|
class="tc-popup-handle" primaryListFilter=<<titleSearchFilter>> secondaryListFilter=<<allSearchFilter>>
|
||||||
|
filterMinLength={{$:/config/Search/MinLength}} inputCancelActions=<<cancel-search-actions>>
|
||||||
|
inputAcceptActions=<<input-accept-actions>> inputAcceptVariantActions=<<input-accept-variant-actions>> cancelPopups="yes" />
|
||||||
|
<$reveal state=<<searchTiddler>> type="nomatch" text="">
|
||||||
|
<$button tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class="tc-btn-invisible">
|
||||||
|
<$action-setfield $tiddler="$:/temp/advancedsearch" text={{$:/temp/search}}/>
|
||||||
|
<<delete-state-tiddlers>>
|
||||||
|
<$action-navigate $to="$:/AdvancedSearch"/>
|
||||||
|
{{$:/core/images/advanced-search-button}}
|
||||||
|
</$button>
|
||||||
|
<$button class="tc-btn-invisible">
|
||||||
|
<<delete-state-tiddlers>>
|
||||||
|
{{$:/core/images/close-button}}
|
||||||
|
</$button>
|
||||||
|
<<count-popup-button>>
|
||||||
</$reveal>
|
</$reveal>
|
||||||
<$reveal state="$:/temp/search" type="match" text="">
|
<$reveal state=<<searchTiddler>> type="match" text="">
|
||||||
<$button to="$:/AdvancedSearch" tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class="tc-btn-invisible">
|
<$button to="$:/AdvancedSearch" tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class="tc-btn-invisible">
|
||||||
{{$:/core/images/advanced-search-button}}
|
{{$:/core/images/advanced-search-button}}
|
||||||
</$button>
|
</$button>
|
||||||
</$reveal>
|
</$reveal>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<$reveal tag="div" class="tc-block-dropdown-wrapper" state="$:/temp/search" type="nomatch" text="">
|
<$reveal tag="div" class="tc-block-dropdown-wrapper" state=<<searchTiddler>> type="nomatch" text="">
|
||||||
|
|
||||||
<$reveal tag="div" class="tc-block-dropdown tc-search-drop-down tc-popup-handle" state=<<qualify "$:/state/popup/search-dropdown">> type="nomatch" text="" default="">
|
<$reveal tag="div" class="tc-block-dropdown tc-search-drop-down tc-popup-handle" state=<<qualify "$:/state/popup/search-dropdown">> type="nomatch" text="" default="">
|
||||||
|
|
||||||
<$list filter="[{$:/temp/search}minlength{$:/config/Search/MinLength}limit[1]]" emptyMessage="""<div class="tc-search-results">{{$:/language/Search/Search/TooShort}}</div>""" variable="listItem">
|
<<search-results-list>>
|
||||||
|
|
||||||
{{$:/core/ui/SearchResults}}
|
|
||||||
|
|
||||||
</$list>
|
|
||||||
|
|
||||||
</$reveal>
|
</$reveal>
|
||||||
|
|
||||||
</$reveal>
|
</$reveal>
|
||||||
|
|
||||||
</$set>
|
</$vars>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -11,6 +11,11 @@ heading-3: {{$:/language/Buttons/Heading3/Hint}}
|
|||||||
heading-4: {{$:/language/Buttons/Heading4/Hint}}
|
heading-4: {{$:/language/Buttons/Heading4/Hint}}
|
||||||
heading-5: {{$:/language/Buttons/Heading5/Hint}}
|
heading-5: {{$:/language/Buttons/Heading5/Hint}}
|
||||||
heading-6: {{$:/language/Buttons/Heading6/Hint}}
|
heading-6: {{$:/language/Buttons/Heading6/Hint}}
|
||||||
|
input-accept: {{$:/language/Shortcuts/Input/Accept/Hint}}
|
||||||
|
input-accept-variant: {{$:/language/Shortcuts/Input/AcceptVariant/Hint}}
|
||||||
|
input-cancel: {{$:/language/Shortcuts/Input/Cancel/Hint}}
|
||||||
|
input-down: {{$:/language/Shortcuts/Input/Down/Hint}}
|
||||||
|
input-up: {{$:/language/Shortcuts/Input/Up/Hint}}
|
||||||
italic: {{$:/language/Buttons/Italic/Hint}}
|
italic: {{$:/language/Buttons/Italic/Hint}}
|
||||||
link: {{$:/language/Buttons/Link/Hint}}
|
link: {{$:/language/Buttons/Link/Hint}}
|
||||||
linkify: {{$:/language/Buttons/Linkify/Hint}}
|
linkify: {{$:/language/Buttons/Linkify/Hint}}
|
||||||
|
@ -11,6 +11,11 @@ heading-3: ctrl-3
|
|||||||
heading-4: ctrl-4
|
heading-4: ctrl-4
|
||||||
heading-5: ctrl-5
|
heading-5: ctrl-5
|
||||||
heading-6: ctrl-6
|
heading-6: ctrl-6
|
||||||
|
input-accept: Enter
|
||||||
|
input-accept-variant: Alt-Enter
|
||||||
|
input-cancel: Escape
|
||||||
|
input-down: Down
|
||||||
|
input-up: Up
|
||||||
link: ctrl-L
|
link: ctrl-L
|
||||||
linkify: alt-shift-L
|
linkify: alt-shift-L
|
||||||
list-bullet: ctrl-shift-L
|
list-bullet: ctrl-shift-L
|
||||||
|
51
core/wiki/macros/keyboard-driven-input.tid
Normal file
51
core/wiki/macros/keyboard-driven-input.tid
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
title: $:/core/macros/keyboard-driven-input
|
||||||
|
tags: $:/tags/Macro
|
||||||
|
|
||||||
|
\define keyboard-input-actions()
|
||||||
|
<$list filter="[<__index__>match[]]">
|
||||||
|
<$action-setfield $tiddler=<<__storeTitle__>> text={{{ [<__tiddler__>get<__field__>] }}}/>
|
||||||
|
</$list>
|
||||||
|
<$list filter="[<__index__>!match[]]">
|
||||||
|
<$action-setfield $tiddler=<<__storeTitle__>> text={{{ [<__tiddler__>getindex<__index__>] }}}/>
|
||||||
|
</$list>
|
||||||
|
\end
|
||||||
|
|
||||||
|
\define input-next-actions(afterOrBefore:"after",reverse:"")
|
||||||
|
<$list filter="[<__storeTitle__>get[text]minlength<__filterMinLength__>] [<__filterMinLength__>match[0]] +[limit[1]]" variable="ignore">
|
||||||
|
<$vars userInput={{{ [<__storeTitle__>get[text]] }}} selectedItem={{{ [<__selectionStateTitle__>get[text]] }}}>
|
||||||
|
<$set name="filteredList" filter="[subfilter<__primaryListFilter__>addsuffix[-primaryList]] =[subfilter<__secondaryListFilter__>addsuffix[-secondaryList]]">
|
||||||
|
<$set name="nextItem" value={{{ [enlist<filteredList>$afterOrBefore$<selectedItem>] ~[enlist<filteredList>$reverse$nth[1]] }}}>
|
||||||
|
<$list filter="[<nextItem>minlength[1]]">
|
||||||
|
<$action-setfield $tiddler=<<__selectionStateTitle__>> text=<<nextItem>>/>
|
||||||
|
<$list filter="[<__index__>match[]]">
|
||||||
|
<$action-setfield $tiddler=<<__tiddler__>> $field=<<__field__>> $value={{{ [<nextItem>] +[splitregexp[(?:.(?!-))+$]] }}}/>
|
||||||
|
</$list>
|
||||||
|
<$list filter="[<__index__>!match[]]">
|
||||||
|
<$action-setfield $tiddler=<<__tiddler__>> $index=<<__index__>> $value={{{ [<nextItem>] +[splitregexp[(?:.(?!-))+$]] }}}/>
|
||||||
|
</$list>
|
||||||
|
<$action-setfield $tiddler=<<__refreshTitle__>> text="yes"/>
|
||||||
|
</$list>
|
||||||
|
</$set>
|
||||||
|
</$set>
|
||||||
|
</$vars>
|
||||||
|
</$list>
|
||||||
|
\end
|
||||||
|
|
||||||
|
\define keyboard-driven-input(tiddler,storeTitle,field:"text",index:"",tag:"input",type,focus:"",inputAcceptActions,inputAcceptVariantActions,inputCancelActions,placeholder:"",default:"",class,primaryListFilter,secondaryListFilter,focusPopup,rows,minHeight,tabindex,size,autoHeight,filterMinLength:"0",refreshTitle,selectionStateTitle,cancelPopups:"")
|
||||||
|
<$keyboard key="((input-accept))" actions=<<__inputAcceptActions__>>>
|
||||||
|
<$keyboard key="((input-accept-variant))" actions=<<__inputAcceptVariantActions__>>>
|
||||||
|
<$keyboard key="((input-up))" actions=<<input-next-actions "before" "reverse[]">>>
|
||||||
|
<$keyboard key="((input-down))" actions=<<input-next-actions>>>
|
||||||
|
<$keyboard key="((input-cancel))" actions=<<__inputCancelActions__>>>
|
||||||
|
<$edit-text tiddler=<<__tiddler__>> field=<<__field__>> index=<<__index__>>
|
||||||
|
inputActions=<<keyboard-input-actions>> tag=<<__tag__>> class=<<__class__>>
|
||||||
|
placeholder=<<__placeholder__>> default=<<__default__>> focusPopup=<<__focusPopup__>>
|
||||||
|
focus=<<__focus__>> type=<<__type__>> rows=<<__rows__>> minHeight=<<__minHeight__>>
|
||||||
|
tabindex=<<__tabindex__>> size=<<__size__>> autoHeight=<<__autoHeight__>>
|
||||||
|
refreshTitle=<<__refreshTitle__>> cancelPopups=<<__cancelPopups__>>/>
|
||||||
|
</$keyboard>
|
||||||
|
</$keyboard>
|
||||||
|
</$keyboard>
|
||||||
|
</$keyboard>
|
||||||
|
</$keyboard>
|
||||||
|
\end
|
@ -1,36 +1,54 @@
|
|||||||
title: $:/core/macros/tag-picker
|
title: $:/core/macros/tag-picker
|
||||||
tags: $:/tags/Macro
|
tags: $:/tags/Macro
|
||||||
|
|
||||||
|
\define delete-tag-state-tiddlers() <$action-deletetiddler $filter="[<newTagNameTiddler>] [<storeTitle>] [<tagSelectionState>]"/>
|
||||||
|
|
||||||
\define add-tag-actions(actions)
|
\define add-tag-actions(actions)
|
||||||
<$set name="tag" value={{{ [<newTagNameTiddler>get[text]] }}}>
|
<$set name="tag" value={{{ [<__tiddler__>get[text]] }}}>
|
||||||
|
<$list filter="[<currentTiddler>!tag<tag>]" variable="ignore" emptyMessage="""
|
||||||
|
<$action-sendmessage $message="tm-remove-tag" $param=<<tag>>/>
|
||||||
|
""">
|
||||||
<$action-sendmessage $message="tm-add-tag" $param=<<tag>>/>
|
<$action-sendmessage $message="tm-add-tag" $param=<<tag>>/>
|
||||||
<$action-deletetiddler $tiddler=<<newTagNameTiddler>>/>
|
|
||||||
$actions$
|
$actions$
|
||||||
|
</$list>
|
||||||
</$set>
|
</$set>
|
||||||
|
<<delete-tag-state-tiddlers>>
|
||||||
|
<$action-setfield $tiddler=<<refreshTitle>> text="yes"/>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\define tag-button(actions)
|
\define tag-button(actions,selectedClass)
|
||||||
<$button class="tc-btn-invisible" tag="a" tooltip={{$:/language/EditTemplate/Tags/Add/Button/Hint}}>
|
<$button class="tc-btn-invisible $selectedClass$" tag="a" tooltip={{$:/language/EditTemplate/Tags/Add/Button/Hint}}>
|
||||||
<$action-sendmessage $message="tm-add-tag" $param=<<tag>>/>
|
<$action-sendmessage $message="tm-add-tag" $param=<<tag>>/>
|
||||||
<$action-deletetiddler $tiddler=<<newTagNameTiddler>>/>
|
<<delete-tag-state-tiddlers>>
|
||||||
$actions$
|
$actions$
|
||||||
<$macrocall $name="tag-pill" tag=<<tag>>/>
|
<$macrocall $name="tag-pill" tag=<<tag>>/>
|
||||||
</$button>
|
</$button>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
|
\define clear-tags-actions()
|
||||||
|
<$list filter="[<__storeTitle__>has[text]] [<__tiddler__>has[text]]" variable="ignore" emptyMessage="""<<delete-tag-state-tiddlers>><$action-sendmessage $message="tm-cancel-tiddler"/>""">
|
||||||
|
<<delete-tag-state-tiddlers>>
|
||||||
|
</$list>
|
||||||
|
\end
|
||||||
|
|
||||||
\define tag-picker-inner(actions)
|
\define tag-picker-inner(actions)
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
|
<$vars tagSelectionState=<<qualify "$:/state/selected-tag">> storeTitle=<<qualify "$:/temp/NewTagName/input">> refreshTitle=<<qualify "$:/temp/NewTagName/refresh">> nonSystemTagsFilter="[tags[]!is[system]search:title<userInput>sort[]]" systemTagsFilter="[tags[]is[system]search:title<userInput>sort[]]">
|
||||||
<div class="tc-edit-add-tag">
|
<div class="tc-edit-add-tag">
|
||||||
<div>
|
<div>
|
||||||
<span class="tc-add-tag-name">
|
<span class="tc-add-tag-name">
|
||||||
<$keyboard key="ENTER" actions="""<$macrocall $name="add-tag-actions" actions=<<__actions__>>/>""">
|
<$macrocall $name="keyboard-driven-input" tiddler=<<newTagNameTiddler>> storeTitle=<<storeTitle>> refreshTitle=<<refreshTitle>>
|
||||||
<$edit-text tiddler=<<newTagNameTiddler>> tag="input" default="" placeholder={{$:/language/EditTemplate/Tags/Add/Placeholder}} focusPopup=<<qualify "$:/state/popup/tags-auto-complete">> class="tc-edit-texteditor tc-popup-handle" tabindex=<<tabIndex>> focus={{{ [{$:/config/AutoFocus}match[tags]then[true]] ~[[false]] }}} cancelPopups="yes"/>
|
selectionStateTitle=<<tagSelectionState>> primaryListFilter=<<nonSystemTagsFilter>> secondaryListFilter=<<systemTagsFilter>>
|
||||||
</$keyboard>
|
inputAcceptActions="""<$macrocall $name="add-tag-actions" actions=<<__actions__>>/>""" inputCancelActions=<<clear-tags-actions>> tag="input"
|
||||||
|
placeholder={{$:/language/EditTemplate/Tags/Add/Placeholder}} focusPopup=<<qualify "$:/state/popup/tags-auto-complete">>
|
||||||
|
class="tc-edit-texteditor tc-popup-handle" tabindex=<<tabIndex>> focus={{{ [{$:/config/AutoFocus}match[tags]then[true]] ~[[false]] }}}
|
||||||
|
filterMinLength={{$:/config/Tags/MinLength}} cancelPopups=<<cancelPopups>> />
|
||||||
</span> <$button popup=<<qualify "$:/state/popup/tags-auto-complete">> class="tc-btn-invisible tc-btn-dropdown" tooltip={{$:/language/EditTemplate/Tags/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Tags/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button> <span class="tc-add-tag-button">
|
</span> <$button popup=<<qualify "$:/state/popup/tags-auto-complete">> class="tc-btn-invisible tc-btn-dropdown" tooltip={{$:/language/EditTemplate/Tags/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Tags/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button> <span class="tc-add-tag-button">
|
||||||
<$set name="tag" value={{{ [<newTagNameTiddler>get[text]] }}}>
|
<$set name="tag" value={{{ [<newTagNameTiddler>get[text]] }}}>
|
||||||
<$button set="$:/temp/NewTagName" setTo="" class="">
|
<$button set=<<newTagNameTiddler>> setTo="" class="">
|
||||||
<$macrocall $name="add-tag-actions" actions=<<__actions__>>/>
|
<$action-sendmessage $message="tm-add-tag" $param=<<tag>>/>
|
||||||
<$action-deletetiddler $tiddler=<<newTagNameTiddler>>/>
|
$actions$
|
||||||
|
<<delete-tag-state-tiddlers>>
|
||||||
{{$:/language/EditTemplate/Tags/Add/Button}}
|
{{$:/language/EditTemplate/Tags/Add/Button}}
|
||||||
</$button>
|
</$button>
|
||||||
</$set>
|
</$set>
|
||||||
@ -38,22 +56,27 @@ $actions$
|
|||||||
</div>
|
</div>
|
||||||
<div class="tc-block-dropdown-wrapper">
|
<div class="tc-block-dropdown-wrapper">
|
||||||
<$reveal state=<<qualify "$:/state/popup/tags-auto-complete">> type="nomatch" text="" default="">
|
<$reveal state=<<qualify "$:/state/popup/tags-auto-complete">> type="nomatch" text="" default="">
|
||||||
<div class="tc-block-dropdown">
|
<div class="tc-block-dropdown tc-block-tags-dropdown">
|
||||||
<$set name="newTagName" value={{{ [<newTagNameTiddler>get[text]] }}}>
|
<$set name="userInput" value={{{ [<storeTitle>get[text]] }}}>
|
||||||
<$list filter="[<newTagName>minlength{$:/config/Tags/MinLength}limit[1]]" emptyMessage="""<div class="tc-search-results">{{$:/language/Search/Search/TooShort}}</div>""" variable="listItem">
|
<$list filter="[<userInput>minlength{$:/config/Tags/MinLength}limit[1]]" emptyMessage="""<div class="tc-search-results">{{$:/language/Search/Search/TooShort}}</div>""" variable="listItem">
|
||||||
<$list filter="[tags[]!is[system]search:title<newTagName>sort[]]" variable="tag">
|
<$list filter=<<nonSystemTagsFilter>> variable="tag">
|
||||||
|
<$list filter="[<tag>addsuffix[-primaryList]] -[<tagSelectionState>get[text]]" emptyMessage="""<$macrocall $name="tag-button" actions=<<__actions__>> selectedClass="tc-tag-button-selected"/>""">
|
||||||
<$macrocall $name="tag-button" actions=<<__actions__>>/>
|
<$macrocall $name="tag-button" actions=<<__actions__>>/>
|
||||||
|
</$list>
|
||||||
</$list></$list>
|
</$list></$list>
|
||||||
<hr>
|
<hr>
|
||||||
<$list filter="[<newTagName>minlength{$:/config/Tags/MinLength}limit[1]]" emptyMessage="""<div class="tc-search-results">{{$:/language/Search/Search/TooShort}}</div>""" variable="listItem">
|
<$list filter="[<userInput>minlength{$:/config/Tags/MinLength}limit[1]]" emptyMessage="""<div class="tc-search-results">{{$:/language/Search/Search/TooShort}}</div>""" variable="listItem">
|
||||||
<$list filter="[tags[]is[system]search:title<newTagName>sort[]]" variable="tag">
|
<$list filter=<<systemTagsFilter>> variable="tag">
|
||||||
|
<$list filter="[<tag>addsuffix[-secondaryList]] -[<tagSelectionState>get[text]]" emptyMessage="""<$macrocall $name="tag-button" actions=<<__actions__>> selectedClass="tc-tag-button-selected"/>""">
|
||||||
<$macrocall $name="tag-button" actions=<<__actions__>>/>
|
<$macrocall $name="tag-button" actions=<<__actions__>>/>
|
||||||
|
</$list>
|
||||||
</$list></$list>
|
</$list></$list>
|
||||||
</$set>
|
</$set>
|
||||||
</div>
|
</div>
|
||||||
</$reveal>
|
</$reveal>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</$vars>
|
||||||
\end
|
\end
|
||||||
\define tag-picker(actions)
|
\define tag-picker(actions)
|
||||||
\whitespace trim
|
\whitespace trim
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
title: keyboard-driven-input Macro
|
||||||
|
tags: Macros [[Core Macros]]
|
||||||
|
|
||||||
|
The <<.def keyboard-driven-input>> [[macro|Macros]] generates an input field or textarea that lets you cycle through a given list of entries with the <kbd>up</kbd> and <kbd>down</kbd> arrow keys. Doing so, an entry gets selected and can be processed with further actions
|
||||||
|
|
||||||
|
!! Parameters
|
||||||
|
|
||||||
|
To create the input field or textarea, the <<.def keyboard-driven-input>> [[macro|Macros]] accepts all parameters of the EditTextWidget
|
||||||
|
|
||||||
|
The additional parameters are:
|
||||||
|
|
||||||
|
| |purpose |h
|
||||||
|
|storeTitle |the title of the tiddler that stores the user input |
|
||||||
|
|selectionStateTitle |the title of the tiddler that stores the selected entry with a -list1 or -list2 suffix to make it unique |
|
||||||
|
|inputAcceptActions |the actions that get processed when the user hits <kbd>{{$:/config/shortcuts/input-accept}}</kbd> |
|
||||||
|
|inputAcceptVariantActions |the actions that get processed when the user hits <kbd>{{$:/config/shortcuts/input-accept-variant}}</kbd> |
|
||||||
|
|inputCancelActions |the actions that get processed when the user hits <kbd>{{$:/config/shortcuts/input-cancel}}</kbd> |
|
||||||
|
|primaryListFilter |a filter that specifies the first item-list |
|
||||||
|
|secondaryListFilter |a second filter that specifies a second item-list |
|
||||||
|
|
@ -32,6 +32,8 @@ The content of the `<$edit-text>` widget is ignored.
|
|||||||
|minHeight |Minimum height for automatically resized `textarea` editors, specified in CSS length units such as "px", "em" or "%" |
|
|minHeight |Minimum height for automatically resized `textarea` editors, specified in CSS length units such as "px", "em" or "%" |
|
||||||
|rows|Sets the rows attribute of a generated textarea |
|
|rows|Sets the rows attribute of a generated textarea |
|
||||||
|cancelPopups |<<.from-version "5.1.23">> if set to "yes", cancels all popups when the input gets focus |
|
|cancelPopups |<<.from-version "5.1.23">> if set to "yes", cancels all popups when the input gets focus |
|
||||||
|
|inputActions |<<.from-version 5.1.23>> Optional actions that are triggered every time an input event occurs within the input field or textarea |
|
||||||
|
|refreshTitle |<<.from-version 5.1.23>> An optional tiddler title that makes the input field update whenever the specified tiddler changes |
|
||||||
|
|
||||||
! Notes
|
! Notes
|
||||||
|
|
||||||
|
@ -19,3 +19,6 @@ The content of the `<$edit>` widget is ignored.
|
|||||||
|class |A CSS class to be added the generated editing widget |
|
|class |A CSS class to be added the generated editing widget |
|
||||||
|tabindex |Sets the `tabindex` attribute of the input or textarea to the given value |
|
|tabindex |Sets the `tabindex` attribute of the input or textarea to the given value |
|
||||||
|cancelPopups |<<.from-version "5.1.23">> if set to "yes", cancels all popups when the input gets focus |
|
|cancelPopups |<<.from-version "5.1.23">> if set to "yes", cancels all popups when the input gets focus |
|
||||||
|
|inputActions |<<.from-version 5.1.23>> Optional actions that are triggered every time an input event occurs within the input field or textarea |
|
||||||
|
|refreshTitle |<<.from-version 5.1.23>> An optional tiddler title that makes the input field update whenever the specified tiddler changes |
|
||||||
|
|
||||||
|
@ -120,6 +120,9 @@ function CodeMirrorEngine(options) {
|
|||||||
// Set up a change event handler
|
// Set up a change event handler
|
||||||
this.cm.on("change",function() {
|
this.cm.on("change",function() {
|
||||||
self.widget.saveChanges(self.getText());
|
self.widget.saveChanges(self.getText());
|
||||||
|
if(self.widget.editInputActions) {
|
||||||
|
self.widget.invokeActionString(self.widget.editInputActions);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.cm.on("drop",function(cm,event) {
|
this.cm.on("drop",function(cm,event) {
|
||||||
event.stopPropagation(); // Otherwise TW's dropzone widget sees the drop event
|
event.stopPropagation(); // Otherwise TW's dropzone widget sees the drop event
|
||||||
@ -142,10 +145,17 @@ CodeMirrorEngine.prototype.setText = function(text,type) {
|
|||||||
var self = this;
|
var self = this;
|
||||||
self.cm.setOption("mode",type);
|
self.cm.setOption("mode",type);
|
||||||
if(!this.cm.hasFocus()) {
|
if(!this.cm.hasFocus()) {
|
||||||
this.cm.setValue(text);
|
this.updateDomNodeText(text);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Update the DomNode with the new text
|
||||||
|
*/
|
||||||
|
CodeMirrorEngine.prototype.updateDomNodeText = function(text) {
|
||||||
|
this.cm.setValue(text);
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get the text of the engine
|
Get the text of the engine
|
||||||
*/
|
*/
|
||||||
|
@ -198,6 +198,13 @@ input[type="checkbox"] {
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input[type="search"]::-webkit-search-decoration,
|
||||||
|
input[type="search"]::-webkit-search-cancel-button,
|
||||||
|
input[type="search"]::-webkit-search-results-button,
|
||||||
|
input[type="search"]::-webkit-search-results-decoration {
|
||||||
|
-webkit-appearance:none;
|
||||||
|
}
|
||||||
|
|
||||||
.tc-muted {
|
.tc-muted {
|
||||||
color: <<colour muted-foreground>>;
|
color: <<colour muted-foreground>>;
|
||||||
}
|
}
|
||||||
@ -713,6 +720,12 @@ button.tc-btn-invisible.tc-remove-tag-button {
|
|||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tc-tag-button-selected,
|
||||||
|
.tc-list-item-selected a.tc-tiddlylink {
|
||||||
|
background-color: <<colour primary>>;
|
||||||
|
color: <<colour tiddler-background>>;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Page layout
|
** Page layout
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user