在编辑操作中使用茧时如何实现 flatpickr?
How to implement flatpickr when using cocoon in edit action?
我正在使用嵌套茧形式的 flatpickr 日历。创建新表单时一切正常,但当我想编辑现有表单时:
- 第一个 flatpickr 字段正确呈现
- 添加一个带有 cocoon 的新 flatpickr 字段可以正确渲染
- 第一个 之后的所有其他现有 flatpickr 字段不会 呈现。
edit_form
<div class="form-container col col-sm-6 col-lg-12">
<%= simple_form_for [@accommodation_category, @extra_guest] do |f|%>
<div class="options-form">
<div class="options-form-item">
<h4 class="p-3">Price for guest per period:</h4 class="m-3">
<%= f.simple_fields_for :extra_guest_prices do |price| %>
<div class="reservation-details">
<%= render 'extra_guest_price_fields', f: price %>
</div>
<% end %>
<div>
<%= link_to_add_association f, :extra_guest_prices do %>
<div class="option-add-option-price">
<div class="prices-border">
<i class="fas fa-plus"></i> Add another period
</div>
</div>
<% end %>
</div>
<div class="row">
<div class="col col-sm-6"> <%= f.button :submit, "Save new option", class: "create-reservation-btn"%>
</div>
</div>
<% end %>
</div>
</div>
</div>
</div>
javascript 对于 edit_form
<script>
$(document).ready(function(){
const startDateInput = $(document).find("#first_date")
const endDateInput = $(document).find("#second_date")
if (startDateInput && endDateInput) {
flatpickr(startDateInput, {
format: "d-m-Y",
altFormat: "d-m-Y",
altInput: true,
onChange: function(selectedDates, selectedDate) {
if (selectedDate === '') {
endDateInput.disabled = true;
}
let minDate = selectedDates[0];
minDate.setDate(minDate.getDate() + 1);
endDateCalendar.set('minDate', minDate);
endDateInput.disabled = false;
}
});
const endDateCalendar =
flatpickr(endDateInput, {
format: "d-m-Y",
altFormat: "d-m-Y",
altInput: true,
},
);
};
});
</script>
extra_guest_price_fields
<div class="nested-fields border-bottom">
<div class="row">
<div class="col col-sm-6"><%= f.input :price, placeholder: "e.g. 12.99" %></div>
<div class="col col-sm-6"><%= f.input :weekend_extra, placeholder: "Price on top of normal price" %></div>
</div>
<div class="row">
<div class="col col-sm-6"><%= f.input :start_date,
as: :string,
label:"Start date",
placeholder: "From",
wrapper_html: { class: "inline_field_wrapper" },
input_html:{ id: "first_date"} %></div>
<div class="col col-sm-6"><%= f.input :end_date,
as: :string,
label:"End date",
placeholder: "to",
wrapper_html: { class: "inline_field_wrapper" },
input_html:{ id: "second_date"} %></div>
</div>
<div class="col col-sm-6 option-price-delete">
<%= link_to_remove_association f do %>
<i class="fas fa-trash"> Delete price</i>
<% end %>
</div>
</div>
<script>
$(document).on('cocoon:after-insert', function(e, added_guest_price_form){
const startDateInput = $(added_guest_price_form.find("#first_date"))
const endDateInput = $(added_guest_price_form.find("#second_date"))
if (startDateInput && endDateInput) {
flatpickr(startDateInput, {
format: "d-m-Y",
altFormat: "d-m-Y",
altInput: true,
onChange: function(selectedDates, selectedDate) {
if (selectedDate === '') {
endDateInput.disabled = true;
}
let minDate = selectedDates[0];
minDate.setDate(minDate.getDate() + 1);
endDateCalendar.set('minDate', minDate);
endDateInput.disabled = false;
}
});
const endDateCalendar =
flatpickr(endDateInput, {
format: "d-m-Y",
altFormat: "d-m-Y",
altInput: true,
},
);
};
});
</script>
因为你没有显示部分 extra_guest_price_fields
我只能猜测,但在你的 js 中你指的是 #first_date
和 #second_date
。这听起来像是对重复元素使用 html-ids,因为你肯定会有不止一对这样的元素。 HTML ID 应该在一个页面上只存在一次,因此使用该选择器它将在第一个找到时停止。
我建议你像 .first_date
和 .second_date
一样使用 html 类 并相应地调整你的 js 然后它应该工作。
我正在使用嵌套茧形式的 flatpickr 日历。创建新表单时一切正常,但当我想编辑现有表单时:
- 第一个 flatpickr 字段正确呈现
- 添加一个带有 cocoon 的新 flatpickr 字段可以正确渲染
- 第一个 之后的所有其他现有 flatpickr 字段不会 呈现。
edit_form
<div class="form-container col col-sm-6 col-lg-12">
<%= simple_form_for [@accommodation_category, @extra_guest] do |f|%>
<div class="options-form">
<div class="options-form-item">
<h4 class="p-3">Price for guest per period:</h4 class="m-3">
<%= f.simple_fields_for :extra_guest_prices do |price| %>
<div class="reservation-details">
<%= render 'extra_guest_price_fields', f: price %>
</div>
<% end %>
<div>
<%= link_to_add_association f, :extra_guest_prices do %>
<div class="option-add-option-price">
<div class="prices-border">
<i class="fas fa-plus"></i> Add another period
</div>
</div>
<% end %>
</div>
<div class="row">
<div class="col col-sm-6"> <%= f.button :submit, "Save new option", class: "create-reservation-btn"%>
</div>
</div>
<% end %>
</div>
</div>
</div>
</div>
javascript 对于 edit_form
<script>
$(document).ready(function(){
const startDateInput = $(document).find("#first_date")
const endDateInput = $(document).find("#second_date")
if (startDateInput && endDateInput) {
flatpickr(startDateInput, {
format: "d-m-Y",
altFormat: "d-m-Y",
altInput: true,
onChange: function(selectedDates, selectedDate) {
if (selectedDate === '') {
endDateInput.disabled = true;
}
let minDate = selectedDates[0];
minDate.setDate(minDate.getDate() + 1);
endDateCalendar.set('minDate', minDate);
endDateInput.disabled = false;
}
});
const endDateCalendar =
flatpickr(endDateInput, {
format: "d-m-Y",
altFormat: "d-m-Y",
altInput: true,
},
);
};
});
</script>
extra_guest_price_fields
<div class="nested-fields border-bottom">
<div class="row">
<div class="col col-sm-6"><%= f.input :price, placeholder: "e.g. 12.99" %></div>
<div class="col col-sm-6"><%= f.input :weekend_extra, placeholder: "Price on top of normal price" %></div>
</div>
<div class="row">
<div class="col col-sm-6"><%= f.input :start_date,
as: :string,
label:"Start date",
placeholder: "From",
wrapper_html: { class: "inline_field_wrapper" },
input_html:{ id: "first_date"} %></div>
<div class="col col-sm-6"><%= f.input :end_date,
as: :string,
label:"End date",
placeholder: "to",
wrapper_html: { class: "inline_field_wrapper" },
input_html:{ id: "second_date"} %></div>
</div>
<div class="col col-sm-6 option-price-delete">
<%= link_to_remove_association f do %>
<i class="fas fa-trash"> Delete price</i>
<% end %>
</div>
</div>
<script>
$(document).on('cocoon:after-insert', function(e, added_guest_price_form){
const startDateInput = $(added_guest_price_form.find("#first_date"))
const endDateInput = $(added_guest_price_form.find("#second_date"))
if (startDateInput && endDateInput) {
flatpickr(startDateInput, {
format: "d-m-Y",
altFormat: "d-m-Y",
altInput: true,
onChange: function(selectedDates, selectedDate) {
if (selectedDate === '') {
endDateInput.disabled = true;
}
let minDate = selectedDates[0];
minDate.setDate(minDate.getDate() + 1);
endDateCalendar.set('minDate', minDate);
endDateInput.disabled = false;
}
});
const endDateCalendar =
flatpickr(endDateInput, {
format: "d-m-Y",
altFormat: "d-m-Y",
altInput: true,
},
);
};
});
</script>
因为你没有显示部分 extra_guest_price_fields
我只能猜测,但在你的 js 中你指的是 #first_date
和 #second_date
。这听起来像是对重复元素使用 html-ids,因为你肯定会有不止一对这样的元素。 HTML ID 应该在一个页面上只存在一次,因此使用该选择器它将在第一个找到时停止。
我建议你像 .first_date
和 .second_date
一样使用 html 类 并相应地调整你的 js 然后它应该工作。