【SAPUI5】動的なFragment表示（ダイアログとポップオーバー）

# はじめに
動的なフラグメント表示は良くあることですが、
フラグメント内のコントロールによって表示方法が少し異なると気づきました。

今回気づいた下記2つについてまとめておこうと思います。

- ダイアログ
- ポップオーバー


# 前提
ボタンを2つ用意しただけの簡単な画面を用意しておきます。
それぞれのボタン押下時にフラグメントを表示していきます。

![コメント 2020-05-29 203922.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320261/70cb93f8-0287-f3d8-50d9-3924ff19be62.png)


プロジェクトは以下のように構成しています。

![コメント 2020-05-29 204018.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320261/6a2afd8d-6464-3b28-5181-6498058113aa.png)



上記で紹介したボタンを2つ表示した画面はApp.view.xmlです。
以下のようしています。

```html
<mvc:View 
	controllerName="sample.sample.controller.App" 
	xmlns:mvc="sap.ui.core.mvc" 
	displayBlock="true" 
	xmlns="sap.m">
	<Shell id="shell">
		<App id="app">
			<pages>
				<Page id="AppPage" title="{i18n>title}" showHeader="false">
					<content>
						<Button id="test" text="ダイアログ表示" press="onOpenDialog" class="sapUiMediumMarginBeginEnd" />
						<Button text="ポップオーバー表示" press="onOpenPopover" />
					</content>
				</Page>
			</pages>
		</App>
	</Shell>
</mvc:View>
```


# ダイアログを表示
ダイアログ表示用のためXMLファイルを用意します。

```html
<core:FragmentDefinition
   xmlns="sap.m"
   xmlns:core="sap.ui.core">
   <Dialog showHeader="false">
		<content>
			<List
				headerText="ダイアログが開きました"
				items="{path: 'testModel>/results'}">
				<StandardListItem
					title="{testModel>product}"
					counter="{testModel>price}">
				</StandardListItem>
			</List>
		</content>
		<buttons>
			<Button text="閉じる" press="onClose" />
		</buttons>
   </Dialog>
</core:FragmentDefinition>
```


Controllerに押下時のイベントを作成します。

```JavaScript
onOpenDialog: function(oEvent) {
	if (!this.byId("dialogFragment")) {
		Fragment.load({
			id: "dialogFragment",
			name: "sample.sample.view.fragments.dialog",
			controller: this
		}).then(function (oDialog) {
			this.getView().addDependent(oDialog);
			oDialog.open();
		}.bind(this));
	} else {
		this.byId("dialogFragment").open();
	}
}
```

ダイアログ表示ボタンを押下してみると以下のようにダイアログが表示されました。
![コメント 2020-05-29 204303.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320261/a571798b-c679-7179-5ed9-4cfd255fa1d0.png)



# ポップオーバーを表示
次はポップオーバー表示用のためXMLファイルを用意します。

```html
<core:FragmentDefinition
	xmlns="sap.m"
	xmlns:core="sap.ui.core">
	<ActionSheet>
		<Button text="パスタ" />
		<Button text="ラーメン" />
		<Button text="うどん" />
		<Button text="そば" />
	</ActionSheet>
</core:FragmentDefinition>
```


Controllerに押下時のイベントを作成します。
ポップオーバー表示の際は、`this.getView().addDependent`の後で`openBy`を使います。
`openBy`の引数にポップオーバーを配置するコントロールを設定します。

```JavaScript
onOpenPopover: function(oEvent) {
	var oButton = oEvent.getSource();
	if (!this.byId("popoverFragment")) {
		Fragment.load({
			id: "popoverFragment",
			name: "sample.sample.view.fragments.popover",
			controller: this
		}).then(function (oDialog) {
			this.getView().addDependent(oDialog);
			oDialog.openBy(oButton);	// ダイアログの表示とはここが違う
		}.bind(this));
	} else {
		this.byId("popoverFragment").open();
	}
}
```

ポップ―オーバー表示ボタンを押下してみると以下のようにポップオーバーが表示されました。
![コメント 2020-05-29 212655.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320261/8fb16d65-808e-da9a-a64a-969150a70cce.png)



試しにダイアログ表示ボタンにポップオーバーを配置してみることにします。
XMLファイルは変更せず、Controllerのみ一部修正します。

```JavaScript
onOpenPopover: function(oEvent) {
	// var oButton = oEvent.getSource();
	var oButton = this.getView().byId("test");  // ダイアログ表示ボタンのIdを指定
	if (!this.byId("popoverFragment")) {
		Fragment.load({
			id: "popoverFragment",
			name: "sample.sample.view.fragments.popover",
			controller: this
		}).then(function (oTarget) {
			this.getView().addDependent(oTarget);
			oTarget.openBy(oButton);
		}.bind(this));
	} else {
		this.byId("popoverFragment").open();
	}
}
```
ポップオーバーの配置がダイアログ表示ボタンの下に変わりました。
![コメント 2020-05-29 212549.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320261/4cc9da7a-4c9a-f0a7-d495-b7382c9742f2.png)


今回はUI5コントローラーにポップオーバーを配置しましたが、DOMの参照でもいいようです。
https://sapui5.hana.ondemand.com/1.68.1/#/api/sap.m.Popover/methods/openBy