Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Ruby on Rails 4 - bootstrap3+simple_form+datetimepicker

More than 5 years have passed since last update.

simple_form と bootstrap3は導入されているという前提で進めます。

Gemの追加

Bootstrap 3 Datepickerのマニュアルの通り

Gemfile
gem 'momentjs-rails', '>= 2.9.0'
gem 'bootstrap3-datetimepicker-rails', '~> 4.14.30'

を追加します。

追記したあと、bundle installをしましょう。

inilinitializers設定

まず、/config/inilinitializers/に下記の設定ファイルを作ります

date_time_picker_input.rbを作成。

  • サンプルソース1
/config/inilinitializers/date_time_picker_input.rb
class DateTimePickerInput < SimpleForm::Inputs::Base
  def input
    # classにform_datetimeを指定することで、coffee scriptの方で要素指定に使用されています。(見た目は変わりません)
    template.content_tag(:div, class: 'input-group date form_datetime') do
      template.concat @builder.text_field(attribute_name, input_html_options)
      template.concat span_table
    end
  end

  def input_html_options
    # classには配列で複数の設定が入ってくるので、それに'form-control'を追加してあげる
    # 単純にmergeしてしまうと、前のものが消えて'form-control'のみになってしまいバグる
    classes = (super[:class] || [])
    classes << :'form-control'
    # viewで指定された'readonly'がある場合は上書きしないようにする
    # カレンダーからの入力のみを許可したい場合は readonly: true を設定
    options = super
    options.merge({class: classes})
    options.merge({readonly: false}) unless options[:readonly]
    options
  end


  def span_table
    template.content_tag(:span, class: 'input-group-addon') do
      template.concat icon_table
    end
  end

  def icon_table
    "<span class='glyphicon glyphicon-calendar'></span>".html_safe
  end

end
  • input_html_optionsメソッドではreadonly: falseを指定していますが、カレンダーからの入力のみを許可したい場合はreadonly: trueを設定してください。
  • inputメソッドの最初でclassform_datetimeを設定していますが、これを使用してcoffee script側で要素指定しています。

参考サイトのsimple_form Wiki - Custom inputs examplesでは、下記のようになっています。

app/inputs/date_time_picker_input.rb
class DateTimePickerInput < SimpleForm::Inputs::Base
  def input
    template.content_tag(:div, class: 'input-group date form_datetime') do
      template.concat @builder.text_field(attribute_name, input_html_options)
      template.concat span_remove  # サンプルソース1では削除
      template.concat span_table
    end
  end

  def input_html_options
    super.merge({class: 'form-control', readonly: true})  # サンプルソース1では readonly: false に設定
  end

  # サンプルソース1では削除
  def span_remove
    template.content_tag(:span, class: 'input-group-addon') do
      template.concat icon_remove
    end
  end

  def span_table
    template.content_tag(:span, class: 'input-group-addon') do
      template.concat icon_table
    end
  end

  # サンプルソース1では削除
  def icon_remove
    "<i class='glyphicon glyphicon-remove'></i>".html_safe
  end

  def icon_table
    "<i class='glyphicon glyphicon-th'></i>".html_safe # サンプルソース1では<span>タグに変更
  end

end
  • 上記で紹介したサンプルソース1ではspan_removeicon_removeを削除。
  • icon_tableメソッドで追加しているHTMLタグを<i>から<span>へ変更。
  • アイコンのクラス指定をglyphicon-thからglyphicon-calendarに変更

これは、Bootstrap 3 Datepicker v4 Docsにあるサンプルソースに合わせるためです。

また、/app/inputs/配下にdate_time_picker_input.rbを作成していますが、サンプルソース1では、/config/inilinitializers/配下に作成しています。 初期設定で行うべき処理に思うので/config/inilinitializers/に移動しました。

coffee scriptサンプル

24時間表記で日本にロケールを合わせる場合は下記のようにします。

init_datetimepciker = ->
  (->
    $(".form_datetime").datetimepicker
      locale: "ja"
      format: "YYYY/MM/DD HH:mm"
      sideBySide: true
  )

$(document).ready ->
  init_datetimepciker()

$(document).on "ready page:load", init_datetimepciker()
  • sideBySide: trueを指定するのは見た目が私はこちらのほうが好きなので、指定しています。
    ポップアップのカレンダーの見た目が変わるだけです。

  • turbolinksを使用していると、ページ遷移時にcoffee scriptが動作しない(リロードすれば動作する状態)なので"ready page:load"時も実行するよう設定しています。

  • $(".form_datetime")で要素を選択しています。classform_datetimeが指定されている要素全てが対象になるので、cssの方で重ならないよう注意してください。class名変更などカスタマイズしたい場合は/config/inilinitializers/date_time_picker_input.rb(rubyコード)と合わせて調整する必要があります。


参考サイトのsimple_form Wiki - Custom inputs examplesでは、下記のようになっています。

$(document).ready ->
  $('.form_datetime').datetimepicker({
    autoclose: true,
    todayBtn: true,
    pickerPosition: "bottom-left",
    format: 'mm-dd-yyyy hh:ii'
  });

view側の呼び出し

f.input :my_date, as: :date_time_picker

参考URL

Bootstrap 3 Datepicker v4 Docs

simple_form Wiki - Custom inputs examples

まとめ(忙しい人のためのやること一覧)

1. Install

Gemfile
gem 'momentjs-rails', '>= 2.9.0'
gem 'bootstrap3-datetimepicker-rails', '~> 4.14.30'

を追加します。

追記したあと、bundle install


2. DateTimePickerInputクラス追加

/config/inilinitializers/date_time_picker_input.rb
class DateTimePickerInput < SimpleForm::Inputs::Base
  def input
    template.content_tag(:div, class: 'input-group date form_datetime') do
      template.concat @builder.text_field(attribute_name, input_html_options)
      template.concat span_table
    end
  end

  def input_html_options
    # classには配列で複数の設定が入ってくるので、それに'form-control'を追加してあげる
    # 単純にmergeしてしまうと、前のものが消えて'form-control'のみになってしまいバグる
    classes = (super[:class] || [])
    classes << :'form-control'
    # viewで指定された'readonly'がある場合は上書きしないようにする
    # カレンダーからの入力のみを許可したい場合は readonly: true を設定
    options = super
    options.merge({class: classes})
    options.merge({readonly: false}) unless options[:readonly]
    options
  end


  def span_table
    template.content_tag(:span, class: 'input-group-addon') do
      template.concat icon_table
    end
  end

  def icon_table
    "<span class='glyphicon glyphicon-calendar'></span>".html_safe
  end

end

を追加。


3. coffeeスクリプトを追加

init_datetimepciker = ->
  (->
    $(".form_datetime").datetimepicker
      locale: "ja"
      format: "YYYY/MM/DD HH:mm"
      sideBySide: true
  )

$(document).ready ->
  init_datetimepciker()

$(document).on "ready page:load", init_datetimepciker()

を追加。


※補足
javascriptで指定したい場合はcoffee scriptjavascriptの相互変換は下記サイトでできます。
http://js2coffee.thomaskalka.de/


4. view側の呼び出し

as: :date_time_pickerを指定して呼び出し。

f.input :my_date, as: :date_time_picker
azusanakano
中野システム研究所、所長(仮) 東京四念処禅道場、師範(仮)
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away