1. はじめに
SAP Fioriには「Floorplan」と呼ばれるアプリの画面構成のテンプレートがあります。
その中でも「Wizard Floorplan」は「手順を順番に進めながらデータを登録/処理を実行する」ためのレイアウトです。
例えば、品目マスタを登録するときに
1.基本情報を入力
2.分類やタイプを選択
3.数量単位を指定
…といった流れをユーザーに迷わず進めてもらうときに便利です。
「一度に大量のフィールドを見せずに、順番に入力してもらう」ことができるのが特徴です。
私がよく使う「Wizard Floorplan」のアプリといえば「アプリケーションジョブ」が思い当たります。
これまで私は「List Report」アプリを作ることがほとんどだったので、「Floorplan」アプリはどのように開発するのか気になっていました。
そこで今回は、初めてWizard Floorplanを実際に開発してみました。
2. Wizard Floorplanとは?
Wizard Floorplanはどのような場面で使う必要なのか、Fiori Design guidelineに記載があったので紹介いたします。
いつ使うべきか
大きなタスクや複雑なタスクを分割してユーザーを助けることを目的としています。
・長い作業
・ユーザーにとって不慣れな作業
こうしたケースで利用します。フローは 最小3ステップ、最大8ステップ で構成するのが推奨です。
使うべきでないケース
・ステップが2つしかない場合
・ユーザーにとって馴染みのある作業(日常的に行う作業など)の場合
こうしたケースでは、ウィザードは逆にクリック数を増やすだけなので不向きです。
また、9ステップ以上が必要な場合もウィザードは対応できません。タスクを再構成するか、他のUI(編集画面やオブジェクトページ)を検討すべきです。
3.開発していく
では、実際に Business Application Studio (BAS) を使ってWizard Floorplanアプリを作ってみます。
今回が初めての開発なので、必ずしもベストプラクティスとは限りませんが、初心者が一歩目を踏み出すサンプルとして見てもらえれば嬉しいです。
ここからはステップを進めて「品目マスタ」の登録ができるアプリを作ってみます。
3-1.Project template選択
勝手なイメージでWizard Floorplanのテンプレートがあるのかと思ってたのですが、ありませんでした。
よく分からないのでとりあえず自由にFioriアプリを作成可能である「Basic」を選んで進めていきます。
3-2.見た目の作成
「Basic」を選んで作成した場合、プロジェクトはMVCモデル(Model-View-Controller)で構成されます。
そのため、画面(View)、処理ロジック(Controller)、データ(Model)を分けて開発していく形になります。
まずはアプリの画面を作っていくので、viewフォルダの中を作っていきます。
viewフォルダに下記のファイルを作成しました。
zproductwiz2.view.xml
<mvc:View controllerName="zproductwiz2.controller.zproductwiz2"
xmlns:mvc="sap.ui.core.mvc" displayBlock="true"
xmlns="sap.m">
<Page id="page" title="品目マスタ登録">
<content>
<Wizard id="ProductWizard">
<!-- Step 1 -->
<WizardStep id="step1" title="名称の登録" validated="true">
<VBox id="_IDGenVBox1" class="sapUiSmallMargin">
<Label id="_IDGenLabelCode" text="品目コード" />
<Input id="_IDGenInputCode" value="{productModel>/Product}" placeholder="例:P-001" />
<Label id="_IDGenLabel" text="品目名称" />
<Input id="_IDGenInput" value="{productModel>/ProductDescription}" placeholder="例:ノートパソコン" />
</VBox>
</WizardStep>
<!-- Step 2 -->
<WizardStep id="step2" title="タイプと産業コード" validated="true">
<VBox id="_IDGenVBox2" class="sapUiSmallMargin">
<Label id="_IDGenLabel1" text="品目タイプ" />
<Input id="_IDGenInput1" value="{productModel>/ProductType}" placeholder="例:FERT" />
<Label id="_IDGenLabel2" text="産業コード" />
<Input id="_IDGenInput2" value="{productModel>/IndustrySector}" placeholder="例:ELEC" />
</VBox>
</WizardStep>
<!-- Step 3 -->
<WizardStep id="step3" title="基本数量単位" validated="true">
<VBox id="_IDGenVBox3" class="sapUiSmallMargin">
<Label id="_IDGenLabel3" text="基本数量単位" />
<Input id="_IDGenInput3" value="{productModel>/BaseUnit}" placeholder="例:PC" />
</VBox>
</WizardStep>
</Wizard>
</content>
<footer>
<Bar id="_IDGenBar">
<contentRight>
<Button id="_IDGenButton2" text="登録" press="onSubmit"/>
</contentRight>
</Bar>
</footer>
</Page>
</mvc:View>
Wizardのステップは下記のUI componentを定義しています。
Wizard:ステップバーと進行管理を担います。
WizardStep:各入力段。title はステップ見出し。validated="true" は「このステップは有効(検証済み)」というフラグ。本来は入力チェックの結果に応じて true/false を切り替える運用がベターです。
<Wizard id="ProductWizard">
<WizardStep id="step1" title="名称の登録" validated="true"> ... </WizardStep>
<WizardStep id="step2" title="タイプと産業コード" validated="true"> ... </WizardStep>
<WizardStep id="step3" title="基本数量単位" validated="true"> ... </WizardStep>
</Wizard>
一旦この状態でプレビューを表示してみます。
しっかりできているように見えますね!
3-3.controllerの作成
ここでは、「登録」ボタンを押したときに、入力した情報をOData経由でSAPに送信する処理を追加していきます。
controllerフォルダに下記のファイルを作成しました。
zproductwiz2.controller.ts(一部)
public onSubmit(): void {
console.log("[onSubmit] 登録ボタンが押されました");
const oView = this.getView();
console.log("[onSubmit] View を取得:", oView);
const oModel = oView.getModel("productModel") as JSONModel;
const oData = oModel.getData();
console.log("[onSubmit] 入力データ:", oData);
const oODataModel = oView.getModel() as ODataModel;
console.log("[onSubmit] ODataModel を取得:", oODataModel);
// 入力バリデーション
if (!oData.Product || !oData.ProductDescription || !oData.ProductType || !oData.BaseUnit) {
console.warn("[onSubmit] 入力値に不足があります:", oData);
MessageBox.warning("すべての必須項目を入力してください。");
return;
}
// ODataエンティティへcreate(POST)
console.log("[onSubmit] OData create 実行開始");
oODataModel.create("/A_Product", {
Product: oData.Product,
ProductType: oData.ProductType,
IndustrySector: oData.IndustrySector,
BaseUnit: oData.BaseUnit,
to_Description: [{
Product: oData.Product,
Language: "JA",
ProductDescription: oData.ProductDescription
}]
}, {
success: () => {
console.log("[onSubmit] 登録成功");
// 入力フィールドを初期化する
const oNewModel = new JSONModel({
Product: "",
ProductDescription: "",
ProductType: "",
IndustryStandardName: "",
BaseUnit: ""
});
this.getView().setModel(oNewModel, "productModel");
MessageToast.show("品目マスタの登録が完了しました!");
},
error: (err: { message: string }) => {
console.error("[onSubmit] 登録失敗:", err);
MessageBox.error("登録に失敗しました:" + err.message);
}
});
}
これでバックエンドの実装が完了しました。
4. 実際に動かしてみる
では作成したアプリをプレビューで動かしてみましょう。
4-1.第一ステップ
4-2.第二ステップ
ここでは品目タイプと産業タイプを入力します。
今回の開発ではヘルプを作っていないですが、本来は作成したいところです。
4-3.第三ステップ
最後に基本数量単位を入力します。
これしか入力しないです。本当に品目登録の最小限で開発しています。
4-4.登録
「登録」ボタン押下により、登録完了です!
完了するとポップアップが表示されます。
4-5.SAP上で確認
MM03(品目照会)で今登録した品目を見てみましょう。
問題なく登録されていることが確認できました。
5. まとめ
今回、初めて「Wizard Floorplan」を使ってアプリを開発してみて感じたのは、
「ユーザーにとって優しいUIを簡単に実装できる」という点です。
これまで作ってきた「List Report」や「Object Page」のように一度に大量のフィールドを並べるのではなく、
ステップごとに入力を分割できるため、ユーザーが迷わず操作できるのが大きな利点だと感じました。
また、「Wizard Floorplan」は見た目もガイド付きのUIになっているため、
新入社員や業務初心者など、操作に不慣れな人にもやさしい設計ができると感じます。
一方で、テンプレートが最初から用意されていない点や、
入力検証・ナビゲーション制御などは自分で実装する必要があるため、
自由度が高い分、実装の理解はやや求められるという印象もありました。
今回は単純なステップでしたが、今後は分岐などの複雑な処理を実装してより理解をふかめていけたらと思っています。