javascript 使用自定义/货币模式强制 iOS 数字键盘

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19684855/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 16:28:54  来源:igfitidea点击:

Force iOS numeric keyboard with custom / currency pattern

javascriptiosjquery-mobilekeyboard

提问by tronc

Is there a possiblity to force an iOS-device to show the numeric keyboard while using a custom pattern as input type?

在使用自定义模式作为输入类型时,是否有可能强制 iOS 设备显示数字键盘?

my input pattern:

我的输入模式:

<input id="price" class="numeric" pattern="\d+((\.|,)\d{1,2})?" name="price" 
title="" data-mini="true" data-clear-btn="true" autocomplete="off" autofocus />

I want to type a currency value like '14.99' and show up a keyboard with access to numbers on the iOS device

我想输入一个像“14.99”这样的货币值,并在 iOS 设备上显示一个可以访问数字的键盘

<input type='number' />
<input pattern='[0-9]*' />
<input pattern='[\d]*' />

are all missing the decimal sign and/or are not validating as number when adding a decimal sign. An alternative way could be a javascript function which is creating the decimal sign on the right place, like pressing 1->2->9->9 in this order creates on keypress() 0.01->0.12->1.29->12.99, but this requires the input field to be type='text'--> obvious problem here is that the text keyboard is showed when focussing the input field.

都缺少小数点和/或在添加小数点时未验证为数字。另一种方法可能是一个 javascript 函数,它在正确的位置创建十进制符号,例如按 1->2->9->9 的顺序在 keypress() 0.01->0.12->1.29->12.99 上创建,但这需要输入字段type='text'--> 这里明显的问题是在聚焦输入字段时会显示文本键盘。

How can I solve this issue?

我该如何解决这个问题?

EDIT

编辑

Environment:

环境:

  • JQM 1.3.2
  • jquery 1.8.2
  • JQM 1.3.2
  • jQuery 1.8.2

回答by Vizllx

For now, JavaScript is the only solution. Here's the simplest way to do it (using jQuery):

目前,JavaScript 是唯一的解决方案。这是最简单的方法(使用 jQuery):

HTML

HTML

<input type="text">

JavaScript

JavaScript

$('input[type="text"]').on('touchstart', function() {
  $(this).attr('type', 'number');
});

$('input[type="text"]').on('keydown blur', function() {
  $(this).attr('type', 'text');
});

The idea is simple. The input starts off and ends up with type="text", but it briefly becomes type="number" on the touchstart event. This causes the correct iOS keyboard to appear. As soon as the user begins to enter any input or leave the field, the input becomes type="text" once again, thus circumventing the validation.

这个想法很简单。输入开始并以 type="text" 结束,但它在 touchstart 事件中短暂地变为 type="number"。这会导致出现正确的 iOS 键盘。一旦用户开始输入任何输入或离开该字段,输入将再次变为 type="text",从而绕过验证。

There's one downside to this method. When the user returns to an input that has already been filled out, the input will be lost (if it doesn't validate). This means the user won't be able to go back and edit previous fields. In my case, this isn't all that bad because the user may want to use the calculator over and over again with different values, so automatically deleting the input will save them a few steps. However, this may not be ideal in all cases.

这种方法有一个缺点。当用户返回到已经填写好的输入时,该输入将丢失(如果未验证)。这意味着用户将无法返回并编辑以前的字段。在我的情况下,这并不是那么糟糕,因为用户可能希望使用不同的值一遍又一遍地使用计算器,因此自动删除输入将节省几个步骤。然而,这可能并非在所有情况下都是理想的。

It looks like Mobile Safari supports the new HTML5 input type attributes of email, number, search, tel, and url. These will switch the keyboard that is displayed. See the type attribute.

看起来 Mobile Safari 支持新的 HTML5 输入类型属性,包括电子邮件、号码、搜索、电话和网址。这些将切换显示的键盘。请参阅类型属性。

So for example, you could do this:

例如,你可以这样做:

<input type="number" />

And when the input box has focus, the number keyboard is shown (as if the user had the full keyboard and hit the "123" button.

当输入框有焦点时,会显示数字键盘(就好像用户有全键盘并点击了“123”按钮。

If you really only want numbers, you could specify:

如果你真的只想要数字,你可以指定:

<input type="tel" />

And then the user would get the phone number dialing keypad.

然后用户将获得电话号码拨号键盘。

I know this works with Mobile Safari -- I only assume it will work with UIWebView.

我知道这适用于 Mobile Safari——我只假设它适用于 UIWebView。

http://conecode.com/news/2011/12/mobile-safari-uiwebview-input-types/

http://conecode.com/news/2011/12/mobile-safari-uiwebview-input-types/

回答by Omar

I made this little snippet to achieve what you want and I've tested it on iPhone 5 v7.0.3

我做了这个小片段来实现你想要的,我已经在 iPhone 5 v7.0.3 上测试过了

I used e.whichto read CharCodeentered and then push it into an array (before) which represents digits before decimal mark and another array (after) to move values from (before) array past the decimal mark.

我曾经e.which读取CharCode输入,然后将其推入一个数组(before),它表示小数点之前的数字和另一个数组(after)以将(before)数组中的值移动到小数点之后。

It might look complicated, due to my humble programming skills.

由于我卑微的编程技能,它可能看起来很复杂。

1) Code demo- 2) Currency conversion demo

1)代码演示- 2)货币转换演示

HTML:

HTML:

<input type="tel" id="number" />

JS

JS

Variables and functions:

变量和函数:

// declare variables
var i = 0,
    before = [],
    after = [],
    value = [],
    number = '';

// reset all values
function resetVal() {
    i = 0;
    before = [];
    after = [];
    value = [];
    number = '';
    $("#number").val("");
    $(".amount").html("");
}

// add thousand separater
function addComma(num) {
  return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

Main code:

主要代码:

// listen to keyup event
$("#number").on("keyup", function (e, v) {

    // accept numbers only (0-9)
    if ((e.which >= 48) && (e.which <= 57)) {

        // convert CharCode into a number   
        number = String.fromCharCode(e.which);

        // hide value in input
        $(this).val("");

        // main array which holds all numbers
        value.push(number);

        // array of numbers before decimal mark
        before.push(value[i]);

        // move numbers past decimal mark
        if (i > 1) {
            after.push(value[i - 2]);
            before.splice(0, 1);
        }

        // final value
        var val_final = after.join("") + "." + before.join("");

        // show value separated by comma(s)
        $(this).val(addComma(val_final));

        // update counter
        i++;

        // for demo
        $(".amount").html(" " + $(this).val());

    } else {

        // reset values
        resetVal();
    }
});

Reset:

重启:

// clear arrays once clear btn is pressed
$(".ui-input-text .ui-input-clear").on("click", function () {
    resetVal();
});

Result:

结果:

enter image description here

在此处输入图片说明

回答by dcorbatta

I think that you can use the same approach that I suggested to Ranjan.

我认为您可以使用我向Ranjan建议的相同方法。

Using a textfield like a buffer. First you need to detect when the keyboard appears and check if the first responder is the webview. Then you become a textview as the first responder.

使用像缓冲区一样的文本字段。首先,您需要检测键盘何时出现并检查第一响应者是否为 webview。然后你成为一个文本视图作为第一响应者。

When you are setting the text inside the input of the webview, you can add some logic to validate the number.

当您在 webview 的输入中设置文本时,您可以添加一些逻辑来验证数字。

Hereis a link of my example project with the solution, in your case you don't need change the inputView. But the approach is the same, use a Man in the middle.

是我的示例项目与解决方案的链接,在您的情况下,您不需要更改 inputView。但是方法是一样的,在中间使用一个Man。

回答by Mark Anthony Torres

Cant comment on https://stackoverflow.com/a/19998430/6437391so posting as a separate answer...

无法评论https://stackoverflow.com/a/19998430/6437391所以作为单独的答案发布......

This is the same idea as https://stackoverflow.com/a/19998430/6437391but instead of switching the type, its the pattern that's switched.

这与https://stackoverflow.com/a/19998430/6437391 的想法相同,但不是切换类型,而是切换的模式。

This has the effect of not clearing the value on the textfield on focus when value does not match numeric format, for example, if the value has separators( 1,234.56 ).

当值与数字格式不匹配时,这会导致不会清除焦点文本字段上的值,例如,如果值具有分隔符 ( 1,234.56 )。

$('input[type="text"]').on('touchstart', function() {
  $(this).attr('pattern', '[0-9]*');
});

$('input[type="text"]').on('focus', function() {
  $(this).attr('pattern', actualpattern);
});