cocoon nested_form добавляет поля над существующими объектами в edit.html.erb, а не ниже

Мой new.html.erb работает нормально.

Но в моем edit.html.erb, скажем, у меня есть 3 существующих отдела...

Всякий раз, когда я нажимаю ссылку «Добавить отдел» (чтобы добавить другое поле), она продолжает идти выше существующих отделов, а не ниже.

Кстати, моя ассоциация говорит, что в подразделении есть много отделов, и отделы принадлежат подразделению.

В моем контроллере: мои методы new и edit

def new
    @division = Division.new
     @division.departments.build 
  end

 def edit
    @division = Division.find(params[:id])

  end

Мне нужен js-файл кокона, поэтому я использую файл по умолчанию и не переопределяю что-то еще.

cocoon.js

(function($) {

  function replace_in_content(content, regexp_str, with_str) {
    reg_exp = new RegExp(regexp_str);
    content.replace(reg_exp, with_str);
  }

  function trigger_removal_callback(node) {
    node.parent().parent().trigger('removal-callback');
  }

  $('.add_fields').live('click', function(e) {
    e.preventDefault();
    var $this                 = $(this),
        assoc                 = $this.data('association'),
        assocs                = $this.data('associations'),
        content               = $this.data('template'),
        insertionMethod       = $this.data('association-insertion-method') || $this.data('association-insertion-position') || 'before';
        insertionNode         = $this.data('association-insertion-node'),
        insertionCallback     = $this.data('insertion-callback'),
        removalCallback       = $this.data('removal-callback'),
        regexp_braced         = new RegExp('\\[new_' + assoc + '\\]', 'g'),
        regexp_underscord     = new RegExp('_new_' + assoc + '_', 'g'),
        new_id                = new Date().getTime(),
        newcontent_braced     = '[' + new_id + ']',
        newcontent_underscord = '_' + new_id + '_',
        new_content           = content.replace(regexp_braced, '[' + new_id + ']');

    if (new_content == content) {
        regexp_braced     = new RegExp('\\[new_' + assocs + '\\]', 'g');
        regexp_underscord = new RegExp('_new_' + assocs + '_', 'g');
        new_content       = content.replace(regexp_braced, '[' + new_id + ']');
    }

    new_content = new_content.replace(regexp_underscord, newcontent_underscord);

    if (insertionNode){
      insertionNode = insertionNode == "this" ? $this : $(insertionNode);
    } else {
      insertionNode = $this.parent();
    }

    var contentNode = $(new_content);

    // allow any of the jquery dom manipulation methods (after, before, append, prepend, etc)
    // to be called on the node.  allows the insertion node to be the parent of the inserted
    // code and doesn't force it to be a sibling like after/before does. default: 'before'
    insertionNode[insertionMethod](contentNode);

    $this.parent().trigger('insertion-callback');
  });

  $('.remove_fields.dynamic').live('click', function(e) {
    var $this = $(this);
    trigger_removal_callback($this);
    e.preventDefault();
    $this.closest(".nested-fields").remove();
  });

  $('.remove_fields.existing').live('click', function(e) {
    var $this = $(this);
    trigger_removal_callback($this);
    e.preventDefault();
    $this.prev("input[type=hidden]").val("1");
    $this.closest(".nested-fields").hide();
  });

})(jQuery);

В моем _form.html.erb

<div class="new-div-box">
<%= simple_form_for [:admin, @division]  do |f| %>
  <%= f.input :name, :label => "Division Name"%>

<div>
<div>

  <%= f.simple_fields_for :departments do |department| %>
  <%= render 'department_fields', :f => department %>

  <% end %>
</div>
  <%=link_to_add_association "Add Department", f, :departments,class: "btn btn-inverse" %>
</div>

  <%= f.submit  :class=>"btn btn-primary submit_btn_division" %>

<% end %>

</div>

И тот, который я визуализировал, это _department_fields.html.erb.

<div class="nested-fields">
  <%= f.input :name, :label => "Department Name"  %>
  <%= link_to_remove_association raw("<img src='../../../assets/remove.png' width='25px' height='25px'>"), f %>
</div>

Интересно, почему недавно добавленное поле идет над существующими полями в моем edit.html.erb


person xirukitepe    schedule 11.12.2012    source источник


Ответы (2)


Я думаю, что он ищет div с ассоциацией в качестве идентификатора, для которого обертываются вложенные поля.

Итак, ваш взгляд

<div id="departments">
  <%= f.simple_fields_for :departments do |department| %>
    <%= render 'department_fields', :f => department %>
  <% end %>
  <div class="links">
    <%=link_to_add_association "Add Department", f, :departments,class: "btn btn-inverse" %>
  </div>
</div>
person spullen    schedule 06.03.2013

Решение @spullen будет работать, но его рассуждения неверны. Если вы проследите код coccon, вы столкнетесь с чем-то вроде этого

var getInsertionNodeElem = function(insertionNode, insertionTraversal, $this){
    if (!insertionNode){
      return $this.parent();
    }
    ...
}

и тогда я считаю, что это var addedContent = insertionNodeElem[insertionMethod](contentNode); добавляет в новый узел.

Дело в том, что новый партиал будет вставлен над родительским узлом link_to_add_association. Таким образом, элемент <a> элемента link_to_add_association и узел-контейнер новых полей ввода будут родственными элементами.

Если вы хотите, чтобы вставленный фрагмент был ниже, link_to_add_association должен быть заключен в отдельный div. Пример:

  <div id="workout-fields">
    <%= f.simple_fields_for :workouts, validate: true do |workout| %>
      <%= render partial: 'shared/workout/form', locals: {f: workout, show_remove: false} %>
    <% end %>
    <div><%= link_to_add_association 'add workout', f, :workouts, partial: 'shared/workout/form'%></div> <!-- this wrapper is IMPORTANT for insertion ordering -->
  </div>
person James L.    schedule 17.08.2017