一覧画面上で各レコードごとに編集ボタンを表示させることはできますか。

何を実現したいのかを書きましょう

一覧画面上で各レコードごとに最後の列に用意されている既存の編集ボタンと同じ処理をレコードの最初の列にaとimgを用いて実現したいです。
一応既存の編集ボタンと同じく以下処理を実行できること。
①編集ボタンを押下したら、一行だけ編集モードに変わる。
②別レコードの編集ボタンは消える。
③保存ボタンを押下したら、保存され再度作成した編集ボタンと既存の編集ボタンが表示される。

発生した問題やエラーメッセージを具体的に書きましょう

現状、エラーは出ていません。
また、上記やりたいことの①と②は実現できましたが、③だけ、保存はされますが、編集を行ったレコードのみ作成した編集ボタンが表示されません。
原因として処理は問題ないようですが、キントーンのstatic内のJavascriptで消されてるようです。
(htmlからもaタグやimgタグが消されてしまうのです。)
これを回避することはできるのでしょうか。

実行したコードをコピー&ペーストしましょう

コードペタ張りですみません。。。

(function() {
  'use strict';

  // 編集ボタンを非表示にする関数
  const hideAllEditButtons = (table) => {
    const editButtons = table.querySelectorAll('.recordlist-edit-gaia, .new_edit_button');
    editButtons.forEach(button => {
      button.classList.add('hidden');  // 'hidden'クラスで非表示にします
    });
  };

  // 編集ボタンを再表示する関数
  const restoreEditButtons = (table, rowIndex) => {
    const editButtons = table.querySelectorAll('.recordlist-edit-gaia, .new_edit_button');
    editButtons.forEach(button => {
      button.classList.remove('hidden');  // 'hidden'クラスを解除して再表示
    });
  };

  // 保存・キャンセルボタンのイベントリスナー追加
  const addSaveCancelListeners = (table) => {
    const saveButtons = document.querySelectorAll('.recordlist-save-gaia, .recordlist-save-button-gaia');
    const cancelButtons = document.querySelectorAll('.recordlist-cancel-gaia, .recordlist-cancel-button-gaia');

    saveButtons.forEach((button) => {
      if (!button.dataset.listenerAdded) {
        button.addEventListener('click', () => {
          console.log('保存ボタンが押されました');
          setTimeout(() => {
            restoreEditButtons(table);
          }, 500);
        });
        button.dataset.listenerAdded = true;
      }
    });

    cancelButtons.forEach(button => {
      if (!button.dataset.listenerAdded) {
        button.addEventListener('click', () => {
          console.log('キャンセルボタンが押されました');
          restoreEditButtons(table);
          initialize();
        });
        button.dataset.listenerAdded = true;
      }
    });
  };

  // 新しいボタンを行に追加
  const addNewButtonToRow = (columns, rowIndex, table) => {
    if (!columns[0].querySelector('.new_edit_button')) {
      if (columns.length > 1 || columns[0].tagName !== 'TD') {
        const newButton = document.createElement('a');
        newButton.classList.add('new_edit_button');
        newButton.style.cssText = 'display: inline-block; width: 35px; height: 35px; background: transparent; border: 0; margin: 0; padding: 0;';
        const newButtonImg = document.createElement('img');
        newButtonImg.src = `https://static.cybozu.com/contents/k/image/argo/component/recordlist/record-edit.png`;
        newButtonImg.alt = 'Edit';
        newButtonImg.style.cssText = 'width: 20px; height: 20px;';
        newButton.appendChild(newButtonImg);

        newButton.addEventListener('click', () => {
          console.log('追加された編集ボタンが押されました');
          hideAllEditButtons(table);
          const existingEditButtons = table.querySelectorAll('.recordlist-edit-gaia');
          if (existingEditButtons[rowIndex]) {
            existingEditButtons[rowIndex].click();
            addSaveCancelListeners(table);
          }
        });
        columns[0].appendChild(newButton);
      }
    }
  };

  // 既存の編集ボタンにリスナーを追加
  const addListenersToExistingEditButtons = (table) => {
    const editButtons = table.querySelectorAll('.recordlist-edit-gaia');
    editButtons.forEach((button, rowIndex) => {
      if (!button.dataset.listenerAdded) {
        button.addEventListener('click', () => {
          console.log('既存の編集ボタンが押されました');
          hideAllEditButtons(table);
          addSaveCancelListeners(table);
        });
        button.dataset.listenerAdded = true;
      }
    });
  };

  // テーブルのボタンを更新
  const updateTableButtons = (table) => {
    const rows = table.querySelectorAll('tr');
    rows.forEach((row, rowIndex) => {
      const columns = row.querySelectorAll('td');
      if (columns.length > 0) {
        columns[0].style.width = '76px';
        addNewButtonToRow(columns, rowIndex, table);
      }
    });

    const headers = table.querySelectorAll('th');
    if (headers.length > 0) {
      headers[0].style.width = '76px';
    }

    addListenersToExistingEditButtons(table);
  };

  // 初期化関数
  const initialize = () => {
    const table = document.querySelector('.recordlist-gaia');
    if (table) {
      table.querySelectorAll('.new_edit_button').forEach(button => button.remove());
      updateTableButtons(table);
    } else {
      console.warn('テーブルが見つかりません');
    }
  };

  // リストビューの更新を監視して、再描画後に初期化処理を行う
  kintone.events.on('app.record.index.show', (event) => {
    initialize(); // 初期化処理
    return event;
  });
})();

皆様お手数をおかけしますが何か情報や修正箇所など、ご教授いただけますと幸いです。

【進展】
下記処理を追加することで、保存処理終了後に画面のリフレッシュで以下③を実現することができました。
③保存ボタンを押下したら、保存され再度作成した編集ボタンと既存の編集ボタンが表示される。

ただし、この場合画面が処理を行っている時間があるので描画されたり画面がリフレッシュがかかるなど重いような動きをします。
この動きを改善する方法などありますでしょうか。

kintone.events.on('app.record.index.edit.submit.success',(event) => {
    setTimeout(() => {
      location.reload();
    }, 300);
    return event;
  })

initialize() で、保存時に消されたタグを初期化して復活させる。

    saveButtons.forEach((button) => {
      if (!button.dataset.listenerAdded) {
        button.addEventListener('click', () => {
          console.log('保存ボタンが押されました');
          setTimeout(() => {
            restoreEditButtons(table);
            initialize(); // 保存後にタグを初期化
          }, 500);
        });
        button.dataset.listenerAdded = true;
      }
    });
2 Likes

既存のHTML要素はkintone側の処理で生成/破棄が行われる可能性があるので、Mapleさんが仰っている通り、保存後に再初期化が必要だと思います。
ただ、そもそも手法がDOM操作にあたるので、アップデートにより今後その挙動が変わる可能性もあることは注意したほうがいいと思います。

ところで、最近のアップデートで行をダブルクリックすると編集モードに入れるようになりましたが、それでは対応不可なのでしょうか?

2 Likes

返信ありがとうございます。
アドバイスいただきましたコードで確認してみたのですが、処理は問題ないのにstatic内のJavascriptで無効化されてしまいました。。。

既存のHTML要素はkintone側の処理で生成/破棄が行われる可能性があるので、Mapleさんが仰っている通り、保存後に再初期化が必要だと思います

確認してみたのですが、Javascriptの既存仕様で上書きされてしまい、当該レコードのみ反映されない状態となってしまいました。

ところで、最近のアップデートで行をダブルクリックすると編集モードに入れるようになりましたが、それでは対応不可なのでしょうか?

そもそもこの仕様を確認できていませんでした。。。。 :cry:
それでいいじゃん!! :astonished:
当初の仕様では、行ダブルクリックで一発解消だったのですが、、、

仕様の追加として「締めフラグ」を用いてロックレコードを扱いたいという内容が入ったため、締めフラグも新たに追加対応と下記記述を追加して、ダブルクリックからのロックレコードへの編集は避けるように対応いたしました。

kintone.events.on('app.record.index.edit.show',(event) => {
    const shimeFlag = event.record[shimeflgFName] ? event.record[shimeflgFName].value : '';
    let isUnlocked;
    if (shimeFlag === '') {
      isUnlocked = true;
    } else {
      isUnlocked = shimeFlag[0] === shimeflgFNameS;
    }
    const table = document.querySelector('.recordlist-gaia');
    if (!isUnlocked) {
      alert('このレコードはロックされているため、編集できません。');
      location.reload();
    }
    return event;
  });
1 Like

もみじ様、住田知基様
お二人とも、様々なアドバイスありがとうございます。
当初の内容としては、行編集アイコンを列の先頭に表示したいという内容でした。
ただ、2024年9月のアップデート内容として行クリックからの編集モード移行が実装されていたことに、私が存じ上げていなかった為、大分遠回りなやり方を行っていたことに気づきました。
その為、一旦このトピックは解決として、クローズさせていただきます。
ありがとうございました。

1 Like

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