Reputation: 46493
I'm doing a small number keypad in Javascript, and I can't add a decimal point .
to an <input type="number">
by doing:
document.getElementById('2').onclick = () => document.getElementById('input').value += '2';
document.getElementById('.').onclick = () => document.getElementById('input').value += '.';
<input id="input" type="number" value="3"></input>
<div id="2">click to add 2</div>
<div id=".">click to add .</div>
The specified value "3." cannot be parsed, or is out of range.
But on the other hand, we can manually enter the decimal point with the keyboard when the input has focus.
Full example:
var target = document.querySelector('#input');
document.querySelectorAll('.calcbutton').forEach(el => el.addEventListener("click", evt => { target.value += evt.target.innerHTML; }));
document.querySelector('.calcpoint').onclick = evt => { if (!target.value.includes('.')) target.value += '.'; };
<input id="input" type="number"></input>
<div id="calc">
<table>
<tr><td class="calcbutton">7</td><td class="calcbutton">8</td><td class="calcbutton">9</td></tr>
<tr><td class="calcbutton">4</td><td class="calcbutton">5</td><td class="calcbutton">6</td></tr>
<tr><td class="calcbutton">1</td><td class="calcbutton">2</td><td class="calcbutton">3</td></tr>
<tr><td class="calcbutton">0</td><td class="calcpoint">.</td><td class="calcenter">ENTER</td></tr>
</table>
</div>
Why does pressing .
clear the input?
Upvotes: 13
Views: 1561
Reputation: 2691
If a value is set (per JS), it works like the following (copy from specification)
That means it is immediately checked whether it fits the pattern of a number, whereas on a user input, it waits to a later point (basically to allow the ability to add decimal points)
See https://html.spec.whatwg.org/multipage/input.html#dom-input-value-value for more information.
Upvotes: 11
Reputation: 1
document.getElementById('2').onclick = () => document.getElementById('input').value += '2';
document.getElementById('.').onclick = () => document.getElementById('input').value += '.';
<input id="input" type="number" value="3"></input>
<div id="2">click to add 2</div>
<div id=".">click to add .</div>
Upvotes: -2
Reputation: 122906
I suppose it's because of the number type of the input field and its sanitation (by the interpreter, see @Felix' answer).
If you want to keep using the number field, an idea to work around it may be to use a hidden text field to fill the number field (using parseFloat
). Here's a snippet (text field not hidden for demo), using event delegation for the handling.
document.addEventListener(`click`, handle);
function handle(evt) {
if (evt.target.matches(`.calcbutton`)) {
const value = evt.target.textContent;
const inpNr = document.querySelector('#input');
const inpTxt = document.querySelector('#inputTxt');
const hasDot = /\./.test(inpTxt.value);
// only one dot allowed
inpTxt.value += hasDot && value === `.` ? `` : value;
return inpNr.value = parseFloat(inpTxt.value);
}
// for demo: hide text or number field to see what it's like
if (evt.target.matches(`[data-hidden]`)) {
if (evt.target.dataset.hidden === `txt`) {
document.querySelector('#input').closest(`div`).style.display = `none`;
document.querySelector('#inputTxt').closest(`div`).style.display = ``;
evt.target.dataset.hidden = `nr`;
return evt.target.textContent = `Hide text field`;
}
document.querySelector('#input').closest(`div`).style.display = ``;
document.querySelector('#inputTxt').closest(`div`).style.display = `none`;
evt.target.dataset.hidden = `txt`;
return evt.target.textContent = `Hide number field`;
}
}
.calcbutton {
cursor: pointer;
font-size: 1.5rem;
font-weight: bold;
}
<div><input id="input" type="number" readonly> Number</div>
<div style="display:none"><input id="inputTxt" type="text" readonly> Text</div>
<div id="calc">
<table>
<tr>
<td class="calcbutton">7</td>
<td class="calcbutton">8</td>
<td class="calcbutton">9</td>
</tr>
<tr>
<td class="calcbutton">4</td>
<td class="calcbutton">5</td>
<td class="calcbutton">6</td>
</tr>
<tr>
<td class="calcbutton">1</td>
<td class="calcbutton">2</td>
<td class="calcbutton">3</td>
</tr>
<tr>
<td class="calcbutton">0</td>
<td class="calcbutton">.</td>
<td class="calcenter">ENTER</td>
</tr>
</table>
</div>
<button data-hidden="txt">Hide number field</button>
Upvotes: 5