LoginSignup
5
3

More than 1 year has passed since last update.

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

Last updated at Posted at 2017-12-25

はじめに

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:

5
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3