質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.10%

動的にtableを追加、削除

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 64

obake_

score 16

function addRow(idx){
    var tags;
    tags += "<tr> <td class=text-center> <button type=button class='btn deleterowbtn'>削除</button></td>";
    tags += "<td class='text-center'><input name='hoge_name" + idx + "' id='hoge" + idx + "' type=checkbox></td>";
    tags += "<td><input name='hoge2" + idx + "' id='hoge2" + idx + "' class=form-control type=text></td>";
    tags += "<td><input name='hoge3" + idx + "' id='hge3" + idx + "' class=form-control type=text></td></tr>";
    $('#hoge_table tbody').append(tags);
};
$("#hoge_add").click(function(){
    // テーブルの行取得
    var idx = $("#hoge_table > tbody > tr").length;
    addRow(idx + 1);
});
// 追加した行を削除
$(document).on("click",".deleterowbtn", function(){
    var row = $(this).closest("tr").remove();
     $(row).remove();
});


現在このようなコードで動的にテーブルの行を追加するコードを記述しているのですがこれで削除するとIDの部分が行を削除したときにIDの数字にズレが出てしまいます。
うまく説明できないのですが追加ボタンを3回クリックすると3行新しく作成されます。このときIDに割り振っている数字は上から1,2,3になるかと思います。
この状態で真ん中の行を削除すると上からIDに割り振っているIDは1,3となってしまいます。この時に削除したタイミングで1,2となるように変更したいです。
どのように変更するば良いかご教授いただければ幸いです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • miyabi_takatsuk

    2019/10/09 23:13

    idとnameは変えない方がいいような・・・。
    まぁ、変える必要があるのなら別ですが(通常よっぽどの理由がない限り変えるようなものではない)

    キャンセル

  • jun68ykt

    2019/10/10 00:52

    @obake_ さん
    > できればnameの値の末尾も変更
    するコードを回答しました。参考になれば幸いです。

    キャンセル

  • obake_

    2019/10/10 06:38

    @jun68yktさん
    とても丁寧な解説ありがとうございます。

    キャンセル

回答 1

checkベストアンサー

0

こんにちは

修正の方針や方法が、色々ありそうですが、以下その一例として回答します。

まず、あるjQueryオブジェクトに対する操作として、当該要素の内側にある <input> の name属性 と id 属性を、 与えられた引数 idx から得られる規則的な値に上書きするプラグインを作成します。

$.fn.setInputsAttrs = function(idx) {
    $('input', this).each(function(i, e) {
        const value = `hoge${i > 0 ? i+1 : ''}${idx}`;
        $(e).attr({
            name: value,
            id: value
        });
    });
}

これによって、 ある <tr> を参照する e があったときに、例えば

$(e).setInputsAttrs(5);


とすると、この<tr> の中に出現する最初 <input> の name属性 と id 属性の値は、 hoge5 になり、2番目の<input> については hoge25、3番目の<input> については hoge35 になります。

次に、上記のプラグインを使うために、 addRow を以下のように修正します。

function addRow(idx) {
    var tags = "<tr><td class='text-center'><button type='button' class='btn deleterowbtn'>削除</button></td>" +
        "<td class='text-center'><input type='checkbox' /></td>" +
        "<td><input class='form-control' type='text' /></td>" +
        "<td><input class='form-control' type='text' /></td></tr>";

    var row = $(tags);
    $('#hoge_table tbody').append(row);

    return row;
};


上記のように、 addRow の中では、各<input> の id と name は設定せずに、先の setIdAndName でそれらの設定を行うようにするため、追加した行のjQueryオブジェクトを返すようにします。

これまでの追加、修正によって、追加ボタンがクリックされたときの処理は以下のように書けます。

$("#hoge_add").click(function() {
    var rowsCount = $("#hoge_table > tbody > tr").length;
    addRow().setInputsAttrs(rowsCount + 1);
});

最後に削除時の修正です。ある行が削除されたとき、その行より後にある行について、idname を更新します。

$(document).on("click", ".deleterowbtn", function() {
    var row = $(this).closest("tr").remove();
    var removedIndex = $('tr').index(row);

    $(row).remove();

    $('tr').each(function(i, e) {
        if (i >= removedIndex) $(e).setInputsAttrs(i + 1);
    });
});


上記のように、remove する前に、削除される行のインデクスを取っておき、削除した後に、そのインデクスの行も含めた以降の行について、setInputsAttrs を実行します。

以下は、上記の修正後のコードの動作確認用に CodePen に上げたものです。

以上、参考になれば幸いです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.10%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる