Flexを使ったApexアプリケーション開発(2)

by Shinichi Tomita on 6月 28, 2007 at 03:38 午後

Salesforceのレコードを一覧表示する

Flexでは多数の再利用可能なユーザーインターフェース部品がコンポーネントとして提供されています。特にDataGridコンポーネントは、複数レコードの情報を表形式で一覧表示することができるため、データベースのレコード検索結果を表示するのによく使われます。

ここではSalesforceのデータベースから検索したレコードを、DataGridコンポーネントに一覧表示するアプリケーションを作成します。

AccountGrid1.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
                xmlns:salesforce="com.salesforce.*"
                layout="vertical"
                applicationComplete="login()" >
  <mx:Script>
    <![CDATA[
import mx.collections.ArrayCollection;
import com.salesforce.*;
import com.salesforce.events.*;
import com.salesforce.objects.*;
import com.salesforce.results.*;

/**
* 取引先情報レコードを保管する変数
* Bindable メタデータを記述して、コンポーネントにデータを関連付けられるように設定
*/
[Bindable]
private var accounts:ArrayCollection = new ArrayCollection();


/**
* Salesforceにログインして、セッションを構築する
* アプリケーションのロード完了時に呼び出される
*/
private function login():void {
  var lr:LoginRequest = new LoginRequest({
    server_url : Application.application.parameters.server_url,
    session_id : Application.application.parameters.session_id,
    // username : '', // <-- put your username here!
    // password : '', // <-- put your password here!
    callback : new AsyncResponder(function(result:Object):void {
      // ログイン後、取引先データを取得
      queryAccounts();
    })
  });
  conn.login(lr);
}

/**
* 取引先レコード情報の取得
* テーブル内の全レコードを上限まで取得
*/
private function queryAccounts():void {
  var soql:String = "SELECT Id, Name, Type, Rating, BillingState, Phone FROM Account";
  // SOQLクエリを送信
  conn.query(soql, new AsyncResponder(function(result:QueryResult):void {
    // 取得したレコードをそのままaccounts変数に格納
    accounts = result.records;
  }));
}
    ]]>
  </mx:Script>

  <!-- Salesforce Connection オブジェクト -->
  <salesforce:Connection id="conn" />

  <!-- 検索結果表示 -->
  <mx:DataGrid width="100%" height="100%" dataProvider="{accounts}">
    <mx:columns>
      <mx:DataGridColumn headerText="ID" dataField="Id" />
      <mx:DataGridColumn headerText="取引先名" dataField="Name" />
      <mx:DataGridColumn headerText="種別" dataField="Type" />
      <mx:DataGridColumn headerText="評価" dataField="Rating" />
      <mx:DataGridColumn headerText="都道府県(請求先)" dataField="BillingState" />
      <mx:DataGridColumn headerText="電話番号" dataField="Phone"/>
    </mx:columns>
  </mx:DataGrid>

</mx:Application>
実行結果(AccountGrid1.mxml)

Ws000005

上記のソースコード(AccountGrid1.mxml)では、ログイン完了後にコールバック関数からqueryAccounts メソッドが呼び出され、その中でSOQLクエリをSalesforceに対して送信しています。クエリの結果は非同期で取得するため、レスポンスを受け取るためのコールバック関数を指定してクエリを送信します。コールバック関数が結果レスポンスを受け取ると、そのままレコード情報がaccounts変数に設定されます。

DataGrid中のデータ表示には、Flexのデータバインディングの仕組みを用いているので、開発者はレンダリングについて特に気にする必要はありません。あらかじめMXML中のDataGrid要素のdataProvider属性にバインディングするデータを指定しておくだけです。バインディングされた変数にデータ変更があった場合は自動的にグリッド表示にも反映されます。

DataGridには、ソートや列の入れ替えといった機能もあらかじめ備わっています。そのため、上記コードは最小のコード量ではありますが、実際に実行してみると、結果として単なるレコード一覧表示のみにはとどまっていないのが確認できるかと思います。

検索の条件を指定する

次のステップとして、上記のアプリケーションを拡張して、検索するレコードの絞込みができるようにします。ここでは検索条件として、項目値の選択リストを用いることで、合致するレコードのみを抽出するように設定します。

AccountGrid2.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
                xmlns:salesforce="com.salesforce.*"
                layout="vertical"
                applicationComplete="login()" >
  <mx:Script>
    <![CDATA[
import mx.collections.ArrayCollection;
import com.salesforce.*;
import com.salesforce.events.*;
import com.salesforce.objects.*;
import com.salesforce.results.*;

/**
* 取引先情報レコードを保管する変数
* Bindable メタデータを記述して、コンポーネントにデータを関連付けられるように設定
*/
[Bindable]
private var accounts:ArrayCollection = new ArrayCollection();

/**
* 「種別」フィールド値の選択リストデータを保管する変数
*/
[Bindable]
private var typeDefs:ArrayCollection = new ArrayCollection([
  { label : '--------', data : 0 }
]);

/**
* 「評価」フィールド値の選択リストデータを保管する変数
*/
[Bindable]
private var ratingDefs:ArrayCollection = new ArrayCollection([
  { label : '--------', data : 0 }
]);


/**
* Salesforceにログインして、セッションを構築する
* アプリケーションのロード完了時に呼び出される
*/
private function login():void {
  var lr:LoginRequest = new LoginRequest({
    server_url : Application.application.parameters.server_url,
    session_id : Application.application.parameters.session_id,
    // username : '', // <-- put your username here!
    // password : '', // <-- put your password here!
    callback : new AsyncResponder(function(result:Object):void {
      setupForm();
    })
  });
  conn.login(lr);
}


/**
* 検索絞込みフォームのセットアップ
* 選択リストの定義をdescribeSObjectメソッドで取得
*/
private function setupForm():void {
  conn.describeSObject("Account", new AsyncResponder(function(result:DescribeSObjectResult):void{
    // 「種別(Type)」項目の選択リスト値を取得
    for each (var p:PickListEntry in result.fields['Type'].picklistValues) {
      // アクティブな選択リストのラベルと値のペアを保存
      if (p.active) typeDefs.addItem({ label : p.label, data : p.value });
    }
    // 「評価(Rating)」項目の選択リスト値を取得
    for each (var p:PickListEntry in result.fields['Rating'].picklistValues) {
      // アクティブな選択リストのラベルと値のペアを保存
      if (p.active) ratingDefs.addItem({ label : p.label, data : p.value });
    }
    // 検索ボタンを有効化する
    queryButton.enabled = true;
  }));
}

/**
* 取引先レコード情報の取得
* 検索条件に合致するレコードを上限まで取得する
*/
private function queryAccounts():void {
  var soql:String = "SELECT Id, Name, Type, Rating, BillingState, Phone FROM Account";
  var conditions:Array = [];
  if (ratingPicklist.value) {
    conditions.push(" Rating = '"+ratingPicklist.value+"' ");
  }
  if (typePicklist.value) {
    conditions.push(" Type = '"+typePicklist.value+"' ");
  }
  if (conditions.length>0) { // 条件指定があればWHERE句としてSOQLに追加
    soql += ' WHERE '+conditions.join(' AND ');
  }
  conn.query(soql, new AsyncResponder(function(result:QueryResult):void {
    accounts = result.records;
  }));
}
    ]]>
  </mx:Script>

  <!-- Salesforce Connection オブジェクト -->
  <salesforce:Connection id="conn" />
 
  <!-- 検索フォーム -->
  <mx:HBox>
    <mx:FormHeading label="種別" />
    <mx:ComboBox id="typePicklist" dataProvider="{typeDefs}" />
    <mx:FormHeading label="評価" />
    <mx:ComboBox id="ratingPicklist" dataProvider="{ratingDefs}" />
    <mx:Button id="queryButton" click="queryAccounts()" label="検索" enabled="false" />
  </mx:HBox>

  <!-- 検索結果表示 -->
  <mx:DataGrid width="100%" height="100%" dataProvider="{accounts}">
    <mx:columns>
      <mx:DataGridColumn headerText="ID" dataField="Id" editable="false"/>
      <mx:DataGridColumn headerText="取引先名" dataField="Name" />
      <mx:DataGridColumn headerText="種別" dataField="Type" />
      <mx:DataGridColumn headerText="評価" dataField="Rating" />
      <mx:DataGridColumn headerText="都道府県(請求先)" dataField="BillingState" />
      <mx:DataGridColumn headerText="電話番号" dataField="Phone"/>
    </mx:columns>
  </mx:DataGrid>

</mx:Application>
実行結果(AccountGrid2.mxml)

Ws000006

今回のソースコード(AccountGrid2.mxml)では、コンポーネントとして新しく、2つの選択リスト(ComboBoxコンポーネント)と検索実行のためのボタン(Buttonコンポーネント)が追加されました。

また、ログイン後に自動的に取引先レコードの検索を行うのではなく、検索ボタンをクリックした場合にクエリが呼び出されるように変更しています。

アプリケーションの初期化作業としてログイン処理後にsetupFormメソッドが呼び出されます。その中では、取引先オブジェクトの定義情報をdescribeSObjectメソッドで呼び出して、あらかじめ定義されている「種別(Type)」および「評価(Rating)」選択リスト項目の選択リストの値を取り出しています。

取り出された選択リストの情報は、typeDefsおよびratingDefs変数に格納され、データバインディングによって検索フォームのComboBoxコンポーネントに値が反映されます。

検索ボタンがクリックされるとqueryAccountsメソッドが呼び出されます。queryAccountsメソッドでは、検索実行前に検索フォームの値をチェックし、検索条件が設定されている場合には動的にSOQLクエリに条件句(WHERE)を追加しています。検索後、グリッドに表示されるレコードがあらかじめ選択リストに設定した条件に絞り込まれたものになっていることを確認してください。

トラックバック

このページのトラックバックURL: http://www.typepad.jp/t/trackback/7240/7030613

このページへのトラックバック一覧 Flexを使ったApexアプリケーション開発(2):

コメント

Posted by on 9月 22, 2007 12:50 午後:

パートナー募集でますか?

申請職務:Flexプログラム要員

忙しい時にお邪魔します。会社は全部にFlexプログラム要員の30名ぐらいにいる。費用は600円/時間しかないです。ご連絡してください。よろしくお願い致します。会社のホームページhttp://www.busycode.jp。メールアドレスcogoing@gmail.com。


どうもありがとうございます、
田中

コメントを投稿

コメントは記事の投稿者が承認するまで表示されません。