inuinu blog(開発用)

BOT @wagagun の開発ノウハウや、IT向け?の雑記ブログです。

【Ruby on Rails7】cocoonを導入(その10:任意の行からコピーしたい)

この記事では、Ruby on Rails7のgemパッケージcocoonについて、導入・カスタマイズ行います。
今回は行追加時に、任意の行から値をコピーする手法を考えます。

前回の続き。

inuinu-tech.hatenablog.jp

前回は最終行からのコピーでしたが、今回は任意の行からコピーできるようにします。
(前回の実装が完了したという前提で話を進めていきます。)

ビュー側の変更

前回、親側のフォームに「□行コピーする」を追加しましたが、その横に、行位置を選択するセレクトボックスを追加します。
その場合、OPTIONタグは空欄にします。

●親の入力フォーム

= select :copy_select, :copy_option, []

JQueryを変更

OPTIONタグを描画

以下のようなファンクションを用意します。

function resetSelectOption(id, cnt) {
  let sl = document.getElementById(id);
  // nullの場合は処理中止(戻るボタン対応)
  if (sl == null) { return; }
  // 現状のoptionをすべてクリア
  while(sl.lastChild)
  {
    sl.removeChild(sl.lastChild);
  }

  // optionを追加
  for (let idx = 1; idx <= cnt; idx++) {
    let option = document.createElement("option");
    option.setAttribute("value", idx);
    option.innerHTML = idx + "件目";
    sl.appendChild(option);
    if (idx == cnt) {   //最終行
      option.setAttribute("selected", true);    // selectedの属性を付与
    }
  }
} // function

引数のidはSELECTタグのid。ビューの例ですと「copy_select_copy_option」といった値になっているはずです。
cntは、

inuinu-tech.hatenablog.jp

で求めた件数をセットします。

私の環境ですと、なぜか「戻る」ボタンでも発火したようなので、SELECTタグが存在しない場合は、早期リターンさせます。

次に、前回描画したOPTIONタグをすべて削除します。

さらに、件数分、OPTIONタグを追加します。
最終行にselectedをつけておくと良いでしょう。

どこから実行するか?

このファンクションは、下記のタイミングで呼び出します。
(cntを求めるファンクションも一緒に呼び出します。)

  • 初期処理(onLoadはエラーになるので、connect()の最初の方で呼び出す。)
  • cocoon:after-insert
  • cocoon:after-remove

コピー元を求める箇所を変更する

前回、

inuinu-tech.hatenablog.jp

の、

let copy_moto = flds_id.length - 2;

を変更します。

let copy_moto = document.getElementById(copy_select_id).value - 1; // コピー元

上記は、表示の行位置とvalueが一致している場合です。
(valueが行位置−1である場合は、マイナス1をする必要はありません。)

以上で、任意の行位置からコピーできるはずです。

ついでに、各行に行番号をつけたいのだが…

SELECTタグに「○件目」という選択肢を用意した都合上、「各明細に何行目か表す文字を表示したい」というニーズが生じるかもしれません。

行番号については、こちら

inuinu-tech.hatenablog.jp

の「1行目のみ削除ボタンを表示させない」にあるf.options[:child_index]が(0から始まる)明細行なので、これを+1したものを表示すれば、初期表示は可能です。

しかし、明細行を削除した場合に、番号を詰めてくれません。
また、明細行を追加した場合、その行番号エリアに「new_tasks」という、謎の文言が表示されます。

これらをJQueryで採番し直すのは、ちょっと億劫でしょうね。
(cocoon:after-insertで、SPANタグのidにユニークな値をセットする手法が、ちょっと思い浮かびませんので…)

ですので、避けたほうが良いでしょうね。

最後に

続編をアップしました。

inuinu-tech.hatenablog.jp