Lightning ComponentだけでAutocompleteっぽいものを実装してみる

はじめに

みなさん、こんにちは。
走れるシステムエンジニア、溝口です。

3月13日に行われた横浜マラソンは2時間51分49秒と大撃沈してしまいました。
立て続けに試合に出た疲労感もありましたが、調整をミスった感がありました。

春先はトラックレースで5000mで15分30秒切りを目標に練習していきます!

Autocomplete機能について

さてさて、今回はLightningに関しての小ネタを書いて行こうと思います。

みなさんはSalesforce上でアプリケーション開発をする際に、テキストフィールドにAutocomplete機能を実装しよう、となった場合、どういった手段を取るでしょうか?

大丈夫です、聞かなくても分かっています。この世の中には気の利いたjavascriptのAutocomplete用のライブラリが沢山用意されていますので、どれを使おうかな、と頭を悩ませる所から始めるのでしょう。

では

もし外部のライブラリが使えない状況に陥ったら?
そうなったらLightningの機能のみでAutocompleteを実装しなければいけません。
(そんな状況あるはず無い!と思っているアナタ!この世の中には往々にして予想外のことが起こり得るのです!)

今回はそんな状況に陥ったことを前提として、Lightningで提供されている機能のみでAutocompleteを実装してみることにしましょう!

ui:autocomplete があるじゃん!

まず手始めにauraのドキュメント
http://documentation.auraframework.org/auradocs
を眺めてみることにしました。(これがそもそもの間違いだったのですが・・・)

そうすると何ということでしょう「ui:autocomplete」なる素敵なタグがあるではありませんか。

中に書いてあることもそれっぽい感じですし、やった!これで全てが上手くいく!と思ったのですが。

ん?

んんん?

僕の目に飛び込んできた「PROTO」の文字。そう、このコンポーネントはまだGAされていなかったのです!

みなさん、Lihgtning開発する際はauraのドキュメントではなく、GAされたコンポーネントが記載されているSalesforceのドキュメントを読みましょう。
https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/aura_compref.htm

ui:menuとui:inputTextを組み合わせてしまおう

そんなこんなで絶望に暮れている時間など無く、あるものでどうにかしないといけない状況になってしまいました。

そこで僕はドキュメントを探りながら考えました。
「あれ、このui:menuってコンポーネント、よく見るとAutocompleteっぽく見えるんじゃね・・・?」
と。

ということは、このui:menuをui:inputTextの下にピロっと出せばそれっぽく見えるはず!
今度こそ上手くいくはずです!!

実装してみた

まず、Lightning Componentを以下のように実装しました。

単純にui:inputTextの下にui:menuを配置し、ui:inputTextのフォーカスイベントでui:menuを表示させるようにしています。

<aura:component >
    <aura:attribute name="menuListVisible" type="Boolean" default="false" description="MenuListを表示するかどうか"/>
    <aura:attribute name="autoCompleteList" type="String[]" default="value1, value2, value3" description="MenuListで表示する値"/>
    
    <ui:inputText value="" focus="{!c.textFieldOnFocus}"/>
    <ui:menu >
        <ui:MenuList aura:id="actionMenu" closeOnClickOutside="false" visible="{!v.menuListVisible}">
            <aura:iteration var="val" items="{!v.autoCompleteList}" indexVar="index">
                <div>{!val}</div>
            </aura:iteration>
        </ui:MenuList>
    </ui:menu>
</aura:component>


次にコントローラ側の実装です。
コンポーネント側のフォーカスイベントで呼び出され、menuの出す、出さないを制御する値をバインドします。

({
	textFieldOnFocus : function(component, event, helper) {
        var menulistVisible = component.get("v.menuListVisible");
        if (menulistVisible) {
          component.set("v.menuListVisible", false);
        } else {
          component.set("v.menuListVisible", true);
        }
	}
})

これをLightningアプリケーションに組み込んで動かしてみましょう。


そ、それっぽい!
スタイルを付けていないのでかなり味気ない感じですが、ちゃんと加工すればそれっぽく映るようになります。

今回はとりあえず表示させる為にフォーカスイベントでアクションを呼んでいますが、keyupやkeydownのイベントでui:menuのリストの値を都度書き換えることでAutcompleteとしての機能は満たせるようになります。

まとめ

Lightningのuiコンポーネントはこれからどんどん増えてくると思われますが、現状あるもので何とかしなければいけなくなったとしても、既存の機能の組み合わせで意外と動くものが出来たります。

Lightningコンポーネント自体を継承する機能も備わっているので、既存のコンポーネントを継承して独自のコンポーネントを作ってしまうことも出来ます。

今回はかなりイレギュラーなケースを想定したものですが、みなさんも色々なコンポーネントを組み合わせてLightning開発をしてみてはいかがでしょうか!