2023年10月25日水曜日

チェックボックスのフォーカスをEnterの入力で移動する

以前に書いた記事「Enterの入力でページ・アイテムのフォーカスを移動する」にて、ページ・アイテムがチェックボックス・グループだとうまくいかない、との相談がありました。

そのため、以前に作成したAPEXアプリケーションにチェックボックス・グループを追加し、Enterによるフォーカスの移動を実装してみました。

作成したチェックボックス・グループがページに表示されています。


Oracle APEXが生成したチェックボックス・グループのHTMLは、以下のようになっています。

<div tabindex="-1" id="P1_CHECKBOX_GROUP" aria-labelledby="P1_CHECKBOX_GROUP_LABEL" class="checkbox_group apex-item-group apex-item-group--rc apex-item-checkbox" role="group">
<div class="apex-item-option"><input type="checkbox" id="P1_CHECKBOX_GROUP_0" name="P1_CHECKBOX_GROUP" data-display="有効" value="1" aria-label="有効"><label class="u-checkbox" for="P1_CHECKBOX_GROUP_0" aria-hidden="true">有効</label></div>
<div class="apex-item-option"><input type="checkbox" id="P1_CHECKBOX_GROUP_1" name="P1_CHECKBOX_GROUP" data-display="無効" value="0" aria-label="無効"><label class="u-checkbox" for="P1_CHECKBOX_GROUP_1" aria-hidden="true">無効</label></div>
</div>
IDP1_CHECKBOX_GROUPのDIV要素の属性としてtableindex="-1"が設定されているため、この要素にフォーカスが当たりません。

以下の2通りの対応方法が考えられます。
  1. P1_CHECKBOX_GROUPのtabindexを0に変更し、フォーカスが当たるようにする。
  2. 子要素のチェックボックスにフォーカスを当てる。
最初の方法の実装です。

ページ・プロパティJavaScriptファンクションおよびグローバル変数の宣言に、以下のJavaScriptを記述します。

// P1_TEXT to P1_LIST
document.getElementById("P1_TEXT").onkeydown = function(event) {
if (event.key == "Enter") {
apex.items.P1_LIST.setFocus();
}
};
// P1_LIST to P1_LOV
document.getElementById("P1_LIST").onkeydown = function(event) {
if (event.key == "Enter") {
apex.items.P1_LOV.setFocus();
}
};
// P1_LOV to P1_DATE
document.getElementById("P1_LOV").onkeydown = function(event) {
if (event.key == "Enter") {
apex.items.P1_DATE.setFocus();
}
};
document.getElementById("B_SUBMIT").onkeydown = function(event) {
if (event.key == "Tab") {
apex.items.P1_TEXT.setFocus();
event.preventDefault();
}
};
/* 今回の記事での変更 */
// P1_DATE to checkbox group P1_CHECKBOX_GROUP
document.getElementById("P1_DATE").onkeydown = function(event) {
if (event.key == "Enter") {
document.getElementById("P1_CHECKBOX_GROUP").focus();
// APEXのAPIでは、チェックボックス・グループにフォーカスを当てられない。
// apex.items.P1_CHECKBOX_GROUP.setFocus();
}
};
// P1_CHECKBOX_GROUP to P1_TEXT
document.getElementById("P1_CHECKBOX_GROUP").onkeydown = function(event) {
if (event.key == "Enter") {
apex.items.P1_TEXT.setFocus();
}
};

ページ・ロード時に実行に以下を記述し、P1_CHECKBOX_GROUPtabindex0に変更します。

document.getElementById("P1_CHECKBOX_GROUP").setAttribute("tabindex",0);


以上で、チェックボックス・グループにフォーカスが当たるようになります。


チェックボックス・グループに含まれるチェックボックスの数に依存するとは思いますが、これじゃない感はあります。

チェックボックス・グループに含まれる、それぞれのチェックボックスにフォーカスを移動するJavaScriptのコードは以下のように記述します。ページ・ロード時に実行のコードは消去します。

// P1_TEXT to P1_LIST
document.getElementById("P1_TEXT").onkeydown = function(event) {
if (event.key == "Enter") {
apex.items.P1_LIST.setFocus();
}
};
// P1_LIST to P1_LOV
document.getElementById("P1_LIST").onkeydown = function(event) {
if (event.key == "Enter") {
apex.items.P1_LOV.setFocus();
}
};
// P1_LOV to P1_DATE
document.getElementById("P1_LOV").onkeydown = function(event) {
if (event.key == "Enter") {
apex.items.P1_DATE.setFocus();
}
};
document.getElementById("B_SUBMIT").onkeydown = function(event) {
if (event.key == "Tab") {
apex.items.P1_TEXT.setFocus();
event.preventDefault();
}
};
/* 今回の変更と追加 */
// P1_DATE to first checkbox in checkbox group P1_CHECKBOX_GROUP
document.getElementById("P1_DATE").onkeydown = function(event) {
if (event.key == "Enter") {
document.getElementById("P1_CHECKBOX_GROUP_0").focus();
}
};
// first checkbox in P1_CHECKBOX_GROUP to second checkbox
document.getElementById("P1_CHECKBOX_GROUP_0").onkeydown = function(event) {
if (event.key == "Enter") {
document.getElementById("P1_CHECKBOX_GROUP_1").focus();
}
};
// second checkbox in P1_CHECKBOX_GROUP to P1_TEXT
document.getElementById("P1_CHECKBOX_GROUP_1").onkeydown = function(event) {
if (event.key == "Enter") {
apex.items.P1_TEXT.setFocus();
}
};


上記のJavaScriptコードをコード・エディタで記述していると、チェックボックスのIDであるP1_CHECKBOX_GROUP_0およびP1_CHECKBOX_GROUP_1について、アイテムP1_CHECKBOX_GROUP_0は存在しません。といった警告が表示されます。これらのIDはAPEXのアイテムではないため、この警告は無視できます。


この実装では、以下のようにチェックボックそれぞれにフォーカスが動作します。


今回の記事は以上です。

2番目の実装をしたAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/on-enter-move-focus-with-checkbox.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。