In JavaScript possiamo gestire i campi di input di tipo numerico con facilità.
Partiamo dalla seguente marcatura.
<form action="" method="post">
<div class="input-number">
<input type="number" min="1" max="10" value="1">
<div class="plus-minus" aria-hidden="true">
<span class="plus">+</span>
<span class="minus">-</span>
</div>
</div>
</form>
Vogliamo che i nostri controlli personalizzati si sovrappongano a quelli predefiniti per questo tipo di campo. Definiamo quindi i seguenti stili CSS.
.input-number {
width: 100%;
position: relative;
}
input[type=number] {
display: block;
width: 100%;
box-sizing: border-box;
padding: 10px;
background: #fff;
border: 1px solid #ccc;
}
.plus-minus {
width: 2.6em;
background: #fff;
position: absolute;
top: 6px;
right: 3px;
z-index: 1000;
}
.plus-minus span {
cursor: pointer;
font-size: 18px;
font-family: Helvetica, Arial, sans-serif;
display: inline-block;
margin: 0 4px;
font-weight: bold;
}
Ora dobbiamo fare in modo che l'utente non inserisca valori maggiori o minori di quelli stabiliti negli attributi min e max.
const handleChange = inputs => {
inputs.forEach(input => {
input.addEventListener('change', () => {
const min = parseInt(input.getAttribute('min'), 10);
const max = parseInt(input.getAttribute('max'), 10);
if(/^\d+$/.test(input.value)) {
let value = parseInt(input.value, 10);
if(value < min) {
input.value = min;
}
if(value > max) {
input.value = max;
}
}
});
});
};
Quindi definiamo i controlli personalizzati che andranno ad incrementare o decrementare il valore del campo. Facciamo in modo che ad ogni modifica venga innescato l'evento change per permettere al codice definito in precedenza di operare.
const handleVariations = elements => {
elements.forEach(element => {
const plus = element.querySelector('.plus');
const minus = element.querySelector('.minus');
const input = element.previousElementSibling;
plus.addEventListener('click', () => {
if(/^\d+$/.test(input.value)) {
let value = parseInt(input.value, 10);
input.value = value + 1;
const event = new Event('change', { bubbles: true });
input.dispatchEvent(event);
}
});
minus.addEventListener('click', () => {
if(/^\d+$/.test(input.value)) {
let value = parseInt(input.value, 10);
input.value = value - 1;
const event = new Event('change', { bubbles: true });
input.dispatchEvent(event);
}
});
});
};
Infine, inizializziamo il nostro codice.
document.addEventListener('DOMContentLoaded', () => {
handleChange(document.querySelectorAll('input[type="number"]'));
handleVariations(document.querySelectorAll('.plus-minus'));
});