Hotwire 模态表单无法正确呈现 Flatpickr
Hotwire Modal Form Not Rendering Flatpickr Correctly
我有一个模态表单,可以很好地通过热线创建新的详细记录。这些字段中有 flatpickr 日期字段和两个 flatpickr 时间字段。如果我有验证错误表单呈现,错误显示在模态内部,但 flatpickr 输入被重置为没有 flatpickr 作为文本字段。当显示验证错误时,如何确保它再次呈现 flatpickr 字段?
控制器创建:
def create
@detail = Detail.new(detail_params)
@detail.user_id = current_user.id
respond_to do |format|
if @detail.save
format.html { redirect_to details_path, notice: "Detail was successfully created." }
format.json { render :show, status: :created, location: @detail }
else
format.turbo_stream
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @detail.errors, status: :unprocessable_entity }
end
end
end
create.turbo_stream.erb
<%= turbo_stream.replace "new_detail", partial: "details/form", locals: { detail: @detail } %>
形式:
<%= form_with(model: detail, id: dom_id(detail)) do |form| %>
<div class="modal-header">
<h1 class="h3" id="exampleModalLabel">Post New Detail</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<% if detail.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(detail.errors.count, "error") %> prohibited this detail from being saved:</h2>
<ul>
<% detail.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<form>
<div class="mb-3">
<label class="form-label">Name</label>
<%= form.text_field :name, class: 'form-control', id: 'floatingInput1' %>
</div>
<div class="mb-3">
<label class="form-label">Description</label>
<%= form.text_field :description, class: 'form-control', id: 'floatingInput2' %>
</div>
<div class="mb-3">
<label class="form-label">Date</label>
<%= form.text_field :detail_date, class: 'form-control', id: 'floatingInput3', data: { behavior: "flatpickr" } %>
</div>
<div class="mb-3">
<label class="form-label">Start Time</label>
<%= form.text_field :start_time, class: 'form-control flatpickr1', id: 'floatingInput4', data: { behavior: "flatpickr1" } %>
</div>
<div class="mb-3">
<label class="form-label">End Time</label>
<%= form.text_field :end_time, class: 'form-control flatpickr2', id: 'floatingInput5', data: { behavior: "flatpickr2" } %>
</div>
</div>
<div class="modal-footer">
<%= form.submit class: 'btn btn-primary' %>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
</div>
</form>
<script>
$( '.flatpickr1' ).flatpickr({
enableTime: true,
noCalendar: true,
dateFormat: "H:i",
time_24hr: true
});
$( '.flatpickr2' ).flatpickr({
enableTime: true,
noCalendar: true,
dateFormat: "H:i",
time_24hr: true
});
</script>
<% end %>
我认为您的问题是您在 script
标记内调用了 flatpickr。最好将这些调用移动到 Stimulus 控制器(旨在与 Turbo 集成)或 Turbo 事件侦听器内部。基本上这只是一个时间问题,并且有特定于 Turbo 的方法告诉页面在正确的时间加载 JS。
Stimulus 控制器会非常简单。类似于:
new controller file, e.g. test_controller.js
import { Controller } from "stimulus"
export default class extends Controller {
connect() {
// call flatpickr here
}
}
then in form.html.erb, add the stim controller to the form element
<form data-controller="test">
...
</form>
事件侦听器与提到的类似 。
document.addEventListener("turbo:before-fetch-response", function (e) {
// call flatpickr here
})
我有一个模态表单,可以很好地通过热线创建新的详细记录。这些字段中有 flatpickr 日期字段和两个 flatpickr 时间字段。如果我有验证错误表单呈现,错误显示在模态内部,但 flatpickr 输入被重置为没有 flatpickr 作为文本字段。当显示验证错误时,如何确保它再次呈现 flatpickr 字段?
控制器创建:
def create
@detail = Detail.new(detail_params)
@detail.user_id = current_user.id
respond_to do |format|
if @detail.save
format.html { redirect_to details_path, notice: "Detail was successfully created." }
format.json { render :show, status: :created, location: @detail }
else
format.turbo_stream
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @detail.errors, status: :unprocessable_entity }
end
end
end
create.turbo_stream.erb
<%= turbo_stream.replace "new_detail", partial: "details/form", locals: { detail: @detail } %>
形式:
<%= form_with(model: detail, id: dom_id(detail)) do |form| %>
<div class="modal-header">
<h1 class="h3" id="exampleModalLabel">Post New Detail</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<% if detail.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(detail.errors.count, "error") %> prohibited this detail from being saved:</h2>
<ul>
<% detail.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<form>
<div class="mb-3">
<label class="form-label">Name</label>
<%= form.text_field :name, class: 'form-control', id: 'floatingInput1' %>
</div>
<div class="mb-3">
<label class="form-label">Description</label>
<%= form.text_field :description, class: 'form-control', id: 'floatingInput2' %>
</div>
<div class="mb-3">
<label class="form-label">Date</label>
<%= form.text_field :detail_date, class: 'form-control', id: 'floatingInput3', data: { behavior: "flatpickr" } %>
</div>
<div class="mb-3">
<label class="form-label">Start Time</label>
<%= form.text_field :start_time, class: 'form-control flatpickr1', id: 'floatingInput4', data: { behavior: "flatpickr1" } %>
</div>
<div class="mb-3">
<label class="form-label">End Time</label>
<%= form.text_field :end_time, class: 'form-control flatpickr2', id: 'floatingInput5', data: { behavior: "flatpickr2" } %>
</div>
</div>
<div class="modal-footer">
<%= form.submit class: 'btn btn-primary' %>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
</div>
</form>
<script>
$( '.flatpickr1' ).flatpickr({
enableTime: true,
noCalendar: true,
dateFormat: "H:i",
time_24hr: true
});
$( '.flatpickr2' ).flatpickr({
enableTime: true,
noCalendar: true,
dateFormat: "H:i",
time_24hr: true
});
</script>
<% end %>
我认为您的问题是您在 script
标记内调用了 flatpickr。最好将这些调用移动到 Stimulus 控制器(旨在与 Turbo 集成)或 Turbo 事件侦听器内部。基本上这只是一个时间问题,并且有特定于 Turbo 的方法告诉页面在正确的时间加载 JS。
Stimulus 控制器会非常简单。类似于:
new controller file, e.g. test_controller.js
import { Controller } from "stimulus"
export default class extends Controller {
connect() {
// call flatpickr here
}
}
then in form.html.erb, add the stim controller to the form element
<form data-controller="test">
...
</form>
事件侦听器与提到的类似
document.addEventListener("turbo:before-fetch-response", function (e) {
// call flatpickr here
})