SAP UI5 表單

主選單 BaseController.js

controller/BaseController.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/core/routing/History"
], function (Controller, History) {
"use strict";

return Controller.extend("my.navigation.app.controller.BaseController", {
// 封裝獲取 Router 的方法
getRouter: function () {
return this.getOwnerComponent().getRouter();
},

// 全域導頁按鈕事件
onNavToHome: function () { this.getRouter().navTo("RouteHome"); },

onNavToProduct: function () { this.getRouter().navTo("RouteProduct"); },

onNavToForms: function () { this.getRouter().navTo("RouteForms"); },

onNavToContact: function () { this.getRouter().navTo("RouteContact"); }
});
});

Label
在 SAP UI5 中,sap.m.Label 是一種專門用來顯示「文字標籤」的 UI 控制項(Control)。它最常見的用途是放在輸入框(如 sap.m.Input)、下拉選單或核取方塊的前面或上方,用來提示使用者該欄位需要填寫或選擇什麼內容。
  • 核心特性與重要屬性
  • text 屬性:用來設定標籤要顯示的文字。通常會透過資料綁定 (Data Binding) 連接到 i18n 國際化語系檔案,以支援多國語言。
  • labelFor 屬性: 這是 Label 最關鍵的關聯屬性。你需要將它設定為對應輸入控制項的 id(例如:labelFor="myInputId")。這樣做有兩大好處:
    • 無障礙螢幕閱讀器支援 (Accessibility):讓盲人或視障使用者使用的螢幕閱讀器能正確讀出該輸入框的含義。
    • 點擊導向:使用者用滑鼠點擊該 Label 文字時,游標會自動聚焦(Focus)到對應的輸入框中。
  • required 屬性:當設為 true 時,標籤文字的前面或後面會自動出現一個紅色的星號(*),用來視覺化提示使用者該欄位為「必填欄位」。
  • 樣式調整::支援透過屬性微調設計,例如設定文字加粗(design="Bold")或文字對齊方式(textAlign)。
程式碼範例 (XML View)在 SAP UI5 的檢視畫面(View)中,通常會結合佈局控制項(如 Form)一起使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" xmlns:f="sap.ui.layout.form">
<f:SimpleForm editable="true">
<f:content>
<!-- 宣告 Label,並使用 labelFor 綁定到下方的 Input 控制項 -->
<Label text="使用者名稱" required="true" labelFor="usernameInput" />
<Input id="usernameInput" placeholder="請輸入您的姓名" />

<Label text="電子郵件" labelFor="emailInput" />
<Input id="emailInput" type="Email" />
</f:content>
</f:SimpleForm>
</mvc:View>

controller/Forms.controller.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/** 引入相關元件BaseController 主選單,
* MessageToast:內建提示工具:在使用 MessageToast 之前,必須先在 Controller 的最上方(AMD 載入模組區)將 sap/m/MessageToast 引入。=>如果主選單已經引入就不需要重複引入
*/
sap.ui.define([
"my/navigation/app/controller/BaseController",
"sap/m/MessageToast",
"sap/ui/model/json/JSONModel",
"sap/m/MessageBox",
"sap/m/Dialog",
"sap/m/Button",
"sap/ui/layout/form/SimpleForm",
"sap/m/Label",
"sap/m/Input",
], function (BaseController, MessageToast,JSONModel,MessageBox,Dialog, Button, SimpleForm, Label, Input) {
"use strict";

return BaseController.extend("my.navigation.app.controller.Forms", {
onInit: function ()
{
var oDataSource = this.getOwnerComponent().getMetadata().getManifestEntry("sap.app").dataSources.orderApi;
this._sBaseUrl = oDataSource.url;
console.log('this._sBaseUrl', this._sBaseUrl)
this.onReadData()

// 1. 準備下拉選單的資料來源
var oData = {
// Select 的資料
zones: [
{ key: "Z1", text: "台北總部" },
{ key: "Z2", text: "台中分部" },
{ key: "Z3", text: "高雄辦事處" }
],
// 預設選中台北
selectedZone: "Z1",

// ComboBox 的資料
owners: [
{ id: "EMP001", name: "王大同" },
{ id: "EMP002", name: "李小美" },
{ id: "EMP003", name: "張三豐" }
],
selectedOwner: "",

// MultiComboBox 的資料
tags: [
{ tagId: "T1", tagName: "科技" },
{ tagId: "T2", tagName: "金融" },
{ tagId: "T3", tagName: "教育" }
],
selectedTags: ["T1"] // 預設多選勾選科技與金融
};

// 2. 建立 JSON 模型並設置到 View 上
var oModel = new JSONModel(oData);
this.getView().setModel(oModel);
},
// 讀取
onReadData: function () {
jQuery.ajax({
url: this._sBaseUrl ,
method: "GET",
dataType: "json",
success: function (aData) {
console.log('aData',aData)
// 將拿到的陣列塞入 JSONModel
this._oQuizModel.setProperty("", aData);
oTable.setBusy(false);
MessageToast.show("題庫加載完畢!");
}.bind(this),
error: function (oError) {
oTable.setBusy(false);
MessageBox.error("加載失敗,原因:" + oError.responseText);
}
});
},
// 下拉選單數值改變時的事件監聽
onZoneChange: function (oEvent)
{
console.log('onZoneChange',oEvent)
var oSelectedItem = oEvent.getParameter("selectedItem");
var sSelectedKey = oSelectedItem.getKey();
var sSelectedText = oSelectedItem.getText();

console.log("使用者選擇了 Key: " + sSelectedKey + " , Text: " + sSelectedText);
},
onTagsChange: function (oEvent)
{
console.log('onTagsChange',oEvent)
var oSelectedItem = oEvent.getParameter("selectedItem");
var sSelectedKey = oSelectedItem.getKey();
var sSelectedText = oSelectedItem.getText();
console.log("使用者選擇了 Key: " + sSelectedKey + " , Text: " + sSelectedText);
},
onDateChange: function (oEvent) {
// === 方法 A:取得格式化後的字串(例如 "2026-07-13")===
// 這是最常用的做法,可以直接拿來傳給後端 API
var sValue = oEvent.getParameter("value");
var bValid = oEvent.getParameter("valid"); // 檢查使用者輸入的日期是否合法

if (!bValid) {
MessageToast.show("請輸入正確的日期格式!");
return;
}

// === 方法 B:取得原生 JS Date 物件 ===
// 如果你需要拿這個日期去做計算(例如計算天數、判斷是否大於今天)
var oDatePicker = oEvent.getSource();
var oDateObject = oDatePicker.getDateValue(); // 得到標準的 Date 物件

// 測試輸出
console.log("字串格式 (value):", sValue);
console.log("JS 物件 (dateValue):", oDateObject);

MessageToast.show("您選擇了:" + sValue);
},
onCreatePress: function () {
MessageToast.show("表單已成功創建!");
},

onResetPress: function () {
MessageToast.show("表單已重置。");
// 在此處加入清除各控制項欄位值的邏輯
},
onSubmit: function () {
MessageToast.show("表單已成功送出,我們將盡快與您聯絡!");
}
});
});

view/Forms.view.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<mvc:View
controllerName="my.navigation.app.controller.Forms"
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
xmlns:f="sap.ui.layout.form"
xmlns:core="sap.ui.core">
<Page showHeader="true" title="聯絡我們">
<OverflowToolbar width="100%" class="sapUiContentPadding">
<Button text="首頁" press="onNavToHome" />
<Button text="產品介紹" press="onNavToProduct" />
<Button text="表單" press="onNavToForms" />
<Button text="聯絡我們" type="Emphasized" press="onNavToContact" />
</OverflowToolbar>
<content>
<VBox class="sapUiMediumMargin">
<Title text="表單" titleStyle="H1" class="sapUiSmallMarginBottom" />
<f:SimpleForm
editable="true"
layout="ResponsiveGridLayout"
labelSpanXL="3"
labelSpanL="3"
labelSpanM="3"
labelSpanS="12"
adjustLabelSpan="false"
emptySpanXL="4"
emptySpanL="4"
emptySpanM="4"
emptySpanS="0"
columnsXL="1"
columnsL="1"
columnsM="1"
singleContainerFullWidth="true">
<f:content>
<VBox>
<Label text="產品名稱" required="true" />
<Input
placeholder="請輸入產品名稱..."
/>

<Label text="活動區域" required="true" />
<Select
id="zoneSelect"
selectedKey="{/selectedZone}"
items="{path: '/zones'}"
change="onZoneChange"
>
<items>
<!-- key 是傳給後台的值,text 是顯示給使用者看的文字 -->
<core:Item key="{key}" text="{text}" />
</items>
</Select>

<!-- 職業 -->
<Label text="職業" required="true" />
<Select placeholder="請選擇職業"
selectedKey="{/selectedTags}"
items="{path: '/tags'}"
change="onTagsChange"
>
<core:Item key="{tagId}" text="{tagName}" />

</Select>
<Label text="活動時間" required="true" />
<!-- 運用 HBox 將日期與時間選擇器並排 -->
<HBox alignItems="Center">
<DatePicker
placeholder="Pick a date" valueFormat="yyyy-MM-dd"
displayFormat="yyyy/MM/dd"
change="onDateChange"
/>
<Text text="-" class="sapUiTinyMarginEnd" />
<TimePicker placeholder="Pick a time" />
</HBox>
<!-- 即時送達 -->
<Label text="即時送達" />
<Switch state="false" type="AcceptReject" />

<!-- 活動地點 -->
<Label text="活動地點" required="true" />
<SegmentedButton selectedKey="home">
<items>
<SegmentedButtonItem key="home" text="Home" />
<SegmentedButtonItem key="company" text="Company" />
<SegmentedButtonItem key="school" text="School" />
</items>
</SegmentedButton>
<!-- 活動類型 -->
<Label text="活動類型" required="true" />
<VBox>
<HBox>
<CheckBox text="公司" class="sapUiLargeMarginEnd" />
<CheckBox text="車站" />
</HBox>
<HBox>
<CheckBox text="辦公室" class="sapUiLargeMarginEnd" />
<CheckBox text="捷運" />
</HBox>

<!-- 資源 -->
<Label text="資源" required="true" />
<RadioButtonGroup columns="2">
<buttons>
<RadioButton text="Sponsorship" />
<RadioButton text="Venue" />
</buttons>
</RadioButtonGroup>
<!-- Activity form -->
<Label text="Activity form" required="true" />
<TextArea rows="4" growing="true" width="100%" />
</VBox>
<Button
text="送出資料"
press="onButtonClick"
type="Emphasized" />
</VBox>
</f:content>
</f:SimpleForm>
</VBox>
</content>
</Page>
</mvc:View>