Создание Web приложения с помощью фреймворка SAPUI5 (4)
Создание Web приложения с помощью фреймворка SAPUI5 (4)
В предыдущей заметке по обозначенной теме, я вывел информацию по работникам в представление (View), которое используется в моем приложении.
См заметку Создание Web приложения с помощью фреймворка SAPUI5 (1)
См заметку Создание Web приложения с помощью фреймворка SAPUI5 (2)
См заметку Создание Web приложения с помощью фреймворка SAPUI5 (3)
В этой заметке я добавлю возможность фильтрации данных по таблице, в которой размещается какая-то часть информации по работникам. Все, что не поместилось в основной таблице, будет выведено на экран по нажатию на пиктограмму, расположенную в одном из столбцов таблицы.
Control SearchField
См. SearchField
Контрол, который будет применяться для поиска/фильтра по таблице, нужно добавить в представление (View).
<mvc:View controllerName="com.employeeDb.controller.Default" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc"
xmlns:core="sap.ui.core" displayBlock="true" xmlns="sap.m">
<App>
<Page title="">
<Table id="idEmployeeTable" inset="false" items="{employee>/}">
<headerToolbar>
<OverflowToolbar>
<content>
<Title text="Employee's DB" level="H2"/>
<ToolbarSpacer/>
<OverflowToolbar>
<SearchField liveChange="onSearch" width="100%" />
</OverflowToolbar>
</content>
</OverflowToolbar>
</headerToolbar>
<columns>
<Column>
<Text text="Name"/>
</Column>
<Column>
<Text text="Last Name"/>
</Column>
<Column>
<Text text="Phone Number"/>
</Column>
<Column>
<Text text="Workplace"/>
</Column>
<Column>
<Text text="Additional Info"/>
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Text text="{employee>emplName}"/>
<Text text="{employee>emplLName}"/>
<Text text="{employee>emplPhoneNum}"/>
<Text text="{employee>emplWorkPlace}"/>
<core:Icon src="sap-icon://process"/>
</cells>
</ColumnListItem>
</items>
</Table>
</Page>
</App>
</mvc:View>
Проверяю изменения
Событие onSearch. Controller
Для обработки введенной пользователем строки поиска/фильтра, необходимо определить событие onSearch в контроллере приложения. Фильтр будет применен к столбцу, в котором содержится фамилия работника
См. Filter
<mvc:View controllerName="com.employeeDb.controller.Default" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc"
xmlns:core="sap.ui.core" displayBlock="true" xmlns="sap.m">
<App>
<Page title="">
<Table id="idEmployeeTable" inset="false" items="{employee>/}">
<headerToolbar>
<OverflowToolbar>
<content>
<Title text="Employee's DB" level="H2"/>
<ToolbarSpacer/>
<OverflowToolbar>
<SearchField liveChange="onSearch" width="100%" />
</OverflowToolbar>
</content>
</OverflowToolbar>
</headerToolbar>
<columns>
<Column>
<Text text="Name"/>
</Column>
<Column>
<Text text="Last Name"/>
</Column>
<Column>
<Text text="Phone Number"/>
</Column>
<Column>
<Text text="Workplace"/>
</Column>
<Column>
<Text text="Additional Info"/>
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Text text="{employee>emplName}"/>
<Text text="{employee>emplLName}"/>
<Text text="{employee>emplPhoneNum}"/>
<Text text="{employee>emplWorkPlace}"/>
<core:Icon src="sap-icon://process"/>
</cells>
</ColumnListItem>
</items>
</Table>
</Page>
</App>
</mvc:View>
Проверяю
Fragments
В модели данных employee содержится несколько больше информации, чем представлено в основной таблице. Чтобы отобразить недостающую информацию пользователю я воспользуюсь фрагментом, который будет загружаться по нажатию на пиктограмму из столбца Additional info
Fragments support the definition of light-weight stand-alone UI control trees. This class acts as factory which returns the UI control tree defined inside the Fragments. When used within declarative Views, the Fragment content is imported and seamlessly integrated into the View.
Fragments are used similar as sap.ui.core.mvc.Views, but Fragments do not have a Controller on their own (they may know one, though), they are not a Control, they are not part of the UI tree and they have no representation in HTML. By default, in contrast to declarative Views, they do not do anything to guarantee ID uniqueness.
But like Views they can be defined in several Formats (XML, declarative HTML, JavaScript; support for other types can be plugged in), the declaration syntax is the same as in declarative Views and the name and location of the Fragment files is similar to Views. Controller methods can also be referenced in the declarations, but as Fragments do not have their own controllers, this requires the Fragments to be used within a View which does have a controller. That controller is used, then.
Фрагмент может находиться, например, по следующему пути структуры проекта в SAP WebIDE.
/webapp/fragments/DetailedEmployeeInfo.fragment.xml
Обрабатываться он будет тем же контроллером, откуда выполняется его вызов.
<core:FragmentDefinition xmlns="sap.m"
xmlns:l="sap.ui.layout"
xmlns:mvc="sap.ui.core.mvc"
xmlns:f="sap.ui.layout.form" xmlns:core="sap.ui.core">
<Dialog id="idDetailedEmployeeInfo" title="">
<VBox class="sapUiSmallMargin">
<f:Form id="FormDisplay354" editable="false">
<f:title>
<core:Title text="Employee Detailed Infromation"/>
</f:title>
<f:layout>
<f:ResponsiveGridLayout singleContainerFullSize="true"></f:ResponsiveGridLayout>
</f:layout>
<f:formContainers>
<f:FormContainer>
<f:formElements>
<f:FormElement label="Employee Name">
<f:fields>
<Text text="{employee>emplName}"/>
</f:fields>
</f:FormElement>
<f:FormElement label="Employee Last Name">
<f:fields>
<Text text="{employee>emplLName}"/>
</f:fields>
</f:FormElement>
<f:FormElement label="Employee Birth Day">
<f:fields>
<Text text="{employee>/emplBDay}"/>
</f:fields>
</f:FormElement>
<f:FormElement label="Employee Phone Number">
<f:fields>
<Text text="{employee>emplPhoneNum}" />
</f:fields>
</f:FormElement>
<f:FormElement label="Employee Work Place">
<f:fields>
<Text text="{employee>emplWorkPlace}" />
</f:fields>
</f:FormElement>
<f:FormElement label="Employee Department">
<f:fields>
<Text text="{employee>emplDepartment}" />
</f:fields>
</f:FormElement>
<f:FormElement label="Employee Address">
<f:fields>
<Text text="{employee>emplAddres}" />
</f:fields>
</f:FormElement>
</f:formElements>
</f:FormContainer>
</f:formContainers>
</f:Form>
<Button icon="sap-icon://decline" press="onCloseDialog" text="Close"/>
</VBox>
</Dialog>
</core:FragmentDefinition>
См. Form
Загрузка фрагмента
По моей задумке, фрагмент должен быть загружен по нажатию на пиктограмму в столбце Additional info. Чтобы выполнить загрузку фрагмента, нужно отловить нажатие пользователем этой самой пиктограммы, которая расположена в основном представлении (View)
/webapp/view/Default.view.xml
<mvc:View controllerName="com.employeeDb.controller.Default" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc"
xmlns:core="sap.ui.core" displayBlock="true" xmlns="sap.m">
<App>
<Page title="">
<Table id="idEmployeeTable" inset="false" items="{employee>/}">
<headerToolbar>
<OverflowToolbar>
<content>
<Title text="Employee's DB" level="H2"/>
<ToolbarSpacer/>
<OverflowToolbar>
<SearchField liveChange="onSearch" width="100%"/>
</OverflowToolbar>
</content>
</OverflowToolbar>
</headerToolbar>
<columns>
<Column>
<Text text="Name"/>
</Column>
<Column>
<Text text="Last Name"/>
</Column>
<Column>
<Text text="Phone Number"/>
</Column>
<Column>
<Text text="Workplace"/>
</Column>
<Column>
<Text text="Additional Info"/>
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Text text="{employee>emplName}"/>
<Text text="{employee>emplLName}"/>
<Text text="{employee>emplPhoneNum}"/>
<Text text="{employee>emplWorkPlace}"/>
<core:Icon src="sap-icon://process" press="onOpenDialog" />
</cells>
</ColumnListItem>
</items>
</Table>
</Page>
</App>
</mvc:View>
Определяю событие onOpenDialog в контроллере приложения
onOpenDialog: function(oEvent) {
var oView = this.getView();
var oSelectedItem = oEvent.getSource();
var oContext = oSelectedItem.getBindingContext("employee");
var sPath = oContext.getPath();
var oDialog2 = this.byId("idDetailedEmployeeInfo");
if (!oDialog2) {
Fragment.load({
id: oView.getId(),
name: "com.employeeDb.fragments.DetailedEmployeeInfo",
controller: this
}).then(function(oDialog) {
oView.addDependent(oDialog);
oDialog.bindElement({
path: sPath,
model: "employee"
});
oDialog.open();
});
} else {
oDialog2.bindElement({
path: sPath,
model: "employee"
});
oDialog2.open();
}
}
Проверяю
Закрытие фрагмента
Удобное закрытие фрагмента может быть выполнено через добавление одноименной кнопки, и события в контроллере приложения, которое закончит начатое пользователем действие. Без наличия таковой, фрагмент может быть закрыт нажатием на клавишу Esc.
<core:FragmentDefinition xmlns="sap.m"
xmlns:l="sap.ui.layout"
xmlns:mvc="sap.ui.core.mvc"
xmlns:f="sap.ui.layout.form" xmlns:core="sap.ui.core">
<Dialog id="idDetailedEmployeeInfo" title="">
<VBox class="sapUiSmallMargin">
<f:Form id="FormDisplay354" editable="false">
<f:title>
<core:Title text="Employee Detailed Infromation"/>
</f:title>
<f:layout>
<f:ResponsiveGridLayout singleContainerFullSize="true"></f:ResponsiveGridLayout>
</f:layout>
<f:formContainers>
<f:FormContainer>
<f:formElements>
<f:FormElement label="Employee Name">
<f:fields>
<Text text="{employee>emplName}"/>
</f:fields>
</f:FormElement>
<f:FormElement label="Employee Last Name">
<f:fields>
<Text text="{employee>emplLName}"/>
</f:fields>
</f:FormElement>
<f:FormElement label="Employee Birth Day">
<f:fields>
<Text text="{employee>emplBDay}"/>
</f:fields>
</f:FormElement>
<f:FormElement label="Employee Phone Number">
<f:fields>
<Text text="{employee>emplPhoneNum}" />
</f:fields>
</f:FormElement>
<f:FormElement label="Employee Work Place">
<f:fields>
<Text text="{employee>emplWorkPlace}" />
</f:fields>
</f:FormElement>
<f:FormElement label="Employee Department">
<f:fields>
<Text text="{employee>emplDepartment}" />
</f:fields>
</f:FormElement>
<f:FormElement label="Employee Address">
<f:fields>
<Text text="{employee>emplAddres}" />
</f:fields>
</f:FormElement>
</f:formElements>
</f:FormContainer>
</f:formContainers>
</f:Form>
<Button icon="sap-icon://decline" press="onCloseDialog" text="Close"/>
</VBox>
</Dialog>
</core:FragmentDefinition>
Код события onCloseDialog в контроллере
onCloseDialog: function() {
this.byId("idDetailedEmployeeInfo").close();
}
Проверяю