質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

Safari

SafariはAppleのウェブブラウザであり、Mac OS XとiOSのデフォルトのブラウザです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

3回答

3380閲覧

IpadOSのsafariにおけるinput type="number"で数字のみ入力させたい(入力制限)

teratail-boy

総合スコア20

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

Safari

SafariはAppleのウェブブラウザであり、Mac OS XとiOSのデフォルトのブラウザです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2022/04/18 06:14

編集2022/04/18 07:04

お世話になります。
タイトルについて、なにかいいアイデアがあれば教えていただきたいです。

現在の状況

type="number"が指定してあるクラスをページ内から取得し、そのクラス内でキーボードから入力された値が数字以外であれば、値を一つ前の情報に戻す処理を行う。という処理を実現したいのですが、うまく動いていないです。コードは下記です。

javascript

1document.addEventListener('DOMContentLoaded', function() { 2 const inputTypeNumberDoc = document.querySelectorAll("input[type='number']"); 3 inputTypeNumberDoc.forEach((matche) => { 4 matche.addEventListener('keydown',e => { 5 const val = matche.value; 6 console.log("eCode:"+e.code); 7 if(!((e.code=="Digit1")&&(e.code==="Backspace")&&(e.code=="Digit2")&&(e.code=="Digit3")&&(e.code=="Digit4")&&(e.code=="Digit5")&&(e.code=="Digit6")&&(e.code=="Digit7")&&(e.code=="Digit8")&&(e.code=="Digit9")&&(e.code=="Digit0")&&(e.key==1)&&(e.key==2)&&(e.key==3)&&(e.key==4)&&(e.key==5)&&(e.key==6)&&(e.key==7)&&(e.key==8)&&(e.key==9)&&(e.key==0))){ 8 setTimeout(() => { 9 if(!( (e.code==="Backspace")||(e.key=='1')||(e.key=='2')||(e.key=='3')||(e.key=='4')||(e.key=='5')||(e.key=='6')||(e.key=='7')||(e.key=='8')||(e.key=='9')||(e.key=='0') )){ 10 matche.value=val; 11 } 12 }) 13 }else{ 14 setTimeout(() => { 15 matche.value=val; 16 }) 17 } 18 }); 19 }); 20 }); 21

html

1<div class="col-md-3 col-lg-4"> 2 <input type="number" class="form-control form-control-lg inputTypeNumberDoc" id="capacity" name="capacity" value=""> 3 </div> 4input type="number"がページ内に複数あります。

コード内にある"digit"はe.codeを用いて数字を出力すると、その値になっています。

ナレッジの共有

数字以外の値(-マイナス)などを入力し、hoge.valueで出力しようとすると値はnullが返ってきます。↓
__
入力した値{ 1-112-2}
hoge.valueを用いて出力した値{""}
__

e.keyやe.codeを用いて今回は実現できないだろうか...

・試したこと

下記ページと同じものを実装したがsafariでは挙動がおかしく適切な実装ができなかった。
(chromeでは正しく機能しました。)
input type="number" ハイフン除去サンプル

意外と知られていないtype="number"入力欄の5つの問題点


input要素のpattern属性を利用し制限をかけようとしたが、safariではpatten属性は利用できないみたいでした。
pattern属性について


以上になります。よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

int32_t

2022/04/18 06:54

> うまく動いていないです 現在のコードでは具体的にどういう動作をするのでしょうか。
teratail-boy

2022/04/18 07:07

ごめんなさい、DOMを読み込む処理を書いていませんでした。 具体的にはinput要素に数字以外の入力をした場合は、その文字が入力された後に入力前の情報をinputに代入するといった動作をしています。 コード修正いたしました。いかがでしょうか?
int32_t

2022/04/18 07:09

> その文字が入力された後に入力前の情報をinputに代入するといった動作をしています。 それは、実現したい動作では? 現在のコードでどういう不具合があるのかを聞いています。
teratail-boy

2022/04/18 07:24

>input要素に数字以外の入力をした場合は、その文字が入力された後に入力前の情報をinputに代入するといった動作をしています。 PC環境のchromeでは上記の動きをするのですが、 ipadのsafariでは数字以外の文字を入力しても入力前の値が代入されません。ですが、2回数字以外の同じ文字を入力するとその文字が代入されます。 __例__ 入力1回目:"1" input内出力結果1:"1" → 入力2回目:"-"  input内出力結果2:"1-" → 入力三回目:"-" input内出力結果3:"-" ___ 上記のように動いてしまう状況で...
guest

回答3

0

追記:ソフトウェアキーボードを使ったほうがいいかもしれないですね...
自分は導入しました。ほかに解決方法あればご教授お願い致します。

投稿2022/04/21 05:48

teratail-boy

総合スコア20

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

お世話になります。
回答ありがとうございました。

回答通りに直したところ、ipad上のキーボード設定でEnglishの時のみ数字の入力制限をすることができました。

全角入力については現在できていない状況なので、調査してみたいと思います。
コードについては以下のように直しました。検証途中なので各所にalert文が入っていますが了承ください。

ありがとうございました!

javascript

1document.addEventListener('DOMContentLoaded', function() { 2 const inputTypeNumberDoc = document.querySelectorAll("input[type='number']"); 3 inputTypeNumberDoc.forEach((matche) => { 4 matche.addEventListener('keydown',e => { 5 const val = matche.value; 6 var eCodeVal=e.code; 7 console.log("eCode:"+eCodeVal); 8 var eKeyVal=e.key; 9 console.log("ekey:"+eKeyVal); 10 //alert("keydown処理開始,value:"+val+"ecode:"+eCodeVal+"ekey"+eKeyVal); 11 //value="" ecode=KyeA eKye=a 12 if(e.isComposing){ 13 e.preventDefault(); 14 //alert("isComposing開始,value:"+val+"ecode:"+eCodeVal+"ekey"+eKeyVal); 15 }else{ 16 //alert("else文開始,value:"+val+"ecode:"+eCodeVal+"ekey"+eKeyVal); 17 //value="" ecode:KeyA ekey:a 18 if(((eCodeVal=="Digit1")||(eCodeVal==="Backspace")||(eCodeVal=="Digit2")||(eCodeVal=="Digit3")||(eCodeVal=="Digit4")||(eCodeVal=="Digit5")||(eCodeVal=="Digit6")||(eCodeVal=="Digit7")||(eCodeVal=="Digit8")||(eCodeVal=="Digit9")||(eCodeVal=="Digit0")||(eKeyVal==1)||(eKeyVal==2)||(eKeyVal==3)||(eKeyVal==4)||(eKeyVal==5)||(eKeyVal==6)||(eKeyVal==7)||(eKeyVal==8)||(eKeyVal==9)||(eKeyVal==0))){ 19 if((eCodeVal==="Backspace")|| (eKeyVal==1)||(eKeyVal==2)||(eKeyVal==3)||(eKeyVal==4)||(eKeyVal==5)||(eKeyVal==6)||(eKeyVal==7)||(eKeyVal==8)||(eKeyVal==9)||(eKeyVal==0) ){ 20 //console.log("成功"); 21 //alert("成功,value:"+val+"ecode:"+eCodeVal+"ekey"+eKeyVal); 22 }else{ 23 e.preventDefault(); 24 //alert("消去,value:"+val+"ecode:"+eCodeVal+"ekey"+eKeyVal); 25 } 26 27 }else{ 28 //alert("最後のELSE,value:"+val+"ecode:"+eCodeVal+"ekey"+eKeyVal); 29 //value="" ecode:KeyA ekey:a 30 e.preventDefault(); 31 } 32 } 33 }); 34 //matche.addEventListener( "compositionend", compostionFn); 35 }); 36 }); 37 38var compostionFn = function ( event ) { 39 //alert("eventData:"+event.data); 40 const paragraph = event.data; 41 const regex = /[0-9]/g; 42 const found = paragraph.match(regex); 43 if(found==null){ 44 event.data=""; 45 } 46 //alert("処理後:event.data:"+event.data+"found:"+found); 47}

投稿2022/04/21 05:40

編集2022/04/21 05:42
teratail-boy

総合スコア20

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

現象を確認していませんのであてずっぽで回答を書いてみます。

  • setTimeout() のコールバック内で e.codee.key を参照していますが、このタイミングで e が指すイベントオブジェクトがイベント発生時と同じ値を保持しているとは限らない気がします。e.codee.key をローカル変数にコピーしてから参照してみたらどうでしょうか。

  • 「禁止文字が来たら入力完了後に前の値を書き戻す」よりは「禁止文字が来たら e.preventDefault() で入力をキャンセルする」のほうが素直な気がします。

if(!((e.code=="Digit1")&&(e.code==="Backspace")&& ...

e.codeDigit1 かつ Backspace」になることはあり得ないので、この if は常に成り立ちます。

投稿2022/04/18 08:08

int32_t

総合スコア20941

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問