Обновите поле внутри fields_for с помощью Cocoon и Jquery

Я хотел бы установить значение поля внутри fields_for с драгоценным камнем Cocoon, используя Jquery. Я использую событие изменения на jquery.

_форма

<%= form_for(@invoice) do |f| %>

  <div class="field">
    <%= f.label :total_order %><br>
    <%= f.number_field :total_order %>
    <%= f.object_id %>
  </div>
  <div id="items">
    <%= f.fields_for :items do |i| %>
      <%= render 'item_fields', :f => i %>
    <% end %>
    <div class="links">
      <%= link_to_add_association '+ produk', f, :items %>
    </div>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

_item_fields

<div class="nested-fields">
<tr>
    <td><%= f.select :product_id,
                        Product.all.collect {|p| [p.name, p.id, 
                        {'data-unit_cost'=>p.unit_cost}]}, 
                        { include_blank: true },
                        { class: "product-select"} %>
    </td>
    <td><%= f.number_field :unit_cost, 
                    label: false,
                class: "cost-input" %>
    </td> 
    <td><%= f.number_field :quantity,
                    label: false,
                    class: "qty-input" %>
    </td>
    <td style="vertical-align: top;"><%= link_to_remove_association '- remove', f %></td>
</tr>
</div>

сценарий кофе

$("#items").on "cocoon:after-insert", ->
    $(".product-select").change ->
        $(".cost-input").val($(".product-select :selected").data("unit_cost"))

Дело в том, что это работает только для первой вложенной записи. Это может быть связано с динамическим идентификатором, создаваемым fields_for, но я не знаю, как с этим бороться.

Любая помощь будет оценена по достоинству.


В сценарий внесены изменения, и это ответ на мой вопрос.

$("#items").on "change", ".product-select", ->
    product_select = $(this)
    product_select.parent().find('.cost-input').val(product_select.find(':selected').data('unit_cost'))

Спасибо nathanvda за помощь.


person dango    schedule 12.05.2014    source источник


Ответы (1)


Вы используете идентификатор элемента. Предполагается, что он уникален на HTML-странице. Вместо этого вы должны использовать классы.

[ОБНОВЛЕНИЕ] Хорошо. Вы используете глобальные селекторы, поэтому вы изменяете все элементы, имеющие класс.

Я думаю, что вы на самом деле хотите изменить только что вставленные элементы. Как показано в документации, это возможно. Просто пиши

$("#items").on "cocoon:after-insert", (e, added_item) -> 
  added_item.find(".product-select").change ->
    $(this).parent().find(".cost-input").val($(this).selected.data("unit_cost"))

Этот код не проверен, но что я делаю: прикрепляю событие change. В событии изменения используйте $(this), который указывает на контейнер, вызывающий событие, и используйте его как относительную точку для поиска нужного элемента.

Обратите внимание, что это намного проще решить, если вы просто используете jquery.

$('#items").on "change", ".product-select", ->
  product_select = $(this)
  product_select.parent().find('.cost_input').val(product_select.selected().data("unit_cost"))

Это зафиксирует все события change внутри #items, которые происходят с элементом .product-select. Который является динамическим, поэтому он будет работать и для недавно добавленных элементов. Возможно, вам придется немного повозиться с jquery, чтобы найти выбранное значение. Как я уже сказал: непроверенный код, но я надеюсь, что вы поняли суть.

person nathanvda    schedule 13.05.2014
comment
Привет, спасибо за ответ. Я изменил его на класс (см. отредактированный код), теперь вторая строка unit_cost имеет то же значение, что и первая. Так же и третий и так далее. - person dango; 13.05.2014
comment
Второй - ответ. Большое спасибо! Я также добавил скрипт для тех, у кого может быть похожая проблема. - person dango; 14.05.2014