More Squiffy Loops by one None-Too-Bright for people who want to make Squiffy more automatic
IFforClassroom
25 Sept 2021, 04:43<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");}
IFforClassroom
25 Sept 2021, 05:29You 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}
mrangel
25 Sept 2021, 08:59I think your JS could be abbreviated to:
$("input").each(function () {
set (this.id, this.value);
});
mrangel
25 Sept 2021, 09:42If 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)
IFforClassroom
25 Sept 2021, 12:54Hi 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.
mrangel
25 Sept 2021, 13:17Yeah… 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);
});
IFforClassroom
26 Sept 2021, 05:49That 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.