SapUI5: Умный элемент управления (smartControls)
SapUI5 предоставляет ряд умных элементов (библиотека sap.ui.comp), которые принимают тот или иной вид в зависимости от типа поля, которое указывается в метаданных oData сервиса.
Smart Field
Элемент управления SmartField предлагает оболочку для других элементов управления, которые выбираются в зависимости от метаданных OData, а именно, от типа поля!
Посмотрите на табличку:
В ней показана связь между типом поля в oData и тем элементом, который будет отображен на экране.
Меньше слов, перейдем к показательному примеру — https://github.com/kannade/SmartField_sapui5.
Импортируйте его в свой WebIDE.
В примере выше, папка /mockserver/ — данные модели (см. имитация oData).
В методе onInit контроллера SmartField.controller.js инициируем mockserver.
Метод onChangeEditMode контроллера SmartField.controller.js меняет режим элемента setContextEditable с редактирования на просмотр (read only) и обратно. Вызывается при клике на кнопку.
Перейдем к представлению!
< core:View xmlns:core="sap.ui.core" xmlns:smartField="sap.ui.comp.smartfield" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:app="http://schemas.sap.com/sapui5/extension/sap.ui.core.CustomData/1" controllerName="sap.ui.comp.sample.smartfield.SmartField" class="sapUiSizeCompact" xmlns:l="sap.ui.layout" xmlns:f="sap.ui.layout.form" xmlns:m="sap.m" > < m:ToggleButton id="idToggleEdit" pressed="true" text="Перейти в / закрыть режим редактирования" icon="sap-icon://edit" press="onChangeEditMode" /> < f:Form class="editableForm" editable="true" > |
Объявили «ярлык» для библиотеки sap.ui.comp.smartfield — smartField.
Добавили кнопку idToggleEdit для переключения режима редактирование — просмотр.
Добавили форму, в которую будем помешать наш умный элемент управления.
Read-only поле.
Первое наше поле ProductId (номер продукта):
<!-- *********************************** --> <!-- Демонстрация sap:updatable="false" --> <!-- *********************************** --> < f:FormElement > < f:label > < smartField:SmartLabel labelFor="idProductId" /> < /f:label > < smartField:SmartField value="{ProductId}" id="idProductId" />< /f:FormElement > |
Описание поля ProductId в /mockserver/metadata.xml:
< Property Name="ProductId" Type="Edm.String" Nullable="false" MaxLength="20" sap:label="Номер продукта (ID)" sap:creatable="false" sap:updatable="false" sap:sortable="false" /> |
sap:updatable=»false» — делает поле не редактируемым!
< smartField:SmartLabel labelFor="idProductId" /> — выводим название поля.
< smartField:SmartField value="{ProductId}" id="idProductId" /> — выводим значение поля из модели.
Так как типом {ProductId} является «Edm.String», то, в соответствии с таблицей, поле, в режиме отображения, будет sap.m.Text!
Посмотрим на поле Email.
Так же как и выше, выводим название элемента (smartField:SmartLabel) используем наш элемент smartField:SmartField для вывода значения {Email}:
<f:label> < smartField:SmartLabel labelFor="idEmail"/></f:label> < smartField:SmartField id="idEmail" value="{Email}"/> |
Хорошо, смотрим как поле описано в метаданных:
< Property Name="Email" Type="Edm.String" Nullable="false" sap:label="Email" sap:creatable="false" sap:updatable="true" sap:sortable="false" sap:quickinfo="Property annotation IsEmailAddress" /> |
Тип Type=»Edm.String» говорит о том, что в режиме редактирования на экране будет отображено поле ввода, а в режиме отображения (чтения) поле примет не совсем стандартный вид. Будет ссылка ссылка на почту (mailto:).
Смотрим метаданные:
<annotations Target="com.sap.GL.zrha.Product/Email" xmlns="http://docs.oasis-open.org/odata/ns/edm"> < Annotation Term="com.sap.vocabularies.Communication.v1.IsEmailAddress" Bool="true"/ > </annotations> |
Мы использовали аннотацию для поля Email (Target=»com.sap.GL.zrha.Product/Email») и присвоили полю «правило» Term=»com.sap.vocabularies.Communication.v1.IsEmailAddress».
В результате чего в режиме отображения (чтения) мы будем видеть специальную (mailto) ссылку на почту.
Подобным образом отображаются поля:
- Адрес электронной почты Email — com.sap.vocabularies.Communication.v1.IsEmailAddress
- Номер телефона Phone — com.sap.vocabularies.Communication.v1.IsPhoneNumber
- URL адрес — Org.OData.Core.V1.IsUrl
- Замаскированное поле пароля Password — com.sap.vocabularies.Common.v1.Masked
- Поле с несколькими линиями (multiline) Description — com.sap.vocabularies.UI.v1.MultiLineText
Полный обзор различных вариаций Term смотрим в документации https://sapui5.hana.ondemand.com/#/api/sap.ui.comp.smartfield.SmartField/annotations/Summary.
Посмотрим как можно отображать boolean тип:
< smartField:SmartField value="{Sale}" id="idSaleDisplay" contextEditable="false"> < smartField:layoutData> < l:GridData spanL="2" spanM="2" spanS="2"/> < /smartField:layoutData> < /smartField:SmartField> < smartField:SmartField value="{Sale}" id="idSaleDisplayOnOff" contextEditable="false" > < smartField:configuration> < smartField:Configuration displayBehaviour="OnOff"/> < /smartField:configuration> < smartField:layoutData> < l:GridData spanL="2" spanM="2" spanS="2"/> < /smartField:layoutData> < /smartField:SmartField> < smartField:SmartField value="{Sale}" id="idSaleDisplayTrueFalse" contextEditable="false"> < smartField:configuration> < smartField:Configuration displayBehaviour="TrueFalse"/> < /smartField:configuration> < smartField:layoutData> < l:GridData spanL="2" spanM="2" spanS="2"/> < /smartField:layoutData> < /smartField:SmartField> |
При помощи свойства displayBehaviour можно управлять форматом вывода полей типа boolean:
ObjectNumber
Элемент ObjectNumber используется для отображения единиц измерения:
< smartField:SmartField value="{Price}" id="idPriceObjectNumber" contextEditable="false"> < smartField:controlProposal> <smartfield:controlproposal controlType="ObjectNumber"> </smartfield:controlproposal> < /smartField:controlProposal> < /smartField:SmartField> |
ObjectStatus
ObjectStatus нужен для отображения какого-либо статуса.
Посмотрим на примере:
< smartField:SmartField value="{Status}" id="idStatusNoIcon"> < smartField:controlProposal> < smartField:ControlProposal> < smartField:objectStatus> <smartfield:objectstatus criticality="{StatusValueState}" criticalityRepresentationType="WithoutIcon"> </smartfield:objectstatus> < /smartField:objectStatus> < /smartField:ControlProposal> < /smartField:controlProposal> < /smartField:SmartField> |
Свойство criticalityRepresentationType=»WithoutIcon» выводит статус без иконки, уберем свойство, появиться иконка:
- Если {StatusValueState} = 3:
- Если {StatusValueState} = 2:
- Если {StatusValueState} = 1:
- Если {StatusValueState} любое другое значение:
Дата (Edm.DateTime)
В примере реализовано несколько форматов вывода даты.
- Вывод просто даты:
/SmartField_sapui5/blob/master/SmartField.view.xml <smartfield:smartfield value="{CreationDate}" id="idCreationDate"></smartfield:smartfield>
- Вывод даты используя style:
/SmartField_sapui5/blob/master/SmartField.view.xml < smartField:SmartField value="{CreationDate}" id="idCreationDateLong"> < smartField:customData> < core:CustomData key="dateFormatSettings" value='\{"style":"long"\}' /> < /smartField:customData> < /smartField:SmartField>
- Вывод даты используя шаблон (pattern):
/SmartField_sapui5/blob/master/SmartField.view.xml < smartField:SmartField value="{CreationDate}" id="idCreationDateCustomPattern"> < smartField:customData> < core:CustomData key="dateFormatSettings" value='\{"pattern":"yyyy-MM-dd"\}' /> < /smartField:customData> < /smartField:SmartField>
Обратите внимание на описание {CreationDate} в метаданных, а именно на свойство sap:display-format=»Date»:
<property Name="CreationDate" Type="Edm.DateTime" Nullable="false" sap:label="Дата создания (Creation Date)" sap:creatable="false" sap:quickinfo="Date when this entity was created" sap:updatable="true" sap:sortable="true" sap:display-format="Date"></property> |
В поле LastChanged свойство sap:display-format=»Date» отсутствует. В результате получается иной вывод даты:
Умное поле со справкой
Рядом с полем есть небольшой элемент, позволяющий организовать поиск по какой-либо справочной информации. В данном примере реализован поиск по валютам.
Посмотрим как это сделано:
< f:label> < smartField:SmartLabel labelFor="idPrice" /> < /f:label> < smartField:SmartField value="{Price}" id="idPrice"/> |
< smartfield:smartlabel labelFor="idPrice">< /smartfield:smartlabel> — вывели название поля (Цена).
< smartfield:smartfield value="{Price}" id="idPrice">< /smartfield:smartfield> — выводим само поле со справочным элементом.
Откроем метаданные и посмотрим, как описан {Price}:
<property Name="Price" Type="Edm.Decimal" Nullable="true" sap:unit="CurrencyCode" sap:label="Цена (Price)" sap:creatable="false" sap:updatable="true" sap:sortable="false"></property> <property Name="CurrencyCode" Type="Edm.String" Nullable="false" MaxLength="3" sap:label="Валюта (Currency)" sap:creatable="false" sap:semantics="currency-code" sap:updatable="true" sap:sortable="false"></property> |
Свойством sap:unit=»CurrencyCode» говорим о том, что у данного поля есть единица измерения CurrencyCode.
В тех же метаданных есть аннотация для поля CurrencyCode:
< EntityType Name="VL_SH_H_TCURC" sap:content-version="1"> < Key> < PropertyRef Name="WAERS" /> < /Key> < Property Name="WAERS" Type="Edm.String" Nullable="false" MaxLength="4" sap:display-format="UpperCase" sap:text="KTEXT" sap:label="Код валюты (Currency Code)" /> < Property Name="KTEXT" Type="Edm.String" MaxLength="25" sap:label="Описание (Description)" /> < /EntityType> … < EntityContainer Name="com.sap.GL.zrha_Entities" m:IsDefaultEntityContainer="true" sap:supported-formats="atom json xlsx"> <entityset Name="VL_SH_H_TCURC" EntityType="com.sap.GL.zrha.VL_SH_H_TCURC" sap:creatable="false" sap:updatable="false" sap:deletable="false" sap:content-version="1" sap:countable="false"></entityset> < /EntityContainer> … < Annotations Target="com.sap.GL.zrha.Product/CurrencyCode" xmlns="http://docs.oasis-open.org/odata/ns/edm"> < Annotation Term="com.sap.vocabularies.Common.v1.ValueList"> < Record> < PropertyValue Property="Label" String="Currencies" /> < PropertyValue Property="CollectionPath" String="VL_SH_H_TCURC" /> < PropertyValue Property="SearchSupported" Bool="true" /> < PropertyValue Property="Parameters"> < Collection> < Record Type="com.sap.vocabularies.Common.v1.ValueListParameterInOut"> < PropertyValue Property="LocalDataProperty" PropertyPath="CurrencyCode" /> < PropertyValue Property="ValueListProperty" String="WAERS" /> < /Record> < Record Type="com.sap.vocabularies.Common.v1.ValueListParameterDisplayOnly"> < PropertyValue Property="ValueListProperty" String="KTEXT" /> < /Record> < /Collection> < /PropertyValue> < /Record> < /Annotation> < /Annotations> |
Похожим образом реализован и выпадающий список с категориями.
Откройте пример (https://github.com/kannade/SmartField_sapui5), поэкспериментируйте, там нет ничего сложного!
Помимо умных полей есть еще и
- умные ссылки (https://sapui5.hana.ondemand.com/#/sample/sap.ui.comp.tutorial.smartControls.03/preview);
- умные таблицы (https://sapui5.hana.ondemand.com/#/sample/sap.ui.comp.tutorial.smartControls.05/preview);
- умные графики (https://sapui5.hana.ondemand.com/#/sample/sap.ui.comp.tutorial.smartControls.09/preview);
Разбирать их в рамках данного поста мы не будем, но основной подход остается тот же.
Больше примеров с sap.ui.comp.tutorial.smartControls — https://sapui5.hana.ondemand.com/#/entity/sap.ui.comp.tutorial.smartControls.
И еще почитать про smart control — https://blogs.sap.com/2017/06/06/dynamic-field-control-using-annotations-in-sapui5/.