はじめに
JavaScript Advent Calendar 2017 - Qiitaの23日目の記事です。
小ネタですが空いてたので失礼します
何がやりたいか
縦にテキストボックスが並んでいるフォームがあるとします
<table>
<tr>
<td>
<input type="text" class="sample-input" id="sample64">
</td>
<tr>
<tr>
<td>
<input type="text" class="sample-input" id="sample256">
</td>
<tr>
<tr>
<td>
<input type="text" class="sample-input" id="sample512">
</td>
<tr>
<tr>
<td>
<input type="text" class="sample-input" id="sample128">
</td>
<tr>
</table>
この各input間を「↓」、「↑」キーで移動できるようにしたいのです。
(実際には左右にもinputがあり、tabでは移動できない画面です)
各機能
「↓」、「↑」のイベント取得
keydownイベントそ取得してなんのキーが押されたかをkeyCodeを使って調べるだけです。
keyCodeは以下の通り。
keyCode | キー |
---|---|
37 | ← |
38 | ↑ |
39 | → |
40 | ↓ |
ソースはこんな感じ。
// 対象フォーム群のキーダウンイベントを取得
$(".sample-input").on("keydown", function(e) {
if(e.keyCode === 40) {
// 「↓」キーが押されました
}else if(e.keyCode === 38) {
// 「↑」キーが押されました
}
});
フォーカスの移動
.focus()で指定した要素にフォーカスを移動できる。
$("#id").focus();
問題発生
ちょっと待て
今回のフロントの実装では、連番ではなく**DBのID(以後「d_id」と呼ぶ)**をinputのidに付与していたので
<input type="text" class="sample-input" id="sample64←ココ!">
id+1とかで次を指定できない
強引に問題解決
一番良かったのは、idの前方一致で$(this)の次の要素が取得すること(感じ取ってくださいw)。
でもちょっと実装が思い浮かばなかったので強引に解決!
そうだ、d_idリストを用意してしまおう
// d_idリストを用意
// d_id_list = [64, 256, 512, 128]
// (今回はPHPで実装しています)
var d_id_list = [];
<?php
$set = '';
foreach ($array as $value) {
if($set){
$set .= ',';
}
$set .= $value;
}
echo "d_id_list = [{$set}];";
?>
完成
全てを合体させて完成したのが以下のソース
// d_idリストを用意
// d_id_list = [64, 256, 512, 128]
// (今回はPHPで実装しています)
var d_id_list = [];
<?php
$set = '';
foreach ($array as $value) {
if($set){
$set .= ',';
}
$set .= $value;
}
echo "d_id_list = [{$set}];";
?>
// 対象フォーム群のキーダウンイベントを取得
$(".sample-input").on("keydown", function(e) {
// キーダウンイベントを検知した要素のidからd_idを取得
// その値とd_idリストを使用してd_idリストのindexを取得する
d_id_list_index = d_id_list.indexOf(Number($(this).attr("id").replace("sample","")));
// 「↓」キーが押された && 最終要素ではない
if(e.keyCode === 40 && d_id_list_index < d_id_list.length-1) {
// d_idリストと先ほど取得したd_idリストでの自分のindexを使用して1つ下のinputへfocusを移す
$("#sample"+d_id_list[d_id_list_index+1]).focus();
// 「↑」キーが押された && 最初の要素ではない
}else if(e.keyCode === 38 && d_id_list_index > 0) {
// d_idリストと先ほど取得したd_idリストでの自分のindexを使用して1つ上のinputへfocusを移す
$("#sample"+d_id_list[d_id_list_index-1]).focus();
}
});
これが一番スマートではないと思います