iOS5 show numeric keypad by default without using type="number" or type="tel"
Asked Answered
H

11

36

With the release of iOS5, Apple has added their own validation to input type="number" form fields. This is causing some issues; see this question below which sums it up:

Input type='number' new validation removes leading zeros and formats number in Safari for iPhone iOS5 and latest Safari for Mac

Although input type="tel" works to bring up a numeric keypad on the iphone, it's the telephone keypad which has no decimal points.

Is there a way to set the numeric keypad as default using html/js? This not an iphone app. At minimum I need numbers and a decimal point in the keypad.

Update

Number input fields in Safari 5.1/iOS 5 only accept digits and decimal points. The default value for one of my inputs is $500,000. This is resulting in Safari showing a blank input field because $ , % are invalid characters.

Furthermore, when I run my own validation onblur, Safari clears the input field because I'm adding a $ to the value.

Thus Safari 5.1/iOS5's implementation of input type="number" has rendered it unusable.

jsfiddle

Try it here - http://jsfiddle.net/mjcookson/4ePeE/ The default value of $500,000 won't appear in Safari 5.1, but if you remove the $ and , symbols, it will. Frustrating.

Horsemanship answered 22/11, 2011 at 5:46 Comment(10)
why do you need leading zeros? they don't affect the value of any real numberFincher
@esqew: Maybe an ID number. My Student ID number, for example, has a leading zero.Malcommalcontent
@Evan Mulawski then it's stored as a string and not a number. It's impossible to represent a number with leading zeros.Alfredalfreda
@Strelok: I understand that. But the user will not like entering a leading zero into a text box and seeing it disappear when they dismiss the keyboard.Malcommalcontent
what place do you work for that has decimal points in id numbers?Fincher
@esqew: It was just an example for why leading zeros are sometimes necessary. ID numbers are not the only numbers that use leading zeros, either.Malcommalcontent
@EvanMulawski I just don't know when you would need decimals WITH leading zeros...Fincher
@esqew: for Interest Rates eg. 0.5%Horsemanship
The silly thing is that the input type="number" keyboard that comes up still has the symbol keys, and you can select them.. but when you hit Done, they get stripped from the input field. Terrible UX decision on Apple's part in my opinion.Mahaliamahan
Also from my testing type=number doesn't show trailing zeros (even with step="0.01" or step="any"), so it is almost useless for dollars and cents.Curry
H
3

Working solution: Tested on iPhone 5, Android 2.3, 4

Tadeck's solution (bounty winner) of using a <span> to contain the input field symbols and place a formatted <span> on top of the currency input is essentially what I ended up doing.

My final code is different and shorter however so I'm posting it here. This solution resolves the iOS5 validation issue of $ , % symbols inside input fields and so input type="number" can be used by default.

Symbol field eg. "xx %" "xx years"

<input name="interest-rate" value="6.4" maxlength="4" min="1" max="20" />
<span class="symbol">%</span>
  • Simply use a number input field and a span outside the input to display the symbol.

Currency field eg. "$xxx,xxx"

<span id="formatted-currency">$500,000</span>
<input id="currency-field" type="number" name="loan-amount" value="500000" maxlength="8" min="15000" max="10000000" />
  • Position the span on top of the currency input and set the input to display:none
  • When a user clicks/taps on the span, hide the span and show the input. If you position the span perfectly the transition is seamless.
  • The number input type takes care of the validation.
  • On blur and submit of the input, set the span html to be the input's value. Format the span. Hide the input and show the span with the formatted value.

$('#formatted-currency').click(function(){
    $(this).hide();
    $('#currency-field').show().focus();
});
$('#currency-field').blur(function(){
    $('#formatted-currency').html(this.value);
    $('#formatted-currency').formatCurrency({
        roundToDecimalPlace : -2
    });
    $(this).hide();
    $('#formatted-currency').show();
});
// on submit
$('#formatted-currency').html($('#currency-field').val());
$('#formatted-currency').formatCurrency({
    roundToDecimalPlace : -2
});
$('#currency-field').hide();
$('#formatted-currency').show();
Horsemanship answered 19/3, 2013 at 1:39 Comment(0)
O
16

Styling the field to contain symbols

When it comes to including the symbols within this number field, you can use some walkaround like that:

HTML:

<span id="number-container">
    <input type="number" name="number" id="number-field" value="500" />
    <span id="number-container-symbol">$</span>
</span>

CSS:

#number-container {
    position: relative;
}
#number-container-symbol {
    left: 5pt;
    position: absolute;
    top: 0px;
}
#number-field {
    background-color: transparent;
    padding-left: 10pt;
}

Treat it as a proof of concept. See this jsfiddle for a live example. It looks like that in Chrome:

enter image description here

Defining smaller granularity

Based on the documentation on number input (Editor's Draft), to define granularity you need to add step="<some-floating-point-number>" attribute to the <input> tag:

<input type="number" name="number" value="500.01" step="0.01" />

and it will work in many modern browsers. See this jsfiddle for tests.

Conclusion

You should be able to style it to contain symbols you need. There is also a feature that, according to documentation, enables support for floating-point numbers.

Alternative solution - empty field in front of something else

You can also trick someone into believing he is seeing content of the input field, but show him something else behind the field (this is some extension of my original solution). Then if someone taps the field, you can propagate proper value etc., then go back to the previous state on blur. See this code (live example on jsfiddle - blue color means you are looking at something that is not within the field):

// store original value from INPUT tag in jQuery's .data()
var input_field = jQuery('#number-field');
var display_span = jQuery('#number-container-value');
var base_val = parseFloat(input_field.val());
input_field.data('storedVal', base_val);
input_field.val('');
display_span.html(base_val);

// react to field gaining and losing focus
jQuery('#number-field').on('focus', function(event){
    var el = jQuery(this);
    var display = jQuery('#number-container-value');
    if (typeof el.data('storedVal') != 'undefined'){
        el.val(el.data('storedVal'));
    };
    display.html('');
}).on('blur', function(event){
    var el = jQuery(this);
    var display = jQuery('#number-container-value');
    var new_val = parseFloat(el.val());
    el.data('storedVal', new_val);
    display.html(new_val);
    el.val('');
});

(the full code with styling is on the mentioned jsfiddle). The code needs shortening & cleaning up, but it is a proof of concept. Try it and share your findings, please.

Oarlock answered 27/11, 2011 at 23:31 Comment(0)
P
7

Why not put the $ outside the input field (as a label). Or the percent sign to the right of the input field? Seems like that'd solve your issue and you'd be able to use input type="number" and it'd just work.

Possessed answered 27/11, 2011 at 23:18 Comment(0)
K
5

You're stuck between a rock and a hard place. Until there's a place in the HTML spec for type="currency" (and that'll probably never happen cos of the different ways different countries write currency), you're going to have to use some JS magic to get around the problem.

Of course number nor telephone won't be the best idea, however by using a bit of JS cunning I've come up with this solution:

var i   = document.getElementById( 'input' );

i.onblur    = function()
{
    i.type  = 'text';

    i.value = number_format( i.value );
}

i.onfocus   = function()
{
    var v   = Number( i.value.replace( /\D/, '' ) );

    i.type  = 'number';

    i.value = v > 0 ? v : '';
}

Simply I swap the type of the input depending on focus/blur, this means that once the user has left the text field, we can format its ass. When the user returns, we take the value, if there's one that's > 0 and we stick it back in as a number. Here's the working test, I hope it helps: http://jsfiddle.net/ahmednuaman/uzYQA/

Ketonuria answered 30/11, 2011 at 10:24 Comment(1)
Actually type='currency' could be implemented on the basis of localization settings etc. The only information such field would need would be currency (eg. "USD", "EUR" etc.) and optionally format (eg. whether it should be displayed as "12 USD" or "$12", it can depend on the localization settings). Value could be then an integer or a float. But this is rather unrelated to the problem OP is having :)Digit
C
3

The following pops up the numeric keyboard for iPad with iOS5, allows any character to be typed, and allows any value to be set:

<input type="text" pattern="\d*">

However it is ugly, fragile (probably will break in future ...), and doesn't work on iPhone (iPhone shows the numeric keypad that only allows 0 to 9). The solution only seems to work using the pattern \d* or its equivalent [0-9]*.

Maybe better to use type="tel" which seems to act the same.

Curry answered 16/5, 2012 at 2:9 Comment(0)
H
3

Working solution: Tested on iPhone 5, Android 2.3, 4

Tadeck's solution (bounty winner) of using a <span> to contain the input field symbols and place a formatted <span> on top of the currency input is essentially what I ended up doing.

My final code is different and shorter however so I'm posting it here. This solution resolves the iOS5 validation issue of $ , % symbols inside input fields and so input type="number" can be used by default.

Symbol field eg. "xx %" "xx years"

<input name="interest-rate" value="6.4" maxlength="4" min="1" max="20" />
<span class="symbol">%</span>
  • Simply use a number input field and a span outside the input to display the symbol.

Currency field eg. "$xxx,xxx"

<span id="formatted-currency">$500,000</span>
<input id="currency-field" type="number" name="loan-amount" value="500000" maxlength="8" min="15000" max="10000000" />
  • Position the span on top of the currency input and set the input to display:none
  • When a user clicks/taps on the span, hide the span and show the input. If you position the span perfectly the transition is seamless.
  • The number input type takes care of the validation.
  • On blur and submit of the input, set the span html to be the input's value. Format the span. Hide the input and show the span with the formatted value.

$('#formatted-currency').click(function(){
    $(this).hide();
    $('#currency-field').show().focus();
});
$('#currency-field').blur(function(){
    $('#formatted-currency').html(this.value);
    $('#formatted-currency').formatCurrency({
        roundToDecimalPlace : -2
    });
    $(this).hide();
    $('#formatted-currency').show();
});
// on submit
$('#formatted-currency').html($('#currency-field').val());
$('#formatted-currency').formatCurrency({
    roundToDecimalPlace : -2
});
$('#currency-field').hide();
$('#formatted-currency').show();
Horsemanship answered 19/3, 2013 at 1:39 Comment(0)
K
2

I had a similar problem, and came up with this dead-ugly js solution, forcing the iPad to popup the numeric keypad.

My problem was that safari filter away everything except digits when the form is posted, and I need various extra characters, for example "3/7", or "65$".

var elem = document.getElementById('MathAnswer');
elem.type = 'number';

elem.onfocus = function() {
  setTimeout(function() {
    elem.type = 'text'; 
  }, 1);
};

It simply set the input type back to 'text' after iPad has shown the numeric keypad, and voila, safari no longer removes any non-digits.

Hope it helps someone!

Kaczmarek answered 16/7, 2014 at 22:10 Comment(1)
oops, I saw @Curry had provided a similar answer, but my answer might add to his idea. :)Kaczmarek
C
0

There is potentially another way around the issue for the iPhone:

<input id="test" TYPE="text" value="5.50" ontouchstart="this.type='number'" onfocus="this.type='text'" />

This changes the type to number before the input gets focus when touched (so that the numeric keyboard shows) and then changes the type to text so that the correct value can be edited.

Getting it working reliably might be hard though e.g. currently touch input but then slide finger off control leaves it as type=number, and I can't think of a way to detect the Next button on keyboard, amongst other issues.

Curry answered 16/5, 2012 at 2:49 Comment(0)
C
0

This solution works on iPad and iPhone, and even Next/Previous work. Try http://fiddle.jshell.net/L77Cq/2/show/ (or http://jsfiddle.net/L77Cq/ to edit).

<!DOCTYPE html>
<head>
<style>
    .riggedinput::-webkit-input-placeholder {
    margin: 0em;
    font: -webkit-small-control;
    color: initial;
    letter-spacing: normal;
    word-spacing: normal;
    line-height: normal;
    text-transform: none;
    text-indent: 0px;
    text-shadow: none;
}
</style>
<script>
    function focused() {
        var test = document.getElementById('test');
        setTimeout(function() { // timeout needed so that keyboard changes to numeric when using Next/Previous keyboard navigation buttons
            if (document.activeElement === test) {
                test.type = 'text';
                test.value = test.placeholder;
                test.placeholder = '';
            }
        }, 1);
    }
    function blurred() {
        var test = document.getElementById('test');
        var value = test.value;
        test.placeholder = value;
        test.value = '';
        test.type = 'number';
    }
    if (!/^(iPhone|iPad|iPod)$/.test(navigator.platform)) alert ('Code specific to Mobile Safari');
</script>
</head>
<body>
    <input>
    <input id="test" type="number" class="riggedinput" placeholder="$100.10USD" onfocus="focused()" onblur="blurred()">
    <input>
</body>

It still has the following issues: * If using forms, needs to copy value to a hidden field. * For some reason the page scrolls funny (iPhone address bar hides, iPad Debug Console hides).

PS: I found this technique independently of Ahmed Nuaman's comment above (I had tried it in the past, and noticed his comment just now - arrrgh!).

Curry answered 16/5, 2012 at 5:35 Comment(0)
M
0

Your problem would be solved if Safari would support the HTML5 'inputmode' attribute for input elements. Nobody knows if, or when that is going to happen. In the meantime this link provides some interesting reading.

Mammiemammiferous answered 15/8, 2014 at 12:56 Comment(0)
C
0

We ended up using a hacky solution to enable the numbersandpunctuation keyboard to show when focused which works on an iPhone: we record the keypresses and simulate the value.

https://output.jsbin.com/necuzoj/quiet

We tried changing the input type from type=number to type=text on focus, but it was unreliable: (1) the numeric keyboard didn't show 100% of the time, and (2) if a form was was longer than the screen then the auto scrolling to show the focused input was completely stuffed up (sometimes the focused input would be off-screen or under the virtual keyboard).

Showing the numeric keypad (e.g. type=tel) didn't allow the entry of a decimal point or colon.

On an iPad you can just use <input type=text pattern=[0-9]*> to show the numbersandpunctiation keyboard, but that solution doesn't work for an iPhone (an iPhone shows the numeric keypad with no decimal point).

Curry answered 10/12, 2015 at 5:11 Comment(0)
N
-3

I just use something like <input type="number" name="job_order_id" maxlength="7" size="10px" value="" /> and I get the keyboard with numbers and not the telephone keypad. You could also put the leading values into value, and they would already be there.

Newby answered 26/11, 2011 at 23:22 Comment(5)
I can't use input type="number". Please read the question. ThanksHorsemanship
I think you're going to have to. You could use a tooltip or hint to guide them as to input... but if "At minimum I need numbers and a decimal point in the keypad" I don't think you have another choice. I did read the question, but there seems to be some disconnect between what you need and what you're asking.Newby
You also say that "This is resulting in Safari displaying nothing in the input field because $ , % are invalid characters." Are you saying they won't show up as the default value, or you can't enter them? My Safari browser seems to accept both.Newby
There's a disconnect because Safari 5.1/iOS5's implementation of input type="number" has rendered it unusable: Default values of '$500,000' and '7.8%' don't show up; the field is blank. When I run my own validation onblur, Safari clears the input field because I'm adding a $ to the value. This only occurs in Safari 5.1/iOS5. Added jsfiddle to answerHorsemanship
You did say iOS5, and I'm looking at it in 4. Oops. <!-- puts hands in pocket, looks away and starts whistling -->Newby

© 2022 - 2024 — McMap. All rights reserved.