Reputation: 12545
I added the code below to select whole text when user click on input box:
<input type="number" onclick="this.setSelectionRange(0, this.value.length)" name="quantity" />
But I receive the error below:
Uncaught InvalidStateError: Failed to execute 'setSelectionRange' on 'HTMLInputElement': The input element's type ('number') does not support selection.
Upvotes: 45
Views: 55669
Reputation: 1591
input type="number"
doesn't support setSelectionRange
You can use: type="text"
and inputmode="numeric"
, This will show a numeric keyboard for mobile users and supports setSelectionRange
<input
type="text"
inputmode="numeric"
onclick="this.setSelectionRange(0, this.value.length)"
name="quantity" />
Upvotes: 4
Reputation: 10381
As a variation of Tri Q Tran's answer and make it a more generic one. This may be a better approach:
const element = document.createElement('input');
element.type = 'number';
(function(originalFn){
element.setSelectionRange = function() {
this.type = 'text';
originalFn.apply(this, arguments);
this.type = 'number';
}
})(element.setSelectionRange);
Or if you don't mind contaminating the prototype, this is a more generic solution:
(function(originalFn){
HTMLInputElement.prototype.setSelectionRange = function() {
if ( this.type === 'number' ) {
this.type = 'text';
originalFn.apply(this, arguments);
this.type = 'number';
} else {
originalFn.apply(this, arguments);
}
}
})(HTMLInputElement.prototype.setSelectionRange);
Upvotes: 6
Reputation: 5690
I know this is an old question, but I did find a good workaround without using the tel
input type. By changing the input type from number
to text
before the selection, the error goes away and you get to keep all the benefits of the number
input type.
tel
allows text input, which may not work with numbers.tel
does not show the number "spinner" next to the input (only if you want it).function onInputFocus(event) {
const target = event.currentTarget;
target.type = 'text';
target.setSelectionRange(0, target.value.length);
target.type = 'number';
}
Upvotes: 29
Reputation: 15186
Use input type="tel"
instead.
For your example:
<input type="tel" onclick="this.setSelectionRange(0, this.value.length)" name="quantity" />
That will do the trick and avoid the error message.
And on mobile phones, it shows up the desired number pad.
Upvotes: 23
Reputation: 51
I kind of got this working in angular 1.5 using a nifty custom directive (see example below in typescript).
Since it appears there is no way to programmatically select the entire value while the input type="number", the strategy here is to temporarily change the input type from number to text while editing the value, then change it back to the original type on blur.
This results in behavior that differs slightly from the native behavior in that it will actually allow you to type in "invalid" data into the field. However, on blur, all of the browser's native number validation logic will kick in and prevent any invalid data from being submitted. I'm sure there's some other gotchas but it's works well enough in Chrome and FireFox for us so I thought I'd share.
/// Selects the entire input value on mouse click.
/// Works with number and email input types.
export class SelectOnClick implements ng.IDirective {
require = 'ngModel';
restrict = 'A';
private ogType: any
constructor(private $window: ng.IWindowService) { }
link = (scope: ng.IScope, element: any) => {
element.on('click', () => {
if (!this.$window.getSelection().toString()) {
this.ogType = element[0].type;
element[0].type = 'text';
element[0].setSelectionRange(0, element[0].value.length);
}
})
element.on('blur', () => {
element[0].type = this.ogType;
})
}
static factory(): ng.IDirectiveFactory {
var directive = ($window: ng.IWindowService) => new SelectOnClick($window);
directive['$inject'] = ['$window'];
return directive;
}
}
Upvotes: 1
Reputation: 41
The evt.target.select()
selects content of input type="number"
in Chrome, the "if" structure does the same on touch devices.
document.querySelector('.number_input').addEventListener('focus', function (evt) {
evt.target.select();
if ('ontouchstart' in window) {
setTimeout(function() {
evt.target.setSelectionRange(0, 9999);
}, 1);
}
}, true);
Unfortunately that "if" prevents that autoselect in Mac Safari, I don't know how to get the same result both in desktop browsers and mobile.
Upvotes: 3
Reputation: 106077
Just like the error message says, you can't use setSelectionRange
with a number input. If you want to modify the selection using JavaScript, you'll have to use <input type="text"/>
instead.
Upvotes: 3