simple_formカスタマイズTIPS集




# 必須のマークをラベル右側に出す
こんな風にしたいとき↓

![kobito.1468975061.061055.png](https://qiita-image-store.s3.amazonaws.com/0/31687/4961f00b-817d-e685-b3fe-22b988ff3ec5.png "kobito.1468975061.061055.png")

configの以下の部分のコメントアウトを外します。

```config/initializers/simple_form.rb
config.label_text = lambda { |label, required, explicit_label| "#{label} #{required}" }
```


# エラーメッセージをフルメッセージで出す
デフォルトの設定のままだとエラーメッセージは以下のように表示されます。
でもこれだとレイアウトによってはおかしなことになってしまいます。
こんな風に↓

![kobito.1468975666.373236.png](https://qiita-image-store.s3.amazonaws.com/0/31687/3dcb9787-2f35-90fa-1053-efb8854b5db5.png "kobito.1468975666.373236.png")



configで:errorの行をコメントアウト、:full_errorの行のコメントアウトを外します。

```config/initializers/simple_form.rb
# b.use :error, wrap_with: { tag: :span, class: :error }
b.use :full_error, wrap_with: { tag: :span, class: :error }
```

すると、このようになりました。

![kobito.1468975355.696076.png](https://qiita-image-store.s3.amazonaws.com/0/31687/77f0602e-2e02-c299-07d0-e38cba943673.png "kobito.1468975355.696076.png")


# 日本語化とplaceholderとhintの扱い
## 日本語化（i18n）対応
i18n対応についてはsimple_formのドキュメントにも書いてあるとおりですが、config/locale以下にドキュメントにあるenファイルと同じような構成で以下のようなymlファイルを作ります。

```config/locales/simple_form.ja.yml
ja: # jaにする
  simple_form:
    labels:
      user:
        username: 'ユーザー名'
        password: 'パスワード'
    hints:
      user:
        username: 'サインインするユーザ名を入力してください'
        password: '半角英数字のみ使えます'
    placeholders:
      user:
        username: 'なまえ'
        password: '****'
```

上のymlは抜粋なので全部の構成はこちらを参考に：https://github.com/plataformatec/simple_form#i18n


## placeholderとhint
__placeholder__はhtml5から実装された仕様でテキストフィールドの背景にうっすらグレーでテキストが表示されます。
よく見るこういうのです。
![kobito.1468976639.344680.png](https://qiita-image-store.s3.amazonaws.com/0/31687/3e0f8688-f486-9098-e0bd-35f1eb2aa946.png "kobito.1468976639.344680.png")

__hint__はフォームの下に小さめの文字で書いてある、入力内容についてのヒントです。
![kobito.1468976921.001296.png](https://qiita-image-store.s3.amazonaws.com/0/31687/f8afb4cb-3b4f-caa5-1e1a-d4bc81c44228.png "kobito.1468976921.001296.png")


placeholderはerbやslimなどのviewファイルに記載することでも表示できますが…

```_form.html.slim
= f.input :parking_details, 
	placeholder: '¥500/1時間　100台', 
	hint: '駐車場料金、利用制限がある場合は制限内容、専用駐車場がない場合は近隣の駐車場情報など'
```
ymlに書くだけでも表示されるので、ymlにまとめて書く方がテキストが一箇所で管理できてviewファイルに余計な内容を書かずに済むのでおすすめです。

```config/locales/simple_form.ja.yml
ja:
  simple_form:
    hints:
      spot:
        parking_details: '駐車場料金、利用制限がある場合は制限内容、専用駐車場がない場合は近隣の駐車場情報など'
    placeholders:
      spot:
        parking_details: '¥500/1時間　100台'
```
ymlに上のように書いておけばslimはこれ↓でOK。

```_form.html.slim
= f.input :parking_details
```

# radio/checkboxなどをdivで囲む

simple_formのconfigに以下の行があります。
デフォルトではコメントアウトされてますが、これを有効にして囲みたいタグとclass名を設定します。

```config/initializers/simple_form.rb
config.collection_wrapper_tag = :div
config.collection_wrapper_class = 'group_input'
```


この設定をすることにより、form中のすべてのradio/check boxが`<div class="group_input">`で囲まれます。


囲んだdivに更に別のclass名を当てたい時には以下のようにします。

```
= f.input :gender, as: :radio_buttons, collection_wrapper_class: 'hoge'
```


上記の出力結果

```
<div class="input radio_buttons optional">
	<label class="radio_buttons optional">性別</label>
	<div class="group_input hoge"> <!-- divで囲まれclassが追加されている-->
		<span class="radio">
			<label for="user_gender_male">
				<input class="radio_buttons optional" type="radio" value="male" name="user[gender]" id="user_gender_male">
				"男性"
			</label>
			<label for="user_gender_female">
				<input class="radio_buttons optional" type="radio" value="female" name="user[gender]" id="user_gender_female">
				"女性"
			</label>
		</span>
	</div>
</div>
```
参考：
http://stackoverflow.com/questions/19605976/simple-form-collection-wrapper-radios-buttons-double-encapsulation-of-items

# 子モデルの要素をcollection_select
前提：

```category.rb
has_many :spots
```
```spot.rb
belongs_to :category
```

日本語化の必要が無い場合には、以下の形でcategoryを選択することが出来ます。

```_form.html.slim
= simple_form_for @spot do |f|
	= f.association :category, label_method: :name, value_method: :id
end	
```

ラベルにI18nを適用しようとした場合、f.associationを使ったうまいやり方がどうしてもわからず、以下のような形で実装しました。

```_form.html.slim
= simple_form_for @spot do |f|
	= f.input :category_id, collection: Category.all.map{|v| [t("subcategory.#{v.subcategory}"),v.id]}
end
```
nameとvalueのセットのArrayをcollectionに渡します。
map内でI18n.tを使うことで、nameが日本語化されます。