Search code examples
ruby-on-railsdayjs

how to add dayjs in ruby on rails application?


I add this https://unpkg.com/dayjs@1.10.4/dayjs.min.js file into javascript/packs and

require("packs/dayjs.min.js")

I'm not sure, maybe I need to load some plugins? I want to know how can I convert datetime attribute for clients in them timezone on a .html.erb? I didn't find any examples of use, I will be glad for any help. in my application.js I want to use something as

$('.timestring').each(function() {
  this.textContent = dayjs(this.textContent).format();
});

but I don't know how to implement it in erb + application.js


Solution

  • My way to add dayjs to Rail 6.1.3, first run commands:

    $ yarn add jquery
    $ yarn add dayjs
    

    Then write this code to config/webpack/environment.js

    const { environment } = require('@rails/webpacker')
    const webpack = require('webpack')
    environment.plugins.prepend('Provide',
      new webpack.ProvidePlugin({
        $: 'jquery/src/jquery',
        jQuery: 'jquery/src/jquery',
        dayjs: 'dayjs/dayjs.min'
      })
    )
    module.exports = environment
    

    And call it to run app/javascript/packs/application.js, all will be ok!

    import Rails from "@rails/ujs"
    import Turbolinks from "turbolinks"
    import * as ActiveStorage from "@rails/activestorage"
    import "channels"
    
    Rails.start()
    Turbolinks.start()
    ActiveStorage.start()
    
    require("jquery")
    require("dayjs")
    
    jQuery(function(){
      alert(dayjs().format('{YYYY} MM-DDTHH:mm:ss SSS [Z] A'))
    })
    

    Bonus, example use javascript function to show local datetime: Create table Event with 2 fields: name:string, starts_at:datetime.

    $ rails generate model Event name:string starts_at:datetime
    $ rails db:migrate
    

    Run rails console to create faker datas for Event model:

    $ rails console
    > Event.new(name: "Event 1", starts_at: Time.now).save
    > Event.new(name: "Event 2", starts_at: Time.now).save
    > Event.new(name: "Event 3", starts_at: Time.now).save
    > Event.new(name: "Event 4", starts_at: Time.now).save
    

    Create app/javascript/packs/convert.js with content:

    jQuery(function(){
      // alert(12345)
      $("span[data-utc-time]").each(function() {
        var timestamp = $(this).attr("data-utc-time");
        var localeTimestamp = new Date(timestamp).toLocaleString();
        $(this).html(localeTimestamp);
    });
    })
    

    Include this javascript in app/views/pages/home.html.erb

    Welcome to project railstrace !
    <% @events.each do |e| %>
      <p> <%= e.name %>: 
      <span data-utc-time="<%= e.starts_at %>">&nbsp;</span>
      </p>
    <% end %>
    <%= javascript_pack_tag 'convert' %>
    

    Route config/routes.rb

    Rails.application.routes.draw do
     root to: "pages#home"
    end
    

    In app/controllers/pages_controller.rb

    class PagesController < ApplicationController
      def home
        @events = Event.all
      end
    end
    

    This is just example use simple javascript, with some advance processes for datetime, you can use the lib dayjs.

    If have any problems, tell me, I will try to help you, Lemon!

    Update code to use dayjs:

    Edit file app/javascript/packs/convert.js with content:

    jQuery(function(){
      //Extend dayjs plugin 
      var relativeTime = require('dayjs/plugin/relativeTime')
      dayjs.extend(relativeTime)
      // alert(dayjs().from(dayjs('2021-05-19 11:21:55 UTC'), true) )
      $("span[data-utc-time]").each(function() {
        var timestamp = $(this).attr("data-utc-time")
        var localeTimestamp = new Date(timestamp).toLocaleString()
        var fromNow = dayjs().from(dayjs(timestamp), true)
        var content = `Start at: ${localeTimestamp}. Ago: ${fromNow}`
        // $(this).html(localeTimestamp)
        $(this).html(content)
    });
    })
    

    enter image description here