TodoAppに期限日をつける 一番簡単なDatePicker編

ポートフォリオとして作成中のTodoAppに期限日機能を付けていきます

Taskテーブルにdeadline:dateカラムを加える

% rails g migration AddDeadlineToTasks deadline:date

sqliteはややこしい・・

class AddDeadlineToTasks < ActiveRecord::Migration[6.0]
  def up
    add_column :tasks, :deadline, :date
    change_column :tasks, :deadline, :date, null: false
  end

  def down
    remove_column :tasks, :deadline
  end
end
% rails db:migrate


StrongParameterに:deadlineを追加する

忘れがちなやつ

[ tasks_controller.rb ]

(省略)
    def task_params
      params.require(:task).permit(:done, :title, :description, :image, :public, :deadline)
    end


シードにdeadlineを追加して、`rails db:seedする

[ db/seeds.rb ]

deadline = Date.today.next_day(2)

こんな感じに入れてみる


Viewをいじる

formにdeadlineの場所を作ってあげる

[ form.html.slim ]_

  = form_with model: task, local: true do |f|
   
(省略)

      = f.label :deadline, '期限日'
      = f.text_field :deadline, class: 'form-control'
    .row.justify-content-center
      = f.submit '登録', class: 'btn btn-success col-2'

一覧ページに表示されるようにする(適当に)

[ tasks/index.html.slim ]

=  "期日:#{l private_task.deadline}"


Bootstrap Material DatePicker

やっとです!

一番簡単なdatepickerです。(がちで)

いろいろ試して失敗しまくった末に見つけたンスよ。

https://designlink.work/ja/bootstrap-material-datepicker/

こちらのサイトを見ればすぐ使えますが、説明していきます


準備は簡単

views/layouts/application.html.slimheader内に上記URLの組み込みファイルとベーシックマークアップを記述するだけ。全て、CDNとして読み込まれるので、bundleyarnを使う必要なしです。楽ちん

そして、使いたいページで

<input class="result" type="text" id="date-time" placeholder="Date Picker...">(例)

と書くだけ!


実際にやってみます!

私は、application.html.slimがごちゃごちゃになるのが嫌なので_datepicker.html.slimを作成しました。

[ layouts/_datepicker.html.slim ]

link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-material-datetimepicker/2.7.1/css/bootstrap-material-datetimepicker.min.css"
link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"
script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"
script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"
script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/locale/ja.js"
script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-material-datetimepicker/2.7.1/js/bootstrap-material-datetimepicker.min.js"
javascript:
  $(function(){
    $("#date").bootstrapMaterialDatePicker({
      weekStart:0,
      lang:"ja",
      time: false,
      format:"YYYY-MM-DD"
    });
  });

設定について

  • weekStart:0 不明

  • lang: "ja" 表記を日本語にしてくれる

  • time: false 日時ではなく日付のみになる

  • format:"YYYY-MM-DD 日付のみのフォーマット

  • #date はidです!viewと合わせてください。

詳しくはドキュメントを! https://designlink.work/ja/bootstrap-material-datepicker/


これをhead内にrenderするのを忘れずに

[ layouts/application.html.slim ]

doctype html
html
  head
    title
      | Welldone
    = csrf_meta_tags
    = csp_meta_tag
    = stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
    = javascript_pack_tag 'application', 'data-turbolinks-track': 'reload'
    = render 'layouts/datepicker'      #これよ!
  body
    = render 'layouts/header'
    .container-md
      = render 'layouts/flash'
      = yield
    = render 'layouts/footer'


そして

単独で使うなら

input class="result" type="text" id="date"

でいいんですが、form内に使いたかったので、

[ _form.html.slim ]

  = form_with model: task, local: true do |f|
   
(省略)

      = f.label :deadline, '期限日'
      = f.text_field :deadline, class: 'form-control result', id: 'date'
    .row.justify-content-center
      = f.submit '登録', class: 'btn btn-success col-2'


試しにclass: 'result'id: 'date'を書いてみたら・・


f:id:yukitoku_sw:20200201092747p:plain

見事表示されました!


選択して、okを押すと

f:id:yukitoku_sw:20200201092825p:plain

日付のみ入力されました!

ラッキー


次回、期限日にそのまま日付を表示してもつまらない(つまらない)