Appirio's Tech Blog

2011年8月2日火曜日

Force.com アプリケーションで入力補完を提供する方法

Google サジェストなどに代表される入力補完機能を Force.com で簡単に実現する方法をご紹介します。

今回は入力補完のライブラリとして jQuery と jquery.suggest.js を利用し、Force.com 上に入力補完が有効な Account の Name 入力フィールドを用意してみます。

jquery.suggest.js

jquery.suggest.js の登録


開発に先立って jquery.suggest.js を Force.com 上に静的リソースとして登録します。
"jquery.suggest.js" と "jquery.suggest.css" 及び jQuery をダウンロードし zip 形式でアーカイブします。アーカイブが完了したら静的リソースに "BLG_Typeahead" という名前で登録します。

少し分かりにくいですが "jquery.suggest.js"、"jquery.suggest.css" は画面下部よりダウンロード可能です。下の画像を参考にしてください。



入力補完データ作成


jquery.suggest.js からユーザの入力文字列を受け取り、入力補完用のデータを返すロジックを Force.com 上に作成します。ここでは "BLG_SearchAccount.cls" という Apex Class と "BLG_SearchAccount.page" という Visualforce Page の 2 ファイルを作成します。

BLG_SearchAccount.cls
public class BLG_SearchAccount {

    public List<String> results {get; private set;}

    public void search() {
        this.results = new List<String>();

        // 検索条件を用意
        String query = System.currentPageReference().getParameters().get('q');
        if(query == null || query == '') {
            return;
        }
        String nameCondition = String.escapeSingleQuotes(query.replaceAll('%', '')) + '%';

        // 検索
        List<AggregateResult> accounts = [select Name from Account
                                                     where Name like :nameCondition
                                                  group by Name
                                                  order by Name
                                                     limit 10];
        for(AggregateResult account : accounts) {
            this.results.add('' + account.get('Name'));
        }
    }
}
jquery.suggest.js は "q" というパラメータでユーザ入力文字列を送出します。BLG_SearchAccount.cls ではパラメータ "q" を取得し前方一致で Account を検索します。入力補完用のデータ作成が目的ですので重複したデータを除く先頭 10 件のみを返しています。

BLG_SearchAccount.page
<apex:page controller="BLG_SearchAccount" action="{!search}" contentType="plain/text">
 <apex:repeat value="{!results}" var="result">
  {!result}
 </apex:repeat>
</apex:page>
BLG_SearchAccount.page では BLG_SearchAccount.cls で作成した入力補完用のデータをテキストファイルとして出力します。 jquery.suggest.js は 1 行 1 アイテムの単純なテキストファイルを期待していますので、contentType に "plain/text" を指定しています。 ソースコードの改行位置で出力が変わりますので注意してください。

入力補完の組み込み


Account の Name を入力するフィールドを用意し、入力補完機能を組み込みます。ここでは "BLG_Typeahead.page" という Visualforce Page を作成します。 BLG_Typeahead.page

 <apex:page id="p" sidebar="false">
   <apex:stylesheet value="{!URLFOR($Resource.BLG_Typeahead, 'jquery.suggest.css')}"/>
   <apex:includeScript value="{!URLFOR($Resource.BLG_Typeahead, 'jquery-1.4.4.min.js')}"/>
   <apex:includeScript value="{!URLFOR($Resource.BLG_Typeahead, 'jquery.suggest.js')}"/>

   <apex:form id="f">
     <apex:pageBlock id="b">
       Account name  <apex:inputText id="name" />
     </apex:pageBlock>
   </apex:form>

   <!-- Typeahead を有効化 -->
   <script type="text/javascript" language="javascript" >
     function escapeVfId(vfId) {
       return '#' + vfId.replace(/(:|\.)/g,'\\\\$1');
     }
     jQuery(function() {
       jQuery(escapeVfId("p:f:b:name")).suggest("{!URLFOR($Page.BLG_SearchAccount)}",{});
     });
   </script>
 </apex:page>

jquery.suggest.js を有効にするため前述の "jquery.suggest.css"、"jquery.suggest.js" を読み込みます。併せて jquery.suggest.js が依存している jQuery も読み込んでおきます。

Name 入力用のフィールドに ID を付与し、その ID を用いて jquery.suggest.js に入力補完の有効化を指示します。 Force.com の用意する ":" で区切られた ID は jQuery でそのまま利用することができません。jQuery で利用可能な形式にエスケープする必要があります。

動作確認


Web ブラウザで "/apex/BLG_Typeahead" にアクセスし、動作確認をしてみます。 予め Account のデータをいくつか用意しておいてください。ここでは "dummy01" 〜 "dummy09" というアカウントを用意しています。

Name 入力用のフィールドに "dumm" を順番に入力してみます。入力補完が動作しフィールドの下に候補が表示されました。これで入力補完機能の作成は完了です。



jquery.suggest.js の動作を確認するため、画面下部に Firebug パネルを表示しています。 ユーザが 2 文字 ("du") 入力した段階で最初のデータ取得が実行されています。後は 1 文字毎に繰り返しデータ取得が行われます。 かなり頻繁にデータ取得が行われますので実業務に適用する際には SOQL の条件を見直す等のパフォーマンスチューニングが必要になる可能性があります。 今のところ検索対象のデータ量が多くなければ実用に耐える速度で動作しています。 日本に設置されたインスタンスを利用できれば快適な動作を期待できそうです。

さいごに


Force.com では標準機能として各種検索機能が提供されています。これらと今回ご紹介した入力補完機能を上手く組み合わせることでデータ入力負荷をかなり軽減することが出来ると思います。是非活用してみてください。


Posted by Takahashi Eiichiro (Appirio Japan)

0 コメント:

コメントを投稿

 
2006-2011 Appirio Inc. All rights reserved.
アピリオ | リソースセンター(英語) | お問い合わせ先 | 採用情報 | プライバシーポリシー(英語)