Give Your Dates: Ruby on Rails 6 With Webpacker
A tutorial to get Bootstrap, jQuery and flatpickr working on Rails 6 with Webpacker.
Join the DZone community and get the full member experience.
Join For FreeAll Rails applications I had built and maintained so far were on RoR version 4. A hobby project that I had started recently was on Ruby on Rails 6 with webpacker, which is the JavaScript scripts, styles, and assets bundler.
I wanted to add Bootstrap, then code a form that has two date picker fields and two submit buttons with tool tip text. Pretty simple requirement, right? Ideally, it should have taken me just a few minutes to get it working. But turns out, I had to spend 2-3 hours. In this era of online documentation, Googling and stackoverflowing is an atrocious waste of time. Hence this article, so others can implement similar requirements in just a few minutes.
For the datepicker, I chose flatpickr.
Here are the steps:
- Run the following command in your project folder:
$ yarn add bootstrap jquery popper.js flatpickr
- Create the file application.scss and import the required css files.
- In application.js, add require bootstrap, flatpickr and add event handler actions for the buttons' tooltips and flatpickr instantiation.
- Write some pre-pending jabberwocky in environment.js
- Code the rails form with text_field_tag and submit_tag with proper attributes.
The controller method process_dates checks params[:commit] to find which button was clicked and takes appropriate action. Code blocks for steps 2 - 5 are given below:
app/javascript/stylesheets/application.scss
xxxxxxxxxx
@import "bootstrap/scss/bootstrap";
@import "flatpickr/dist/flatpickr.css";
app/javascript/packs/application.js
xxxxxxxxxx
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require("bootstrap")
require("flatpickr")
import flatpickr from "flatpickr";
document.addEventListener("turbolinks:load", () => {
$('[data-tooltip-display="true"]').tooltip(),
flatpickr("[class='flatpickr']", {})
})
// stylesheets
require("../stylesheets/application.scss")
config/webpack/environment.js
xxxxxxxxxx
const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
environment.plugins.append('Provide', new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
Popper: ['popper.js', 'default']
}))
module.exports = environment
app/views/application/_form.html.erb
xxxxxxxxxx
<div class="container bg-primary">
<h1>Give Your Dates</h1>
<%= form_with(url: "/process_dates") do %>
<div class="row">
<div class="border">
<%= text_field_tag 'first_date', "Select Date One", class: 'flatpickr' %>
</div>
<div class="col-md-auto"> </div>
<div class="border">
<%= text_field_tag 'second_date', "Select Date Two", class: 'flatpickr' %>
</div>
</div>
<div class="row"><div> </div></div>
<div class="row">
<div>
<%= submit_tag("Hist", class: "btn btn-secondary", data: {tooltip_display: :true, placement: :bottom}, title: "Historical Events") %>
</div>
<div class="col-md-auto"> </div>
<div>
<%= submit_tag("Diff", class: "btn btn-secondary", data: {tooltip_display: :true, placement: :bottom}, title: "Difference in days") %>
</div>
</div>
<div class="col-md-auto"> </div>
<% end %>
</div>
For the sake of giving a complete use case, I added a little fun feature. On clicking the first button titled ‘Hist’, the action ‘process_dates’ validates the flatpickr entries for proper dates and then calls curl on the year and date APIs of numbersapi.com to fetch historical events that happened on the date(s). Of course, in the controller action, I do some text manipulation to give a better display on the view.
The second button, titled 'Diff', has very simple functionality: if two valid dates are selected, it just gets the number of days between the two dates.
You can grab the complete code from my git repository (here). I have also deployed the application on the web (here), so you can see it working.
For those interested in cloud deployment, here is configuration:
/etc/nginx/nginx.conf
x
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 600;
types_hash_max_size 2048;
fastcgi_read_timeout 600;
proxy_read_timeout 600;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
/etc/nginx/sites-enabled/rails6-bootstrap-flatpickr
xxxxxxxxxx
server {
listen 80;
listen [::]:80;
server_name _;
root /var/www/rails6-bootstrap-flatpickr/public;
passenger_enabled on;
passenger_app_env development;
location /* {
try_files $uri $uri/ =404;
proxy_read_timeout 600;
proxy_connect_timeout 600;
proxy_send_timeout 600;
send_timeout 600;
}
location ~ ^/(assets|packs) {
expires max;
gzip_static on;
}
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
Opinions expressed by DZone contributors are their own.
Comments