前回の続き。
前回は最終行からのコピーでしたが、今回は任意の行からコピーできるようにします。
(前回の実装が完了したという前提で話を進めていきます。)
ビュー側の変更
前回、親側のフォームに「□行コピーする」を追加しましたが、その横に、行位置を選択するセレクトボックスを追加します。
その場合、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
は、
で求めた件数をセットします。
私の環境ですと、なぜか「戻る」ボタンでも発火したようなので、SELECTタグが存在しない場合は、早期リターンさせます。
次に、前回描画したOPTIONタグをすべて削除します。
さらに、件数分、OPTIONタグを追加します。
最終行にselectedをつけておくと良いでしょう。
どこから実行するか?
このファンクションは、下記のタイミングで呼び出します。
(cntを求めるファンクションも一緒に呼び出します。)
- 初期処理(onLoadはエラーになるので、connect()の最初の方で呼び出す。)
cocoon:after-insert
cocoon:after-remove
コピー元を求める箇所を変更する
前回、
の、
let copy_moto = flds_id.length - 2;
を変更します。
let copy_moto = document.getElementById(copy_select_id).value - 1; // コピー元
上記は、表示の行位置とvalue
が一致している場合です。
(value
が行位置−1である場合は、マイナス1をする必要はありません。)
以上で、任意の行位置からコピーできるはずです。
ついでに、各行に行番号をつけたいのだが…
SELECTタグに「○件目」という選択肢を用意した都合上、「各明細に何行目か表す文字を表示したい」というニーズが生じるかもしれません。
行番号については、こちら
の「1行目のみ削除ボタンを表示させない」にあるf.options[:child_index]
が(0から始まる)明細行なので、これを+1したものを表示すれば、初期表示は可能です。
しかし、明細行を削除した場合に、番号を詰めてくれません。
また、明細行を追加した場合、その行番号エリアに「new_tasks」という、謎の文言が表示されます。
これらをJQueryで採番し直すのは、ちょっと億劫でしょうね。
(cocoon:after-insert
で、SPANタグのidにユニークな値をセットする手法が、ちょっと思い浮かびませんので…)
ですので、避けたほうが良いでしょうね。
最後に
続編をアップしました。