Salesforce：テキスト項目の入力内容に応じてlightning-button の有効/無効（disabled属性）を切り替える方法

<font color="Red">
2020/5/20更新：この記事を書いた後、コメント頂いたり、直接、助言を頂けたので、ベストな書き方として見直した版を追記しました！
</font>

## 背景
`Lightning Web Component(lwc)`を触って開発していると、テキストエリアに文字が入力されていない間は、`lightning-button`を無効化させたままとし、文字入力されたらボタンが有効化される仕組みを実装したいと思った。

やり方を忘備録として残す。

### 当時の試行錯誤
<details><summary>5/19時点、私が試行錯誤した結果です。（見たい人だけ見てね！）</summary><div>


``` inputForm.html
<template>
  <div class="slds-form-element">
    <label class="slds-form-element__label">入力してください</label>
    <div class="slds-form-element__control slds-grow textarea-container">
      <textarea
        class="slds-textarea"
        style="height:6rem;"
        onkeyup={handleInput}
        onblur={handleInput}
      ></textarea>
    </div>
  </div>
  <div slot="footer">
    <lightning-button
      label="保存"
      disabled={isDisableSave}
      variant="brand"
      onclick={save}>
    </lightning-button>
  </div>
</template>
```
html側では対象としたいテキスト入力要素のキーイベントをキャッチして入力てチェックするようにする。
今回は、以下イベント時に入力チェックする（`handleInput`メソッドを呼ぶ）ようにした。

 - テキストエリア要素上でキーボードの何れかのキーを放した時のイベント(`onkeyup`)
 - テキストエリア要素上でキーボードのフォーカスが外れた時(`onblur`)

そして、`lightning-button`の`disabled`属性に対して項目`isDisableSave`の内容によって変更するように指定する。



``` inputForm.js
import { LightningElement, track } from 'lwc';

export default class InputForm extends LightningElement {
  @track isDisableSave = true;  // 初期値：保存ボタン無効

  handleInput() {
    const input = this.template.querySelector('.slds-textarea');
    if(!input) {
      this.isDisableSave = true;  // null ならば保存ボタン無効
    }
    if(input.value.length === 0) {
      this.isDisableSave = true;  // 未入力ならば保存ボタン無効
    } else {
      this.isDisableSave = false; // 入力されていた場合、保存ボタンが入力可能
    }
  }

  save() {
    // 省略
  }
}
```
js側では、`isDisableSave`項目には、@track を装飾させて、値の変更があった時に再レンダリングするようにした。
そして、`handleInput`メソッドが各イベントで呼び出されるたびに、テキストエリアの入力要素を取得し、文字数が0以外だった場合に、保存ボタンが有効にするようにした。

この仕組みで、テキストエリアに文字が入力されていない間は、`lightning-button`を無効化させたままとし、文字が入力されたらボタンが有効化されるようにしました。
<font color="Red">
改めてこのやり方は、テキストエリアの値をバインドしたくない時などには使えるかもしれないです。
</font>
</div></details>


### 助言いただいた書き方記録

@shunkosa さん、また口頭で助言くださった方、本当にありがとうございます。


``` app.html
<template>
    <div class="slds-p-around_medium">
        <lightning-textarea label="Textarea 1" value={text} onchange={handleInput}></lightning-textarea>
        <lightning-button label="Submit" variant="brand" disabled={disabled}></lightning-button>
    </div>
</template>
```
html側では対象としたいテキスト入力要素の`onchange`イベントをキャッチして、入力チェックする（`handleInput`メソッドを呼ぶ）。

そして、`lightning-button`の`disabled`属性に対して項目`disabled`の内容によって変更するように指定する。



``` app.js
import { LightningElement, track } from 'lwc';

export default class App extends LightningElement {
    text;

    handleInput(event) {
        this.text = event.target.value;
    }
    
    get disabled() {
        return !this.text;
    }
}

```
js側では、`text`項目に、@track を装飾させて、値の変更があった時に再レンダリングが動く（getterである`disabled`メソッドが動く）ようにします。
そして、`handleInput`メソッドでは、イベント発生時のテキストエリアの入力内容を`text`項目に適用させてあげる。

`disabled`メソッドでは、入力されていなければ、ボタン無効、入力されていればボタン有効というように実装します。
なお、私自身JavaScriptは常に勉強中の身で・・・知らなかったのですが、JavaScriptの文字列変数は`!変数名(上記例：!this.text)` という書き方で文字に値が入力されているかチェックできるそうです。これはJavaScriptならではであり、他の言語では書けない書き方ですが、本当・・・JavaScriptは奥が深い・・・。


この仕組みで、テキストエリアに文字が入力されていない間は、`lightning-button`を無効化させたままとし、文字が入力されたらボタンが有効化されるようになります。




## 最後に
<details><summary>5/19時点、のコメントなのでクローズ。（見たい人だけ見てね！）</summary><div>

これ以外のやり方があるかもしれないけれど、見つけきれなかったのでひとまず上記のやり方になりました。
`lwc`で`Vue.js`の`watch`のような入力監視があればロジック減って嬉しいなぁ・・・。
もし、ないなら未来的に入力監視の機能とかが増えると嬉しいなぁ。・・・と、そう思いました。
</div></details>

（5/20追記）
最後に、助言くださりありがとうございます。
Qiitaに忘備録として上げましたが、より理解が深まりました。

同時に、これまた知らなかったことですが、`Salesforce`の`Playground`って、サンプルソースを共有する仕組みがあるのですね・・・本当感動です。
化物ようにすごいplatformですわ・・・なんというか本当すごい。

以上です。ではでは。