Mark Thomas Miller's logo

Adding a datetime picker to Ruby on Rails

October 20, 2018

When you need to incorporate a datetime picker in a Rails 5 application, you can use the flatpickr_rails gem. It's based around flatpickr, a project with 10,000+ stars on GitHub, requires no dependencies, and has well-documented configuration options. Not to mention a polished design and multiple themes.

Here's how to incorporate it in your Rails 5 application:

  1. If you haven't already, run a migration to generate a field with the type of datetime. Then run rails db:migrate.

  2. Add flatpickr_rails to your Gemfile.

  3. Run bundle install.

  4. Add this line to app/assets/stylesheets/application.css.

    *= require flatpickr
    
  5. Add this line to app/assets/javascripts/application.js:

    //= require flatpickr
    
  6. Restart your server.

  7. Add your input field to the form. Change foo to the name of your input, and change bar to the ID you want to use to create flatpickr's instance in the next step:

    <%= form.label :foo %><br>
    <%= form.text_field :foo, id: 'bar' %>
    <!--
    If you're retrieving a value from your controller:
    <%= form.text_field :foo, value: @date, id: 'bar' %>
    -->
    
  8. Add your JS. Change bar to your ID from Step 7.

    <script type="text/javascript">
      const el = document.getElementById('bar');
      flatpickr(el);
    </script>
    
  9. If you want to configure flatpickr, pass a configuration object as the second param:

    <script type="text/javascript">
      const el = document.getElementById('bar');
      flatpickr(el, {
        // flatpickr.js.org/options
      });
    </script>
    
  10. The Rails database saves in the UTC format (i.e. 2020-01-01 15:00:00 -0400), but your users would punch you in the face if you used that, so let's make it easier to read. Let's also apply a minimum date of today and a default minute/hour.

    <script type="text/javascript">
      const el = document.getElementById('bar');
      flatpickr(el, {
        enableTime:      true,
        altInput:        true,
        minDate:         "today",
        altFormat:       "F j, Y at h:i K",
        dateFormat:      "Y-m-d H:i",
        defaultHour:     23,
        defaultMinute:   59,
        minuteIncrement: 1
      });
    </script>
    

Congratulations, you now have a working datetime picker!