【问题标题】:Adding/Removing Cocoon Nested Fields添加/删除 Cocoon 嵌套字段
【发布时间】:2019-11-15 22:23:34
【问题描述】:

我正在使用令人敬畏的 gem Cocoon 根据用户可以选择的“长度”值生成嵌套字段。我的问题是我需要找到一种方法来检查有多少嵌套字段已经添加到表单中,然后只添加当前不在表单中的字段。例如:

一个用户的长度值设置为 2,有 2 组嵌套字段形成它们可以使用。现在用户想要将他们的值更改为 3,这就是我遇到困难的地方。我不完全确定如何根据更改的值添加/删除字段,而不仅仅是删除所有字段并重新运行嵌套字段插入。以下是一些代码供参考:

HTML

<div class="row px-md-4">
  <div class="col-12">
    <div class="d-flex flex-column pb-3">
      <h2 class="f-500 dark_grey_text pt-3" style="font-size:1.8em;">Itinerary Details</h2>
      <p class="f-300">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    </div>
  </div>
  <div class="col-12 py-3">
    <div class="form-group">
      <h6>Set your length</h6>
      <%= f.number_field :length, placeholder:"How many days is your adventure?", value: number_with_precision(f.object.length, precision: 2), step: 1, class: 'stepper_navtext form-control', id: 'length' %>
    </div>
  </div>

  <div class="col-12 py-3">
    <div class="form-row mb-3" id="days">
      <div class="nav nav-pills" id="tab-menu" role="tablist">

      </div>

      <div class="tab-content" id="itinerary-tab-content">

      </div>

        <div id='itineraries' class='w-100 itineraries'>
          <%= f.fields_for :itineraries do |itinerary| %>
            <%= render 'adventure/listings/forms/itinerary_fields', :f => itinerary %>
          <% end %>
          <div class='links'>
            <%= link_to_add_association 'add day', f, :itineraries, partial: 'adventure/listings/forms/itinerary_fields', class:"d-none" %>
          </div>
        </div>
    </div>
  </div>
</div>

JS

$('#length').on('focusin', function(){
    console.log("Saving value " + $(this).val());
    $(this).data('val', $(this).val());
});

$( "#length" ).change(function() {

      var prev = $(this).data('val');
      var current = $(this).val();
      console.log("Prev value " + prev);
      console.log("New value " + current);

      $('#tab-menu').empty();

      $('.nested-fields').remove();

      let days = $('#length').val();
      var i;
      var counter = current - prev;
      console.log('The difference is' + counter);
      var text_max = 40;

      for (i = 0; i < days; i++) {
        var new_id;
        $(".links").find(">:first-child").trigger("click");
      }  ...

我找到的唯一解决方案是清除表单中的所有字段,并重新生成对 Cocoon 中添加关联按钮的点击。对我来说,这一切似乎都很老套,我认为我这样做的方式不正确:/。任何建议将不胜感激!

【问题讨论】:

  • 你在使用turbolinks吗?
  • 我为受影响的部分关闭了 turbolinks。我认为我最大的问题是如何使用数学/代码块来检查现有字段的概念,并且仅根据更改的值差异添加/删除。

标签: jquery ruby-on-rails cocoon-gem


【解决方案1】:

您非常接近恕我直言,所以我想知道是什么阻碍了您实际找到解决方案。所以让我先用伪代码解释一下(当某些问题似乎无法解决时,这总是对我有帮助):

  • 长度变化时
  • 检查长度是如何变化的
  • 如果长度增加:添加字段
  • 如果减少:从后面删除字段

所以在代码中,可能看起来像

$( "#length" ).change(function() 
  var prev = $(this).data('val');
  var current = $(this).val();

  if (current > prev) {
    var days_to_add = current - prev; 
    for (i = 0; i < days_to_add; i++) {
      $(".links").find(">:first-child").trigger("click");
    }  
  } else {
    var days_to_remove = prev - current; 
    for (i = 0; i < days_to_remove; i++) {
      $('#itineraries .nested-fields').last().remove();  
    }  
  }

我不完全确定您的prev / current 是否设置正确,除非您设置了data('val'),但由于prev 只是当前可见的日期,您也可以执行以下操作:

var prev = $("#itineraries .nested-fields:visible').length; 
var current = $this.val();

(为什么使用:visible?因为如果您还允许在编辑时删除字段,我们必须“隐藏”该字段而不是仅仅删除它们)

这提醒了我:如果您确实显示link_to_remove_association,最好单击它,或者如果您将其添加为“隐藏”,因为这样可以保持您的表单正确。这仅适用于您还允许编辑现有表单的情况,因为在这种情况下,我们需要保留带有 _destroy 标志集的嵌套子级,因此 rails 可以在保存表单时将其销毁。

【讨论】:

  • 谢谢!!这极大地帮助了我,尤其是伪代码部分真正理解了我试图采取的步骤。当我将每个嵌套字段设置到选项卡/窗格引导设置中时,我必须进行一些调整,因此默认情况下它们是不可见的。接下来我将尝试编辑设置,但仍需要在文档中阅读该过程:)。再次感谢您制作出色的宝石并为社区提供了如此多的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多