LoginSignup
14
14

More than 5 years have passed since last update.

railsでフォームのフィールドをjQueryでコピーして追加する

Posted at

fields_forでhas_manyなフィールドを作って、それをどんどんページ内で追加して行きたい場合ありますよね。そんな時はモデルに、

accepts_nested_attributes_for
http://apidock.com/rails/ActiveRecord/NestedAttributes/ClassMethods/accepts_nested_attributes_for

を指定してgemで

nested_form
https://github.com/ryanb/nested_form

を使うと簡単にできます。できるはずなんですが、自分の環境でform-builderをもろもろ拡張している関係か、link_to_addがどうもちゃんと動かなかったのでjQueryでさっくり最後のフィールドをコピーして末尾に追加する仕組みを作りました。

  $.fn.nestedResource = function(options) {

    var result = {
      update: function(fields) {
        $(fields).find("input").each(function(index, field) {
          $(field).attr("id", $(field).attr("id").replace(/\_[0-9]+\_/,"_" + count + "_"));
          $(field).attr("name", $(field).attr("name").replace(/\[[0-9]+\]/,"[" + count + "]"));
        });
      },
      append: function() {
        this.update(templateDom);
        count++;
        $(tailSelector).before($(templateDom).clone(false));
      },
    };
    var count = 0;
    var selector = options["selector"];
    var tailSelector = options["tail-selector"];

    $(selector).each(function(index, fields) {
      result.update(fields);
      count++;
    });

    var templateDom = $(selector).last().clone(false);
    return result;
  };

.clone(false)とfalseを指定しないと、イベントも一緒にコピーされてしまいます。

tail-selectorで指定した箇所にコピーしたDOMを入れます。

var nestedResource = $(document).nestedResource({
  "selector": "#schedules .fields",
  "tail-selector": "#schedules_tail"
});

フィールドの追加はこんな感じで呼び出します。

<%= link_to "フィールドを追加", "javascript:void(0)", :onclick=> "nestedResource.append(); return false;" %>

これで分かりやすくフィールドがコピーされて増えます。

14
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
14