At peopleforce.io we try to stick to as close as possible to the recommended Rails technologies available. This includes Stimulus JS to help separate common behaviours into their own controllers across views.
For our data pickers we decided to use flatpickr which we found to be the most flexible datepicker available in terms of configuration options and features.
Below is our implementation of how we extracted Flatpickr to be used across all our Rails forms with support of different date formats and I18n.
.erb
<%= f.date_picker_field :date_of_birth %>
application_form_builder.rb
class ApplicationFormBuilder < ActionView::Helpers::FormBuilder
def date_picker_field(method, options = {})
options[:class] = options[:class] || "form-control "
options[:placeholder] = Current.user.settings.date_format
options[:data] = {"target" => "date-picker.picker"}
options[:autocomplete] = "off"
options[:required] = options[:required] if options[:required]
inner_tags = @template.text_field_tag(method, (options.has_key?(:value) ? options[:value] : object.send(method)), options)
inner_tags << @template.hidden_field(@object_name, method, {
value: (options.has_key?(:value) ? options[:value] : object.send(method).try(:strftime, "%F")),
data: {target: "date-picker.input"}
})
return @template.content_tag(:div, inner_tags, {data: {controller: "date-picker"}})
end
end
date_picker_controller.js
// LOCALE - global variable for preferred user language. eg. "en", "es", "ru"
// DATE_FORMAT - global variable for user preferred date format. eg. 'DD-MM-YYYY'
import {Controller} from "stimulus"
import flatpickr from "flatpickr";
import "flatpickr/dist/l10n/ru.js"
import "flatpickr/dist/l10n/uk.js"
import moment from "moment";
flatpickr.l10ns.en.firstDayOfWeek = 1;
export default class extends Controller {
static targets = ["input", "picker"]
initialize() {
let controller = this;
var DATE_FORMATS = {
"YYYY-MM-DD": "Y-m-d",
"DD.MM.YYYY": "d.m.Y",
"DD/MM/YYYY": "d/m/Y",
"MM.DD.YYYY": "m.d.Y",
"MM/DD/YYYY": "m/d/Y"
}
let flatPicker = flatpickr(this.pickerTarget, {
"dateFormat": DATE_FORMATS[DATE_FORMAT],
"locale": LOCALE,
allowInput: true,
onClose: (selectedDates, dateStr, instance) => {
if (dateStr == "") {
controller.inputTarget.value = "";
instance.clear();
} else {
let d = instance.parseDate(controller.pickerTarget.value, DATE_FORMATS[DATE_FORMAT]);
flatPicker.setDate(d);
controller.inputTarget.value = moment(d).format("YYYY-MM-DD");
controller.pickerTarget.value = instance.formatDate(d, DATE_FORMATS[DATE_FORMAT]);
}
}
});
}
}
Top comments (1)
Hey
you might want to check github.com/adrienpoly/stimulus-fla... and a detailed article
There is a built in strftime format converter to Flatpickr Date/Time model. This can avoid loading the costly moment library
happy Stimulus