我正在使用真棒宝石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对添加关联按钮的点击。对我来说,这似乎是一个小问题,我认为我的做法不正确:/。任何建议将不胜感激!
您非常接近我,所以我想知道是什么使您无法真正找到解决方案。因此,让我首先用伪代码进行解释(当某些问题似乎无法解决时,这总是对我有帮助):
因此在代码中,可能看起来像
$( "#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在保存表单时可以销毁它。