HTML5のinputにはtype属性、pattern属性によるフォームバリデーションが用意されています。これらはそれぞれ特定の形式しか送信を認めない、任意の正規表現に従った形式しか送信を認めない、といったものです。送信と書いたはフォームを送る時にのみバリデーションが動作するためです。ユーザビリティの観点からするといざ送る時につまづかされるよりも、入力した時点で警告してくれた方が手戻りが少なく親切です。タグに埋め込んでも早期にならない程度のjavascriptでこれを実現します。
inputタグ中のonchange属性でこれを解決します。onchangeは要素中の値がユーザによって変更されたときに発火します。
GlobalEventHandlers.onchange | MDN
onchange="this.value = this.value.replace(/入力を認めない文字の正規表現/g,'')"
これで入力を認めない文字が入力された状態でchangeイベントが発火した時、その文字らがinput内から削除されます。注意メッセージなどを合わせてLaravelのblade様に拡張すると次の様に記述できます。
@php if(isset($validation_template)){ switch($validation_template){ case 'mail': $exclude_pattern = '[^";\w!#$%&\'*+\-\/=?^`{|}~. \(\)<>\[\]:;@,]'; $validation_err_msg = '半角英数字と次の記号のみが入力できます。"!#$%&\'*+-/=?^`{|}~. ()<>[]:;@,'; break; case 'tel': $exclude_pattern = '[^\-\d]'; $validation_err_msg = '半角数字と-のみが入力できます。'; break; } } @endphp @if(isset($exclude_pattern)) onchange=" if(this.value.length > this.value.replace(/{!!str_replace('"','"',$exclude_pattern)!!}/gu,'').length) { this.value = this.value.replace(/{!!str_replace('"','"',$exclude_pattern)!!}/gu,''); document.querySelector('#{{$input_id}}-validate-msg-box').innerText = `{{str_replace('`','\`',$validation_err_msg)}}`; } else { document.querySelector('#{{$input_id}}-validate-msg-box').innerText = ''; } " @endif
もし、削除された文字があるならば注意文を#{{$input_id}}-validate-msg-boxに表示、ないならば注意文を空にする、という動作が増えました。#{{$input_id}}-validate-msg-boxはinput要素毎に作成します。冒頭の$validation_templateは定型パターンの入力時バリデーションとそのメッセージのセットです。これを使うと次の様に動きます。