フォームブリッジをJavascriptでカスタマイズしたが、kintoneに値が保存されない。

以前にも投稿させていただいたのですが、Javascriptでカスタマイズした内容が
kintoneのアプリに反映されず…調べたところ

" 実装だけではDOM上に値が表示されているだけなので、保存時にstate.recordに入れてあげる必要がある ようです。"

という記事を見つけたので、そのコードを生成AIで書いてみたのですが、それでも
kintoneアプリに保存されない状態です。エラー等は特に表示されないです。
皆様は、どのようにアプリに保存できるようにされておりますでしょうか。
ご教示いただければと。お手数ですが、よろしくお願いいたします。

(function() {
    'use strict';

    window.addEventListener('DOMContentLoaded', (event) => {

        // --- 設定項目 ---
        const yearMonthInputId = '年月入力'; 
        const dateDisplayFieldPrefix = '日・曜日'; 
        const maxDays = 31; 
        // --- 設定項目ここまで ---

        const yearMonthInput = document.getElementById(yearMonthInputId);

        if (!yearMonthInput) {
            console.error(`年月入力フィールド(ID: ${yearMonthInputId})が見つかりません。`);
            return;
        }

        const weekdays = ['日', '月', '火', '水', '木', '金', '土'];

        /**
         * 日付フィールドを更新する関数
         */
        const updateDateFields = () => {
            const selectedValue = yearMonthInput.value;

            // 全ての日付表示フィールドをクリア
            for (let i = 1; i <= maxDays; i++) {
                const fieldCode = (i === 1) ? dateDisplayFieldPrefix : `${dateDisplayFieldPrefix}_${i - 2}`;
                const displayInput = document.querySelector(`input[name="${fieldCode}"]`);
                if (displayInput) {
                    displayInput.value = '';
                }
            }

            if (!selectedValue || selectedValue.length !== 6) {
                return;
            }

            const year = parseInt(selectedValue.substring(0, 4), 10);
            const month = parseInt(selectedValue.substring(4, 6), 10);

            if (isNaN(year) || isNaN(month) || month < 1 || month > 12) {
                console.warn('無効な年月が入力されました:', selectedValue);
                return;
            }

            const lastDayOfMonth = new Date(year, month, 0).getDate();

            for (let i = 1; i <= lastDayOfMonth; i++) {
                const currentDate = new Date(year, month - 1, i);
                const dayOfWeek = weekdays[currentDate.getDay()];

                const fieldCode = (i === 1) ? dateDisplayFieldPrefix : `${dateDisplayFieldPrefix}_${i - 2}`;
                const displayInput = document.querySelector(`input[name="${fieldCode}"]`);

                if (displayInput) {
                    displayInput.value = `${i}-${dayOfWeek}`;
                } else {
                    console.warn(`日付表示フィールドが見つかりません: ${fieldCode}`);
                }
            }
        };

        /**
         * DOM上の値をstate.recordに反映する関数
         * フォームブリッジの内部状態に値を設定します
         */
        function domToRecord(state) {
            console.log('domToRecord実行開始');
            
            // 年月入力フィールドの値を反映
            const yearMonthInput = document.getElementById(yearMonthInputId);
            if (yearMonthInput && state.record[yearMonthInputId]) {
                state.record[yearMonthInputId].value = yearMonthInput.value;
                console.log(`${yearMonthInputId} = ${yearMonthInput.value}`);
            }

            // 日付表示フィールドの値を反映
            for (let i = 1; i <= maxDays; i++) {
                const fieldCode = (i === 1) ? dateDisplayFieldPrefix : `${dateDisplayFieldPrefix}_${i - 2}`;
                const displayInput = document.querySelector(`input[name="${fieldCode}"]`);
                
                if (displayInput && state.record[fieldCode]) {
                    state.record[fieldCode].value = displayInput.value;
                    if (displayInput.value) {
                        console.log(`${fieldCode} = ${displayInput.value}`);
                    }
                }
            }
            
            console.log('domToRecord実行完了');
        }

        // イベントリスナーを設定
        yearMonthInput.addEventListener('input', updateDateFields);
        yearMonthInput.addEventListener('change', updateDateFields);

        // ページロード時の初期処理
        if (yearMonthInput.value) {
            updateDateFields();
        }

        // フォームブリッジのsubmitイベントを監視・設定
        // 既存のイベントハンドラーがある場合は追加、ない場合は新規作成
        function setupFormBridgeEvents() {
            // windowオブジェクトにフォームブリッジの関数を設定
            window.formBridgeSubmitHandler = function(state) {
                console.log('FormBridge submit handler実行');
                domToRecord(state);
                return state;
            };

            window.formBridgeConfirmHandler = function(state) {
                console.log('FormBridge confirm handler実行');
                domToRecord(state);
                return state;
            };

            // 直接的なイベント設定も試行
            if (typeof window.fb !== 'undefined' && window.fb.events) {
                console.log('fb.eventsが利用可能です');
                
                window.fb.events.form = window.fb.events.form || {};
                window.fb.events.form.submit = window.fb.events.form.submit || [];
                window.fb.events.form.confirm = window.fb.events.form.confirm || [];
                
                window.fb.events.form.submit.push(window.formBridgeSubmitHandler);
                window.fb.events.form.confirm.push(window.formBridgeConfirmHandler);
            }
        }

        // 定期的にフォームブリッジのイベント設定を試行
        const setupInterval = setInterval(() => {
            setupFormBridgeEvents();
            
            // グローバルスコープでのイベントハンドラー設定も試行
            if (typeof window.FormBridge !== 'undefined') {
                console.log('FormBridgeオブジェクトが見つかりました');
                clearInterval(setupInterval);
            }
        }, 1000);

        // 10秒後にクリア
        setTimeout(() => {
            clearInterval(setupInterval);
        }, 10000);

        // フォーム送信やボタンクリック時の追加処理
        document.addEventListener('click', function(event) {
            const target = event.target;
            
            if (target.matches('button') || target.matches('input[type="submit"]') || 
                target.textContent.includes('確認') || target.textContent.includes('送信')) {
                
                console.log('送信系ボタンクリック - 値を再設定');
                
                // DOM値の再確認と設定
                setTimeout(() => {
                    if (yearMonthInput.value) {
                        updateDateFields();
                    }
                    
                    // 疑似的なstate.recordオブジェクトを作成してテスト
                    const mockState = {
                        record: {}
                    };
                    
                    // 全フィールドのrecordオブジェクトを作成
                    mockState.record[yearMonthInputId] = { value: '' };
                    for (let i = 1; i <= maxDays; i++) {
                        const fieldCode = (i === 1) ? dateDisplayFieldPrefix : `${dateDisplayFieldPrefix}_${i - 2}`;
                        mockState.record[fieldCode] = { value: '' };
                    }
                    
                    domToRecord(mockState);
                }, 100);
            }
        });

        console.log('FormBridge完全対応版が初期化されました');
    });

})();

前回の記事 でも同じ回答をしましたが、 FormBridge 自体のイベントではなく、自前で input 要素を取得して値を操作しているように見受けられます。

公式からカスタマイズに関するドキュメントが出てますので、そちらに則って書かれてみてはいかがでしょうか。

旧バージョンのフォームを使用しているのであれば JavaScriptカスタマイズ | FormBridge から仕様を見ることができます。

ご回答いただきましてありがとうございます。

それが、公式カスタマイズのドキュメントを利用すると値が表示されず
fbオブジェクトがロードされない状況で…。

ブラウザのコンソールで、fbと入力しましたら「Uncaught ReferenceError: fb is not defined」
と表示され、 「window.fb」と入力すると 「undefined」と表示される状態です…。

それであれば、新バージョンのフォームを使用しているのではないでしょうか。新バージョンの API は https://formbridge.kintoneapp.com/help/customize/v2 に載っています。

ありがとうございます。

それが、新バージョンにしても、上記と同じエラーになりまして…。

V2のAPIも利用できないみたいです。

フォームブリッジのバージョンは [Ver.1.34.26]です。

フォームブリッジは、Next.jsベースのようなんですがV2 APIが利用できず…かつ
旧バージョンのAPIも利用できないようですね…。

下記の件について

それが、公式カスタマイズのドキュメントを利用すると値が表示されず
fbオブジェクトがロードされない状況で…。
ブラウザのコンソールで、fbと入力しましたら「Uncaught ReferenceError: fb is not defined」
と表示され、 「window.fb」と入力すると 「undefined」と表示される状態です…。

windowオブジェクトにfbが定義されていないという意味です。例えば、alert(message);を使うとき、普段はalert('Hello World!');と書くと思います。本来はwindow.alert('Hello World!')で、この省略形になります。

対応方法としては、新FormBridgeにバージョンアップしているなら、DOMContentLoadedform.showに置き換えることで動作すると思います。
現在のコード

window.addEventListener('DOMContentLoaded', (event) => {
	// 変数や関数の定義があるので、設計の見直しが必要かもしれません
});

置き換え後のコード

formBridge.events.on('form.show', function (context) {
	console.log('ハンドラー1を実行');

	// kintoneに値を保存するときはsetFieldValue(fieldCode, newValue);を使う
	const fieldCode = 'hogehoge'; // FormBridgeのフィールドコードを設定してください
	const newValue = 'test';
	context.setFieldValue(fieldCode, newValue);
});

上記の他addEventListener()は新FormBridgeで独自イベントが定義されており、置き換えることが可能だと思います。

生成AIを利用しているとのことですが、特に新FormBridgeの独自イベントは公開されて日が浅いため、これを覚えさせないと欲しい回答が得られないと思います。

「いいね!」 1

ありがとうございます!

「いいね!」 1

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