0 votes
by (150 points)

I want the user to be able to modify a numeric value something like: 

 

_total_energy <<textbox "$_total_energy" $_total_energy>>

However, the above code treats the input as a string. How do I make it treat the input as an integer? 

2 Answers

0 votes
by (23.6k points)
selected by
 
Best answer

You can use the parseInt() method to turn a string into an integer.

by (150 points)
Th thing I like about textbox is when I switch passages the variable has been changed to match the users input (I'm assuming there's a variable assignment when the user leaves the text box behind the scenes?)

Where/how would I wire parseInt() to have the same behavior?
by (159k points)
edited by

As the name of the <<textbox>> macro suggests the value assigned to the associated story variable is always Text, which in programming terms is known as a String value.

If you want the value stored in the associated variable to be an number then you need to use something like the Number() function to do this. You will also need to check that the Reader entered an actual number, because there is no guaranty that they did.

The following example shows how to do what you want, and also how to check that the number is within a set range.

<<set $number to 1>>

Enter a number between 1 and 10 inclusive <<textbox "$number" $number>>
@@#textbox-reply;@@ /% for error messages %/

<<link "Next Passage">>
	/* Try to convert the String value into a number. */
	<<set $number to Math.trunc($number)>>

	/* Check that the number is an Integer. */
	<<if not Number.isInteger($number)>>
		/* Show error message. */
        <<replace '#textbox-reply'>>Value is not a number.<</replace>>

	/* Check that the integer is within the range. */
	<<elseif $number < 1 or $number > 10 >>
		/* Show error message. */
		<<replace '#textbox-reply'>>Value is outside expected range.<</replace>>

	<<else>>
		/* Proceed to next passage. */
		<<goto "Some Other Passage">>
	<</if>>
<</link>>

 

by (23.6k points)

At the start of the next passage after the textbox you'd put something like:

<<set $myVariable to parseInt($myVariable)>>

That should do the trick. You might also send the player back to the previous passage if their input results in NaN.

0 votes
by (68.6k points)
edited by

First.  Your example code probably isn't doing what you think it is.  You're using two separate variables there: the temporary variable _total_energy and the story variable $_total_energy.  If that was intentional, then you're probably only going to be confusing potential helpers by doing that, so you might want to reconsider your naming scheme.

----

You'll probably want to verify that the player hasn't entered something that cannot be converted into an integer at, or near, the <<textbox>> itself, so you'll more than likely want something like the following:

@@#display_total_energy;$total_energy@@ <<textbox "_total_energy" $total_energy>> \
<<button "Change">>
	<<replace "#error_total_energy">><</replace>>
	<<set _total_energy to Number.parseInt(_total_energy.trim(), 10)>>
	<<if not Number.isInteger(_total_energy)>>
		<<replace "#error_total_energy">>Error: invalid integer<</replace>>
	<<else>>
		<<set $total_energy to _total_energy>>
		<<replace "#display_total_energy">>$total_energy<</replace>>
	<</if>>
<</button>> \
@@#error_total_energy;@@

 

PS:  If you ever needed to accept both floating point and integer numbers, then that might look something like the following instead:

@@#display_total_energy;$total_energy@@ <<textbox "_total_energy" $total_energy>> \
<<button "Change">>
	<<replace "#error_total_energy">><</replace>>
	<<set _total_energy to Number(_total_energy.trim())>>
	<<if Number.isNaN(_total_energy) or not Number.isFinite(_total_energy)>>
		<<replace "#error_total_energy">>Error: invalid number<</replace>>
	<<else>>
		<<set $total_energy to _total_energy>>
		<<replace "#display_total_energy">>$total_energy<</replace>>
	<</if>>
<</button>> \
@@#error_total_energy;@@

 

by (150 points)
Thanks for the detailed explanation!
...