【jQuery】詳細情報のプルダウン表示


# はじめに
カスタムデータ属性とは

htmlの属性の１つで要素に独自の属性を付与することができます。
idを付与することによってその要素の取得や変更が行いやすくなります。

カスタムデータ属性はdataから任意の名前のidを設定することができます。


```erb:example.html.erb

<div class="tweet" data-id="#{tweet.id}">
```

# 今回したいこと
簡単な家計簿アプリを作成しています。
ある**月ごとのカテゴリーの詳細項目を、カテゴリーごとの詳細項目の数だけ項目を表示する**ことに苦労したのでまとめました。
主にjQueryとカスタムデータ変数について説明してます。


### before
　給料の右の▶︎をクリックすると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532838/5a8e323c-1a28-7687-4e65-da1aeb80c7eb.png)
### after
　カテゴリーごとの詳細が展開する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532838/34804b08-572d-4edc-e8f9-1804e9411135.png)

## 考え方
カテゴリーごとの詳細情報をjQueryで表示しようとした際、各カテゴリーごとに持っている詳細の数が違うため、データ属性なしでは１つしか表示ができなかった為、データ属性でカテゴリーごとの詳細の数をカウントして、その数だけ表示させるようにしました。


#1.カテゴリーごとに１つずつデータ属性を用いて、詳細項目の数をカウントする。
## html.hamlのコード

```haml:views/incomes/show.html.haml
%table.left-content__list__category
          - @income_categories_hash.each do |k,v|
            %tr.category{"data-cat-id": v[1].income_contents.where("month_id = #{@month.id}").where("user_id = #{@user}").length}
              %td.triangle-open
                ▶︎
              %td.triangle-close.hidden
                ▼
              %td.category-name
                = "●#{k}" + ":"
              %td
                = "¥#{v[0]}"  
            
            - v[1].income_contents.where("month_id = #{@month.id}").where("user_id = #{@user}").each do |con|
              %tr.content-show.hidden
                %td
                %td
                  = "・#{con.content}"+":"
                %td
                  = "¥#{con.money}"
                %td
                  =link_to edit_income_income_content_path(@month.id, con.id), class: "edit_link" do
                    .edit_btn 編集する
                %td
                  =link_to income_income_content_path(@month.id, con.id),method: :delete, class: "destroy_link" doa
                    .destory_btn 削除する

:css
  .triangle-open {
    cursor: pointer;
  }
  .triangle-close {
    cursor: pointer;
  }
  .category-name {
    width: 200px;
  }
  .hidden {
    display: none;
  }

```

###1-1. データ属性でデータの数を取得する。
ハッシュのバリュー（v［１］）の対応する詳細項目を１つ１つlengthで数を数えて、データ属性として取得。

```haml
%tr.category{"data-cat-id": v[1].income_contents.where("month_id = #{@month.id}").where("user_id = #{@user}").length}
```


取得に成功すると、下記の検証のようにdata-cat-id="3"と詳細データの数を取得できていることが確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532838/0b6741e9-a2aa-e273-e3af-25a00e096eee.png)

#２.jQueryでidの数だけ表示させる

##jQueryのコード
```assets/javascripts/show.js
$(document).on('turbolinks:load', function(){

  $(".triangle-open").on("click", function(){
  
  //詳細を取得、表示する
  let id = $(this).parent().data('cat-id');
  var gethidden = ($(this).parent().nextAll().slice(0, id));
  gethidden.removeClass("hidden");
  //▼の三角形を取得、表示する
  var gettriangleclose = ($(this).next(".triangle-close"));
  gettriangleclose.removeClass("hidden");
  //▶︎の三角形を消す
  $(this).addClass("hidden");
  })

  $(".triangle-close").on("click", function(){
  
  //詳細を取得、消す
  let id = $(this).parent().data('cat-id');
  var getshow = ($(this).parent().nextAll().slice(0, id));
  getshow.addClass("hidden")
  //▶︎の三角形を取得、表示する
  var gettriangleopen = ($(this).prev(".triangle-open"));
  gettriangleopen.removeClass("hidden")
  //▼の三角形を消す
  $(this).addClass("hidden")
  })
});

```
### 2-１.項目の数を特定する
詳細項目の数を取得したいので、変数idにdataメソッドで項目の数であるデータ属性を取得してます。
ちなみにここの＄（this）は発火させたtriangle-openをさしてます。

```javascript
let id = $(this).parent().data('cat-id');
```
### 2-2.詳細項目をidの数だけ取得
sliceメソッドで0から先ほど取得したidの数まで詳細項目を取り出します。

```javascript
var gethidden = ($(this).parent().nextAll().slice(0, id));
```
### 2-3.詳細項目を表示させる
hiddenクラスをremoveで取り除くことで隠れていた詳細がidの数だけ表示されます。

```javascript
gethidden.removeClass("hidden");
```