1
1
お題は不問!Qiita Engineer Festa 2024で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

ゼロから始めるstimulus入門2(現実的なものを作る)

Last updated at Posted at 2024-06-11

はじめに

前回から引き続いて、ドキュメントを読み進めます。
前回の記事はこちら→ゼロから始めるstimulus入門1
今回は、より具体的な実装をドキュメントを見ながらやっていきます。

コピーボタンを実装

PIN(個人識別番号)を生成して、ほかのユーザーにアクセス権を付与できるアプリを考えます。
以下のコードは生成されたPINをクリップボードにコピーできる機能です。

<div>
  PIN: <input type="text" value="1234" readonly>
  <button>Copy to Clipboard</button>
</div>

実装方法1(クリップボードがひとつだけの場合)

clipboard_controller.js

htmlと見比べながら、読んでいってください。

  • static targets = [ "source" ]でターゲットを定義。htmlのdata-clipboard-target="source"と対応
    • this.sourceTargetのようにアクセスできるようになる
  • navigator.clipboardでClipboard APIが呼び出され、writeTextでクリップボードにテキストを書き込む
// src/controllers/clipboard_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = [ "source" ]

  copy(event) {
    navigator.clipboard.writeText(this.sourceTarget.value)
  }
}

html

  • data-controller="clipboard"でclipboard_controller.jsと接続
  • data-clipboard-target="source"でテキストフィールドを参照
  • data-action="clipboard#copy"でclipboard_controller.jsのcopyメソッドが呼び出される
<div data-controller="clipboard">
  PIN: <input data-clipboard-target="source" type="text" value="1234" readonly>
  <button data-action="clipboard#copy">Copy to Clipboard</button>
</div>

実際の画面

PINが一つ表示され、値がコピーできます。
image.png

実装方法2(クリップボードが複数ある場合)

clipboard_controller.js

jsに変更はありません。

// src/controllers/clipboard_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = [ "source" ]

  copy(event) {
    navigator.clipboard.writeText(this.sourceTarget.value)
  }
}

html

jsはいじらずに、inputのvalueだけ変更したPINを追加するとそれぞれコピーすることができます。

<div data-controller="clipboard">
  PIN: <input data-clipboard-target="source" type="text" value="1234" readonly>
  <button data-action="clipboard#copy">Copy to Clipboard</button>
</div>

<div data-controller="clipboard">
  PIN: <input data-clipboard-target="source" type="text" value="3737" readonly>
  <button data-action="clipboard#copy">Copy to Clipboard</button>
</div>

実際の画面

PINが二つ表示され、それぞれコピーボタンをおしたら、値をコピーできました。
image.png

ターゲットの定義について

static targetsというようなものをつけてtargetを指定していますが、これの意味について深掘っていこうと思います。

export default class extends Controller {
  static targets = [ "source" ]

  // ...
}

static配列であるtargetsの中にターゲット名の文字列を探しています。
配列内の各ターゲット名に対して、Stimulusは以下の3つの新しいプロパティをコントローラーに追加しています。

  • this.sourceTarget
    コントローラーのスコープ内で最初のsourceターゲットを指定する。
    sourceターゲットが存在しない場合、このプロパティにアクセスするとエラーが投げられる。
  • this.sourceTargets
    コントローラーのスコープ内のすべてのsourceターゲットを含む配列を指定する。
  • this.hasSourceTarget
    sourceターゲットが存在する場合はtrue、存在しない場合はfalseを返す。

イベントの省略

本来ならば、クリックイベントではclick->をつけますが、アクションの記述でclick->を省略していました。これは、Stimulusが要素に対するアクションのデフォルトイベントとしてclickを定義していいるためです。
他にもいくつかの要素にデフォルトイベントが設定されています。

要素 デフォルトイベント
a click
button click
details toggle
form submit
input input
input type=submit click
select change
textarea input

次回

さらに、ドキュメントを進めていきます。
イベントの種類についてもどこかでまとめられたらと思います。

1
1
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
1
1