My web page allows users to generate strings/phrases by selecting a combination of two radio buttons from two different groups: mode and category. After selecting their choice of buttons, they click the 'Push' button and a string pops up. See the snippet below:
class modes {
constructor(items) {
this.items = items;
this.randomUnused = [...items];
this.forwardIndex = 0;
this.reverseIndex = items.length - 1;
}
forwardItem() {
return this.items[this.forwardIndex++ % (this.items.length)];
}
randomItem() {
if (!this.randomUnused.length) {
this.randomUnused.push(...this.items);
}
const index = Math.floor(Math.random() * this.randomUnused.length);
return this.randomUnused.splice(index, 1);
}
reverseItem() {
if (this.reverseIndex < 0) {
this.reverseIndex = this.items.length - 1;
}
return this.items[this.reverseIndex--];
}
}
const categ = {
A: new modes([
"A example 1",
"A example 2",
"A example 3",
"A example 4",
]),
B: new modes([
"B example 1",
"B example 2",
"B example 3",
"B example 4",
]),
C: new modes([
"C example 1",
"C example 2",
"C example 3",
"C example 4",
]),
D: new modes([
"D example 1",
"D example 2",
"D example 3",
"D example 4",
])
};
function main() {
const output = document.querySelector("output");
if(!(document.forms.thingSelection2.type.value in categ)) {
return false;
}
const list = categ[document.forms.thingSelection2.type.value];
const method = document.forms.thingSelection1.mode.value + "Item";
const item = list[method]();
output.innerHTML = item;
}
const abutton = document.getElementById("abutton");
if(abutton) {
abutton.addEventListener("click", main);
}
<output></output>
<button id="abutton">Push</button>
<form name="thingSelection1">
Forwards<input type="radio" name="mode" value="forward">
Random<input type="radio" name="mode" value="random">
Backwards<input type="radio" name="mode" value="reverse">
</form>
<form name="thingSelection2">
<li><input type="radio" name="type" value="A">Choice A</li>
<li><input type="radio" name="type" value="B">Choice B</li>
<li><input type="radio" name="type" value="C">Choice C</li>
<li><input type="radio" name="type" value="D">Choice D</li>
</form>
Each category is currently represented by a radio button and has its own separate array, so only one may be selected at a time. My goal is to allow the user to select multiple categories and combine them into a new array, then cycle through them.
Problem 1: Changing the category radio buttons into checkboxes causes the function to break. The snippet below illustrates this. I figure this is due to the fact that checkboxes have 3 possible states (checked, unchecked, indeterminate) while radio buttons can only be true or false. I am unsure what changes to make to the function to allow the checkboxes to work. I could use some assistance. I'm fairly new to javascript, so please be patient.
class modes {
constructor(items) {
this.items = items;
this.randomUnused = [...items];
this.forwardIndex = 0;
this.reverseIndex = items.length - 1;
}
forwardItem() {
return this.items[this.forwardIndex++ % (this.items.length)];
}
randomItem() {
if (!this.randomUnused.length) {
this.randomUnused.push(...this.items);
}
const index = Math.floor(Math.random() * this.randomUnused.length);
return this.randomUnused.splice(index, 1);
}
reverseItem() {
if (this.reverseIndex < 0) {
this.reverseIndex = this.items.length - 1;
}
return this.items[this.reverseIndex--];
}
}
const categ = {
A: new modes([
"A example 1",
"A example 2",
"A example 3",
"A example 4",
]),
B: new modes([
"B example 1",
"B example 2",
"B example 3",
"B example 4",
]),
C: new modes([
"C example 1",
"C example 2",
"C example 3",
"C example 4",
]),
D: new modes([
"D example 1",
"D example 2",
"D example 3",
"D example 4",
])
};
function main() {
const output = document.querySelector("output");
if(!(document.forms.thingSelection2.type.value in categ)) {
return false;
}
const list = categ[document.forms.thingSelection2.type.value];
const method = document.forms.thingSelection1.mode.value + "Item";
const item = list[method]();
output.innerHTML = item;
}
const abutton = document.getElementById("abutton");
if(abutton) {
abutton.addEventListener("click", main);
}
<output></output>
<button id="abutton">Push</button>
<form name="thingSelection1">
Forwards<input type="radio" name="mode" value="forward">
Random<input type="radio" name="mode" value="random">
Backwards<input type="radio" name="mode" value="reverse">
</form>
<form name="thingSelection2">
<li><input type="checkbox" name="type" value="A">Choice A</li>
<li><input type="checkbox" name="type" value="B">Choice B</li>
<li><input type="checkbox" name="type" value="C">Choice C</li>
<li><input type="checkbox" name="type" value="D">Choice D</li>
</form>
Problem 2: Constructing the custom array in a specific order. While internet searches provide many ways to combine multiple arrays into one, like concat, none of them explain how to organize the strings in a custom order.
Example of what im looking for: ["A example 1", "B example 1", "C example 1", "D example 1", "A example 2", "B example 2"...]
Rather than simply stacking the array contents on top of each other, like concat and every other method of combining arrays: ["A example 1", "A example 2", "A example 3", "A example 4", "B example 1", "B example 2"...]
I'm unaware of any method to achieve this. No external libraries please.