More Squiffy Loops by one None-Too-Bright for people who want to make Squiffy more automatic

<input>s, <textarea>s, and <span contenteditable="true"> let the player have their say, but it's bothersome to make Squiffy get the input. When I made a parser-based game, I got really tired of repeatedly needing to copy>paste>change labels and variables>copy>paste>change>copy>paste>change.

While the below, unholy illegitimate son of Squiffy and JS, does not parse or interpret the input, at least it keeps one from having to mess with JS for each and every basic input.

Of course I'll be delighted if any of our friendly neighborhood JS heroes (Here's lookin' at you K.V., Bluevoss, and the magnificent mrangel.) want to magically turn this cancerous frog into a healthy Prince(ss) of [[]]: or Gender-Neutral Heir to the Throne of story.js!


[[start]]:

First Name: <input id="fname" value="John"><br>
Middle Name:  <input id="mname" value="Jacob"><br>
Surname: <input id="sname" value="Jingleheimer"><br>
Mother's Maiden Name: <input id="mmname" value="Schmidt"> [[Go]](enterInputs, next=second)


[[second]]:


Full name: {fname} {mname} {sname} {mmname} (His name is my name, too!)


[[enterInputs]]:
@inc loops
@inc id
@inc value
    var id = get("id");
    var value = get("value");
    var loops = get("loops");

    var inputs = document.getElementsByTagName("input").length;
    var id = document.getElementsByTagName("input")[inputs - loops].id;
    var value = document.getElementsByTagName("input")[inputs - loops].value;
    set(id, value);
    
    var next = get("next");
    if (loops == inputs ){squiffy.story.go(next);}
    else{squiffy.story.go("enterInputs");}

You can even abbreviate the HTML portion with Squiffy.

@set MY = <input id="
@set IS = "/>

First Name: {MY}first name{IS}<br>
Middle Name:  {MY}middle name{IS}<br>
Surname: {MY}surname{IS}<br>
Mother's Maiden Name: {MY}mothers maiden name{IS}

[[Go]](enterInputs, next=second)


[[second]]:
Full name: {first name} {middle name} {surname} {mothers maiden name}

I think your JS could be abbreviated to:

    $("input").each(function () {
        set (this.id, this.value);
    });

If you don't mind modifying story.js, you could add 4 lines to this function:

    var newSection = function() {
        if (currentSection) {
            disableLink(jQuery('.squiffy-link', currentSection));
            currentSection.find('input').each(function () {
                set ($(this).data('attribute') || this.id, this.value);
                this.disabled = true;
            });
        }
        var sectionCount = squiffy.get('_section-count') + 1;
        squiffy.set('_section-count', sectionCount);
        var id = 'squiffy-section-' + sectionCount;
        currentSection = jQuery('
', { id: id, }).appendTo(squiffy.ui.output); squiffy.set('_output-section', id); };

so that all input elements are automatically processed at the same time as disabling links (when you leave a section).

You could also add something like:

        function processTextCommand(text, data) {
            if (startsWith(text, 'if ')) {
                return processTextCommand_If(text, data);
            }
            else if (startsWith(text, 'else:')) {
                return processTextCommand_Else(text, data);
            }
            else if (startsWith(text, 'label:')) {
                return processTextCommand_Label(text, data);
            }
            else if (startsWith(text, 'input:')) {
                var attribute = text.replace(/^input:\s*/,"").replace(/\s*$/,"");
                var value = squiffy.get(attribute) || "";
                if (attribute.match(":")) {
                    value ||= attribute.replace(/^.*?\s*:\s*/,"");
                    attribute = attribute.replace(/\s*:.*$/, "");
                }
                var id = text.replace(/\W/g, "");
                return $('<input>', {id: id, value: value, 'data-attribute': attribute}).get(0).outerHTML;
            }
            else if (/^rotate[: ]/.test(text)) {
                return processTextCommand_Rotate('rotate', text, data);
            }
            else if (/^sequence[: ]/.test(text)) {

so that you can just do:

[[start]]:

First Name: {input:fname:Elric}<br>
Middle Name:  {input:mname:Middlename}<br>
Surname: {input:sname:Spongehammer}<br>
Mother's Maiden Name: {input:mmname:Sporf} [[Go]](enterInputs)

(This code should fill the form with the existing values if those attributes have values; and the defaults otherwise. But I've not tested it as I'm replying on my phone)


Hi mrangel,

I pasted

    $("input").each(function () {
        set (this.id, this.value);
    });

into [[]]:, and it worked perfectly...

But then I got greedy. I changed $("input") to $("span") (I had already changed the inputs into contenteditable spans in my original Squiffy-JS mule recipe. I wanted to freely stylize with markups and .GIF carets and such, you see.) The $("span") version created a massively long list of nameless true Squiffy attributes before nulling the outputs.

And how odd, I feel as thought I ought to apologize. Very odd.


Yeah… you don't want it to treat every span as an input.

In that case, your selector will be $("[contenteditable]") or $("span[contenteditable]") which matches all elements with that attribute.

You probably also want to put $(this).removeProp("contenteditable") inside the loop, so that they cease to be editable once the JS has read their value.
So:

    $("span[contenteditable]").each(function () {
        $(this).removeProp("contenteditable");
        set (this.id, this.innerHTML);
    });

That works well. At first, I couldn't figure it out. But then I remembered a kind and wise person once told me this.value needs to be this.innerHTML or this.innerText. You've helped me far more with JS for free than many people I pay have helped me with house and car maintenance.


This topic is now closed. Topics are closed after 180 days of inactivity.

Support

Forums