My web-app is about forecasting on sports games. My page shows all the matches and the points you can get out of each outcome from a match (Madrid = 12 points VS Barcelone = 15 points). So a user check a box from a match and select for him the right outcome. I would like each time the user check a box, to show him the number of boxes he checked.
Here is my Javascript to count the box checked :
const updateCount = function() {
var x = document.querySelectorAll(".square:checked").length;
document.querySelector(".plus").innerHTML = x;
};
Here is the HTML where the number of box checked will be displayed
<div class=" d-flex pt-2">
<h3 class="typos">Matchs pronostiqués</h3>
<h3 class="typos pts" style="font-weight: bold; padding-left: 5px;"><%= current_user.forecasts.where(confirmed: true, season_id: Season.last.id).count %>/50</h3>
<span class="plus"></span>
</div>
Here is my Javascript in order to know which game the user forecasted and which outcome he selected :
const selectOutcome = () => {
const selects = document.querySelectorAll(".square");
selects.forEach((outcome)=>{
outcome.addEventListener("click",(event) => {
$('input[type="checkbox"]').on('change', function() {
$(this).siblings('input[type="checkbox"]').not(this).prop('checked', false);
});
const result = event.currentTarget.dataset.outcome;
console.log(result);
const id = event.currentTarget.parentNode.dataset.id;
console.log(id);
const box = event.currentTarget.checked;
console.log(box);
const url = 'store_outcome?result='+result+'&match='+id+'&box='+box
fetch(url)
.then(response => response.json())
.then((data) => {
console.log(data);
});
});
});
}
const validePanier = () => {
const panier = document.getElementById('panier');
panier.addEventListener("click", (event) =>{
console.log("click")
const player = document.getElementById('season_player').value;
fetch('confirm_pending?player='+player)
.then(response => response.json())
.then((data) => {
console.log(data);
});
})
}
Here is my HTML, for each match I have in my database, a match is going to appear in front in this way.
<% @matches.each do |match| %>
<% if Time.parse(match.kick_off) > Time.now && current_user.forecasts.find_by(match_id: match.id, confirmed: true).nil? && match.points_home.present? %>
<% if match.sport == "football" %>
<div class="d-flex justify-content-center mb-2 mt-2">
<h4 class="typopo"><%= match.league %></h4>
</div>
<div class="d-flex justify-content-center mb-2 mt-2">
<h3 class="tit"><%= DateTime.parse(match.kick_off).to_date%></h3><h3 class="typopo pl-2">-</h3>
<h3 class="typopo pl-2"><%= match.kick_off.to_s.gsub("T", " ").split[1].gsub("+", " ").split[0]%></h3>
</div>
<div class="d-flex flex-row justify-content-around mb-4 mt-4" data-id="<%= match.id %>">
<div class="d-flex flex-column align-items-center col-4">
<div class="row">
<h3 class="typopo"><%= image_tag "#{match.team_home_logo_url}", width: 50 %></h3>
</div>
<div class="row text-align-center">
<h3 class="tit"><%= match.team_home %></h3>
</div>
</div>
<div class="d-flex flex-column justify-content-center">
<p class="typopo text-center">VS</p>
<div class="d-flex flex-row align-items-center col-4">
<div class="displaysquares" data-id="<%= match.id %>">
<input type="checkbox" class="square" onclick="updateCount()" data-outcome="1"></input>
<input type="checkbox" class="square" onclick="updateCount()" data-outcome="NULL"></input>
<input type="checkbox" class="square" onclick="updateCount()" data-outcome="2"></input>
</div>
</div>
</div>
There is a data-id. The purpose is when a user check a box, I can get the id of the match, in order to create the right forecast for the right game.
Advertisement
Answer
I would delegate instead of having inline event handlers
Here I COUNT the checkboxes – why do you not want the VALUE of a checked RADIO?
Note I wrapped all matches in <div id="matches">...</div>
document.getElementById("matches").addEventListener("change", function(e) {
const tgt = e.target;
if (tgt.classList.contains("square")) {
const parent = tgt.closest(".displaysquares");
var x = parent.querySelectorAll(".square:checked").length;
document.querySelector(".plus").innerHTML += parent.dataset.id + ": " + x +"<br/>" ;
}
})
<span class="plus"></span>
<div id="matches">
<div class="d-flex justify-content-center mb-2 mt-2">
<h4 class="typopo">League 1</h4>
</div>
<div class="d-flex justify-content-center mb-2 mt-2">
<h3 class="tit">
Some date
</h3>
<h3 class="typopo pl-2">-</h3>
<h3 class="typopo pl-2">Some string</h3>
</div>
<div class="d-flex flex-row justify-content-around mb-4 mt-4" data-id="MATCH 1">
<div class="d-flex flex-column align-items-center col-4">
<div class="row">
<h3 class="typopo">TEAM LOGO </h3>
</div>
<div class="row text-align-center">
<h3 class="tit">Some other team string</h3>
</div>
</div>
<div class="d-flex flex-column justify-content-center">
<p class="typopo text-center">VS</p>
<div class="d-flex flex-row align-items-center col-4">
<div class="displaysquares" data-id="MATCH 1">
<input type="checkbox" class="square" data-outcome="1">
<input type="checkbox" class="square" data-outcome="NULL">
<input type="checkbox" class="square" data-outcome="2">
</div>
</div>
</div>
</div>
<div class="d-flex justify-content-center mb-2 mt-2">
<h4 class="typopo">League 2</h4>
</div>
<div class="d-flex justify-content-center mb-2 mt-2">
<h3 class="tit">
Some date
</h3>
<h3 class="typopo pl-2">-</h3>
<h3 class="typopo pl-2">Some string</h3>
</div>
<div class="d-flex flex-row justify-content-around mb-4 mt-4" data-id="MATCH 2">
<div class="d-flex flex-column align-items-center col-4">
<div class="row">
<h3 class="typopo">TEAM LOGO </h3>
</div>
<div class="row text-align-center">
<h3 class="tit">Some other team string</h3>
</div>
</div>
<div class="d-flex flex-column justify-content-center">
<p class="typopo text-center">VS</p>
<div class="d-flex flex-row align-items-center col-4">
<div class="displaysquares" data-id="MATCH 2">
<input type="checkbox" class="square" data-outcome="1">
<input type="checkbox" class="square" data-outcome="NULL">
<input type="checkbox" class="square" data-outcome="2">
</div>
</div>
</div>
</div>
</div>
Using Radios instead
const matches = document.getElementById("matches")
matches.addEventListener("change", function(e) {
const tgt = e.target;
if (tgt.classList.contains("square")) {
var x = [matches.querySelectorAll(".square:checked")].map(chk => chk.closest(".displaysquares").dataset.id + ": "+chk.dataset.outcome)
document.querySelector(".plus").innerHTML = x.join("<br/>");
}
})
<span class="plus"></span>
<div id="matches">
<div class="d-flex justify-content-center mb-2 mt-2">
<h4 class="typopo">League 1</h4>
</div>
<div class="d-flex justify-content-center mb-2 mt-2">
<h3 class="tit">
Some date
</h3>
<h3 class="typopo pl-2">-</h3>
<h3 class="typopo pl-2">Some string</h3>
</div>
<div class="d-flex flex-row justify-content-around mb-4 mt-4" data-id="MATCH 1">
<div class="d-flex flex-column align-items-center col-4">
<div class="row">
<h3 class="typopo">TEAM LOGO </h3>
</div>
<div class="row text-align-center">
<h3 class="tit">Some other team string</h3>
</div>
</div>
<div class="d-flex flex-column justify-content-center">
<p class="typopo text-center">VS</p>
<div class="d-flex flex-row align-items-center col-4">
<div class="displaysquares" data-id="MATCH 1">
<input type="radio" name="outcome1" class="square" data-outcome="1">
<input type="radio" name="outcome1" class="square" data-outcome="NULL">
<input type="radio" name="outcome1" class="square" data-outcome="2">
</div>
</div>
</div>
</div>
<div class="d-flex justify-content-center mb-2 mt-2">
<h4 class="typopo">League 2</h4>
</div>
<div class="d-flex justify-content-center mb-2 mt-2">
<h3 class="tit">
Some date
</h3>
<h3 class="typopo pl-2">-</h3>
<h3 class="typopo pl-2">Some string</h3>
</div>
<div class="d-flex flex-row justify-content-around mb-4 mt-4" data-id="MATCH 2">
<div class="d-flex flex-column align-items-center col-4">
<div class="row">
<h3 class="typopo">TEAM LOGO </h3>
</div>
<div class="row text-align-center">
<h3 class="tit">Some other team string</h3>
</div>
</div>
<div class="d-flex flex-column justify-content-center">
<p class="typopo text-center">VS</p>
<div class="d-flex flex-row align-items-center col-4">
<div class="displaysquares" data-id="MATCH 2">
<input type="radio" name="outcome2" class="square" data-outcome="1">
<input type="radio" name="outcome2" class="square" data-outcome="NULL">
<input type="radio" name="outcome2" class="square" data-outcome="2">
</div>
</div>
</div>
</div>
</div>