As the title says: is there a way to limit a <$text-edit type=number>
widget to positive, non-zero values only? (in other words set a min value)
Unfortunately $edit-text
doesn’t currently support HTML <input>
attributes like step
, min
, and max
, though I agree this would be a nice upgrade!
What you could do is display an error message when the field input doesn’t match your desired specifications. For instance:
<$edit-text type=number field=myField />
<% if [<currentTiddler>get[myField]compare:number:lteq[0]] %>
@@color:red; Please input a number greater than 0!@@
<% endif %>
Note that I’m using <currentTiddler>get[myField]
rather than simply {!!myField}
because get[myField]
only returns a result if myField
exists and is non-blank. You could substitute {!!myField}!is[blank]
or {!!myField}!match[]]
for the same result, but I tend to prefer get
because it’s easier to substitute a variable as the parameter.
Damn! From this old thread back in 2017, where @EricShulman seemed to have solved this, I really thought there was a way but it wasn’t documented
Good find! It looks like that PR never happened, though I don’t quite understand the arguments against it.
The code additions I suggested back in 2017 never made it into the core, and I don’t see any PR for them, but they are still valid in the current release (v5.3.6), and you can apply them in your own wiki, like this:
in $:/core/modules/editor/factory.js
, in EditTextWidget.prototype.execute()
, after this line:
this.isFileDropEnabled = this.getAttribute("fileDrop","no") === "yes";
add these lines:
this.editRangeMin = this.getAttribute("min",0);
this.editRangeMax = this.getAttribute("max",100);
this.editRangeStep = this.getAttribute("step",1);
and in $:/core/modules/editor/engines/simple.js
, in SimpleEngine(options)
, after this:
if(this.widget.isDisabled === "yes") {
this.domNode.setAttribute("disabled",true);
}
add these lines:
if(this.widget.editRangeMin) {
this.domNode.setAttribute("min",this.widget.editRangeMin);
}
if(this.widget.editRangeMax) {
this.domNode.setAttribute("max",this.widget.editRangeMax);
}
if(this.widget.editRangeStep) {
this.domNode.setAttribute("step",this.widget.editRangeStep);
}
enjoy,
-e
I added the lines as you instructed, then proceeded to write my textwidget like this:
<$edit-text tiddler=<<spellbook>> index=<<spell>> type=number min="0" default="1" size="2" tag=input/>
… and it works
(I did refresh the page to reload js stuff)
Maybe you could, alternatively, use the inputActions
of the EditTextWidget to run a macro on each change that checks if the value is greater than zero. If it is, then use an ActionSetfieldWidget to set it to a valid value. This way you wouldn’t need to overwrite core widgets.