mirror of
https://github.com/kmitresse/Cards-Rush.git
synced 2026-05-13 17:11:49 +00:00
feat(DevWeb): Edit new-game form
This commit is contained in:
@@ -2,71 +2,81 @@
|
||||
<%@ tag import="uppa.project.database.pojo.Game" %>
|
||||
<%@tag description="form/new-game" pageEncoding="UTF-8" %>
|
||||
|
||||
<form id="new-game-form" action="${pageContext.request.contextPath}/main-menu" method="post">
|
||||
<%@attribute name="back_button" fragment="true" %>
|
||||
|
||||
<form id="new-game-form" action="${pageContext.request.contextPath}/new" method="post">
|
||||
|
||||
<h2 class="title is-5">Paramètres Généraux</h2>
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Difficulté</label>
|
||||
<div class="control columns">
|
||||
<div class="column">
|
||||
<label class="radio button is-fullwidth is-primary is-light">
|
||||
<input type="radio" name="difficulty" checked/>
|
||||
<input type="radio" name="difficulty" value="EASY" checked/>
|
||||
Facile
|
||||
</label>
|
||||
</div>
|
||||
<div class="column">
|
||||
<label class="radio button is-fullwidth is-light">
|
||||
<input type="radio" name="difficulty"/>
|
||||
<input type="radio" value="HARD" name="difficulty"/>
|
||||
Difficile
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<h2 class="title is-5">Paramètres des Manches</h2>
|
||||
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<div class="field">
|
||||
<div class="field column">
|
||||
<label class="label" for="nbRounds">Nombre de manches</label>
|
||||
<input class="input" type="number" id="nbRounds" name="nbRounds" value="<%= Deck.NB_COLORS_MAX * Deck.NB_VALUES_PER_COLOR_MAX %>" min="<%= Deck.NB_COLORS_MIN * Deck.NB_VALUES_PER_COLOR_MIN %>" max="<%= Deck.NB_COLORS_MAX * Deck.NB_VALUES_PER_COLOR_MAX %>">
|
||||
<input class="input" required type="number" id="nbRounds" name="nbRounds"
|
||||
value="${Deck.NB_COLORS_MAX * Deck.NB_VALUES_PER_COLOR_MAX}"
|
||||
min="${Deck.NB_COLORS_MIN * Deck.NB_VALUES_PER_COLOR_MIN}"
|
||||
max="${Deck.NB_COLORS_MAX * Deck.NB_VALUES_PER_COLOR_MAX}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="field">
|
||||
<div class="column field">
|
||||
<label class="label" for="timer">Durée d'une manche</label>
|
||||
<input class="input" type="number" id="timer" name="timer" value="<%= Game.TIMER_MIN %>" min="<%= Game.TIMER_MIN %>" max="<%= Game.TIMER_MAX %>">
|
||||
<input class="input" required type="number" id="timer" name="timer"
|
||||
value="${Game.TIMER_MIN}"
|
||||
min="${Game.TIMER_MIN}"
|
||||
max="${Game.TIMER_MAX}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<h2 class="title is-5">Paramètres du Deck</h2>
|
||||
<div class="columns">
|
||||
<div class="column field">
|
||||
<label class="label" for="nbValues">
|
||||
Nombre de valeurs: <span class="tag is-medium is-light is-primary" id="tooltip-values">${Deck.NB_VALUES_PER_COLOR_MAX}</span>
|
||||
</label>
|
||||
<div class="control is-flex is-1">
|
||||
<span class="mr-1 tag"><strong>${Deck.NB_VALUES_PER_COLOR_MIN}</strong></span>
|
||||
<input type="range" required id="nbValues" name="nbValues" class="is-flex-grow-1" data-tooltip="#tooltip-values"
|
||||
value="${Deck.NB_VALUES_PER_COLOR_MAX}"
|
||||
min="${Deck.NB_VALUES_PER_COLOR_MIN}"
|
||||
max="${Deck.NB_VALUES_PER_COLOR_MAX}">
|
||||
<span class="ml-1 tag"><strong>${Deck.NB_VALUES_PER_COLOR_MAX}</strong></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column field">
|
||||
<label class="label" for="nbColors">
|
||||
Nombre de couleurs: <span class="tag is-medium is-light is-primary" id="tooltip-colors">${Deck.NB_COLORS_MAX}</span>
|
||||
</label>
|
||||
<div class="control is-flex is-1">
|
||||
<span class="mr-1 tag"><strong>${Deck.NB_COLORS_MIN}</strong></span>
|
||||
<input type="range" required id="nbColors" name="nbColors" class="is-flex-grow-1" data-tooltip="#tooltip-colors"
|
||||
value="${Deck.NB_COLORS_MAX}"
|
||||
min="${Deck.NB_COLORS_MIN}"
|
||||
max="${Deck.NB_COLORS_MAX}">
|
||||
<span class="ml-1 tag"><strong>${Deck.NB_COLORS_MAX}</strong></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="columns">
|
||||
<jsp:invoke fragment="back_button"/>
|
||||
<div class="column">
|
||||
<div class="field">
|
||||
<label class="label" for="nbValues">Nombre de valeurs <span id="tootltip-values"> <%= Deck.NB_VALUES_PER_COLOR_MAX %></span> </label>
|
||||
<div class="range-field">
|
||||
<div class="value left"><%= Deck.NB_VALUES_PER_COLOR_MIN %></div>
|
||||
<input type="range" id="nbValues" name="nbValues" value="<%= Deck.NB_VALUES_PER_COLOR_MAX %>" min="<%= Deck.NB_VALUES_PER_COLOR_MIN %>" max="<%= Deck.NB_VALUES_PER_COLOR_MAX %>">
|
||||
<div class="value right"><%= Deck.NB_VALUES_PER_COLOR_MAX %></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="field">
|
||||
<label class="label" for="nbColors">Nombre de couleurs <span id="tootltip-colors"> <%= Deck.NB_COLORS_MAX %></span> </label>
|
||||
<div class="range-field">
|
||||
<div class="value left"><%= Deck.NB_COLORS_MIN %></div>
|
||||
<input type="range" id="nbColors" name="nbColors" value="<%= Deck.NB_COLORS_MAX %>" min="<%= Deck.NB_COLORS_MIN %>" max="<%= Deck.NB_COLORS_MAX %>">
|
||||
<div class="value right"><%= Deck.NB_COLORS_MAX %></div>
|
||||
</div>
|
||||
</div>
|
||||
<input type="submit" class="button is-fullwidth is-primary has-text-white" value="Créer la partie"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -75,113 +85,73 @@
|
||||
label.radio.button > input[type="radio"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.range-field .value {
|
||||
|
||||
font-size: 18px;
|
||||
color: #045fa4;
|
||||
font-weight: 600;
|
||||
}
|
||||
.left {
|
||||
left: 0;
|
||||
}
|
||||
.right {
|
||||
right: 0;
|
||||
}
|
||||
.field input {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.sliderValue {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sliderValue span {
|
||||
position: absolute;
|
||||
height: 45px;
|
||||
width: 45px;
|
||||
transform: translateX(-70%) scale(0);
|
||||
font-weight: 500;
|
||||
top: -40px;
|
||||
line-height: 55px;
|
||||
z-index: 2;
|
||||
color: #fff;
|
||||
transform-origin: bottom;
|
||||
transition: transform 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.sliderValue span:after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: #045fa4;
|
||||
border: 3px solid #fff;
|
||||
z-index: -1;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) rotate(45deg);
|
||||
border-bottom-left-radius: 50%;
|
||||
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.1);
|
||||
border-top-left-radius: 50%;
|
||||
border-top-right-radius: 50%;
|
||||
}
|
||||
|
||||
.sliderValue span.show {
|
||||
transform: translateX(-70%) scale(1);
|
||||
}
|
||||
</style>
|
||||
|
||||
<script defer type="module">
|
||||
const nbColorsElement = document.getElementById("nbColors");
|
||||
const nbColorsInputValue=document.querySelector("span[id='tootltip-colors']");
|
||||
const nbValuesElement = document.getElementById("nbValues");
|
||||
const nbValueInputValue=document.querySelector("span[id='tootltip-values']");
|
||||
const nbRoundsElement = document.getElementById("nbRounds")
|
||||
|
||||
/**
|
||||
* Mise à jour de la valeur du slider
|
||||
*/
|
||||
nbColorsElement.addEventListener("input", () => {
|
||||
nbColorsInputValue.textContent = nbColorsElement.value;
|
||||
nbColorsInputValue.style.left = 0.5 * (nbColorsElement.value) + "%";
|
||||
// Range inputs
|
||||
const rangeInputs = document.querySelectorAll("input[type='range']");
|
||||
rangeInputs.forEach(input => {
|
||||
const tooltip = document.querySelector(input.dataset.tooltip);
|
||||
input.addEventListener("input", () => tooltip.innerHTML = input.value);
|
||||
});
|
||||
|
||||
|
||||
nbValuesElement.addEventListener("input", () => {
|
||||
nbValueInputValue.textContent = nbValuesElement.value;
|
||||
nbValueInputValue.style.left = 0.5 * (nbValuesElement.value) + "%";
|
||||
});
|
||||
|
||||
// nbValueInputValue.style.left = 0.5 * (nbValuesElement.value) + "%";
|
||||
// nbValueInputValue.style.left = 0.5 * (nbValuesElement.value) + "%";
|
||||
|
||||
|
||||
/**
|
||||
* Mise à jour du nombre de rounds max en fonction du nombre de couleurs et de valeurs séléctionnés
|
||||
*/
|
||||
function updateOnChange() {
|
||||
nbRoundsElement.max = nbColorsElement.value * nbValuesElement.value;
|
||||
|
||||
nbRoundsElement.value =
|
||||
(nbRoundsElement.value > nbRoundsElement.max)
|
||||
? nbRoundsElement.max
|
||||
: nbRoundsElement.value
|
||||
;
|
||||
}
|
||||
|
||||
nbColorsElement.addEventListener("change", updateOnChange);
|
||||
nbValuesElement.addEventListener("change", updateOnChange);
|
||||
|
||||
// Radio buttons
|
||||
const radioButtons = document.querySelectorAll('input[type="radio"]');
|
||||
|
||||
// if radio is checked, add class 'is-primary' to the parent label
|
||||
radioButtons.forEach(radio => {
|
||||
radio.addEventListener('change', () => {
|
||||
radioButtons.forEach(radio => {
|
||||
radio.parentElement.classList.remove('is-primary');
|
||||
});
|
||||
radioButtons.forEach(radio => radio.parentElement.classList.remove('is-primary'));
|
||||
radio.parentElement.classList.add('is-primary');
|
||||
});
|
||||
});
|
||||
|
||||
// Form submission
|
||||
const form = document.getElementById('new-game-form');
|
||||
|
||||
form.addEventListener('submit', evt => {
|
||||
evt.preventDefault();
|
||||
|
||||
const {action, method} = form;
|
||||
|
||||
const url = new URL(action);
|
||||
const formData = new FormData(form);
|
||||
for (const [key, value] of formData.entries()) {
|
||||
url.searchParams.append(key, value);
|
||||
}
|
||||
|
||||
fetch(url, {headers: {"Content-Type": "application/json"}, method})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (data.code !== 200) throw new Error(data.message);
|
||||
|
||||
// Redirect to game page
|
||||
window.location.href = "${pageContext.request.contextPath}/game?id=" + data.message;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error)
|
||||
|
||||
// Notification
|
||||
const notification = document.createElement("div");
|
||||
notification.classList.add("notification", "is-danger");
|
||||
|
||||
const notificationTitle = document.createElement("p");
|
||||
notificationTitle.classList.add("title", "is-6");
|
||||
notificationTitle.innerHTML = "Erreur";
|
||||
|
||||
const notificationIcon = document.createElement("span");
|
||||
notificationIcon.classList.add("icon");
|
||||
notificationIcon.innerHTML = "<i class='fas fa-exclamation-triangle'></i>";
|
||||
|
||||
const notificationMessage = document.createElement("p");
|
||||
notificationMessage.classList.add("subtitle", "is-6");
|
||||
notificationMessage.innerHTML = error.message;
|
||||
|
||||
notificationTitle.appendChild(notificationIcon);
|
||||
notification.appendChild(notificationTitle);
|
||||
notification.appendChild(notificationMessage);
|
||||
document.body.appendChild(notification);
|
||||
|
||||
// Remove notification and animation after 5s
|
||||
setTimeout(() => notification.remove(), 5010);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user