この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
フォームの要素を追加・削除する機能がよくあるので作成方法をまとめます。
例として作る機能
特徴や内容量などにつかいそうなフォーム。今回はプロパティという名前で作成。
Modelにメソッド追加
def properties
parse_property = JSON.parse(property) # propertyに不正な値が入っていた場合に例外発生する
return [] unless parse_property.is_a?(Array) && parse_property.all? { |prop| prop.is_a?(Hash) }
parse_property
rescue
[]
end
Helperにメソッド追加
def add_property_button_tag(name)
fields = render 'property_fields', property_key: nil, property_value: nil
button_tag(name, type: :button, class: 'add_property btn btn-default pull-right', data: { fields: fields.delete("\n") })
end
View (_form.slim)
fieldset
.col-md-3
legend プロパティ
.col-md-9
.form-group
/ 入力フィールド
table.table#properties
- @モデルのインスタンス.properties.each do |property|
= render 'property_fields', property_key: property['property_key'], property_value: property['property_value’]
/ 実際に値が入るフィールド↓
= f.hidden_field :property
/ 追加ボタン
= add_property_button_tag 'プロパティ追加'
View (_property_fields.slim)
tr.property
td
= text_field_tag nil, property_key, id: nil, class: :property_key
td
= text_field_tag nil, property_value, id: nil, class: :property_value
td
button.btn.btn-default.pull-right.remove_property type="button"
= '削除'
coffee script
class クラス名
constructor: ->
@properties = $('#properties')
@add_property = $('.add_property')
@add_event_to_property()
# イベント設定
add_event_to_property: ->
@properties.on('change', 'input', @reset_property)
@properties.on('click', '.remove_property', @remove_property)
@properties.on('click', '.remove_property', @reset_property)
@add_property.click(@adding_property_field)
# hiddenフィールドに入れる値設定
reset_property: =>
property_attrbutes = $('.property').map( (_index, property) ->
property_key = $(property).find('.property_key').val()
property_value = $(property).find('.property_value').val()
return unless property_key && property_value
{
'property_key': property_key,
'property_value': property_value
}
)
# JOSN形式で保存
@property.val(JSON.stringify(property_attrbutes.get()))
# 削除
remove_property: ->
$(this).closest('tr').remove()
# 追加
adding_property_field: ->
field_tags = $(this).data('fields')
$field = $(field_tags)
$('#properties').append($field) # タグを追加
保存した値
$ rails c
2.2.0 :002 > モデルインスタンス.property
=> "[{\"property_key\":\"高さ\",\"property_value\":\"10cm\"},{\"property_key\":\"横幅\",\"property_value\":\"20cm\"},{\"property_key\":\"重さ\",\"property_value\":\"100g\"}]”
2.2.0 :003 > モデルインスタンス.properties
=> [{"property_key"=>"高さ", "property_value"=>"10cm"}, {"property_key"=>"横幅", "property_value"=>"20cm"}, {"property_key"=>"重さ", "property_value"=>"100g”}]