This macro set lets user create custom input elements which can run arbitrary code when their value changes.
<<input [...attributes...]>>
...code to run anytime the value changes...
<<onvalue value [override]>> ...code to run when a given value is entered...
[<<onvalue otherValue [override]>> ... ]
[<<default>> ...code to run if no matching value is found... ]
[<<optionsfrom collection>>]
<</input>>
This macro accepts HTML attributes as well as a few custom ones. Check out possible types and attributes on MDN.
The desired input type can be set either by supplying a type
attribute or by using one of the bespoke type aliases :
Macro name | Return value | Accepts <<optionsfrom>> |
---|---|---|
input-area 1 |
string |
false |
input-checkbox |
boolean |
false |
input-color |
string (hexadecimal color code) |
false |
input-date |
Date object | true |
input-email |
string |
true |
input-file |
File list | false |
input-number |
number |
true |
input-password |
string |
true |
input-range |
number |
false |
input-search |
string |
true |
input-select 1 |
string |
required |
input-tel |
string |
true |
input-text |
string |
true |
input-time |
string |
true |
input-url |
string |
true |
When using <<input>>
without a type
attribute, it defaults to text
.
Some valid input types are not part of the built-in presets, like radio
, button
... This is either because Sugarcube already offers better alternatives, or their use did not fit well into the macro's structure. You can still create them by using <<input type 'desired type'>>
, but you will need to do the processing yourself to get the desired effect/data out of them.
Attribute name | Usage | Default value | Input type |
---|---|---|---|
goto |
Sets a passage to navigate to when pressing enter . Accepts link markup or a passage name string |
None | any input you can type in |
label |
Sets the input's label text | Empty string | all |
max |
Sets a number input's max value | Number.MAX_SAFE_INTEGER | number, range |
min |
Sets a number input's min value | Number.MIN_SAFE_INTEGER | number, range |
sanitize |
Disables Sugarcube markup in the return string | false | all that return strings |
type |
Sets <<input>> 's type. Does nothing for the <<input-type>> variations |
text |
- |
value |
The input's starting value. If variable is used, the bound variable is set accordingly |
None | all but file |
variable |
Binds an input to a variable, similar to what Sugarcube's macros do by default | None | all |
Any non-special attribute is added to the resulting input element.
Unlike their Sugarcube counterparts, these macros only initialize their attached variable if a value
attribute is provided.
<<onvalue>>
checks the input's current value against its first argument, if it matches, it executes the attached code. This first argument can be:
- a primitive whose type matches the input's return value
- a callback
- a regular expression for inputs that return strings
- a date object for
date
inputs The second argument is an override which will be set as the input's value instead of the matched result.
<<input>>
<<replace '#result'>>_result<</replace>>
<<onvalue 'Mark'>>
/* With a string */
<<set _result = 'Oh, hi Mark!'>>
<<onvalue `name => name.toLowerCase().startsWith('z')`>>
/* With a callback */
<<set _result = 'Come on, your name can\'t start with a z!'>>
<<onvalue `/[jJ]+[oO]+[hH]+[nN]+/`>>
/* With a regular expression */
<<set _result = 'Hey, John! Welcome!'>>
<<default>>
/* If the value wasn't matched, run this */
<<set _result = 'Welcome '+ _this.value>>
<</input>>
<span id='result'/>
Code in the main macro call runs whenever the input changes, after <<onvalue/default>>
. This is why we can afford to set _result
, then use <<replace>>
to print it to passage.
<<optionsfrom>>
is used to provide:
- auto-complete suggestions
- selectable options for
input-select
It works in the exact same fashion as in vanilla Sugarcube macros.
<<input-url>>
/* Open url in new tab */
<<run open(_this.value)>>
<<optionsfrom ['https://twinery.org','https://github.com/tmedwards/sugarcube-2/tree/master','https://developer.mozilla.org','https://github.com/MalifaciousGames/Mali-s-Macros']>>
<</input-url>>
The _this
variable is a shadowed variable available to all of the macro's callbacks. It is an object containing the following properties :
- value : input's current value
- input : the input element
- wrapper : the input's wrapping
<label>
element - config : the input's inner
config
object
By default, all input elements are wrapped in a <label>
. If the <<optionsfrom>>
tag is used, it will add a <datalist>
with the corresponding <option>
.
<label>
<input>
[<datalist>...</datalist>]
</label>
input-select
is an exception, it generates a <select>
element with the <option>
added directly to it. See MDN for more details.
Setting a player character's name
<<input-text variable '$name' label 'Player name : ' sanitize true>>
<<replace '#proceed'>>
Welcome $name !
[[Proceed|nextPassage]]
<</replace>>
<</input-text>>
<span id='proceed'/>
Here, we use sanitize
so the player cannot input Sugarcube code that would run whenever their name is printed.
A simple password check
<<input-password label 'Enter password : '>>
<<onvalue 'superPassword'>>
<<goto [[nextPassage]]>>
<<default>>
<<replace '#psw'>>INVALID PASSWORD!<</replace>>
<</input-password>>
<span id='psw'/>
Pseudo messenger app
<div id='chat'></div>
<<input sanitize true placeholder 'Your message here.'>>
<<default>>
/* On any input, append a new message to the chat element */
<<append '#chat'>>
<div class='message'>_this.value</div>
<</append>>
/* Empty the input field */
<<run _this.input.value = ''>>
<</input>>
Navigate to any story passage
<<input-text label 'Desired passage : '>>
<<if Story.has(_this.value)>>
/* Passage exists */
<<goto _this.value>>
<<else>>
<<run UI.alert(`No passage found for ${_this.value} !`)>>
<</if>>
<<optionsfrom Story.lookup(p => p).map(p => p.title)>>
<</input-text>>
This is more of a debugging tool but we could use an array of fast-travel locations which the player gradually unlocks.