This page is part of a static HTML representation of the TiddlyWiki at https://tiddlywiki.com/dev/

Widget refresh tutorial part III

29th October 2022 at 8:10pm

This tutorial is intended to demonstrate a few examples of when calls to the refresh method happen vs. when a widget is recreated from scratch.

This is accomplished with a refreshcount.js widget which sets a counter to zero when the widget is created and increments the counter every time the refresh method is called. Here is the full code:

/*\

widget to count the number of times this widget refreshes

\*/
(function() {

/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";

var Widget = require("$:/core/modules/widgets/widget.js").widget;

var MyWidget = function(parseTreeNode, options) {
	this.refreshCount = 0;
	this.initialise(parseTreeNode, options);
};

/*
Inherit from the base widget class
*/
MyWidget.prototype = new Widget();

/*
Render this widget into the DOM
*/
MyWidget.prototype.render = function(parent, nextSibling) {
	this.parentDomNode = parent;
	var textNode = this.document.createTextNode(this.refreshCount + " refreshes");
	parent.insertBefore(textNode, nextSibling);
	this.domNodes.push(textNode);
};

MyWidget.prototype.refresh = function(changedTiddlers) {
	// Regenerate and rerender the widget and replace the existing DOM node
	this.refreshCount++;
	this.refreshSelf();
	return true;
};

exports.refreshcount = MyWidget;

})();

These are the key parts of the code from above:

this.refreshCount = 0;
this.document.createTextNode(this.refreshCount + " refreshes");
this.refreshCount++;

In the following example (see Widget refresh demo III for the code), two instances of the refreshcount widget are created. One at the top level and the other inside a list widget whose filter results depend on the value in the text field of the test widget. The tiddler store can be modified in a few ways via two buttons and an input box:

[ { "title": "$:/DefaultTiddlers", "text": "[[refresh count widget]]" } ] [ { "title": "test", "text": "Text field of tiddler='test'" } ] [ { "title": "refreshcount.js", "text": "/*\\\n\nwidget to count the number of times this widget refreshes\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar MyWidget = function(parseTreeNode, options) {\n\tthis.refreshCount = 0;\n\tthis.initialise(parseTreeNode, options);\n};\n\n/*\nInherit from the base widget class\n*/\nMyWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nMyWidget.prototype.render = function(parent, nextSibling) {\n\tthis.parentDomNode = parent;\n\tvar textNode = this.document.createTextNode(this.refreshCount + \" refreshes\");\n\tparent.insertBefore(textNode, nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\nMyWidget.prototype.refresh = function(changedTiddlers) {\n\t// Regenerate and rerender the widget and replace the existing DOM node\n\tthis.refreshCount++;\n\tthis.refreshSelf();\n\treturn true;\n};\n\nexports.refreshcount = MyWidget;\n\n})();\n", "created": "20190201005026324", "modified": "20190202143451303", "module-type": "widget", "tags": "", "type": "application/javascript" } ] [ { "title": "refresh count widget", "text": "\n\n*<$button set=\"test!!test\" setTo=\"hello\">Modify a different tiddler</$button>\n*<$button set=\"!!test\" setTo=\"hello\">Modify this tiddler</$button>\n*<$edit-text focus=yes tiddler=test tag=input/>\n\n<div>\n<div style=\"display:inline-block;width: 49%;vertical-align: text-top;word-wrap: break-word;}\">\n\n```\n<$refreshcount/>\n```\n\nRenders as:\n\n<$refreshcount/>\n</div>\n\n<div style=\"display:inline-block;width: 49%;vertical-align: text-top;word-wrap: break-word;}\">\n\n```\n<$list filter=\"[[test]get[text]]\">\n<<currentTiddler>><br>\n<$refreshcount/>\n</$list>\n```\n\nRenders as:\n\n<$list filter=\"[[test]get[text]]\">\n<<currentTiddler>><br>\n<$refreshcount/>\n</$list>\n" } ] </div> </div>

  • Modify a different tiddler - every time this button is clicked, both counters increment, indicating the refresh method is being called
  • Modify this tiddler - clicking this button modifies the tiddler itself. In earlier TiddlyWiki versions that caused both widgets to be recreated from scratch and the counters are thereby reset to zero. Since version 5.2.0 modifying another field in this tiddler does not cause the widgets to be recreated and the counters are not reset.
  • Text field of tiddler='test' - typing text into the input box causes the counter in the standalone refreshcount widget to be incremented. But the other instance of the widget is embedded inside a list widget whose filter output depends on the value of the tiddler field which is being modified. This causes it to recreate its children from scratch and the counter is reset every time. So with every keystroke, the counter on the left is incremented, but the counter on the right goes to/stays at zero.