Re-introduce the checkbox widget

This commit is contained in:
Jeremy Ruston 2013-01-18 09:33:16 +00:00
parent 71f6194f01
commit 5e7e1fa93d
2 changed files with 117 additions and 7 deletions

View File

@ -0,0 +1,111 @@
/*\
title: $:/core/modules/widget/checkbox.js
type: application/javascript
module-type: widget
Implements the checkbox widget.
```
<$checkbox tag="done"/>
<$checkbox tiddler="HelloThere" tag="red"/>
<$checkbox tag="done">
<$view title/>
</$checkbox>
```
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var CheckboxWidget = function(renderer) {
// Save state
this.renderer = renderer;
// Generate child nodes
this.generate();
};
CheckboxWidget.prototype.generate = function() {
// Get the parameters from the attributes
this.tiddlerTitle = this.renderer.getAttribute("tiddler",this.renderer.getContextTiddlerTitle());
this.tagName = this.renderer.getAttribute("tag");
this["class"] = this.renderer.getAttribute("class");
// Compute classes
var classes = ["tw-checkbox"];
if(this["class"]) {
$tw.utils.pushTop(classes,this["class"]);
}
// Create the checkbox and span elements
var nodeCheckbox = {
type: "element",
tag: "input",
attributes: {
type: {type: "string", value: "checkbox"}
}
},
nodeSpan = {
type: "element",
tag: "span",
children: this.renderer.parseTreeNode.children
};
// Set the state of the checkbox
if(this.getValue()) {
$tw.utils.addAttributeToParseTreeNode(nodeCheckbox,"checked","true");
}
// Set the return element
this.tag = "label";
this.attributes ={"class": classes.join(" ")};
this.children = this.renderer.renderTree.createRenderers(this.renderer.renderContext,[nodeCheckbox,nodeSpan]);
this.events = [{name: "change", handlerObject: this, handlerMethod: "handleChangeEvent"}];
};
CheckboxWidget.prototype.getValue = function() {
var tiddler = this.renderer.renderTree.wiki.getTiddler(this.tiddlerTitle);
return tiddler ? tiddler.hasTag(this.tagName) : false;
};
CheckboxWidget.prototype.handleChangeEvent = function(event) {
var checked = this.children[0].domNode.checked,
tiddler = this.renderer.renderTree.wiki.getTiddler(this.tiddlerTitle);
if(tiddler && tiddler.hasTag(this.tagName) !== checked) {
var newTags = tiddler.fields.tags.slice(0),
pos = newTags.indexOf(this.tagName);
if(pos !== -1) {
newTags.splice(pos,1);
}
if(checked) {
newTags.push(this.tagName);
}
this.renderer.renderTree.wiki.addTiddler(new $tw.Tiddler(tiddler,{tags: newTags}));
}
};
CheckboxWidget.prototype.refreshInDom = function(changedAttributes,changedTiddlers) {
// Check if any of our attributes have changed, or if a tiddler we're interested in has changed
if(changedAttributes.tiddler || changedAttributes.tag || changedAttributes["class"]) {
// Regenerate and rerender the widget and replace the existing DOM node
this.generate();
var oldDomNode = this.renderer.domNode,
newDomNode = this.renderer.renderInDom();
oldDomNode.parentNode.replaceChild(newDomNode,oldDomNode);
} else {
// Update the checkbox if necessary
if(changedTiddlers[this.tiddlerTitle]) {
this.children[0].domNode.checked = this.getValue();
}
// Refresh children
$tw.utils.each(this.children,function(node) {
if(node.refreshInDom) {
node.refreshInDom(changedTiddlers);
}
});
}
};
exports.checkbox = CheckboxWidget;
})();

View File

@ -2,17 +2,16 @@ title: TaskManagementExample
! Outstanding tasks
<<list filter:"[tag[task]!tag[done]sort[created]]"><
<$list filter="[tag[task]!tag[done]sort[created]]">
<<checkbox tag:done>< <<view title link>> >>
<$checkbox tag="done"> <$view field="title" format="link"/></$checkbox>
>>
</$list>
! Completed tasks
<<list filter:"[tag[task]tag[done]sort[created]]"><
<$list filter="[tag[task]tag[done]sort[created]]">
<<checkbox tag:done>< <<view title link>> >>
>>
<$checkbox tag="done"> <$view field="title" format="link"/></$checkbox>
</$list>