【SAPUI5】リストのフィルタリング

##フィルタとは
リストに表示されるレコードを、特定の条件で絞りたい場合にフィルタを使います。SAPUI5では、SearchFieldというコントロールを使ってフィルタを実装します。

##フィルタの実装
###ゴール
リストに検索条件を追加して、製品名で結果を絞り込めるようにします。

![WS000062.JPG](https://qiita-image-store.s3.amazonaws.com/0/276021/73f9c8e6-0c72-6c86-46e1-5eca79b79cd6.jpeg)

###ステップ

前提：[【SAPUI5】入門編の記事まとめ(2)](https://qiita.com/tami/items/f1537c0e9c81cfaa99e7)

1. ビューにSearchFiledを追加
2. コントローラに検索メソッドを追加

###1. ビューにSearchFiledを追加
App.view.xmlのList以下を次のように変更します。

**変更前**

```xml
                            <List items="{mPricelist>/products}">
                                <items>
                                    <ObjectListItem
                                     ・・・
```
**変更後**

```xml
							<List 
								id="productList"
								items="{mPricelist>/products}">
								<headerToolbar>
									<Toolbar>
										<Title width="100%" text="Products"/>
										<SearchField search="onFilterProducts"/>										
									</Toolbar>
								</headerToolbar>
```

コントローラ側でリストを特定できるようにidを付与します。
Listの先頭にToolbarを置き、その中にTitleとSearchFieldを配置します。
SearchFildには、検索を実行したときに呼ばれるメソッドを指定します。

ところで、Toolbarの中にはどんなコントロールを置けるのでしょうか？
[sap.m.Toolbarのリファレンス](https://sapui5.hana.ondemand.com/#/api/sap.m.Toolbar/controlProperties)を見たところ、Aggregationsの型がsap.ui.core.Controlとなっているので、何でもOKのようです。（試しにButtonを追加してみたところ、できました）
![WS000068.JPG](https://qiita-image-store.s3.amazonaws.com/0/276021/12fc505e-4bda-4748-7f5e-41161c2e7425.jpeg)

###2. コントローラに検索メソッドを追加
App.controller.jsに以下のコードを追加します。

```javascript
sap.ui.define([
	"sap/ui/core/mvc/Controller",
	"sap/ui/model/json/JSONModel",
	"sap/m/MessageToast",
    //追加↓
	"sap/ui/model/Filter",
	"sap/ui/model/FilterOperator",
    //追加↑
	"test/helloworld/model/formatter"
], function (Controller, JSONModel, MessageToast, 追加→Filter, 追加→FilterOperator, formatter) {
   "use strict";
   return Controller.extend("test.helloworld.controller.App", {
   		formatter: formatter,
   	
		_data : {
			"date" : new Date()
		},

		onInit : function (oEvent) {
			var oModel = new JSONModel(this._data);
			this.getView().setModel(oModel);
		},
		
		onShowHello : function () {
			// read msg from i18n model
			var oBundle = this.getView().getModel("i18n").getResourceBundle();
			var sProduct = this.getView().getModel("mPrice").getProperty("/product/name");
			var sMsg = oBundle.getText("helloMessage", [sProduct]);
      	
        	// show a native JavaScript alert
        	MessageToast.show(sMsg);
    	},
      
		//追加
		onFilterProducts : function (oEvent) {

			// build filter array
			var aFilter = [];
			var sQuery = oEvent.getParameter("query");
			if (sQuery) {
				aFilter.push(new Filter("name", FilterOperator.Contains, sQuery));
			}

			// filter binding
			var oList = this.byId("productList");
			var oBinding = oList.getBinding("items");
			oBinding.filter(aFilter);			
		},      
   });
});		
```
まず、FilterとFilterOperatorという2つのクラスを使うために先頭にこれらを追加します。
onFilterProductsメソッドの中では、SearchFieldに入力した検索条件を取得します。
条件が入力されている場合はフィルタオブジェクトを作成して配列に格納します。
※条件が未入力の場合、配列は空のままです。これによって条件を指定せずに検索実行したときにフィルタがかからないようになります。
続いてリストにバインドされたitemを取得し、itemに対してfilterを実行します。

参考までに、デバッグで見てみるとイベントパラメータのqueryというパラメータに入力した条件が設定されているのが確認できました。
![WS000070.JPG](https://qiita-image-store.s3.amazonaws.com/0/276021/08f6f251-ad5b-2da9-5999-61e9374e260c.jpeg)

###結果
以下のように、製品名(name)で絞り込みがされます。検索条件の大文字小文字は区別されません。
![WS000071.JPG](https://qiita-image-store.s3.amazonaws.com/0/276021/26c9a4fb-4bcd-f1fc-6a5c-6db25b97b488.jpeg)

##Filterの生成方法についてもう少し詳しく
Filterオブジェクトは以下のように生成しました。
`new Filter("name", FilterOperator.Contains, sQuery)`
第一引数はpath（どの項目に対してフィルタをかけるか）, 第二引数はoperator（フィルタ条件）、第三引数はvalue（フィルタ値）です。
Filterは以下の3つの生成方法があります。今回のケースは1番目に当たります。

1. path, operator, 1つまたは2つのvalue(value1, value2)
2. path, 独自のフィルタ用ファンクション(test)
3. filtersでくくった複数のフィルタと、それらのフィルタをANDでつなげるかORでつなげるかのフラグ(ture=AND, false=OR)

詳しくは下記を参照してください。
[sap.ui.model.Filter](https://sapui5.hana.ondemand.com/#/api/sap.ui.model.Filter/constructor)

##FilterOperatorとは？
FilterOperatorはフィルタ条件を指定するための定数の集まりです。
フィルタ条件とは、指定した値を「含む」なのか「等しい」なのかといった条件のことです。
今回はContainsを使いましたが、これは「含む」に該当します。
その他、一部を以下に記載します。これ以外の値については下記をご参照ください。
[sap.ui.model.FilterOperator](https://sapui5.hana.ondemand.com/#/api/sap.ui.model.FilterOperator/properties)

|値  |意味  |
|---|---|
|sap.ui.model.FilterOperator.BT  |2つの値の間  |
|sap.ui.model.FilterOperator.EndsWith  |～で終わる  |
|sap.ui.model.FilterOperator.EQ  |～に等しい  |
|sap.ui.model.FilterOperator.GT  |～より大きい  |
|sap.ui.model.FilterOperator.StartsWith  |～で始まる  |


##参考にしたページ
[Get Started: Setup and Tutorials-Walkthrough-Step 24: Filtering](https://sapui5.hana.ondemand.com/#/topic/5295470d7eee46c1898ee46c1b9ad763)