デフォルトボタンについて
Webページ上でエンターキーを押した場合、そのページ上であらかじめ決められたボタンをクリックしたかのように処理を実行する仕組みがある。何らかのデータの検索を行うようなページは、このような仕組みが用意される場合が多い。検索条件欄に条件を入力し、検索ボタンを押さずにそのままエンターキーを押すと、検索結果が表示されるようなケースである。キーボードからの入力後に、マウス操作をせずにボタンをクリックできるので、効率的な操作が実現できる。
このようにページ上でエンターキーを押した場合に実行されるボタンや、その仕組みをデフォルトボタンと呼ぶ。
ブラウザの既定の動作として、HTML(fomr)上の最初のsubmitボタンがデフォルトボタンになります。この辺の詳細はHTML5仕様(“4.10.22.2 Implicit submission”)を参照のこと。
実際の業務アプリ開発では、ちょっとこの仕様では耐えられないので、デフォルトボタンの仕組みを実現するjavascript関数を作成しました。
想定する要件
想定する要件は次の通りです。
bootstrapのボタンやモーダルを想定しています。(btn-primary, modal等)
- 所定のCSSクラスを指定するだけで、リンクやボタン要素をデフォルトボタンにできること。モーダルのボタンもデフォルトボタンにできること。
- モーダルが表示された状態でエンターキーが押された場合、モーダル上のデフォルトボタンが実行されること。複数のモーダルが含まれるページの場合、表示されているモーダルのデフォルトボタンが実行されること。
- テキストエリア(“<textarea>”)では正常に改行を入力できること。
- デフォルトボタンがクリックできない場合は、処理を中止すること。
ソースコード
各ページや共通のjsファイルに下記を追加してください。
ページ上のキー入力に、この関数が実行されます。
説明のためにコメントを冗長に記載しています。実際に使用する際は、コメントやログ出力(console.log)を削除してください。
なお、この実装だけだとエンターキー連打時に何度もクリックが実行されてしまいます。業務アプリではダブルクリック防止を実装していると思うので、それと併せてエンターキー連打が実行されないよう修正してください。(「ダブルクリック時に有効になる条件」を追加したり、デフォルトボタンが押せる/押せないのチェック時(37行目)に追加する、等。)
// デフォルトボタンの設定
const MODAL_SEL = ".modal"; // モーダル要素セレクタ(非表示/非表示要素)
const DEFAULT_BTN_SEL = ".btn-primary"; // デフォルトボタンセレクタ
$(window).keypress(function(e){
// ページ上の任意項目の入力時(1字単位)で実行されるため、
// 軽くて可能性の高い条件を先に判定する。
// 改行コード以外は無視
if(event.keyCode != 13 ){
return;
}
// テキストエリアの場合は改行を意味しているので、ここでは何もしない。
// (結果としてブラウザの既定動作である改行入力になる。)
if ($(":focus").is("textarea") ){
console.log("no click(textarea)");
return;
}
// モーダルが表示されている場合はモーダル上のデフォルトボタン、
// モーダルが非表示の場合は、モーダル外のデフォルトボタンをクリック対象とする。
// 非表示のボタン("display: none;")は対象外とします。
var $btns = $(MODAL_SEL + ":visible").find(DEFAULT_BTN_SEL + ":visible");
if( $btns.length <= 0){
var $modalBtns = $(MODAL_SEL).find(DEFAULT_BTN_SEL);
var $allBtns = $(DEFAULT_BTN_SEL);
var $btns = $($allBtns).not($modalBtns).filter(":visible");
}
if( $btns.length <= 0 ){
console.log("no click(no target)");
return;
}
// 対象のリンクやボタンが無効な場合は中止
var $btn = $btns.get(0);
if( $btns.css("pointer-events") == "none" || $btns.is(":disabled")){
console.log("no click(disabled)");
return;
}
// 別ボタンがクリックされないよう既定動作を中止
e.preventDefault();
console.log("click button: id=" + $btn.id);
$btn.click();
});
