我已经奋斗了 3 个小时,因为我在 Stimulus JS 日期选择器控制器中添加了模式:范围,该控制器在显示屏上工作。
但在逻辑上,我不知道如何将简单的表单输入从两个减少到一个,因为在我的预订表上,我有一个 start_date 和 end_date 列,并且我不知道如何提取日期范围以正确分配它。
我的预订表格部分:
<div class="row justify-content-center mt-7">
<div class="col-6 mb-3 form-inline justify-content-center" data-controller="datepicker"
data-datepicker-price-value="<%= @room.price_per_night.to_json %>">
<%= simple_form_for ([ @room, @booking]) do |f| %>
<%= f.error_notification %>
<%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
<div data-controller="datepicker">
<%= f.input :date_range, as: :string, input_html: { data: { datepicker_target: "range", action: "change->datepicker#dateRangeInput" } } %>
</div>
<div class="d-flex col-9 justify-content-between flex-grow-1">
<p> Total price: </p>
<strong data-datepicker-target="price"></strong>
</div>
<div class="col-9 d-flex justify-content-center" >
<%= f.submit "Let's go!", class: "btn btn-primary" , disabled: true, data: { datepicker_target: "confirm" } %>
</div>
<% end %>
</div>
</div>
如图所示,我仅使用一个带有 :date_range 的输入字段,但得到了预期的结果
#
的未定义方法“date_range”
我的 Stimulus JS 控制器:
import { Controller } from "@hotwired/stimulus"
import flatpickr from "flatpickr";
// Connects to data-controller="datepicker"
export default class extends Controller {
static values = {
dates: Array,
price: Number
};
static targets = ["range", "confirm", "price"]
connect() {
console.log("datepicker active")
console.log(this.rangeTarget);
this.endTarget.disabled = true
flatpickr(this.startTarget, {
dateFormat: "d F Y",
disable: this.datesValue,
})
}
DateInput() {
flatpickr(this.endTarget, {
mode: "range",
dateFormat: "d F Y",
disable: this.datesValue,
minDate: this.startTarget.value,
minDate: "today"
})
}
endDateInput() {
let splitStartDate = this.startTarget.value.split("-")
let splitEndDate = this.endTarget.value.split("-")
let startDate = new Date([splitStartDate[1], splitStartDate[0], splitStartDate[2]].join("/"))
let endDate = new Date([splitEndDate[1], splitEndDate[0], splitEndDate[2]].join("/"))
let price = parseInt((endDate - startDate) / (1000 * 60 * 60 * 24), 10) * Number(this.priceValue)
this.priceTarget.innerText = `${price}`
console.log(price)
this.confirmTarget.disabled = false
}
}
由于一些尝试和错误,造成混乱,敬请谅解。
最后,我的预订控制器:
class BookingsController < ApplicationController
before_action :select_room, only: %i[new create edit]
before_action :select_booking, only: %i[edit update destroy]
def new
@booking = Booking.new
end
def create
@booking = Booking.new(booking_params)
@booking.room = @room
@booking.user = current_user
start_date, end_date = params[:booking][:date_range].split(' to ')
@booking.starts_at = Date.parse(start_date)
@booking.ends_at = Date.parse(end_date)
if @booking.save
redirect_to room_path(@room)
else
render 'rooms/show', status: :unprocessable_entity
end
end
def destroy
@booking.destroy
redirect_to pages_dashboard_path
end
private
def select_room
@room = Room.find(params[:room_id])
end
def select_booking
@booking = Booking.find(params[:id])
end
def booking_params
params.require(:booking).permit(:starts_at, :ends_at)
end
end
我尝试更改生成错误的简单表单输入,然后尝试更改控制器来处理这一更改,所有这些都是为了实现只需要一个字段的日期范围。
您的表单 HTML 和激励控制器应类似于以下代码:
_form.html.erb
<%= simple_form_for(@modelname, data: {controller: 'stimulus_controller_name'}) do |form| %>
<%= form.datetime_field :field_name, class: 'date-range' %>
<%= form.button :submit %>
<% end %>
stimulus_controller.js
import { Controller } from "@hotwired/stimulus"
import flatpickr from "flatpickr";
// Connects to data-controller="flatpickr"
export default class extends Controller {
connect() {
console.log('connected')
flatpickr(".date-range", {
mode: "range"
})
}
}
请注意,输入字段类名称应与刺激 flatpickr('.class-name') 匹配,在本例中为日期范围。