Hello! I've been searching for ways for user to input data, which could be stored, and found only standard javascript alert window with input textbox available. What I would like to use is a textbox for user to type his name or other text, which can be shown directly on a page, and not in the pop-up window. Is there any way to do this? I hope what I have requested is possible.
Comments
1. Harlowe:
Besides the (prompt:) macro there does not appear to be any built-in way to do so.
You could try to use standard HTML <input> & <textarea> tags but Harlowe also does not appear to have a submit button macro so you would have to implement one using some HTML and Javascript. To make things more complex I could not determine a way for an Author to use javascript to save the input into a variable nor to load the next passage after someone clicks on the submit button.
2. SugarCube: (third-party story format)
This story format has both <<textbox>> and <<button>> macros, which I believe still work in Twine 2.
But maybe someone else like Leon will have a better answer.
Two parts: one is a custom script that replaces a hook with the value of a textbox. We call that using an onclick attribute on a button in the passage. Here's the script that you add to your javascript file for the story. I'm also adding it to the "customScripts" namespace: On the passage end of things you need to make sure that the hook and the input use the same name. The hook in this example is named "fname" and the input has an attribute of "fname" as well. When we call the function we need to give it the string "fname" too. Whenever your player clicks on the button it'll call the script from above. "fname" could be anything you want as long as it's the same for the hook, the input name, and the string you give the function.
Then, to make things easier to reuse the information later, we do a check every 100ms to set a variable (in this case $rivalName) equal to whatever the hook currently is. Annoying to set up, however, once it's in place you can use this pattern for any amount of inputs you'd like. Just make sure the hook name and the input name are the same.
I could simplify this further if there was a way to set Harlowe's variables directly from javascript, but I can't seem to find where it stores them.
The steps I followed were:
1. Put the first chunk of code into the "Edit Story JavaScript" part of my Twine 2 story.
2. Put the second lot of code into a start passage called "Passage01" with a Twine link to "Passage 02"
3. In Passage02, I put "The rival name is $rivalName"
Any ideas on how to get it to work, as per the example above?
What’s not happening is that "fname" isn’t communicating properly.
I have an idea, though, but no time right now… I’ll check this out again later.
(Btw, this shouldn’t be too difficult to use with a textarea.)
Tim
You may want to think about a couple of possible issues:
1. The timer event created by Harlowe's (live:) macro will keep firing until you manually (stop:) it.
2. If you show a link to the Reader before they have clicked on the button then it is quite likely that they will click on the link instead of the button.
The following code solves both of these issues:
This is what didn't work for me... The Console updates, yes, but not the Dom.
I'll try your version of the code, though.
Just to be clear, I am using Twine 2.0.4 with Harlowe 1.0.1
By "does not work" I mean that the variable $rivalName stays set to "your unnamed rival" no matter what i put in the box, or how many times I press the button.
And I think in your example, greyelf, when I click the button, the links are supposed to show, but nothing happens when I click the button.
You placed the Javascript code in your story's Story Javascript area and the passage code in a Passage and it does not work?
If you open the browser's Developer Tools Console, refresh the page, enter a value and then click the button does the console show an error?
Yes. I did the above and it does not work.
On that note, I just noticed in another of my posts, that the forum program added some semicolons to the code I posted. I am a total noob when it comes to JavaScript, so I just copied and pasted the JS code above into the Story JavaScript area. I noticed there are some semicolons in the code. Are they meant to be there?
It does not show an error. Nothing actually happens. (I entered the value "Peter" and pressed the button).
The <body> tag that appeared in the developer window on the bottom seems to be automatically highlighted in purple and flickering. (I have attached an image to this post to show you).
Also, as an answer to your question, JavaScript statements are typically ended with a semicolon (similar to ending a sentence with a period).
Okay, I had gone to the developer console. I have now gone to the JavaScript Console, and it is as you say that it mentions that fname changes when I input a new value and click the button. So, it is as you say that the JavaScript is working, but it is not communicating with the twine variable.
I can't make it work with multiple fields, the second always give me an error "not defined". Can you show a basic example, with two fields?
Javascript:
if (typeof window.customScripts == "undefined") {
window.customScripts = {
submitName: function(inputName) {
var newName = $("input[name='" + inputName + "']")[0].value;
$("tw-hook[name*='" + inputName + "']").text(newName);
console.log(inputName + " changed.")
}
};
};
if (typeof window.customScripts == "undefined") {
window.customScripts = {
submitName: function(inputHeight) {
var newHeight= $("input[name='" + inputHeight + "']")[0].value;
$("tw-hook[name*='" + inputHeight + "']").text(newHeight);
console.log(inputHeight + " changed.")
}
};
};
Code (Ok button to valid all fields together):
Name [...]<fname|. <input type="text" name="fname" value="...">
Height [...]<fheight|. <input type="text" name="fheight" value="...">
<button type="submit" onclick="customScripts.submitName('fname');
customScripts.submitName('fheight')">OK</button>
(live:100ms)[(set:$yourName = ?fname)(set:$yourHeight = ?fheight)]
State.variables[varName] = newValue;
So this:
$("tw-hook[title*='" + inputName + "']").text(newName);
Might become:
State.variables[inputName] = newName;
Twine and Harlowe use modern, namespaced Javascript so it is not possible to access those variables from the Javascript console but if you want to explore them you can cache them away this way:
window.interesting_stuff = {"Engine": Engine, "State": State, "Passages": Passages, "Renderer": Renderer, "Selectors": Selectors, "Utils": Utils}
console.log("Stored interesting stuff in window.interesting_stuff");
You can also poke around them with a debugger; statement in your Story Javascript.
What's your character born place?
<input type="radio" name="fhome" value="London">London
<input type="radio" name="fhome" value="São Paulo">São Paulo
<input type="radio" name="fhome" value="Madrid">Madrid
Any hint on how to pass the value of fhome? Original function (to input text) is:
if (typeof window.customScripts == "undefined") {
window.customScripts = {
submitName: function(inputName) {
var newName = $("input[name='" + inputName + "']")[0].value;
$("tw-hook[name*='" + inputName + "']").text(newName);
console.log(inputName + " changed.")
}
};
};
The following Javascript corrects this issue:
Greyelf's edited javascript works perfectly for text input fields, but the downside is that it saves the variable as a string, which doesn't work quite so well when you need a variable as a number (say character age, or similar stuff). Is there a way to modify it to save input as a non-string? Or is there a way to 'convert' a string containing numbers into a numerical value?
Second, is there a way to make a similar script for a dropdown menu? Since it's a <select> rather than an <input> tag, I have no idea how to edit the javascript to do what I want it to do. I can't even figure out how to get l3m35's radio input script to work (it errors out), and that's still an <input> tag.