diff --git a/core/modules/widgets/select.js b/core/modules/widgets/select.js new file mode 100644 index 000000000..79a169f7e --- /dev/null +++ b/core/modules/widgets/select.js @@ -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]]"> + + + +``` + +\*/ +(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; + +})(); diff --git a/editions/tw5.com/tiddlers/widgets/SelectWidget.tid b/editions/tw5.com/tiddlers/widgets/SelectWidget.tid new file mode 100644 index 000000000..e6dabff1f --- /dev/null +++ b/editions/tw5.com/tiddlers/widgets/SelectWidget.tid @@ -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 `` 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=<> default='widget'> +<$list filter='[all[shadows+tiddlers]tags[]sort[title]]'> + + +"/> + +The <$link to=<>>state tiddler currently contains <$edit-text tiddler=<> 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 `