I'm working on a slider input system, and having a bit of trouble. Hopefully some fine folks here can point me in the right direction! I'm using Twine 2 and Sugarcube 2.
Goals:
- Have a slider input that spits out a value.
- I want to be able to use the output for various potential things: A measurement, a percentage, or even just a regular ol' number.
- Ideally I just want it to give me a variable, rather than rendering the output into a span. (Is it possible to convert the contents of a span into a variable?)
- Have a 'partnered' text input box.
- This box should be prefilled with a 'live' update of the slider's value
- If a user enters a value, the slider should adjust accordingly
- If an input value is out of the slider's range, it will snap to the appropriate min/max value
- Bonus points for having the slider animate into position when needed. Some CSS transition magic, perhaps?
- Bonus points for this being set up to update on keyrelease or some such, to make the slider respond to the textbox 'live'
- User input should be limited to numbers
- Bonus points if they can enter decimals (ie 1.8m, which would be stored as 180)
- Have this as a macro, so that it's not necessary to have a bunch of <script> wherever the functionality is needed.
What I've tried so far:
I started out by playing around with the slider in the <<numberpool>> macro set, found at the bottom of this page. This is really nice and all, but for the life of me I couldn't figure out how to use the output value quite in the ways I want, such as displaying it as a measurement, ie 1.7m.
I tried combining it with the <<numberpool>> and <<onchange>> macros from the set and managed to get a textbox updating when the user releases the slider handle, which is a start. Here's my code:
<<set $defaultHeight = "170">>
<<numberpool "$height">>
<<numberslider "$tempHeight" $defaultHeight 140 200 1>>
<<onchange>>
<<replace "#heightSpan">><<textbox "$playerHeight" $tempHeight>><</replace>>
<</numberpool>>
You are <span id="heightSpan"><<textbox "$playerHeight" $defaultHeight>></span>cm tall.
The firstmost issue with this is the error that gets thrown up after the closing <</numberpool>>:
Error: cannot execute macro <<numberslider>>: <<replace>>: no elements matched the selector "#heightSpan"
I'm not sure I'm understanding the cause for this error, as it seems to perform as expected.
Regardless, this solution has some issues:
- I haven't figured out how to remove/hide the slider output from its default position next to the slider. Ideally I'd like for the linked <<textbox>> to sit there instead. [EDIT - currently achieving this with a display: none; in the CSS for the appropriate span]
- Nor can I figure out how to style or otherwise present the output (ie 1.7 meters)
- The reverse functionality I'm after isn't quite there (though I'm still hacking some solution together for that). Currently I have an "update slider" link which re-renders the slicer chunk of code with an updated $defaultHeight that does the job of updating the slider, but I'd rather this happens when the user either hits enter, or deselects the textbox.
- The textbox doesn't update 'live'.
Alternatively, I've also experimented with a javascript approach using the following foundation:
<input type="range" value=0 min=0 max=10 id="rangevalue"> <span id="text">0</span>
<script>
$("#rangevalue").mousemove(function () {
$("#text").html($("#rangevalue").val())
})
</script>
Works like a charm in a vaccuum, however I run into the same issue where I don't know how to turn the contents of that <span id="text"> into a variable that I can track and make proper use of. Also no idea where I'd start as far as making the slider respond to the text input.
I feel like I must be close, but the final pieces of this puzzle elude me. Hopefully I've laid out this post thoroughly enough!
- EDIT -
A thought - maybe I can figure out how to reverse engineer the <<onchange>> macro enough to make a similar one that updates on mouse move, or some such...
- EDIT 2 -
A further thought, <<onchange>> shouldn't be needed at all if I can just figure out how to make the <<numberslider>>'s variable update the moment the value changes, rather than when the mouse is released...