KUCで追加したテキストボックスにフォーカスを当てたい

レコード追加画面で自作ルックアップを作りたいと思い、KUCを使ってテキストボックスを設置しました。
入力中に文字数をカウントし、指定文字数になったらkintoneの別アプリからレコードを取得したいため、kintone標準のテキストボックスではなく自作しています。

レコード追加画面を開いたときにデフォルトでフォーカスが当たってほしいのですが、return eventしないと検索ボックスが生成されず、他のkintone標準のテキストボックスにフォーカスが当たってしまいます。

画像の左の顧客検索がKUCで生成したレコード追加画面を開いたときにフォーカスが当たってほしいテキストボックスです。右の顧客検索は参考のために置いているkintone標準のテキストボックスです。
スクリーンショット 2024-05-24 131626

どのタイミングでフォーカスを当てる処理を入れたらいいのでしょうか。

    // レコード追加・編集画面の表示イベント
    kintone.events.on(['app.record.create.show', 'app.record.edit.show'], (event) => {
        const record = event.record;
        const appId = kintone.app.getId();

        // CUSTOMER_SEARCHスペースにKUCの文字列1行を設置   
        const customer_search_space = kintone.app.record.getSpaceElement('CUSTOMER_SEARCH');
        const customer_search_box = new Kuc.Text({
            label: '顧客検索',
            requiredIcon: true,
            placeholder: '会員コードをスキャンしてください',
            textAlign: 'left',
            className: 'searchbox-class',
            id: 'kuc_smaregi_searchbox',
            visible: true,
            disabled: false
        });
        customer_search_space.appendChild(customer_search_box);

        // 顧客検索ボックスに入力された桁数が9ケタになったら顧客情報を取9桁になったら顧客情報を取得する
        customer_search_box.addEventListener('input', (event) => {
            if (event.target.value.length === 9) {
                getCustomerInfo(event.target.value);
            }
        });

        // 顧客検索ボックスにフォーカスを当てる
        $('#kuc_smaregi_searchbox').focus();

        return event;

    });

usa_pyonさん、こんばんは!
田中太郎と申します。

想定の挙動をされていない理由としましては、2つございます。
①「return eventしないと検索ボックスが生成されず」と書かれておりますが、
正しくは、テキストボックスが表示される前に、
$('#kuc_smaregi_searchbox').focus();
の行に到達してしまい、.focus()関数で、エラーが出てしまっていると思います。
そのため、
customer_search_space.appendChild(customer_search_box);
を非同期処理で行う等で、テキストボックスが表示されるのを待つのが良いかと思います。

②以下の、
$('#kuc_smaregi_searchbox').focus();
ですが、こちらですと、「ustomer_search_box」のdiv要素にフォーカスしてしまっています。
実際に、フォーカスを当てたいのは、もう数段階層が下の、input要素かと思います。
console.log(document.getElementById("kuc_smaregi_searchbox"));
等で、どの要素を指定しているか、確認すると良いと思います。

頑張ってください。

田中太郎さん、ありがとうございます!

とても分かりやすく丁寧に解説いただけたおかげでフォーカスを当てることができました!

フォーカスを当てたいinputのidがページを読み込むごとに変わってしまうようなので動的に取得できないか調べたところquerySelectorAllという便利なものがあるんですね、勉強になりました。

非同期処理もこのページを参考にasync/awaitを使ってみて、期待通り動くことは確認できたのですが、きれいなコードとして書き方は合っているのでしょうか。。。よりよい書き方があれば教えていただけると非常にうれしいです。

また、レコード追加画面を開くときに一瞬カスタマイズが当たっていない画面が見えてから、カスタマイズが適用されたページが開くのですがこれはkintoneの仕様なのでしょうか?

   // レコード追加・編集画面の表示イベント
    kintone.events.on(['app.record.create.show', 'app.record.edit.show'], async (event) => {

        const record = event.record;
        const appId = kintone.app.getId();

        // CUSTOMER_SEARCHスペースにKUCの文字列1行を設置   
        const customer_search_space = kintone.app.record.getSpaceElement('CUSTOMER_SEARCH');
        const customer_search_box = new Kuc.Text({
            label: '顧客検索',
            requiredIcon: true,
            placeholder: '会員コードスキャン',
            textAlign: 'left',
            className: 'searchbox-class',
            id: 'kuc_smaregi_searchbox',
            visible: true,
            disabled: false
        });
        try {
             // 顧客検索ボックスをCUSTOMER_SEARCHスペースに設置
            await customer_search_space.appendChild(customer_search_box);

            const customer_search_box_input = document.querySelectorAll('#kuc_smaregi_searchbox input');
            const customer_search_box_input_id = customer_search_box_input[0].id;
            
            // 顧客検索ボックスにフォーカスを当てる
            await $("#" + customer_search_box_input_id).focus();

        } catch (error) {
            console.error(err);
        }

        // 顧客検索ボックスに入力された桁数が9ケタになったら顧客情報を取得する
        customer_search_box.addEventListener('input', event => {
            (event.detail.value.length == 9) ? getCustomerInfo(event.detail.value, customer_search_box, subscription_space) : null;
        });
        return event;
    });

いろいろと聞いてすみません。お教えいただける範囲で構いませんので、よろしくお願いいたします。

うまくいったようで、良かったです!

書き方も、特に問題ないかと思いますが、
await $("#" + customer_search_box_input_id).focus();
のawait は不要かなと思います。
(動作は試していないので、必要だったらすみません、、、)
非同期処理は、使うと
動作がその行で止まってしまう = ユーザーが待つ時間が増えてしまう
ため、本当に必要な箇所だけに絞って使うのが良いかと思います。

また、画面表示時の挙動ですが、仕様だと思います。
例えばにはなりますが、
今回、UIコンポーネントで作成した、テキストを配置するのに、
const customer_search_space = kintone.app.record.getSpaceElement('CUSTOMER_SEARCH');
でスペース要素を取得し、その位置に、テキストを配置していますが、
もし、先にカスタマイズが当たっていない画面が表示されていないと、
最初の質問の際の.focus()関数で出ていたものと同様の、
「要素が見つかりません。」というエラーが出てしまいます。

今回の処理ですと、待ち時間も少ないので、
カスタマイズが適用された画面が表示されるまでに
ユーザーが操作して問題になる心配もないと思いますが、
処理に時間がかかる場合等は、
スピナーを表示してユーザーが操作できないようにする等、考慮も必要になるかと思います。

おっしゃる通り、

 $("#" + customer_search_box_input_id).focus();

も期待通り動きました。
awaitが不要な理由を確認したいのですが、

await customer_search_space.appendChild(customer_search_box);

とすることで、この行より前の処理が完了するのを待って、この行の処理が完了すれば次の行移行を処理するため、.focus();の行はawait不要という理解で合っていますでしょうか。

また画面表示時の挙動についてもご説明ありがとうございます、納得しました。
スピナーいいですね!検討してみます!

このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。