その他
    ホーム 技術発信 DoRuby 【Rails】フォームの要素を動的に追加・削除 〜JSON編〜【jquery】

    【Rails】フォームの要素を動的に追加・削除 〜JSON編〜【jquery】

    この記事はアピリッツの技術ブログ「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”}]