stimulus、「data-target」「data-action」が複数ある場合、対象をどのように特定するか

##まずは[前々回](https://qiita.com/wkya_4a/items/834a12fa9b5cec01f0ba)の復習がてら

[ハンドブックにある「Hello, Stimulus」](https://stimulusjs.org/handbook/hello-stimulus)を若干書き換えて、ボタンを押すと「A」「B」に入力した文字が「C」に表示されるようにしてみた。

```rails:.html.erb
<div data-controller="test-desu">

  A :<input data-target="test-desu.name_1" type="text">
  <button data-action="click->test-desu#greet" >Greet</button>

  B :<input data-target="test-desu.name_2" type="text">

  <label data-target="test-desu.write_here">C :write here</label>

</div>
```
↓できた画面が、こちら。
![スクリーンショット 2019-05-19 0.18.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410674/ce9fa61c-4caa-8008-2d68-ea355035a337.png)
ターゲット名「name_1」→A行の入力枠
ターゲット名「name_2」→B行の入力枠
ターゲット名「write_here」→"C:write here"の部分

これに対してstimulusのjsで、(ファイル名＝thmlで振ったデータコントローラー名……なお名称については気にしない方向で（「てすと_です」って……いや、他にぱっと思いつかなかったんだ）)

```test_desu_controller.js

import { Controller } from "stimulus"

export default class extends Controller {
  static targets = [ "name_1","name_2","write_here" ]

  greet() {
    this.write_hereTarget.textContent = this.name + "。そして、" + this.name2;
  }

  get name() {
    return this.name_1Target.value
  }
  get name2() {
    return this.name_2Target.value
  }
}
```
「A」「B」に入力してボタンを押すと……

![スクリーンショット 2019-05-19 0.27.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410674/0a48f48d-c150-5e64-85f6-31405c8227fb.png)
うん、ちゃんと表示された。

ターゲット名は、
【実際に使う部分……「name_1Target」「this.name_2Target」「write_hereTarget」】
だけでなく、
【初めの宣言……「static targets = [ "name_1","name_2","write_here" ]」】
にも記述しなければいけないことに注意
なお、
・static targets = [ "name_1" ]
・static targets = [ "name_2" ]
・static targets = [ "write_here" ]
と分けて書いたりすると、エラーになる（当たり前かもしれないけど、実際自分はこう書いてエラーを出しました orz。


##ではもし、「A」の部分が複数あったら？

つまり、

```rails:.html.erb
<div data-controller="test-desu">
  <div>
    A-1 :<input data-target="test-desu.name_1" type="text">
    <button data-action="click->test-desu#greet" >Greet-1</button>
  </div>

  <div>
    A-2 :<input data-target="test-desu.name_1" type="text" >
    <button data-action="click->test-desu#greet" >Greet-2</button>
  </div>

  <div>
    A-3 :<input data-target="test-desu.name_1" type="text" >
    <button data-action="click->test-desu#greet" >Greet-3</button>
  </div>

  B :<input data-target="test-desu.name_2" type="text">

  <label data-target="test-desu.write_here">C :write here</label>

</div>
```
![スクリーンショット 2019-05-19 0.48.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410674/2a2c0efe-9116-43a4-8250-01f4091e993f.png)
これで、「A1〜3のうち、押したボタンの行内容」＋「Bの内容」が「Cの部分」に表示されるようにしたい。

なお[ハンドブックの4](https://stimulusjs.org/handbook/managing-state)にあるように、同名のターゲットを複数用意することは可能。その場合、「Target」ではなく「Targets」を使用する……はず。

なので試しに、jsを止めて検証ツールで見てみると、
![スクリーンショット 2019-05-19 1.03.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410674/eaffb538-c9d2-55d0-0c0e-1e7bfbb19d4f.png)
「this.name_1Targets(番号）」で、行情報を取得できる。

また
「  greet() {」→→→「  greet(el) {」
と変更すれば、
![スクリーンショット 2019-05-19 1.09.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410674/1fab5f5a-47f6-a9af-18d1-e15db31f4d96.png)
「el.target.dataset」で、アクションを発生させたボタンの情報を取得できる。
本当はここで「.index」とかして、【複数あるgreetアクションのうち、何番目が刺激されたのか】を取得したかったのだけど……見つからなくって諦めて（ありそうな気はしているので、「何番目の要素か」の取得方法、ご存知の方がいれば教えてください）、html側に「何番目の要素か」を取得するための「data-」要素を追加することにした。

具体的には、
【data-greet-num = "0〜2の数字"】
を追加記述。これでjs側に番号を渡し、jsでは
el.target.dataset.greetNum
で受け取ってやることにする。

つまり、、、、

```rails:.html.erb
<div data-controller="test-desu">
  <div>
    A-1 :<input data-target="test-desu.name_1" type="text">
    <button data-action="click->test-desu#greet" data-greet-num = "0" >Greet-1</button>
  </div>

  <div>
    A-2 :<input data-target="test-desu.name_1" type="text">
    <button data-action="click->test-desu#greet" data-greet-num = "1" >Greet-2</button>
  </div>

  <div>
    A-3 :<input data-target="test-desu.name_1" type="text">
    <button data-action="click->test-desu#greet" data-greet-num = "2" >Greet-3</button>
  </div>

  B :<input data-target="test-desu.name_2" type="text">


  <label data-target="test-desu.write_here">C :write here</label>

</div>
```

```test_desu_controller.js

import { Controller } from "stimulus"

export default class extends Controller {
  static targets = [ "name_1","name_2","write_here" ]

  greet(el) {
    this.write_hereTarget.textContent =
    this.name_1Targets[el.target.dataset.greetNum].value +
    "。そして、" + this.name_2Target.value;
  }

// ↓「name」に「el」を渡せなかったため、関数自体を取り消して「greet(el)」に纏めた
  // get name(el) {
  //   return this.name_1Targets[el.target.dataset.greetNum].value
  // }
  // get name2() {
  //   return this.name_2Target.value
  // }
}
```

こうすると、
![スクリーンショット 2019-05-19 1.35.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410674/6822890f-04db-46f9-c6c4-c50e29f06c60.png)
こうなる。

#さらに応用
< data-greet-num = "数字" >
の数字番号は、ただ0から順番に振っているだけ。
だから当然、【一覧画面、検索されたデータを「モデル名.each do」で回して一行ずつ表示】している部分にも簡単に当てることができる。

以下は、【「cd」と「name」の列を持つuser情報の一覧画面（scaffoldで作成）】に追記したもの

```rails:user/index.html.erb
<h1>Users</h1>
<div data-controller="greet-user">

  <table>
    <thead>
      <tr>
        <th>Cd</th>
        <th>Name</th>
        <th colspan="4"></th>
      </tr>
    </thead>

    <tbody >

      <% @users.each_with_index do |user,i| %>
        <tr>
          <td><%= user.cd %></td>
          <td data-target="greet-user.name" ><%= user.name %></td>
          <td><%= link_to 'Show', user %></td>
          <td><%= link_to 'Edit', edit_user_path(user) %></td>
          <td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>

          <td><button data-action="click->greet-user#greet" data-greet-num = <%= i.to_s %> >Greet</button></td>

        </tr>
      <% end %>
    </tbody>

  </table>

  <label data-target="greet-user.write_here">write here</label>

</div>

<br>

<%= link_to 'New User', new_user_path %>

```


```greet_user_controller.js


import { Controller } from "stimulus"

export default class extends Controller {
  static targets = [ "name","write_here" ]

  greet(el) {
    this.write_hereTarget.textContent =
    this.nameTargets[el.target.dataset.greetNum].textContent +
    "さん、こんにちは。" ;
  }

}
```
↓↓↓↓
![スクリーンショット 2019-05-19 2.21.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410674/8e58d896-5d23-dc28-118b-97d40e6c1f87.png)

ボタンを押すと、
【選択した行の「Name」 + "さん、こんにちは。"】が表示される。


うん、少しずつではあるが、stimulusの使い方がつかめてきた気がする。