html5入力タイプ番号で浮動小数点数と小数点記号を処理する方法


128

主にモバイルブラウザー用のWebアプリを構築しています。数値タイプの入力フィールドを使用しているため、(ほとんどの)モバイルブラウザーは数値キーボードのみを呼び出してユーザーエクスペリエンスを向上させます。このWebアプリは主に小数点ではなくカンマの領域で使用されるため、両方の小数点を処理する必要があります。

この混乱全体をドットとコンマでカバーする方法は?

私の発見:

デスクトップChrome

  • 入力タイプ=数値
  • ユーザーが入力フィールドに「4,55」を入力します
  • $("#my_input").val(); 「455」を返します
  • 入力から正しい値を取得できません

デスクトップFirefox

  • 入力タイプ=数値
  • ユーザーが入力フィールドに「4,55」を入力します
  • $("#my_input").val(); 「4,55」を返します
  • それは問題ありません。カンマをドットに置き換えて、正しい浮動小数点数を取得できます

Androidブラウザー

  • 入力タイプ=数値
  • ユーザーが入力フィールドに「4,55」を入力します
  • 入力がフォーカスを失うと、値は「4」に切り捨てられます
  • ユーザーを混乱させる

Windows Phone 8

  • 入力タイプ=数値
  • ユーザーが入力フィールドに「4,55」を入力します
  • $("#my_input").val(); 「4,55」を返します
  • それは問題ありません。カンマをドットに置き換えて、正しい浮動小数点数を取得できます

ユーザーがコンマまたはドットを小数点記号として使用する可能性があり、より良いユーザーエクスペリエンスを提供するためにHTML入力タイプを数値として保持したい場合、このような状況での「ベストプラクティス」は何ですか?

キーイベントをバインドして、コンマを「オンザフライ」でドットに変換できますか。数値入力で機能しますか?

編集

現在のところ、解決策はありません。タイプが数値に設定されている入力から浮動小数点値(文字列または数値として)を取得する方法。エンドユーザーが「4,55」と入力すると、Chromeは常に「455」を返し、Firefoxは「4,55」を返します。

また、Android(テスト済み4.2エミュレーター)で、入力フィールドに「4,55」と入力してフォーカスを別の場所に変更すると、入力した数値が「4」に切り捨てられるのも非常に煩わしいです。


私の推測では、いくつかの問題の根本的な原因は、ブラウザーが小数点を小数点として使用するUSロケールに設定されていることです。ChromeとAndroidはこれによってさまざまな方法で混乱しているようです-Chromeはコンマを数字の区切り文字として扱い、入力を数値に変換し、それを再び文字列に変換します.val()。Androidは奇妙なことをします。システム言語を適切なものに設定したときに、それらが同じように動作するかどうかを確認できますか?
ミリムース2013年

1
Nvmがこれを回答として投稿しました
kjetilh 2013年

こちらもご覧ください:stackoverflow.com/a/24423879/196210
以前の

状況はあなたが描いたものよりもさらに悪いです:作業するキーボードを選択した言語に応じて、WPテンキーに小数点またはコンマが表示されます。入力ロケールが何であったかを知る方法もありません(必ずしも優先ブラウザー言語ではありません)...だから私が思いつくことができる最高の(そして私にとって十分なもの)は次のとおりです: var number = $(...).get(0).valueAsNumber; if (isNaN(number)) number = parseFloat($(...).val().replace(',', '.'); しかし、その解決策は、
挿入

回答:


107

上記の回答で欠けているのは、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ます。

:コンマは有効ではありませんが、OSの言語/地域の設定を小数点の記号としてコンマを使用する場所に設定した場合、機能すると思われます。*注意事項*:Ubuntu / Gnome 14.04のOS言語/キーボード設定*ドイツ語*には当てはまりませんでした。


8
小数点以下の桁数を任意に許可したい場合は、ここに示すように、step属性をの"any"代わりに指定します"0.01"。nathciketaのフィドルのこの微調整バージョンをデモでご覧ください。
マークアメリー2014

4
また、「1,234.56」をに入力していましたが、カンマが検証されないという問題も発生しました<input type="number" step="any">。HTML5検証をオフにする方法を見つけることができませんでした。エラーメッセージをオフにしたりカスタマイズしたりできますが、入力から値を取得することは常に問題です。何か案は?
Nick G.

5
This attribute applies when the value of the type attribute is text, search, tel, url, email, or password, otherwise it is ignored.したがって、パターンは役に立たないtype="number"
Michael Laffargue 2017

マイケルが言ったように、をに変更しtypeてくださいtext。そうしないと、あなたの答えは意味がありません。
phil294 '20年

23

w3.orgによると、数値入力の属性は浮動小数点数として定義されています。浮動小数点数の構文は小数点を小数点としてのみ受け入れるようです。

以下に、役立ついくつかのオプションを示します。

1.パターン属性の使用

パターン属性あなたは、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."/>

注:ブラウザー間のサポートはさまざまです。完全であるか、部分的であるか、存在しない可能性があります。

2. JavaScript検証

たとえば、カンマを置き換えるか、すべてをまとめて検証するonchange(および/またはblur)イベントに単純なコールバックをバインドしようとすることができます。

3.ブラウザの検証を無効にする##

3 番目に、そのフィールドのブラウザー検証をすべて無効にすることを目的として、数値入力でformnovalidate属性を使用してみることができます。

<input type="number" formnovalidate />

4.組み合わせ..?

<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
input.valueAsNumber- これは小数点が小数点としてのみ機能し、エンドユーザーがドットまたはコンマを使用する可能性があるため、ヘルプはありません。 フォームタグnovalidate-これに対する影響は見つかりませんでした。
devha

残念ながら、私はアイデアが不足しているので、回避策のソリューションなしにこの作品をクロスブラウザにすることができるかどうかはわかりません。回答を更新して、pattern属性を含めました。formnovalidate属性を入力フィールドで直接使用することもできます。私はそれのようにあなたがいないことを知っているが、すべてが失敗し、あなたは絶対にそれからコンマが必要な場合は、入力=「テキスト」 ...唯一の方法かもしれない
kjetilh

入力タイプ番号は、実際にユーザーエクスペリエンスを向上させるよりも多くの問題を生成するようです。モバイルデバイスでは、ユーザーが数字だけを入力できるようにするには、数字キーボードのみをユーザーに開くことができると便利です。とにかく、これをもう一度
考え直す

小数点とカンマの両方を小数点記号として使用することもサポートする必要があるため、type = "text"と組み合わせてデスクトップでの検証にパターンを使用する予定です。次に、モバイルデバイスを検出するための機能検出を追加し、該当する場合はtype = "number"を使用します。
畏敬の念

9

小数点記号にコンマとピリオドのどちらを使用するかは、完全にブラウザ次第です。ブラウザは、オペレーティングシステムまたはブラウザのロケールに基づいて決定を行います。または、一部のブラウザはWebサイトからヒントを取得します。さまざまなブラウザーサポートがさまざまなローカリゼーション方法を処理する方法を示すブラウザー比較表を作成しました。Safariは、コンマとピリオドを互換的に処理する唯一のブラウザーです。

基本的に、Web作成者はこれを実際に制御することはできません。いくつかの回避策には、整数で2つの入力フィールドを使用することが含まれます。これにより、すべてのユーザーが期待どおりにデータを入力できます。特にセクシーではありませんが、すべてのユーザーがすべてのケースで機能します。


7

valueAsNumber代わりに使用します.val()

入力します。valueAsNumber [=値]

該当する場合、フォームコントロールの値を表す数値を返します。それ以外の場合はnullを返します。
値を変更するために設定できます。
コントロールが日付ベースでも時間ベースでも数値でもない場合、INVALID_STATE_ERR例外をスローします。


2
問題は、彼が小数点区切り文字としてカンマをサポートしたいことであり、入力でtype = "number"を使用すると、コンマを書き込むときに常に無効な数値が得られます。
2014年

Windows Phoneで一貫して機能していないようです。常に戻りますNaN
バート・ブリュヌーフ2015

@bertbruynooghe、値として何を割り当てていますか?
マイクサミュエル

'9'、 '9,1'、 '9.1'では機能しないようです。電話はUSとして構成され、キーボードレイアウトはen-​​US、nl-BEでテストされています。
bert bruynooghe 2015

4

テキストタイプを使用しますが、数字キーボードの外観を強制します

<input value="12,4" type="text" inputmode="numeric" pattern="[-+]?[0-9]*[.,]?[0-9]+">

inputmodeタグがソリューションです


ただし、すべてのブラウザーと互換性があるわけではなく、iOS Safari、Chrome、Chromium、Operaの最新バージョンとのみ互換性があります... caniuse.com/#feat=input-inputmode :(
pgarciacamou

さらに、モバイルデバイスではこのきちんとした数字キーボードを使用できません。
WoIIe

3

完璧な解決策は見つかりませんでしたが、type = "tel"を使用してhtml5検証を無効にする(formnovalidate)のが最善でした。

<input name="txtTest" type="tel" value="1,200.00" formnovalidate="formnovalidate" />

ユーザーがコンマを入力すると、私が試したすべての最新のブラウザー(最新のFF、IE、edge、opera、chrome、safariデスクトップ、android chrome)でコンマが出力されます。

主な問題は次のとおりです。

  • モバイルユーザーには、数字キーボードとは異なる可能性のある電話のキーボードが表示されます。
  • さらに悪いことに、電話のキーボードにはコンマのキーさえないかもしれません。

私の使用例では、私は次のことだけをしました:

  • 初期値をコンマで表示します(firefoxはtype = numberを削除します)
  • html5検証に失敗しません(コンマがある場合)
  • フィールドを入力として正確に読み取らせます(可能なコンマを使用)。

同様の要件がある場合は、これでうまくいくはずです。

注: pattern属性のサポートは好きではありませんでした。formnovalidateの方がはるかにうまく機能するようです。


1

呼び出す$("#my_input").val();と、文字列変数として返されます。使用だから、parseFloatおよびparseInt変換します。parseFloatデスクトップまたは電話を使用すると、ITSELFは変数の意味を理解します。

さらにtoFixed、以下のように引数に桁数を引数として使用することで、floatを文字列に変換できます。

var i = 0.011;
var ss = i.toFixed(2); //It returns 0.01

動作しません。IE11でparseFloat( "1,5")を試してください。戻り値1.言語は、OSとIEの両方でドイツ語です。
T3rm1 2016年

1

どうやらブラウザにはまだ問題があります(ChromeとFirefox Nightlyは問題なく動作します)。私は本当に数値フィールドを使用しなければならない人々のためのハックなアプローチをしています(おそらくテキストフィールドにはない小さな矢印のためです)。

私の解決策

keyupイベントハンドラーをフォーム入力に追加し、状態を追跡し、値が再び有効になったときに値を設定しました。

純粋なJSスニペット JSFIDDLE

Angular 9スニペット


0

私の推薦?jQueryを使用しないでください。私はあなたと同じ問題を抱えていました。$('#my_input').val()いつも変な結果を返すことがわかりました。

document.getElementById('my_input').valueAsNumber代わりに$("#my_input").val();を使用Number(your_value_retrieved)してみて、番号を作成してみてください。値がNaNの場合は、それが数値ではないことは確かです。

追加することの1つは、入力に数値を書き込むと、入力は実際にはほとんどすべての文字を受け入れる(ユーロ記号、ドル、およびその他のすべての特殊文字を書き込むことができる)ため、次を使用して値を取得するのが最善です。.valueAsNumberjQueryを使用する代わりに。

ああ、そしてBTWは、ユーザーが国際化を追加できるようにします(つまり、ドットの代わりにコンマをサポートして、10進数を作成します)。Number()オブジェクトに何かを作成させるだけで、いわば10進数で安全になります。


この問題はjQueryが原因ではなく、valueAsNumberブラウザーで一貫して機能していないこともわかりました。
バート・ブリュヌーフ2015

0

数値入力でtoLocaleString()を使用したいようです。

使用方法については、https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleStringを参照してください

JSでの数値のローカリゼーションは、Chromeで機能しない国際化(数値のフォーマット "num.toLocaleString()")でもカバーされています。


2
リンクされたコンテンツで完全にカバーされている場合の答えであっても、ソリューションの詳細な説明を提供するのが通常です。
IvanH 2013年

ブラウザ自体ではなくバックエンドサーバーがロケールを決定している場合、このアプローチは他のアプローチよりも優れているようです。残念ながら、toLocaleStringはプラットフォーム間で信頼できません。
bert bruynooghe

クロスプラットフォームのサポートは、2015年には私には十分に広いようです。たとえば、Mozillas Devnetを参照してください。ただし、それでも問題がある場合は、ここで可能な解決策を見つけてください。
stackasec 2015

Mozillas Devnetは、モバイルブラウザーに対してほとんど互換性がないことを示しています。まさにそれが、数値テキストフィールドが最も多くの利点を提供できる場所です。(元の質問を参照してください。)
bert bruynooghe

...そして、十分な代替案が示され、参照されています。楽しんで。
stackasec 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.