Reputation: 37
I'm new to programming and am tasked with creating a clickable tournament bracket. 8 teams, where you can pick the winners who will advance to the next round.
The problem I'm running into is when a person would want to revise picks in the first or second round after filling out the bracket.
For example in the first round the user picks:
In the Second Round let's say they pick:
In the Finals, they pick:
Then, let's say the user changes their mind and picks Team8 to upset Team1 in the first round. Right now the code would still show Team1 as the winner and in the final game. How can I remove the text for the future rounds that currently shows Team1?
Attaching JSFiddle here: https://jsfiddle.net/a4hya2c7/5/ or see below code:
<!DOCTYPE html>
<html>
<head>
<title>Button</title>
</head>
<body>
<p>First Round</p>
<div id="round1">
<input type="radio" name="g1" id="i1" value="#1" onclick="changeText(this.value);"><label id="r1">#1</label>
<input type="radio" name="g1" id="i2" value="#8" onclick="changeText(this.value);"><label id="r2">#8</label></br>
<input type="radio" name="g2" id="i3" value="#4" onclick="changeText2(this.value);"><label id="r3">#4</label>
<input type="radio" name="g2" id="i4" value="#5" onclick="changeText2(this.value);"><label id="r4">#5</label></br>
<input type="radio" name="g3" id="i5" value="#3" onclick="changeText3(this.value);"><label id="r5">#3</label>
<input type="radio" name="g3" id="i6" value="#6" onclick="changeText3(this.value);"><label id="r6">#6</label></br>
<input type="radio" name="g4" id="i7" value="#7" onclick="changeText4(this.value);"><label id="r7">#7</label>
<input type="radio" name="g4" id="i8" value="#2" onclick="changeText4(this.value);"><label id="r8">#2</label></br>
</div>
</br>
<p>Second Round</p>
<div id="round2">
<input type="radio" name="g5" id="i9" onclick="changeText5(this.value);"><label id="r9"></label>
<input type="radio" name="g5" id="i10" onclick="changeText5(this.value);"><label id="r10"></label></br>
<input type="radio" name="g6" id="i11" onclick="changeText6(this.value);"><label id="r11"></label>
<input type="radio" name="g6" id="i12" onclick="changeText6(this.value);"><label id="r12"></label></br>
</div>
</br>
<p>Finals</p>
<div id="round3">
<input type="radio" name="g7" id="i13" onclick="changeText7(this.value);"><label id="r13"></label>
<input type="radio" name="g7" id="i14" onclick="changeText7(this.value);"><label id="r14"></label></br>
</div>
</br>
<p>Winner</p>
<div id="round4">
<label value="#8" id="r15"></label></br>
</div>
</br>
</body>
</html>
JS:
function changeText(value) {
document.getElementById('r9').innerHTML = value;
document.getElementById('i9').value = value;
}
function changeText2(value) {
document.getElementById('r10').innerHTML = value;
document.getElementById('i10').value = value;
}
function changeText3(value) {
document.getElementById('r11').innerHTML = value;
document.getElementById('i11').value = value;
}
function changeText4(value) {
document.getElementById('r12').innerHTML = value;
document.getElementById('i12').value = value;
}
function changeText5(value) {
document.getElementById('r13').innerHTML = value;
document.getElementById('i13').value = value;
}
function changeText6(value) {
document.getElementById('r14').innerHTML = value;
document.getElementById('i14').value = value;
}
function changeText7(value) {
document.getElementById('r15').innerHTML = value;
document.getElementById('r15').value = value;
}
Upvotes: 2
Views: 599
Reputation: 1874
Firstly your <br>
tags aren't correct as you can see here:
</div>
</br>
You are using the close tag without the opening. You can either use:
<br/>
Or use the newer html5 self closing tags style:
<br>
As to the JS itself, you can simplify it a lot if you use an attribute, similar as the name
you are already using to point where it must put the value. With that change the code would be a lot smaller and simpler:
const inputs = document.querySelectorAll("input[type=radio]");
for (let inp of inputs){
inp.addEventListener("change", function(){
let targetLabel = document.getElementById(inp.dataset.target);
targetLabel.previousSibling.value = inp.value;
targetLabel.innerHTML = inp.value;
});
}
<p>First Round</p>
<div id="round1">
<input type="radio" name="g1" id="i1" value="#1" data-target="r9"><label id="r1">#1</label>
<input type="radio" name="g1" id="i2" value="#8" data-target="r9"><label id="r2">#8</label><br>
<input type="radio" name="g2" id="i3" value="#4" data-target="r10"><label id="r3">#4</label>
<input type="radio" name="g2" id="i4" value="#5" data-target="r10"><label id="r4">#5</label><br>
<input type="radio" name="g3" id="i5" value="#3" data-target="r11"><label id="r5">#3</label>
<input type="radio" name="g3" id="i6" value="#6" data-target="r11"><label id="r6">#6</label><br>
<input type="radio" name="g4" id="i7" value="#7" data-target="r12"><label id="r7">#7</label>
<input type="radio" name="g4" id="i8" value="#2" data-target="r12"><label id="r8">#2</label><br>
</div>
<br>
<p>Second Round</p>
<div id="round2">
<input type="radio" name="g5" id="i9" data-target="r13"><label id="r9"></label>
<input type="radio" name="g5" id="i10" data-target="r13"><label id="r10"></label><br>
<input type="radio" name="g6" id="i11" data-target="r14"><label id="r11"></label>
<input type="radio" name="g6" id="i12" data-target="r14"><label id="r12"></label><br>
</div>
<br>
<p>Finals</p>
<div id="round3">
<input type="radio" name="g7" id="i13" data-target="r15"><label id="r13"></label>
<input type="radio" name="g7" id="i14" data-target="r15"><label id="r14"></label><br>
</div>
<br>
<p>Winner</p>
<div id="round4">
<label value="#8" id="r15"></label><br>
</div>
<br>
Note that the targets i set were directly to the labels:
<input type="radio" ... data-target="r9">
Then to get to the corresponding radio i used previousSibling
.
I used several functions that you may not know:
for ... of
to iterate on all inputs retrieved by the querySelectorAll
And with just those little lines of Javascript you have the same functionality, and most importantly, without code duplication.
Now if you want to cascade a change on the first radios to the lower ones, you can call the change event directly with:
const event = new Event('change');
element.dispatchEvent(event);
Whenever you see that the target element already has a value set. This works like a recursive call:
const inputs = document.querySelectorAll("input[type=radio]");
for (let inp of inputs){
inp.addEventListener("change", function(){
let targetLabel = document.getElementById(inp.dataset.target);
let targetRadio = targetLabel.previousSibling;
targetRadio.value = inp.value;
targetLabel.innerHTML = inp.value;
//if this isn't the last and it's checked, to not cascade non selected radios
if (targetRadio.hasAttribute && targetRadio.checked){
const nextTargetLabel = document.getElementById(targetRadio.dataset.target);
if (nextTargetLabel.innerHTML != ''){ //if it has a value then cascade
targetRadio.dispatchEvent(new Event('change'));
}
}
});
}
<p>First Round</p>
<div id="round1">
<input type="radio" name="g1" id="i1" value="#1" data-target="r9"><label id="r1">#1</label>
<input type="radio" name="g1" id="i2" value="#8" data-target="r9"><label id="r2">#8</label><br>
<input type="radio" name="g2" id="i3" value="#4" data-target="r10"><label id="r3">#4</label>
<input type="radio" name="g2" id="i4" value="#5" data-target="r10"><label id="r4">#5</label><br>
<input type="radio" name="g3" id="i5" value="#3" data-target="r11"><label id="r5">#3</label>
<input type="radio" name="g3" id="i6" value="#6" data-target="r11"><label id="r6">#6</label><br>
<input type="radio" name="g4" id="i7" value="#7" data-target="r12"><label id="r7">#7</label>
<input type="radio" name="g4" id="i8" value="#2" data-target="r12"><label id="r8">#2</label><br>
</div>
<br>
<p>Second Round</p>
<div id="round2">
<input type="radio" name="g5" id="i9" data-target="r13"><label id="r9"></label>
<input type="radio" name="g5" id="i10" data-target="r13"><label id="r10"></label><br>
<input type="radio" name="g6" id="i11" data-target="r14"><label id="r11"></label>
<input type="radio" name="g6" id="i12" data-target="r14"><label id="r12"></label><br>
</div>
<br>
<p>Finals</p>
<div id="round3">
<input type="radio" name="g7" id="i13" data-target="r15"><label id="r13"></label>
<input type="radio" name="g7" id="i14" data-target="r15"><label id="r14"></label><br>
</div>
<br>
<p>Winner</p>
<div id="round4">
<label value="#8" id="r15"></label><br>
</div>
<br>
Edit:
To clear the following radios instead of cascading the values you can use a while
, and navigating with the targets
until you reach the end:
const inputs = document.querySelectorAll("input[type=radio]");
for (let inp of inputs){
inp.addEventListener("change", function(){
let targetLabel = document.getElementById(inp.dataset.target);
let targetRadio = targetLabel.previousSibling;
targetLabel.innerHTML = inp.value;
targetRadio.value = inp.value;
//while there is a next target clear it
while (targetLabel.previousSibling.hasAttribute){
targetLabel = document.getElementById(targetRadio.dataset.target);
targetRadio = targetLabel.previousSibling;
targetRadio.checked = false;
targetLabel.innerHTML = '';
}
});
}
<p>First Round</p>
<div id="round1">
<input type="radio" name="g1" id="i1" value="#1" data-target="r9"><label id="r1">#1</label>
<input type="radio" name="g1" id="i2" value="#8" data-target="r9"><label id="r2">#8</label><br>
<input type="radio" name="g2" id="i3" value="#4" data-target="r10"><label id="r3">#4</label>
<input type="radio" name="g2" id="i4" value="#5" data-target="r10"><label id="r4">#5</label><br>
<input type="radio" name="g3" id="i5" value="#3" data-target="r11"><label id="r5">#3</label>
<input type="radio" name="g3" id="i6" value="#6" data-target="r11"><label id="r6">#6</label><br>
<input type="radio" name="g4" id="i7" value="#7" data-target="r12"><label id="r7">#7</label>
<input type="radio" name="g4" id="i8" value="#2" data-target="r12"><label id="r8">#2</label><br>
</div>
<br>
<p>Second Round</p>
<div id="round2">
<input type="radio" name="g5" id="i9" data-target="r13"><label id="r9"></label>
<input type="radio" name="g5" id="i10" data-target="r13"><label id="r10"></label><br>
<input type="radio" name="g6" id="i11" data-target="r14"><label id="r11"></label>
<input type="radio" name="g6" id="i12" data-target="r14"><label id="r12"></label><br>
</div>
<br>
<p>Finals</p>
<div id="round3">
<input type="radio" name="g7" id="i13" data-target="r15"><label id="r13"></label>
<input type="radio" name="g7" id="i14" data-target="r15"><label id="r14"></label><br>
</div>
<br>
<p>Winner</p>
<div id="round4">
<label value="#8" id="r15"></label><br>
</div>
<br>
Upvotes: 2