I'm trying to make a NYT connections game, which requires 16 buttons. I created them using a forEach function, but only know how to access each button when I click on it. I want to disable all 4 choices when they are correct. How do I access the 4 buttons that the user chose using the button.group value? :
const parentElement = document.querySelector('.game-container');
wordButtons.forEach (function (b) {
const button = document.createElement('button');
button.innerText = b.word;
button.group = b.group;
button.id = b.buttonId;
button.active = false;
parentElement.appendChild(button);
button.onclick = function(){
if (button.active === false){
//case if you click it and choose it
buttonIDs.push(button.id);
buttonGroups.push(button.group);
button.active = true;
button.style.backgroundColor = "white";
} else {
//case if you un-choose it
button.active = false;
button.style.backgroundColor = "rgb(241, 215, 225)";
// remove button id from array
buttonIDs.splice(buttonIDs.indexOf(button.id));
buttonGroups.splice(buttonGroups.indexOf(button.group),1);
}
if (buttonIDs.length === 4){
if (buttonGroups.every(x => x === buttonGroups[0])){
console.log("you matched a set!");
if (button.group === buttonGroups[0]){
button.disabled = true;
};
}
}
}
})
Sorry if I put too much code here- it is my first time asking a question here.
I tried removing the 'if buttonIds length === 4' case out of the execution context of the onclick function, hoping to access all of the buttons that way and disable them, but if I remove it from the onclick function, the code block does not execute at all.
I could probably create the buttons individually and give them numbers, but that seems like bad form.
I'm not 100% into the game play... In the following example I went with "check state on change".
Instead of using button elements use checkboxes. A checkbox have a state -- checked or not, and can be disabled. I use both properties to decide if all in one group is checked and after that disabling all checkboxes in a group. Checkboxes are also already grouped by the name they are given in a form.
Here, I'm just going with 2 words in one group...
const words = [{
word: 'Word1',
group: 1
}, {
word: 'Word2',
group: 1
}, {
word: 'Word3',
group: 2
}, {
word: 'Word4',
group: 2
}];
words.forEach(word => {
let label = document.createElement('label');
let span = document.createElement('span');
let input = document.createElement('input');
input.name = `group_${word.group}`;
input.groupid = word.group;
input.type = 'checkbox';
span.textContent = word.word;
label.appendChild(input);
label.appendChild(span);
document.forms.game.appendChild(label);
});
document.forms.game.addEventListener('change', e => {
let form = e.target.form;
let checked = [...form.elements].filter(input => input.checked && !input.disabled);
if (checked.length == 2) {
checkGroup(e.target.groupid);
}
if (checked.length > 2) {
e.target.checked = false;
}
});
function checkGroup(groupid) {
let form = document.forms.game;
let inputs = form[`group_${groupid}`];
let checked = [...inputs].filter(input => input.checked);
if (checked.length == 2) {
[...inputs].forEach(input => input.disabled = true);
}
}
label input {
display: none;
}
label span {
display: inline-block;
padding: .2em;
margin: .2em;
background-color: lightgray;
}
input:checked+span {
background-color: darkgray;
}
input:checked:disabled+span {
background-color: green;
}
<form name="game"></form>