Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Introducing Stimulus-Flatpickr wrapper 📅
Adrien Poly
Adrien Poly

Posted on

     

Introducing Stimulus-Flatpickr wrapper 📅

I really enjoyed usingStimulus JS since it has been released early this year. For once I can now easily organize my JS code without pulling a full-blown frontend framework.

Stimulus-flatpickr wrapper started as an experiment, I needed to use Flatpickr in a project and built a Stimulus Controller for it. I quickly realized that it could make sense to have a generic Stimulus controller for this library.

Today we will demonstrate this package through a simple, yet interesting example. I have worked quite a bit recently with date pickers and realized that it is always very simple to convert a field to a date pickers but they are many small details required to make it a real easy to use solution.

The goal is to create a basic booking system where the user:

  • can only select available dates (the ones already booked must be disabled)
  • gets a datepicker in his language
  • see a date in the input field in the locale format
  • see a list of all bookings
  • all of this playing nicely in a Single Page Application

the stack is rather simple: Rails, Stimulus, Turbolinks, and Flatpickr for the date picking solution.

At the end we won't have any Ajax at all and less than 10 lines of Javascript to do this 🎉🎉🎉

Lets get started: New app and stimulus setup

They are several tutorials out there, I won't get into all the details but settings up Stimulus in your Rails app if you already have webpack installed is as simple as that:

rails webpacker:install:stimulus
Enter fullscreen modeExit fullscreen mode

This will add Stimulus package to yourpackage.json, adds the initialization code in your mainapplication.js file and a new controllers directory under javascript for all of your newStimulus controllers

You can read this article for more details aboutsetting up Stimulus in your rails

For today's demo, we are going to create a brand new app

  rails new--webpack=stimulus stimulus-flatpickr
Enter fullscreen modeExit fullscreen mode

...and don't forget to add the packs

  #app/views/layouts/application.html.erb  ...<%=stylesheet_pack_tag'application',media:'all','data-turbolinks-track':'reload'%><%=javascript_pack_tag'application','data-turbolinks-track':'reload'%>  ...
Enter fullscreen modeExit fullscreen mode

Appointment Model and Controller

We are doing a booking engine. We need an Appointment model with a single column a start_at date and ascope method to get theup_comings appointments for the next n days (we can only book for the next 60 days).

#models/appointment.rbclassAppointment<ApplicationRecordvalidates:start_at,uniqueness:truescope:up_comings,->(nb_days){where('start_at >= ? AND start_at < ?',Time.zone.now,Time.zone.now+nb_days.days).order(start_at: :asc)}end
Enter fullscreen modeExit fullscreen mode

Our controller is pretty standard (for simplicity we only handle the success path here 👶, no error managment)

classAppointmentsController<ApplicationControllerbefore_action:set_appointment,only:%i[update destroy]defindex@appointments=Appointment.up_comings(60)@appointments_dates=@appointments.pluck(:start_at)@appointment=Appointment.newenddefcreateredirect_toappointments_pathifAppointment.create(appointment_params)enddefupdateredirect_toappointments_pathif@appointment.update(appointment_params)enddefdestroy@appointment.destroyredirect_toappointments_pathendprivatedefset_appointment@appointment=Appointment.find(params[:id])enddefappointment_paramsparams.require(:appointment).permit(:start_at)endend
Enter fullscreen modeExit fullscreen mode

stimulus-flatpickr controller

As per thedocumentation we are going to create a Stimulus controller that will extend the generic stimulus-flatpickr controller.

First, let's add the packages that we will need

  yarn add stimulus-flatpickr
Enter fullscreen modeExit fullscreen mode

and add the new controller

// ./controllers/flatpickr_controller.jsimportFlatpickrfrom"stimulus-flatpickr";import"flatpickr/dist/themes/dark.css";// creates a new Stimulus controller by extending stimulus-flatpickr wrapper controllerexportdefaultclassextendsFlatpickr{}
Enter fullscreen modeExit fullscreen mode

The views

Lets put a small structure to have the booking form on the left and the up comings appointments list on the right.

#app/views/appointments/index.html.erb<divclass="main"><h2><%=t".title"%></h2><divclass="row"><divclass="col"><h3><%=t".new"%></h3><%=render"form",appointment:@appointment%></div><divclass="col"><h3><%=t".appointments"%></h3><%=render@appointments%></div></div></div>#app/views/appointments/_appointment.html.erb<divclass="appointments"><%=render"form",appointment:appointment%><%=link_to"x",appointment_path(appointment),method: :delete%></div>
Enter fullscreen modeExit fullscreen mode

and our form where all the magic will happen 🎉

#app/views/appointments/_form.html.erb<%=form_withmodel:appointmentdo|f|%><%=f.text_field:start_at,data:{controller:"flatpickr",flatpickr_min_date:Time.zone.now,flatpickr_max_date:Time.zone.now+60.days,flatpickr_disable:Appointment.up_comings(60).pluck(:start_at),}%><%end%>
Enter fullscreen modeExit fullscreen mode

This is the important part to understand :

We defined aflatpickr_controller.js so whenever an HTML element has adata-controller="flatpickr" attribute, then the stimulus controller will enter into action.

So here in the view,data: { controller: "flatpickr" } will be converted todata-controller="flatpickr" and therefore convert the field into a datepicker.

We can also pass options to the datepicker using the same data attributes(data-flatpickr-the-kebab-case-option-name). Here we set a min and max date to disable everything before today and everything after today + 60 days.

Also, we prepare for the next step where we will disable the dates that are already booked by passing an array of the current bookings.

Submit on select

Lets automatically submit whenever a user selects a date (not perfect UX! I know, it is mostly for simple demo purpose).
The flatpickr controller has all the official flatpickr hooks available (open, close, change etc). Here we need to submit the form when the value has changed. So let's override thechange() function.

exportdefaultclassextendsFlatpickr{// automatically submit form when a date is selectedchange(selectedDates,dateStr,instance){constform=this.element.closest("form");Rails.fire(form,"submit");}}
Enter fullscreen modeExit fullscreen mode

Going Live

At this point we have the following result:

stimulus-flatpickr demo

We start to have something interactive.... The cool thing is that Turbolinks being installed by default kicks in automatically andAjaxify all links. All Stimulus controllers are by designed working with Turbolinks.So there is nothing else to do here, it just works!. No custom Ajax call or SRJ to have this SPA look and feel. 💪 🚀 ❤️

Localizing the date picker and the date format

We have a SPA look & feel and the availabilities for our booking engine. The next step is to localize it correctly. Currently, it is only in English and the date format if rather ugly2018-09-12 👎.

date formats

The stimulus-flatpickr wrapper offers a nicebonus feature over the standard library, it will convertstrftime date formats to flatpickr custom date formats.

So to customize the date format we can pass the local format directly to the date picker like this:

data:{controller:"flatpickr",flatpickr_alt_input:true,flatpickr_alt_format:t("date.formats.long"),flatpickr_default_date:appointment.start_at,flatpickr_disable:@appointments_dates-[appointment.start_at],flatpickr_min_date:Time.zone.now,flatpickr_max_date:Time.zone.now+60.days,}
Enter fullscreen modeExit fullscreen mode

flatpickr_alt_format: t("date.formats.long") -> will output"%B %d, %Y" when the locale is:en and"%e %B %Y" when the locale is:fr and this gets converted automatically to the nearest flatpickr format. As DRY as it can be 🎉!

Translations

We now have almost everything. The last point is to correctly translate the datepicker for every locale.

We are going to import the different locales in our stimulus controller. Every time time Turbolinks silently replace the content of the page, theinitialize() function is of the stimulus controller is called. This is where we are going to set our local and pass it to flatpickr.

Our final controller looks like this

importFlatpickrfrom"stimulus-flatpickr";// import a theme (could be in your main CSS entry too...)import"flatpickr/dist/themes/dark.css";// import the translation files and create a translation mappingimport{French}from"flatpickr/dist/l10n/fr.js";import{english}from"flatpickr/dist/l10n/default.js";// create a new Stimulus controller by extending stimulus-flatpickr wrapper controllerexportdefaultclassextendsFlatpickr{locales={fr:French,en:english};initialize(){//set the locale and also sets the global flatpickr settingsthis.config={locale:this.locale,altInput:true,showMonths:2,animate:false};}// automatically submit form when a date is selectedchange(selectedDates,dateStr,instance){constform=this.element.closest("form");Rails.fire(form,"submit");}getlocale(){if(this.data.has("locale")){returnthis.locales[this.data.get("locale")];}}}
Enter fullscreen modeExit fullscreen mode

That's all folks!

stimulus-flatpickr demo

You can find the entire demo project here 👉https://github.com/adrienpoly/rails_stimulus_flatpickr

and more important the stimulus-flatpickr wrapper 👉https://github.com/adrienpoly/stimulus-flatpickr

I hope you enjoyed this introduction. I personally think we will see more and more standard Stimulus controllers and the Rails community will more and more drop Gems used for front end packages only.

I am not senior dev with tons of experience so feel free toComments, issues, PR. They are all welcome and if you feel this package is useful for you, leave it a star ⭐

Happy Coding 🎉

Top comments(2)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
charliechin profile image
Charliechin
  • Joined

Thanks a lot for this post. It really helped!

CollapseExpand
 
bdjohnson529 profile image
bdjohnson529
  • Joined

This is huge! Thank you!

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

CTO @Plume_app, doing mostly Rails and Stimulus stuff. Creator of Stimulus-Use.
  • Location
    Bordeaux France
  • Work
    Freelance
  • Joined

More fromAdrien Poly

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp