10
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

selectとoptionタグをjQueryを使って動的に追加する

Last updated at Posted at 2019-03-02

デモ(動画)

Image from Gyazo

やりたいこと

上記のGIF通り、
カテゴリーが選択されたと同時に、親カテゴリーに紐づく子カテゴリーが出てくるようにしたい。
入れ子構造については以下を参照
【追記予定】awesome_nested_setを使った入れ子構造のDB設計

## 実装概要
jQueryのajaxメソッドを使って、カテゴリーが選択されたら子カテゴリーがappendされるようにした。

## コード

routing

route.rb
Rails.application.routes.draw do
  root 'products#new'
  resources :products,  only: [:create] do
<!-- 今回はsearchアクションをajaxメソッドで叩きます-->
    collection do
      get 'search'
    end
  end
end

view

new.html.haml
= form_for @product do |f|
  = f.label :name
  = f.text_field :name, placeholder: "商品名を入力"
  
  #cat
    = f.select :category_id, Category.roots.map {|i| ["#{i.name}", i.id]}, { selected: @product.category_id, include_blank: true }, {id: "l_category"}

js

category.js
$(document).on('turbolinks:load', function() {

  // selectを追加するHTML
  var cat_seach = $("#cat");

  function appendSelect(catNum) {
    if(catNum == 1) {
      var select_id = `m_category`
    } else if(catNum == 2) {
      var select_id = `s_category`
    }
    var html =
    `<select name="product[category_id]" id="${select_id}">
        <option value>---</option>
    </select>`
    cat_seach.append(html)
  }


  // optionを追加するHTML
  function appendCat(catOption, catNum) {
    if (catNum == 1) {
      var appendId = $("#m_category")
    } else if (catNum == 2) {
      var appendId = $("#s_category")
    }
    appendId.append(
      $("<option>")
        .val($(catOption).attr('id'))
        .text($(catOption).attr('name'))
    )
  }

  // Lカテゴリーが選択された時のアクション
  $("#l_category").on('change', function() {
    l_cat = $(this).val()
    $("#m_category, #s_category").remove()

    // ajaxでリクエストを送信
      $.ajax({
        type: "GET",
        url: "/products/search",
        data: {l_cat: l_cat},
        dataType: 'json'
      })
      // doneメソッドでappendする
      .done(function(m_cat) {
        var catNum = 1
        appendSelect(catNum)
        m_cat.forEach(function(m_cat) {
          appendCat(m_cat, catNum)
        })
      })
    })

// Mカテゴリーが選択された時のアクション
  $(document).on('change', "#m_category", function() {
    m_cat = $(this).val()
    $("#s_category").remove()

    $.ajax({
      type: "GET",
      url: "/products/search",
      data: {m_cat: m_cat},
      dataType: 'json'
    })
    .done(function(s_cat) {
      var catNum = 2
      appendSelect(catNum)
      s_cat.forEach(function(s_cat) {
        appendCat(s_cat, catNum)
      })
    })
  })
})

controller

categories_controller.rb
<!--関係ないアクションは省略しています-->
  def search
    if params[:l_cat]
      @m_cat = Category.find(params[:l_cat]).children
    else
      @s_cat = Category.find(params[:m_cat]).children
    end
    respond_to do |format|
      format.html
      format.json
    end
  end

jbuilder

search.json.jbuilder
json.array! @m_cat do |m_cat|
  json.id   m_cat.id
  json.name m_cat.name
end

json.array! @s_cat do |s_cat|
  json.id   s_cat.id
  json.name s_cat.name
end

勉強になったところ

optionタグの追加の方法

optionの追加

$("#m_category").append(
      $("<option>")
        .val($(m_cat).attr('id'))
        .text($(m_cat).attr('name'))
    )
  }

こういう風に書くことで、selectタグのoptionが追加できることを知りました。
始めはselectを追加すればいいじゃん!と思ってましたが、配列形式で渡ってくるため、配列の中身分selectが増えてしまい、上手な方法が浮かばなかったので、こちらの方法にしました。

参考記事
・jQuery でセレクトボックスのプルダウン項目(option 要素)を追加/削除する方法
https://webllica.com/jquery-select-option-add-del/

10
11
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
10
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?