我正在构建主要面向移动浏览器的网络应用。我使用数字类型的输入字段,因此(大多数)移动浏览器仅调用数字键盘以获得更好的用户体验。这个Web应用程序主要用于小数分隔符是逗号而不是点的区域,所以我需要处理两个小数分隔符。
如何用点和逗号覆盖整个混乱?
我的发现:
桌面版Chrome
$("#my_input").val();
返回“455”桌面Firefox
$("#my_input").val();
返回“4,55”Android浏览器
Windows Phone 8
$("#my_input").val();
返回“4,55”在这种情况下,当用户可能使用逗号或点作为小数点分隔符并且我希望将html输入类型保留为数字时,有什么是“最佳做法”,以提供更好的用户体验?
我可以将逗号转换为“动态”点,绑定关键事件,它是否与数字输入一起使用?
Currenlty我没有任何解决方案,如何从输入中获取浮点值(如字符串或数字),类型设置为数字。如果最终用户输入“4,55”,则Chrome返回“455”,Firefox返回“4,55”,这很好。
同样令人讨厌的是,在Android(经过测试的4.2模拟器)中,当我输入“4,55”输入字段并将焦点更改为其他地方时,输入的数字将被截断为“4”。
答案 0 :(得分:99)
我认为上述答案中缺少的是需要为step
属性指定不同的值,其默认值为1
。如果希望输入的验证算法允许浮点值,请相应地指定步骤。
例如,我想要美元金额,所以我指定了这样一个步骤:
<input type="number" name="price"
pattern="[0-9]+([\.,][0-9]+)?" step="0.01"
title="This should be a number with up to 2 decimal places.">
使用jQuery检索值没有任何问题,但您会发现直接使用DOM API获取元素的validity.valid
属性很有用。
我在小数点上遇到了类似的问题,但我意识到存在问题的原因是因为Twitter Bootstrap添加了一个带有无效值的数字输入的样式。
这是一个小提示,证明添加step
属性使其有效,并且还测试当前值是否有效:
TL; DR: 将step
属性设置为浮点值,因为它默认为1
。
注意:逗号不会对我进行验证,但我怀疑如果我将操作系统语言/区域设置设置为使用逗号作为小数分隔符的某个位置,它会工作。 *注意注意*:在Ubuntu / Gnome 14.04中,操作系统语言/键盘设置不是*德语*。
答案 1 :(得分:22)
根据w3.org,number input的 value 属性被定义为floating-point number。浮点数的语法似乎只接受点作为十进制分隔符。
我在下面列出了一些可能对您有所帮助的选项:
使用 pattern 属性,您可以使用HTML5兼容方式使用正则表达式指定允许的格式。在这里,您可以指定允许使用逗号字符,并在模式失败时指定有用的反馈消息。
<input type="number" pattern="[0-9]+([,\.][0-9]+)?" name="my-num"
title="The number input must start with a number and use either comma or a dot as a decimal character."/>
注意:跨浏览器支持差异很大。它可能是完整的,部分的或不存在的。
您可以尝试将简单的回调绑定到例如 onchange (和/或 blur )事件,该事件将替换逗号或一起验证所有内容。
第三,您可以尝试在数字输入上使用 formnovalidate 属性,以便同时禁用该字段的浏览器验证。
<input type="number" formnovalidate />
<input type="number" pattern="[0-9]+([,\.][0-9]+)?"
name="my-num" formnovalidate
title="The number input must start with a number and use either comma or a dot as a decimal character."/>
答案 2 :(得分:7)
使用valueAsNumber
代替.val()
。
输入。 valueAsNumber [= value]
返回表示表单控件值的数字(如果适用);否则,返回null 可以设置,更改值 如果控件既不是基于日期或时间也不是数字,则抛出INVALID_STATE_ERR异常。
答案 3 :(得分:7)
是否对小数点分隔符使用逗号或句点完全取决于浏览器。浏览器根据操作系统或浏览器的区域设置做出决定,或者某些浏览器从网站上获取提示。我做了一个browser comparison chart,展示了不同浏览器如何支持处理不同的本地化方法。 Safari是唯一可以互换处理逗号和句点的浏览器。
基本上,作为网络作者,你无法真正控制它。一些解决方法涉及使用两个带整数的输入字段。这允许每个用户按照期望输入数据。它不是特别性感,但它适用于所有用户。
答案 4 :(得分:3)
我还没有找到一个完美的解决方案,但我能做的最好的就是使用type =&#34; tel&#34;并禁用html5验证(formnovalidate):
<input name="txtTest" type="tel" value="1,200.00" formnovalidate="formnovalidate" />
如果用户输入逗号,它将在我尝试的每个现代浏览器中输出逗号(最新的FF,IE,边缘,歌剧,chrome,safari桌面,android chrome)。
主要问题是:
对于我的用例,我只需要:
如果您有类似的要求,这应该适合您。
注意:我不喜欢pattern属性的支持。 formnovalidate似乎效果更好。
答案 5 :(得分:1)
当你调用$("#my_input").val();
时,它会返回字符串变量。因此,请使用parseFloat
和parseInt
进行转换。
当您使用parseFloat
桌面或手机时, ITSELF 会理解变量的含义。
另外,你可以使用toFixed
将一个浮点数转换为字符串,其参数的位数如下:
var i = 0.011;
var ss = i.toFixed(2); //It returns 0.01
答案 6 :(得分:1)
使用文本类型,但强制显示数字键盘
<input value="12,4" type="text" inputmode="numeric" pattern="[-+]?[0-9]*[.,]?[0-9]+">
inputmode标签是解决方案
答案 7 :(得分:1)
表面上看来,浏览器仍然有麻烦(尽管Chrome和Firefox Nightly可以正常工作)。 对于确实必须使用数字字段的人,我有一个拙劣的做法(也许是因为文本字段没有小箭头)。
我在表单输入中添加了一个keyup
事件处理程序,并跟踪状态并在该值再次生效后对其进行设置。
var currentString = '';
var badState = false;
var lastCharacter = null;
document.getElementById("field").addEventListener("keyup",($event) => {
if ($event.target.value && !$event.target.validity.badInput) {
currentString = $event.target.value;
} else if ($event.target.validity.badInput) {
if (badState && lastCharacter && lastCharacter.match(/[\.,]/) && !isNaN(+$event.key)) {
$event.target.value = ((+currentString) + (+$event.key / 10));
badState = false;
} else {
badState = true;
}
}
document.getElementById("number").textContent = $event.target.value;
lastCharacter = $event.key;
});
document.getElementById("field").addEventListener("blur",($event) => {
if (badState) {
$event.target.value = (+currentString);
badState = false;
document.getElementById("number").textContent = $event.target.value;
}
});
#result{
padding: 10px;
background-color: orange;
font-size: 25px;
width: 400px;
margin-top: 10px;
display: inline-block;
}
#field{
padding: 5px;
border-radius: 5px;
border: 1px solid grey;
width: 400px;
}
<input type="number" id="field" keyup="keyUpFunction" step="0.01" placeholder="Field for both comma separators">
<span id="result" >
<span >Current value: </span>
<span id="number"></span>
</span>
@Directive({
selector: '[appFloatHelper]'
})
export class FloatHelperDirective {
private currentString = '';
private badState = false;
private lastCharacter: string = null;
@HostListener("blur", ['$event']) onBlur(event) {
if (this.badState) {
this.model.update.emit((+this.currentString));
this.badState = false;
}
}
constructor(private renderer: Renderer2, private el: ElementRef, private change: ChangeDetectorRef, private zone: NgZone, private model: NgModel) {
this.renderer.listen(this.el.nativeElement, 'keyup', (e: KeyboardEvent) => {
if (el.nativeElement.value && !el.nativeElement.validity.badInput) {
this.currentString = el.nativeElement.value;
} else if (el.nativeElement.validity.badInput) {
if (this.badState && this.lastCharacter && this.lastCharacter.match(/[\.,]/) && !isNaN(+e.key)) {
model.update.emit((+this.currentString) + (+e.key / 10));
el.nativeElement.value = (+this.currentString) + (+e.key / 10);
this.badState = false;
} else {
this.badState = true;
}
}
this.lastCharacter = e.key;
});
}
}
<input type="number" matInput placeholder="Field for both comma separators" appFloatHelper [(ngModel)]="numberModel">
答案 8 :(得分:0)
我的推荐?根本不要使用jQuery。我遇到了和你一样的问题。我发现$('#my_input').val()
总是会返回一些奇怪的结果。
尝试使用document.getElementById('my_input').valueAsNumber
代替$("#my_input").val();
,然后使用Number(your_value_retrieved)
尝试创建一个数字。如果值是NaN,那么你肯定知道那不是数字。
要添加的一件事是当你在输入上写一个数字时,输入实际上会接受几乎任何字符(我可以写欧元符号,一美元和所有其他特殊字符),所以最好检索使用.valueAsNumber
而不是使用jQuery的值。
哦,BTW,允许你的用户添加国际化(即:支持逗号而不是点来创建十进制数)。只需让Number()
对象为您创建一些东西,它就是十进制安全的,可以这么说。
答案 9 :(得分:0)
听起来你想在数字输入上使用toLocaleString()。
JS中数字的本地化也包含在Internationalization(Number formatting "num.toLocaleString()") not working for chrome
中