Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

multine textinput, textarea?

Hello,

I'm new to Twine, but I've been trying to figure out how to modify the textinput macro to allow multiline user input, and then save the result to a variable. Is there a straightforward way to do this, and allow textinput to use <textarea ...> or some such (e.g. <textarea name="description" cols="40" rows="5" id = "mytext"></textarea>)?

Thanks.
Wally

Comments

  • You need to state which story format you are using as the answer is different depending on which you are using.
  • Sorry - I'm using Jonah right now, but I only just started so I'm more than willing to switch to any format that would allow this functionality. Please let me know if you have an answer for a different format, or if you recommend a particular format for a game with a lot of text inputs of this time.
  • Creating a new <<textarea>> macro is fairly easy and the existing javascript code you would want to based your new macro on is this. A simple version would look something like the following:

    version.extensions.textAreaMacro = {
    major: 1,
    minor: 0,
    revision: 0
    };

    macros.textarea = {
    handler: function (A, C, D, parser) {
    var match,
    class_ = C.replace('area','Area'),
    q = A.querySelectorAll('textarea'),
    id = class_ + "|" + ((q &amp;&amp; q.length) || 0);
    input = insertElement(null, 'textarea', id, class_);
    input.name=D[0];
    // IE 8 support - delay insertion until now
    A.appendChild(input);
    if (D[1]) {
    match = new RegExp(Wikifier.linkFormatter.lookahead).exec(parser.fullMatch());
    if (match) {
    Wikifier.linkFormatter.makeLink(A,match, macros.button.callback, 'button');
    } else {
    Wikifier.linkFormatter.makeLink(A,[0,(D[2] || D[1]),D[1]], macros.button.callback, 'button');
    }
    }
    }
    };
    The main issue is that the existing <<button>> macro, which is what saves the contents of a <<textinput>> into it's relevant variable, does not know about your <<textarea>> macro so its value will not be saved. To fix this we have to extend/override the part of the <<button>> macro (the callback function) that does the saving of variables.

    There are a number of ways to extend an existing object's functions but I am going to use the override technique. So using the existing <<button>> macro code as a starting point I ended up with:

    function override(object, methodName, callback) {
    object[methodName] = callback(object[methodName])
    }

    override(macros.button, 'callback', function(original) {
    return function() {
    // Call the original version of the callback to process all textinput,checkbox,radiobutton elements.
    original.apply(this, arguments);

    // Now process all the textArea elements.
    var el = findPassageParent(this);
    if (el) {
    var inputs = el.querySelectorAll("textarea");
    for (i = 0; i < inputs.length; i++) {
    macros.set.run(null, Wikifier.parse(inputs[i].name+' = "'+inputs[i].value.replace(/"/g,'\\"')+'"'));
    }
    }
    };
    });
    After adding both of the above pieces of javascript into a Script Passage you can text it by adding the following to a passage:
    (note: remember to give your variables default values within the StoryInit special passage. eg. <<set $desc to "">>

    Describe yourself:
    <<textarea $desc>>
    <<button [[Submit description|Next Passage]]>>
    You can use CSS to size the textarea like so:

    #passages .textArea {
    width: 600px;
    height: 200px;
    }
    I hope that gives you something to start with.
  • Thank you! This *almost* works...the only problem is that it still won't accommodate multiline input. I can change the size of the textbox in CSS, but that doesn't change the number of lines of input, apparently. Where in the script can I pass a secondary argument to the html "textarea" command, such as ' cols="40" rows="5" '?

    Thanks.
  • The textarea itself does allows multiple lines of input, it is the story format code that saves the value into the variable that doesn't because the value has un-escaped newline characters in it when it is multi-lined. To fix this I have to escape these newline characters.

    Replace the override with this new version:

    override(macros.button, 'callback', function(original) {
    return function() {
    // Call the original version of the callback to process all textinput,checkbox,radiobutton elements.
    original.apply(this, arguments);

    // Now process all the textArea elements.
    var el = findPassageParent(this);
    if (el) {
    var inputs = el.querySelectorAll("textarea");
    for (i = 0; i < inputs.length; i++) {
    macros.set.run(null, Wikifier.parse(inputs[i].name+' = "'+inputs[i].value.replace(/"/g,'\\"')+'"').replace(/\n/g, "\\n"));
    }
    }
    };
    });
  • That's great, thanks. The only minor issue is that if I print out the multiline string, sometimes the output is displayed as strikethrough. I've been trying to identify the conditions for this, but haven't quite debugged successfully yet.
  • If you can supply an example of when this happens, I or someone else maybe able to determine what is wrong.
  • When that happens, does the printed string contain at least one pair of the strikethrough markup (e.g two consecutive equal signs: ==) and are you using &lt;&lt;print&gt;&gt;?  If so, then that's your problem.  The &lt;&lt;print&gt;&gt; macro wikifies what it prints, so == is considered the start of the strikethrough markup.  The question is do you need or want wikification of the user input at all?
Sign In or Register to comment.