mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-27 03:57:21 +00:00
Add first pass at select widget
This commit is contained in:
parent
f999b2e931
commit
3182a2d599
139
core/modules/widgets/select.js
Normal file
139
core/modules/widgets/select.js
Normal file
@ -0,0 +1,139 @@
|
||||
/*\
|
||||
title: $:/core/modules/widgets/select.js
|
||||
type: application/javascript
|
||||
module-type: widget
|
||||
|
||||
Select widget:
|
||||
|
||||
```
|
||||
<$select tiddler="MyTiddler" field="text">
|
||||
<$list filter="[tag[chapter]]">
|
||||
<option value=<<currentTiddler>>>
|
||||
<$view field="description"/>
|
||||
</option>
|
||||
</$list>
|
||||
</$select>
|
||||
```
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||
|
||||
var SelectWidget = function(parseTreeNode,options) {
|
||||
this.initialise(parseTreeNode,options);
|
||||
};
|
||||
|
||||
/*
|
||||
Inherit from the base widget class
|
||||
*/
|
||||
SelectWidget.prototype = new Widget();
|
||||
|
||||
/*
|
||||
Render this widget into the DOM
|
||||
*/
|
||||
SelectWidget.prototype.render = function(parent,nextSibling) {
|
||||
this.parentDomNode = parent;
|
||||
this.computeAttributes();
|
||||
this.execute();
|
||||
this.renderChildren(parent,nextSibling);
|
||||
this.setSelectValue();
|
||||
$tw.utils.addEventListeners(this.getSelectDomNode(),[
|
||||
{name: "change", handlerObject: this, handlerMethod: "handleChangeEvent"}
|
||||
]);
|
||||
};
|
||||
|
||||
/*
|
||||
Handle a change event
|
||||
*/
|
||||
SelectWidget.prototype.handleChangeEvent = function(event) {
|
||||
var value = this.getSelectDomNode().value;
|
||||
this.wiki.setText(this.selectTitle,this.selectField,this.selectIndex,value);
|
||||
};
|
||||
|
||||
/*
|
||||
If necessary, set the value of the select element to the current value
|
||||
*/
|
||||
SelectWidget.prototype.setSelectValue = function() {
|
||||
var value = this.selectDefault;
|
||||
// Get the value
|
||||
if(this.selectIndex) {
|
||||
value = this.wiki.extractTiddlerDataItem(this.selectTitle,this.selectIndex);
|
||||
} else {
|
||||
var tiddler = this.wiki.getTiddler(this.selectTitle);
|
||||
if(tiddler) {
|
||||
if(this.selectField === "text") {
|
||||
// Calling getTiddlerText() triggers lazy loading of skinny tiddlers
|
||||
value = this.wiki.getTiddlerText(this.selectTitle);
|
||||
} else {
|
||||
if($tw.utils.hop(tiddler.fields,this.selectField)) {
|
||||
value = tiddler.getFieldString(this.selectField);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(this.selectField === "title") {
|
||||
value = this.selectTitle;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Assign it to the select element if it's different than the current value
|
||||
var domNode = this.getSelectDomNode();
|
||||
if(domNode.value !== value) {
|
||||
domNode.value = value;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Get the DOM node of the select element
|
||||
*/
|
||||
SelectWidget.prototype.getSelectDomNode = function() {
|
||||
return this.children[0].domNodes[0];
|
||||
};
|
||||
|
||||
/*
|
||||
Compute the internal state of the widget
|
||||
*/
|
||||
SelectWidget.prototype.execute = function() {
|
||||
// Get our parameters
|
||||
this.selectTitle = this.getAttribute("tiddler",this.getVariable("currentTiddler"));
|
||||
this.selectField = this.getAttribute("field","text");
|
||||
this.selectIndex = this.getAttribute("index");
|
||||
this.selectClass = this.getAttribute("class");
|
||||
this.selectDefault = this.getAttribute("default");
|
||||
// Make the child widgets
|
||||
var selectNode = {
|
||||
type: "element",
|
||||
tag: "select",
|
||||
children: this.parseTreeNode.children
|
||||
};
|
||||
if(this.selectClass) {
|
||||
$tw.utils.addAttributeToParseTreeNode(selectNode,"class",this.selectClass);
|
||||
}
|
||||
this.makeChildWidgets([selectNode]);
|
||||
};
|
||||
|
||||
/*
|
||||
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||
*/
|
||||
SelectWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes();
|
||||
// If we're using a different tiddler/field/index then completely refresh ourselves
|
||||
if(changedAttributes.selectTitle || changedAttributes.selectField || changedAttributes.selectIndex) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
// If the target tiddler value has changed, just update setting and refresh the children
|
||||
} else {
|
||||
if(changedTiddlers[this.selectTitle]) {
|
||||
this.setSelectValue();
|
||||
}
|
||||
return this.refreshChildren(changedTiddlers);
|
||||
}
|
||||
};
|
||||
|
||||
exports.select = SelectWidget;
|
||||
|
||||
})();
|
80
editions/tw5.com/tiddlers/widgets/SelectWidget.tid
Normal file
80
editions/tw5.com/tiddlers/widgets/SelectWidget.tid
Normal file
@ -0,0 +1,80 @@
|
||||
created: 201310241419
|
||||
modified: 201310300837
|
||||
tags: widget
|
||||
title: SelectWidget
|
||||
|
||||
! Introduction
|
||||
|
||||
The select widget displays an [[HTML select element|https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select]] containing a list of items defined by `<option>` and `<optgroup>` elements and binds the selected value to the text of a tiddler field or index.
|
||||
|
||||
For example, this select widget displays a list of the tags in this wiki:
|
||||
|
||||
<$macrocall $name="wikitext-example-without-html" src="<$select tiddler=<<qualify 'select-demo'>> default='widget'>
|
||||
<$list filter='[all[shadows+tiddlers]tags[]sort[title]]'>
|
||||
<option value=<<currentTiddler>>><$view field='title'/></option>
|
||||
</$list>
|
||||
</$select>"/>
|
||||
|
||||
The <$link to=<<qualify "select-demo">>>state tiddler</$link> currently contains <$edit-text tiddler=<<qualify "select-demo">> tag="input" default=""/>. See the text change as you switch entries in the select widget. Try changing the value of the state tiddler and see the select widget change. Notice how the select widget only displays an entry if there is a precise match with the tiddler text.
|
||||
|
||||
! Content and Attributes
|
||||
|
||||
The content of the `<$select>` widget should be one or more HTML `<option>` or `<optiongroup>` elements that provide the available values.
|
||||
|
||||
|!Attribute |!Description |
|
||||
|tiddler |The title of the tiddler containing the value (defaults to the current tiddler) |
|
||||
|field |The field name for the value in the current tiddler (defaults to "text") |
|
||||
|index |The index of a property in a [[DataTiddler|DataTiddlers]] (takes precedence over the field attribute) |
|
||||
|class |CSS classes to be assigned to the HTML select element |
|
||||
|default |Default value to be used if the tiddler, field or index specifies a missing value |
|
||||
|
||||
|
||||
! Examples
|
||||
|
||||
!! Simple Lists
|
||||
|
||||
This example sets the title of the current wiki [[$:/SiteTitle]] to one of a list of book titles:
|
||||
|
||||
<$macrocall $name="wikitext-example-without-html" src="<$select tiddler='$:/SiteTitle'>
|
||||
<option>A Tale of Two Cities</option>
|
||||
<option>A New Kind of Science</option>
|
||||
<option>The Dice Man</option>
|
||||
</$select>"/>
|
||||
|
||||
!! Value lists
|
||||
|
||||
In this example the `value` attribute has been used to specify the text that should be used as the value of the entry instead of the display text.
|
||||
|
||||
<$macrocall $name="wikitext-example-without-html" src="<$select tiddler='$:/SiteTitle'>
|
||||
<option value='cities'>A Tale of Two Cities</option>
|
||||
<option value='science'>A New Kind of Science</option>
|
||||
<option value='dice'>The Dice Man</option>
|
||||
</$select>"/>
|
||||
|
||||
!! Option Groups
|
||||
|
||||
Entries in the list can be grouped together with the `<optgroup>` element
|
||||
|
||||
<$macrocall $name="wikitext-example-without-html" src="<$select tiddler='$:/SiteTitle'>
|
||||
<optgroup label='Fiction'>
|
||||
<option value='cities'>A Tale of Two Cities</option>
|
||||
<option value='dice'>The Dice Man</option>
|
||||
</optgroup>
|
||||
<optgroup label='Non-fiction'>
|
||||
<option value='science'>A New Kind of Science</option>
|
||||
<option value='recursive'>The Recursive Universe</option>
|
||||
</optgroup>
|
||||
</$select>"/>
|
||||
|
||||
!! Generated Lists
|
||||
|
||||
The ListWidget can be used to generate the options for a select widget. For example, here we combine a select widget listing all the tiddlers tagged ''introduction'' with a transclusion to display the text of the selected one.
|
||||
|
||||
<$macrocall $name="wikitext-example-without-html" src="<$select tiddler='$:/generated-list-demo-state'>
|
||||
<$list filter='[tag[introduction]]'>
|
||||
<option><$view field='title'/></option>
|
||||
</$list>
|
||||
</$select>
|
||||
<$tiddler tiddler={{$:/generated-list-demo-state}}>
|
||||
<$transclude mode='block'/>
|
||||
</$tiddler>"/>
|
Loading…
Reference in New Issue
Block a user