ServiceNowのUI PAGEでREST APIの検索結果をページネーション付きのリストで表示する

# 概要

UI PAGEで下記のような画面を作成する。

![検索結果.png](https://qiita-image-store.s3.amazonaws.com/0/197947/c9472e4a-2a4f-ca59-5e77-af0f000768b8.png)


検索ボタンをクリックすると、検索ワードでiTunes Search APIを使って検索し、
その結果をリストに表示する。
リスト表示はServiceNowのList Layoutをそのまま使用したいため、検索結果を一旦テーブルに保持し、そのテーブルのレコードをList Layoutで表示している。
また、今回の検索結果のみを表示するようにフィルターをかけて表示する。
具体的には検索を実行するたびにGUID(ユニークな３２桁のID)を生成し、検索結果をテーブルに格納時にGUIDを合わせて保存する。表示する時に、今回のGUIDでフィルターをかけている。

なお、List LayoutにArtWorkのURLを保持しているが、このURLを元に、List Layout内でイメージに表示をする方法は不明であったため、そのまま画像のURLを表示している。

## 環境

ServiceNow : KINGSTONE

iTunesのSearch APIの起動は下記で作成したOutbound MESSAGEを使用している。
[ServiceNowでiTunesのRestAPIを使用する(上編）](https://qiita.com/sukkyxp/items/18f950231d73d329fc04)

# 手順

## テーブル作成

検索結果を保存するためのテーブルを作成する。

|項目|値|
|---|---|
|Label|TrackList|
|Name|x_58872_needit_tracklist|

なお、NameはLabelから環境に応じて自動生成されるため、環境によって異なる。
今後、このテーブルを使用時には、自動生成されたNameの値を使用する。

このテーブルに下記の列を追加する。

|Label|Name|Type|Max length|
|---|---|---|---|---|
|Track Name|rack_name|String(Full UTF-8)|200|
|Art Work|art_work|URL|1024|
|runid|runid|String(Full UTF-8)|50|
|Search Word |search_word|String(Full UTF-8)|200|

## List Controlの作成

「Form & UI」の「List Control」を新規作成し、下記の通り設定を行う。

![ListControl.png](https://qiita-image-store.s3.amazonaws.com/0/197947/8ad753b1-7c97-24bd-d032-2f707a89ed0e.png)

これは、検索結果を表示したときに追加ボタンやフィルダー情報を表示しないようにするための制御となる。

Omit new button、Omit edit button、Omit filtersによりそれぞれ、新規ボタン、編集ボタン、フィルターが非表示の設定となる。


## List Layoutの作成

「Form & UI」の「List Layout」を新規作成し、下記のようにTrackNameをArtWorkを選択しておく。

![ListLayout.png](https://qiita-image-store.s3.amazonaws.com/0/197947/b6da82fa-8104-bb03-944e-0ef6c60d9727.png)

これにより、TrackListをリスト表示したときに、TrackNameとArtWorkの列のみ表示される。

## UI PAGE の作成

「Form & UI」の「UI Page」を新規作成する。

HTMLに下記の通り入力する。

```html
<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">


	
<g:ui_form>
	<table>
		<tr>
			<td>
				<g:ui_input_field 
					label="検索ワード" 
					name="searchInput" 
					value="${searchWord}" 
					size="50"/>
			</td>
		<td>
			<g:ui_button>検索</g:ui_button>
			</td>
		</tr>
	</table>


</g:ui_form>


<div id="resultList">       
	
<iframe src="x_58872_needit_tracklist_list.do?sysparm_query=runid=${runid}" 
	style="min-height:1024px;width:100%;" 
	scrolling="no" 
	frameborder="0">
</iframe>
</div>

</j:jelly>
```

iframeのソースとして下記を指定しる。
これがリスト表示の肝となる部分だ。


```html

x_58872_needit_tracklist_list.do?sysparm_query=runid=${runid}" 
```

「x_58872_needit_tracklist_list.do」は、作成したテーブルの「Name」+ 「_list.do」で作成する。テーブルのNameは環境によって異なるので書き換えが必要だ。

「sysparm_query=runid=${runid}」の部分は表示するレコードのフィルターの設定を行なっている。
これにより、「runid」の値が${runid}の値のレコードのみ表示される。
${runid}はサーバー側のスクリプトで設定した値となる。

## UI Pageのサーバースクリプト

UI PageのProcessing sriptには下記の通り入力する。

```javascript
try { 


	var searchWord = searchInput;
	//var searchWord = request.getParameter('searchword');
	 gs.info('searchWord = ' + searchWord);
	var r = new sn_ws.RESTMessageV2('x_58872_needit.iTunesSearch', 'Default GET');

	r.setStringParameterNoEscape('term', searchWord);
	r.setStringParameterNoEscape('country', 'jp');
	r.setStringParameterNoEscape('lang', 'ja_jp');
	r.setStringParameterNoEscape('media', 'music');
	r.setStringParameterNoEscape('attribute', 'artistTerm');
　
	var response = r.execute();
	var responseBody = response.getBody();
	var httpStatus = response.getStatusCode();

	var parser = new global.JSON();
	var parsed = parser.decode(responseBody);
	
	var gr = new GlideRecord('x_58872_needit_tracklist');
	//gr.deleteMultiple();
	
	var runid = gs.generateGUID();
	
	for (var i = 0; i < parsed.results.length; i++) {
		var result = parsed.results[i];
		gs.info('trackName = ' + result.trackName);
		
		 gr.initialize(); // レコード初期化

		//　レコード設定
		gr.setValue('track_name', result.trackName);
		gr.setValue('art_work', result.artworkUrl60);		
		gr.setValue('search_word', searchWord);
		gr.setValue('runid', runid);

		gr.insert();     // レコード追加

	
	}



}
catch(ex) {
 var message = ex.getMessage();
}
```

REST Messageの起動部分については下記を参考にして欲しい。

[ServiceNowでiTunesのRestAPIを使用する(上編）](https://qiita.com/sukkyxp/items/18f950231d73d329fc04)
[中編](https://qiita.com/sukkyxp/items/788c0310e29a56c06802)
[下編](https://qiita.com/sukkyxp/items/9f6fb732e70eaed969f5)

今回は、REST Messageで取得したJSONメッセージからtrackname、artworkUrl60を取得している。
また、「var runid = gs.generateGUID();」は３２桁のユニークなIDを生成している。

取得した検索結果を検索ワード、IDと共にTrackListテーブルに追加している。

画面上のリストでは、このIDでフィルターをかけているので、今回の検索結果のみが表示される。

# 最後に

今回は検索のたびに、検索結果がテーブルに追加される。
たまったレコードは下記を参考に定期的に削除可能だ。

[ServiceNowでお手軽にテストデータの追加と削除を行う](https://qiita.com/sukkyxp/items/b09e3dcaefcebe1ab9d5)