【Formbridge】テーブル明細行ごとの条件非活性制御(新バージョン)

Formbridgeの新バージョンにおいて、テーブル内のフラグをもとに、その行の他項目を活性or非活性にし値の変更をできないようにしたいです。

(非活性対象の項目は日付、文字列、数値フィールドなどが複数あります)

アプローチとしては2つ思い当たりましたが、どちらも失敗しました。

1,明細行ごとのフラグによるDisableまたはEditable制御(best)
2,明細行ごとのフラグによる入力値変更拒否制御(better)

1を試したところ、明細行フラグの判定はできましたがDisableが操作できませんでした。

こちらを参考にしています。

TypeError: context.getState is not a function
となっておりそもそも現在のバージョンではstateでは触れないのでは?と思います。




上記から2を試しました。
2を試したところフラグチェックと値の変更を阻止し、フィールドに対しエラー表示まで可能でした。
ですがフラグをオフにしたまま意図せず値を触ってしまった時に、
エラーを解除するまで確認画面に進めない事象が起きました。

上記の対応策として以下を試しましたがともに不発でした。

・確認ボタン押下時エラーメッセージを消去する
→エラーメッセージ発生下だと確認ボタン押下イベントが発生するまえにエラーバリデーションがかかる模様。イベントキャッチできず

・独自ボタンを設置して、値をセットし直すことでエラーメッセージを消去する
→値の再セットまでは動作しますが
エラーメッセージは消去できませんでした。

エラーが出ているフィールドを手動で操作し、エラーを解消するしかなさそうというのが現時点での見解です。

以下は、2の独自ボタンコードまで実装したスクリプトです。

すみません、実装したコードのフィールドコードに相当する部分をバッサリ切ってます。

// FormBridge テーブル内フィールド編集制御
// チェックボックス値に応じてテーブル内の他フィールドの編集を制御

(function() {
    console.log('[修正チェック活性] スクリプト初期化開始');
  
  // 設定: テーブルコード、チェックボックス、対象フィールドの定義
  const config = {
    '請求内容明細_A': {
      checkboxFields: [{
        checkbox: '修正_A_請求明細',
        targetFields: [
          '月日_A_請求明細',
          '顧客名_A_請求明細',
          '実施形態_A_請求明細',
          '内容_A_請求明細',
          'アシスタント_A_請求明細',
          'キャンセル関連_A_請求明細',
          '明細金額_税抜_A_請求明細'
        ]
      }]
    },
  };
  
    // エラー解除ボタンの追加
    const addErrorCancelButton = function(context) {
      try {
        // エラー解除ボタンの追加
        // フィールドコードが'errorCancel'の要素を検索
        const errorCancelField = document.querySelector('.fb-custom--field[data-field-code="errorCancel"]');
        
        if (errorCancelField) {
          // ボタンHTML
          const buttonHtml = '<button id="errorCancelButton" style="background-color: #4CAF50; color: white; padding: 10px 15px; border: none; border-radius: 4px; cursor: pointer; margin: 10px 0; font-weight: bold;">エラーを解除して確認画面へ進む</button>';
          errorCancelField.innerHTML = buttonHtml;
          console.log('[修正チェック活性] エラー解除ボタンを追加しました (フィールド)');
        } else {
          // 確認ボタンの近くに追加する代替手段
          const confirmButton = document.querySelector('.fb-custom--button--confirm');
          
          if (confirmButton && confirmButton.parentNode) {
            // 新しいボタン要素を作成
            const errorCancelButton = document.createElement('button');
            errorCancelButton.id = 'errorCancelButton';
            errorCancelButton.innerText = 'エラーを解除して確認画面へ進む';
            errorCancelButton.style = 'background-color: #4CAF50; color: white; padding: 10px 15px; border: none; border-radius: 4px; cursor: pointer; margin: 10px 0; font-weight: bold;';
            
            // 確認ボタンの前に挿入
            confirmButton.parentNode.insertBefore(errorCancelButton, confirmButton);
            console.log('[修正チェック活性] エラー解除ボタンを追加しました (確認ボタンの近く)');
          } else {
            // フォーム要素に追加する代替手段
            const formElement = document.querySelector('.fb-custom--content--form');
            
            if (formElement) {
              // ボタンコンテナを作成
              const buttonContainer = document.createElement('div');
              buttonContainer.style = 'text-align: center; margin: 20px 0;';
              
              // ボタン要素を作成
              const errorCancelButton = document.createElement('button');
              errorCancelButton.id = 'errorCancelButton';
              errorCancelButton.innerText = 'エラーを解除して確認画面へ進む';
              errorCancelButton.style = 'background-color: #4CAF50; color: white; padding: 10px 15px; border: none; border-radius: 4px; cursor: pointer;';
              
              // コンテナにボタンを追加し、フォームの最後に配置
              buttonContainer.appendChild(errorCancelButton);
              formElement.appendChild(buttonContainer);
              console.log('[修正チェック活性] エラー解除ボタンを追加しました (フォームの最後)');
            } else {
              console.error('[修正チェック活性] エラー解除ボタンを追加する場所が見つかりません');
              return;
            }
          }
        }
        
        // ボタンにクリックイベントを追加
        setTimeout(function() {
          const button = document.getElementById('errorCancelButton');
          if (button) {
            button.addEventListener('click', function(e) {
              e.preventDefault();
              console.log('[修正チェック活性] エラー解除ボタンがクリックされました');
              clearAllErrors(context);
            });
          } else {
            console.error('[修正チェック活性] エラー解除ボタンが見つかりません');
          }
        }, 500); // ボタンがDOMに反映されるまで少し待つ
      } catch (error) {
        console.error('[修正チェック活性] エラー解除ボタン追加エラー:', error);
      }
    };
    
    // 全てのエラーをクリアする関数
    const clearAllErrors = function(context) {
      console.log('[修正チェック活性] 全てのエラーをクリアします');
      
      // 全てのテーブルについて処理
      for (const tableCode in config) {
        const tableConfig = config[tableCode];
        
        // テーブルのレコード数を取得
        const record = context.getRecord();
        const tableRows = record[tableCode] && record[tableCode].value;
        
        if (!tableRows || !Array.isArray(tableRows)) {
          console.log(`[修正チェック活性] テーブル ${tableCode} にデータがありません`);
          continue;
        }
        
        // 各行について処理
        for (let rowIndex = 0; rowIndex < tableRows.length; rowIndex++) {
          // 各チェックボックス設定について処理
          for (const checkboxConfig of tableConfig.checkboxFields) {
            const { targetFields } = checkboxConfig;
            
            // 各対象フィールドについて同じ値を再設定(エラーを上書き)
            for (const fieldCode of targetFields) {
              try {
                // 現在の値を取得
                const currentRow = tableRows[rowIndex].value;
                const currentValue = currentRow[fieldCode] && currentRow[fieldCode].value;
                
                if (currentValue !== undefined) {
                  // 同じ値を再設定することでエラーを上書き
                  context.setSubtableFieldValue(tableCode, fieldCode, rowIndex, currentValue);
                  
                  // 値を再設定して更新を確定
                  context.setSubtableFieldValue(tableCode, fieldCode, rowIndex, currentValue);
                  
                  console.log(`[修正チェック活性] フィールド値再設定: ${tableCode}.${fieldCode}[${rowIndex}] = ${currentValue}`);
                }
              } catch (error) {
                console.error(`[修正チェック活性] フィールド値再設定エラー: ${tableCode}.${fieldCode}[${rowIndex}]`, error);
              }
            }
          }
        }
      }
      
      console.log('[修正チェック活性] エラークリア完了、確認ボタンを自動クリック');
      
      // 確認ボタンを自動的にクリック
      try {
        // FormBridgeの確認ボタン要素を探す
        const confirmButton = document.querySelector('.fb-custom--button--confirm');
        if (confirmButton) {
          confirmButton.click();
          console.log('[修正チェック活性] 確認ボタンを自動クリックしました');
        } else {
          // 従来の方法で確認ボタンを探す代替手段
          const legacyConfirmButton = document.querySelector('.gaia-ui-actionmenu-save');
          if (legacyConfirmButton) {
            legacyConfirmButton.click();
            console.log('[修正チェック活性] 従来の確認ボタンを自動クリックしました');
          } else {
            console.error('[修正チェック活性] 確認ボタンが見つかりません');
          }
        }
      } catch (error) {
        console.error('[修正チェック活性] 確認ボタン自動クリックエラー:', error);
      }
    };
  
    // イベントリスナーの登録
    const registerEventListeners = function() {
      console.log('[修正チェック活性] イベントリスナー登録開始');
      
      // フォーム表示時のイベント
      formBridge.events.on('form.show', function(context) {
        console.log('[修正チェック活性] フォーム表示イベント発生');
        
        // エラー解除ボタンを追加
        setTimeout(function() {
          addErrorCancelButton(context);
        }, 1000); // フォームが完全に表示されるまで少し待つ
      });
      
      // 各テーブルについて処理
      for (const tableCode in config) {
        const tableConfig = config[tableCode];
        
        // 各チェックボックス設定について処理
        for (const checkboxConfig of tableConfig.checkboxFields) {
          const { checkbox, targetFields } = checkboxConfig;
          
          // 各対象フィールドについて、変更イベントを登録
          for (const fieldCode of targetFields) {
            // テーブル内フィールドの変更イベント
            const eventName = `form.field.change.${tableCode}.${fieldCode}`;
            
            // 変更イベントハンドラーの設定部分を修正
            formBridge.events.on(eventName, function(context) {
              console.log(`[修正チェック活性] フィールド変更イベント発生: ${tableCode}.${fieldCode}[${context.rowIndex}] = ${context.value}`);
              
              // 現在の行のデータを取得
              const record = context.getRecord();
              const currentRow = record[tableCode].value[context.rowIndex].value;
              
              // チェックボックスの値を取得
              const checkboxValue = currentRow[checkbox] && currentRow[checkbox].value;
              
              console.log(`[修正チェック活性] 修正チェック値: ${JSON.stringify(checkboxValue)}`);
              
              // チェックボックス値が配列で"1"を含むか、または直接"1"の場合は編集を許可
              const isCheckboxOn = Array.isArray(checkboxValue) 
                  ? checkboxValue.includes("1") 
                  : checkboxValue === "1";
                  
              // チェックボックスがONでない場合、編集をキャンセル
              if (!isCheckboxOn) {
                console.log(`[修正チェック活性] 編集キャンセル: ${fieldCode}[${context.rowIndex}]`);
                
                // // 変更をキャンセル
                context.preventDefault();
                
                // エラーメッセージを設定
                context.setSubtableFieldValueError(
                  tableCode,
                  fieldCode,
                  context.rowIndex,
                  '修正フラグに1を入れてから編集してください'
                );
                
                // 値を元に戻す試み
                return false;
              } else {
                // エラーメッセージをクリア
                context.setSubtableFieldValueError(tableCode, fieldCode, context.rowIndex, null);
              }
            }, { capture: true }); // ← このオプションを追加
            
            console.log(`[修正チェック活性] イベントリスナー登録: ${eventName}`);
          }
        }
      }
      
      console.log('[修正チェック活性] イベントリスナー登録完了');
    };
  
    // スクリプトの初期化
    try {
      console.log('[修正チェック活性] FormBridge拡張スクリプト開始');
      
      // FormBridgeオブジェクトが存在するか確認
      if (typeof formBridge === 'undefined') {
        console.error('[修正チェック活性] FormBridgeオブジェクトが見つかりません');
        return;
      }
      
      // イベントリスナーを登録
      registerEventListeners();
      
      console.log('[修正チェック活性] FormBridge拡張スクリプト初期化完了');
    } catch (error) {
      console.error('[修正チェック活性] 初期化エラー:', error);
    }
  })();

アプローチは問わず、達成したいことは当初の目的です。
お知恵をお借りできますと幸いです。