LoginSignup
21
30

More than 3 years have passed since last update.

gem active_hash を使ってプルダウンメニューを作成

Posted at

表題の通りgemを使ってプルダウンメニューを作りました。
これ作るのに一日かけたので:confounded:備忘録として投稿します!
またCSSを使った小技なども紹介します!!!

■完成イメージ
7ecd7a56e423bd6f282b6e4d5c9b54cf.png

■まずgemのインストール

gemfile
gem 'active_hash'
コンソール
bundle install

■モデルの作成
※テーブル作成しない方法もあるみたいですが、
現時点で僕が理解していなので今回は以下の方法で作成します。

コンソール
rails g model Address prefecture_id:integer city:string
rake db:migrate

■作成されたモデルを以下のように編集

/app/models/address.rb
class Address < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to_active_hash :prefecture
end 

■モデルを”手動で”作成

/app/models/prefecture.rbを手動で作成して下さい。
基本的にはmodelsの上で右クリ→ファイル作成、みたいな流れになると思います。
作成したファイルに以下を記載。

/app/models/address.rb

class Prefecture < ActiveHash::Base
  self.data = [
      {id: 1, name: '北海道'}, {id: 2, name: '青森県'}, {id: 3, name: '岩手県'},
      {id: 4, name: '宮城県'}, {id: 5, name: '秋田県'}, {id: 6, name: '山形県'},
      {id: 7, name: '福島県'}, {id: 8, name: '茨城県'}, {id: 9, name: '栃木県'},
      {id: 10, name: '群馬県'}, {id: 11, name: '埼玉県'}, {id: 12, name: '千葉県'},
      {id: 13, name: '東京都'}, {id: 14, name: '神奈川県'}, {id: 15, name: '新潟県'},
      {id: 16, name: '富山県'}, {id: 17, name: '石川県'}, {id: 18, name: '福井県'},
      {id: 19, name: '山梨県'}, {id: 20, name: '長野県'}, {id: 21, name: '岐阜県'},
      {id: 22, name: '静岡県'}, {id: 23, name: '愛知県'}, {id: 24, name: '三重県'},
      {id: 25, name: '滋賀県'}, {id: 26, name: '京都府'}, {id: 27, name: '大阪府'},
      {id: 28, name: '兵庫県'}, {id: 29, name: '奈良県'}, {id: 30, name: '和歌山県'},
      {id: 31, name: '鳥取県'}, {id: 32, name: '島根県'}, {id: 33, name: '岡山県'},
      {id: 34, name: '広島県'}, {id: 35, name: '山口県'}, {id: 36, name: '徳島県'},
      {id: 37, name: '香川県'}, {id: 38, name: '愛媛県'}, {id: 39, name: '高知県'},
      {id: 40, name: '福岡県'}, {id: 41, name: '佐賀県'}, {id: 42, name: '長崎県'},
      {id: 43, name: '熊本県'}, {id: 44, name: '大分県'}, {id: 45, name: '宮崎県'},
      {id: 46, name: '鹿児島県'}, {id: 47, name: '沖縄県'}
  ]
end

■ビューの実装

これでプルダウンの情報は設定できたので、ビューの実装に入ります。
また、各要素ごとに解説をつけていますので、見て下さい。

/app/view/identification.html.haml

-# .identification__form__field というクラスを指定しフォームの全体の箱を作成
.identification__form__field 

    -# ヘルパーメソッドを使用します。リンク先が ’’ になっていますので現在フォームの飛び先はありません。
    = form_for '' do |f|

      -# フォームの単体の箱を作成
      .identification__form__field
        -# フォームの単体の箱を作成。小ネタ:spanタグを使うとinline要素になるので要素が横並びなります。
        %span.identification__form__field__lavel 都道府県 
        %span.identification__form__field__arbitrary 任意 

        -# フォームの”自体”の箱を作成。icon-relativeは後々アイコンを使うときに使用するクラスです。アイコンはgemのfont-awesome-sassを使用してます。
        .identification__form__field--input.icon-relative
        -# ここが今回のメイン!collection_select を使います。値はprefecture_idを取得し、先ほど作成したモデルからPrefectureの値を全て取得するような記述をします。
        -# さらにオプションでpromptを設定し、プルダウンの一番上に”—“が表示されるようにします。さらにクラス指定をします。
        -# 最初に結果を言いますが、このクラスは適用されません。あとで説明します。
          = f.collection_select :prefecture_id, Prefecture.all, :id, :name, prompt: "--", class: 'input'
        -# font-awesomeの種類によっては書き方が変わります。
          = fa_icon "chevron-down", class: "identification__form-icon"

一旦ビューを確認しましょう。以下ようになっているはずです。
89ee074ce324898c7c52ffb8b872bb6b.png

■scssで装飾をする。

だいぶそれらしくなってきました!以下でscssの記述をします。
Scssを適用したら以下のような表示になります。
上下のフォームを確認すればわかりますが、今回はinputというクラスを指定しているのになぜか、適用したい要素だけ適用されてません。。。:sob::sob::sob:
a7c99136482bde59c205703c600a0032.png

identification.scss
.identification {
  background-color: white;
  width: 700px;
  padding-bottom: 60px;
  margin-bottom: 60px;  
  &__title {
    font-size: 24px;
    padding: 8px 24px;
    border-bottom: 1px solid #f5f5f5;
    text-align: center;
    font-weight: bold;
    color: rgb(51, 51, 51);
  }
  &__description {
    margin: 8px 0 0;
    font-family: 'Source Sans Pro', Helvetica , Arial, '游ゴシック体', 'YuGothic', 'メイリオ', 'Meiryo', sans-serif;
    font-size: 14px;
    color: #333;
    padding: 60px 60px 0;
  }
  &__link {
    margin: 8px 0 0;
    padding: 0 60px;
    text-align: right;
    color: #0099E8;
    font-size: 14px;
    &--upload {
      color: #0099E8;
      &:hover {
        text-decoration: underline;
        opacity: 0.8;
      }
    }
    &--icon {
      font-size: 14px;
      &:hover {
        opacity: 0.8;
      }
    }
  }
  &__form {
    padding: 0 60px;
    font-size: 14px;
    &--taxt {
      font-weight: 100px;
    }
    &__field {
      font-weight: 600;
      padding: 40px 0 8px;
      &__lavel {
        padding-right: 8px;
      }
      &__arbitrary {
        background-color: #ccc;
        color: white;
        padding: 2px 4px;
        border-radius: 2px;
        font-size: 12px;
        font-weight: 100;
        vertical-align: text-top;
      }
      &--input {
        margin: 8px 0 0;
        font-family: 'Source Sans Pro', Helvetica , Arial, '游ゴシック体', 'YuGothic', 'メイリオ', 'Meiryo', sans-serif;
        font-size: 16px;
        font-weight: 100;
        .input {
          box-sizing: border-box;
          width: 100%;
          height: 50px;
          padding: 10px 16px 8px;
          border-radius: 4px;
          border: 1px solid #ccc;
          background: #fff;
        }
      }
      .icon-relative {
        position: relative;
        &--absolute {
          position: absolute;
          right: 5px;
          top: 50%;
          z-index: 2;
          color: #888;
          font-size: 20px;
          -webkit-transform: translate(0, -50%);
          transform: translate(0, -50%);
          background-color: white;
        }
      }
    }
    &__btn {
      margin: 40px 0 0 0;
      &--submit {
        background: #ea352d;
        color: #fff;
        display: block;
        width: 100%;
        line-height: 48px;
        font-size: 14px;
        transition: all ease-out .3s;
        cursor: pointer;
        text-align: center;
        margin-bottom: 50px;
        opacity: 0.9;
        &:hover {
          opacity: 1;
        }
      }
    }
  }
}

■collection_selectにクラスを適応させる。

検証ツールを見ても、selectタグは生成されているが、クラスだけ適応されてません。
リファレンスや他の方の記事などを見ても対応が見つからなかったので、今回は以下のように対応しました。
select自体にCSSを指定しました。
93bb630dec7273e63989bff6a4f47bcf.png

identification.scss
select {
  box-sizing: border-box;
  width: 100%;
  height: 50px;
  padding: 10px 16px 8px;
  border-radius: 4px;
  border: 1px solid #ccc;
  background: #fff;
}

ここでまた一つ問題が。。。:relaxed:(もうやめて。。。)
collection_selectの矢印とアイコンが被ってしまいました。
ちなみにこの対応が一番時間がかかりましたw
46495ed9b701e9d4f962767c18ce914b.png

■アイコンのCSSを変更し、フォームの矢印を変更する(小技)

先に言っておきますが実際に変更したわけじゃなく、
変更したように見せているだけですw

identification.scss
.identification__form-icon {
  position: absolute;
  right: 5px;
  top: 50%;
  z-index: 2;
  color: #888;
  font-size: 20px;
  -webkit-transform: translate(0, -50%);
  transform: translate(0, -50%);
  background-color: white;
}

バックグラウンドカラーを指定してポジション指定で元々の矢印に上乗せしそれっぽくしました。

一旦これで最初の画像のようなフォームになったかと思います。完成!!!

もしこうした方がいいとか間違ってるとかあったら遠慮なく言って下さい!

21
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
30