web-dev-qa-db-ja.com

数字と+記号のみを使用するHTML入力

数字とプラス(+)記号のみを受け入れる電話番号のカスタムテキスト入力を作成しようとしています。他のすべての文字は破棄する必要があり、フィールドに表示されません。

イベントハンドラー(onkeydown/onkeypress)を使用してこれを実行し、他のキーに対応する入力を破棄しようとしています。しかし、それを行うためのクロスブラウザーの方法を理解することはできません。ここに私が試したがうまくいかないアプローチがあります:

  • onkeypressイベントを使用してevent.keyを見ると、どのキーが押されたかがわかります。機能しませんChrome =( http://caniuse.com/keyboardevent-key を参照)クロスブラウザの回避策はありますか?

  • onkeycodeイベントの使用とevent.keyCode:の表示は、文字を印刷するために複数のキーを押す必要がある場合は機能しません(たとえば、英語のキーボード)レイアウトでは、Shiftと=を押して+を与える必要があります。さらに、!@#$%ˆ&*()などの文字をShiftキーと数字を押すと表示されるため、表示できます。 (これは JavaScriptキーコードが数字とプラス記号のみを許可する に従っているアプローチですが、あまり役に立ちません;))

  • HTMLパターン属性の使用:これは、実際に人々が好きなように書くことを妨げているようには見えません。

ありがとう!

14
unpollito

別の解決策があります。 Array.prototype.filter() を使用して不正な文字を削除し、 Array.prototype.join() を使用して文字列を挿入前に再作成できます入力に。

oninput イベントを使用できます。ユーザーが<input>フィールドに何かを書き込むと、JavaScriptが実行されます。


以下の例を参照してください

var inputEl = document.getElementById('tel');
var goodKey = '0123456789+ ';

var checkInputTel = function(e) {
  var key = (typeof e.which == "number") ? e.which : e.keyCode;
  var start = this.selectionStart,
    end = this.selectionEnd;

  var filtered = this.value.split('').filter(filterInput);
  this.value = filtered.join("");

  /* Prevents moving the pointer for a bad character */
  var move = (filterInput(String.fromCharCode(key)) || (key == 0 || key == 8)) ? 0 : 1;
  this.setSelectionRange(start - move, end - move);
}

var filterInput = function(val) {
  return (goodKey.indexOf(val) > -1);
}

inputEl.addEventListener('input', checkInputTel);
<input type='tel' id='tel' />

注:入力タイプtelを使用して、スマートフォンまたはタブレットでデフォルトの数字パッドを表示します。

tel: html5 電話番号を入力するためのコントロール。改行は入力値から自動的に削除されますが、他の構文は適用されません。 patternmaxlengthなどの属性を使用して、制御。 :valid および :invalid CSS疑似クラスが適切に適用されます。

リファレンス: MDN <input>

14
R3tep

常にサーバー側の検証を行うようにしてください。これは、データを検証するのではなく、ユーザーを「助ける」ことを意味します(いつでもコンソールを開いて入力値の値を変更できます)

今、私が使用する方法は次のとおりです。

変更時に入力全体の値を確認し、「テキストカーソル」がどこにあったかを追跡しながら、その値を正規表現に通して不要な文字を削除します。

const tel = document.getElementById('tel');

tel.addEventListener('input', function() {
  let start = this.selectionStart;
  let end = this.selectionEnd;
  
  const current = this.value
  const corrected = current.replace(/([^+0-9]+)/gi, '');
  this.value = corrected;
  
  if (corrected.length < current.length) --end;
  this.setSelectionRange(start, end);
});
<input type="tel" id="tel">

あなたが望むものに応じてはるかに「正確な」正規表現を作ることができます、これはそのための素晴らしいツールです: RegExr

9
Aramil Rey

このプロジェクトをご覧になることをお勧めします。 https://github.com/igorescobar/jQuery-Mask-Plugin/

そのまま使用できます:$('.phone').mask('0000-0000');例: https://igorescobar.github.io/jQuery-Mask-Plugin/

または、ソースコードを読んで、それがどのように解決されるかを確認することもできます。

8
yeouuu

この堅牢な一般的なアプローチは、@ R3tepの答えに触発されています。 パターン属性 と同様に、data-filter属性を介して正規表現パターンを定義できます。

// Apply filter to all inputs with data-filter:
let inputs = document.querySelectorAll('input[data-filter]');

for (let input of inputs) {
  let state = {
    value: input.value,
    start: input.selectionStart,
    end: input.selectionEnd,
    pattern: RegExp('^' + input.dataset.filter + '$')
  };
  
  input.addEventListener('input', event => {
    if (state.pattern.test(input.value)) {
      state.value = input.value;
    } else {
      input.value = state.value;
      input.setSelectionRange(state.start, state.end);
    }
  });

  input.addEventListener('keydown', event => {
    state.start = input.selectionStart;
    state.end = input.selectionEnd;
  });
}
<input type='tel' data-filter='[0-9|+]*' placeholder='123+456'>
<input type='tel' data-filter='(\+|(\+[1-9])?[0-9]*)' placeholder='+10123'>
<input type='text' data-filter='([A-Z]?|[A-Z][a-z]*)' placeholder='Abcdefg'>
<input type='text' data-filter='([A-Z]{0,3}|[A-Z]{3}[0-9]*)' placeholder='ABC123'>
7
le_m

入力を使用

type = "tel"または "phone"

携帯電話のデフォルトの数字パッドを表示します。

これが役立つことを願っています:)

5
bhagya

keyupイベントリスナー、一部のRegEx/String比較メソッド、および中間変数の組み合わせを使用して、次のことを考え出すことができました。

var ele = document.getElementById('phone');
var curr = "";
var regexPatt = /^(0|[1-9][0-9]*)$/;
ele.addEventListener('keyup',function(e){
  var code = e.keyCode || e.which;
  if(this.value.match(regexPatt) || this.value.indexOf('+') > -1 || code == 8){
    curr = this.value;
    this.value = curr;
  } else {
    this.value = curr;
  }
});

フィドルを見てください: https://jsfiddle.net/Lg31pomp/2/

これは数字、+文字、およびユーザーが入力要素をバックスペースする場合。

2
A.Sharma