I'd like to create custom widget in the way that is similar to React, so I do a simple refactor, seems it is OK to write Widget in ES6 Class syntax:
/*\
title: $:/core/modules/widgets/addup.js
type: application/javascript
module-type: widget
Sum up to 5 variables widget
Usage: <$addup val1="20" val2="80" />
\*/
(function () {
/*jslint node: true, browser: true */
/*global $tw: false */
'use strict';
const Widget = require('$:/core/modules/widgets/widget.js').widget;
class AddUpWidget extends Widget {
constructor(parseTreeNode, options) {
super(parseTreeNode, options);
this.initialise(parseTreeNode, options);
}
/*
Render this widget into the DOM
*/
render(parent, nextSibling) {
this.parentDomNode = parent;
this.computeAttributes();
this.execute();
const textNode = this.document.createTextNode(this.currentSum);
parent.insertBefore(textNode, nextSibling);
this.domNodes.push(textNode);
}
/*
Compute the internal state of the widget
*/
execute() {
// Get parameters from our attributes
this.val1 = this.getAttribute('val1', '0');
this.val2 = this.getAttribute('val2', '0');
this.val3 = this.getAttribute('val3', '0');
this.val4 = this.getAttribute('val4', '0');
this.val5 = this.getAttribute('val5', '0');
// Execute the math
this.currentSum =
Number(this.val1) + Number(this.val2) + Number(this.val3) + Number(this.val4) + Number(this.val5);
}
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
refresh(changedTiddlers) {
// Re-execute the filter to get the count
this.computeAttributes();
var oldCount = this.currentSum;
this.execute();
if (this.currentSum !== oldCount) {
// Regenerate and reRender the widget and replace the existing DOM node
this.refreshSelf();
return true;
} else {
return false;
}
}
}
exports.addup = AddUpWidget;
})();
In this way, I think I can create a button widget that can execute JS. I seems not very strightforward to execute javascript using built-in button widget, at least I didn't find a doc about this.