Edited at

jQuery JavaScript 「↓」、「↑」キーでinputのフォーカスを移動させる

More than 1 year has passed since last update.


はじめに

JavaScript Advent Calendar 2017 - Qiitaの23日目の記事です。

小ネタですが空いてたので失礼します:bride_with_veil:


:lifter:何がやりたいか

縦にテキストボックスが並んでいるフォームがあるとします

<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>

イメージはこんな感じ

スクリーンショット 2017-05-12 10.41.55.png

この各input間を「↓」、「↑」キーで移動できるようにしたいのです。

(実際には左右にもinputがあり、tabでは移動できない画面です)


:gear:各機能


「↓」、「↑」のイベント取得

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();


:japanese_goblin:問題発生


ちょっと待て

今回のフロントの実装では、連番ではなくDBのID(以後「d_id」と呼ぶ)をinputのidに付与していたので

<input type="text" class="sample-input" id="sample64←ココ!">

id+1とかで次を指定できない:sob:


強引に問題解決

一番良かったのは、idの前方一致で$(this)の次の要素が取得すること(感じ取ってくださいw)。

でもちょっと実装が思い浮かばなかったので強引に解決!

そうだ、d_idリストを用意してしまおう:neutral_face:


// 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}];";
?>


:tada:完成

全てを合体させて完成したのが以下のソース


// 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();

}

});

これが一番スマートではないと思います:kissing_heart: