/*\
title: $:/core/modules/widgets/select.js
type: application/javascript
module-type: widget
Select widget:
```
<$select tiddler="MyTiddler" field="text">
<$list filter="[tag[chapter]]">
$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();
//Create element
var domNode = this.document.createElement("select");
if(this.selectClass) {
domNode.className = this.selectClass;
}
// Assign data- attributes
this.assignAttributes(domNode,{
sourcePrefix: "data-",
destPrefix: "data-"
});
if(this.selectMultiple) {
domNode.setAttribute("multiple","multiple");
}
if(this.selectSize) {
domNode.setAttribute("size",this.selectSize);
}
if(this.selectTabindex) {
domNode.setAttribute("tabindex",this.selectTabindex);
}
if(this.selectTooltip) {
domNode.setAttribute("title",this.selectTooltip);
}
this.parentDomNode.insertBefore(domNode,nextSibling);
this.renderChildren(domNode,null);
this.domNodes.push(domNode);
this.setSelectValue();
if(this.selectFocus == "yes") {
this.getSelectDomNode().focus();
}
$tw.utils.addEventListeners(this.getSelectDomNode(),[
{name: "change", handlerObject: this, handlerMethod: "handleChangeEvent"}
]);
};
/*
Handle a change event
*/
SelectWidget.prototype.handleChangeEvent = function(event) {
// Get the new value and assign it to the tiddler
if(this.selectMultiple == false) {
var value = this.getSelectDomNode().value;
} else {
var value = this.getSelectValues()
value = $tw.utils.stringifyList(value);
}
this.wiki.setText(this.selectTitle,this.selectField,this.selectIndex,value);
// Trigger actions
if(this.selectActions) {
this.invokeActionString(this.selectActions,this,event);
}
};
/*
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,value);
} 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
if (this.selectMultiple) {
value = value === undefined ? "" : value;
var select = this.getSelectDomNode();
var values = Array.isArray(value) ? value : $tw.utils.parseStringArray(value);
for(var i=0; i < select.children.length; i++){
select.children[i].selected = values.indexOf(select.children[i].value) !== -1
}
} else {
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.domNodes[0];
};
// Return an array of the selected opion values
// select is an HTML select element
SelectWidget.prototype.getSelectValues = function() {
var select, result, options, opt;
select = this.getSelectDomNode();
result = [];
options = select && select.options;
for (var i=0; i