背景
Lightning Web Component(lwc)
を触って開発していると、テキストエリアに文字が入力されていない間は、lightning-button
を無効化させたままとし、文字入力されたらボタンが有効化される仕組みを実装したいと思った。
やり方を忘備録として残す。
当時の試行錯誤
5/19時点、私が試行錯誤した結果です。(見たい人だけ見てね!)
<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
の内容によって変更するように指定する。
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
を無効化させたままとし、文字が入力されたらボタンが有効化されるようにしました。
改めてこのやり方は、テキストエリアの値をバインドしたくない時などには使えるかもしれないです。
助言いただいた書き方記録
@shunkosa さん、また口頭で助言くださった方、本当にありがとうございます。
<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
の内容によって変更するように指定する。
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
を無効化させたままとし、文字が入力されたらボタンが有効化されるようになります。
最後に
5/19時点、のコメントなのでクローズ。(見たい人だけ見てね!)
これ以外のやり方があるかもしれないけれど、見つけきれなかったのでひとまず上記のやり方になりました。
lwc
でVue.js
のwatch
のような入力監視があればロジック減って嬉しいなぁ・・・。
もし、ないなら未来的に入力監視の機能とかが増えると嬉しいなぁ。・・・と、そう思いました。
(5/20追記)
最後に、助言くださりありがとうございます。
Qiitaに忘備録として上げましたが、より理解が深まりました。
同時に、これまた知らなかったことですが、Salesforce
のPlayground
って、サンプルソースを共有する仕組みがあるのですね・・・本当感動です。
化物ようにすごいplatformですわ・・・なんというか本当すごい。
以上です。ではでは。