SapUI5: Умный элемент управления (smartControls)

SapUI5 предоставляет ряд умных элементов (библиотека sap.ui.comp), которые принимают тот или иной вид в зависимости от типа поля, которое указывается в метаданных oData сервиса.

Smart Field

Элемент управления SmartField предлагает оболочку для других элементов управления, которые выбираются в зависимости от метаданных OData, а именно, от типа поля!
Посмотрите на табличку:
sapui5 smart control field
В ней показана связь между типом поля в oData и тем элементом, который будет отображен на экране.
Меньше слов, перейдем к показательному примеру — https://github.com/kannade/SmartField_sapui5.
Импортируйте его в свой WebIDE.
В примере выше, папка /mockserver/ — данные модели (см. имитация oData).
В методе onInit контроллера SmartField.controller.js инициируем mockserver.
Метод onChangeEditMode контроллера SmartField.controller.js меняет режим элемента setContextEditable с редактирования на просмотр (read only) и обратно. Вызывается при клике на кнопку.
Перейдем к представлению!

/SmartField_sapui5/blob/master/SmartField.view.xml
< 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 (номер продукта):

/SmartField_sapui5/blob/master/SmartField.view.xml
<!-- *********************************** -->
<!-- Демонстрация sap:updatable="false" -->
<!-- *********************************** -->
&lt; f:FormElement &gt;
	&lt; f:label &gt;
		&lt; smartField:SmartLabel labelFor="idProductId" /&gt;	&lt; /f:label &gt;
	&lt; smartField:SmartField value="{ProductId}" id="idProductId" /&gt;&lt; /f:FormElement &gt;

Описание поля ProductId в /mockserver/metadata.xml:

/SmartField_sapui5/blob/master/mockserver/metadata.xml
&lt; Property Name="ProductId" Type="Edm.String" Nullable="false"
	MaxLength="20" sap:label="Номер продукта (ID)" sap:creatable="false"
	sap:updatable="false" sap:sortable="false" /&gt;

sap:updatable=»false» — делает поле не редактируемым!
< smartField:SmartLabel labelFor=»idProductId» /> — выводим название поля.
< smartField:SmartField value=»{ProductId}» id=»idProductId» /> — выводим значение поля из модели.
Так как типом {ProductId} является «Edm.String», то, в соответствии с таблицей, поле, в режиме отображения, будет sap.m.Text!
Запустим пример:
smart control read only

Посмотрим на поле Email.

Так же как и выше, выводим название элемента (smartField:SmartLabel) используем наш элемент smartField:SmartField для вывода значения {Email}:

/SmartField_sapui5/blob/master/SmartField.view.xml
<f:label>
	&lt; smartField:SmartLabel labelFor="idEmail"/&gt;</f:label>
&lt; smartField:SmartField id="idEmail" value="{Email}"/&gt;

Хорошо, смотрим как поле описано в метаданных:

/SmartField_sapui5/blob/master/mockserver/metadata.xml
&lt; 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" /&gt;

Тип Type=»Edm.String» говорит о том, что в режиме редактирования на экране будет отображено поле ввода, а в режиме отображения (чтения) поле примет не совсем стандартный вид. Будет ссылка ссылка на почту (mailto:).
Смотрим метаданные:

/SmartField_sapui5/blob/master/mockserver/metadata.xml
<annotations target="com.sap.GL.zrha.Product/Email" xmlns="http://docs.oasis-open.org/odata/ns/edm">
	&lt; Annotation Term="com.sap.vocabularies.Communication.v1.IsEmailAddress" Bool="true"/ &gt;
</annotations>

Мы использовали аннотацию для поля Email (Target=»com.sap.GL.zrha.Product/Email») и присвоили полю «правило» Term=»com.sap.vocabularies.Communication.v1.IsEmailAddress».
В результате чего в режиме отображения (чтения) мы будем видеть специальную (mailto) ссылку на почту.
Подобным образом отображаются поля:

Полный обзор различных вариаций Term смотрим в документации https://sapui5.hana.ondemand.com/#/api/sap.ui.comp.smartfield.SmartField/annotations/Summary.
sapui5 smart fields

Посмотрим как можно отображать boolean тип:

/SmartField_sapui5/blob/master/SmartField.view.xml
&lt; smartField:SmartField value="{Sale}" id="idSaleDisplay" contextEditable="false"&gt;	&lt; smartField:layoutData&gt;
		&lt; l:GridData  spanL="2" spanM="2" spanS="2"/&gt;
	&lt; /smartField:layoutData&gt;
&lt; /smartField:SmartField&gt;
&lt; smartField:SmartField value="{Sale}" id="idSaleDisplayOnOff" contextEditable="false" &gt;
	&lt; smartField:configuration&gt;
		&lt; smartField:Configuration displayBehaviour="OnOff"/&gt;
	&lt; /smartField:configuration&gt;	&lt; smartField:layoutData&gt;
		&lt; l:GridData  spanL="2" spanM="2" spanS="2"/&gt;
	&lt; /smartField:layoutData&gt;
&lt; /smartField:SmartField&gt;
&lt; smartField:SmartField value="{Sale}" id="idSaleDisplayTrueFalse" contextEditable="false"&gt;
	&lt; smartField:configuration&gt;
		&lt; smartField:Configuration displayBehaviour="TrueFalse"/&gt;
	&lt; /smartField:configuration&gt;
	&lt; smartField:layoutData&gt;		&lt; l:GridData  spanL="2" spanM="2" spanS="2"/&gt;
	&lt; /smartField:layoutData&gt;
	&lt; /smartField:SmartField&gt;

При помощи свойства displayBehaviour можно управлять форматом вывода полей типа boolean:
boolean fields

ObjectNumber

Элемент ObjectNumber используется для отображения единиц измерения:

/SmartField_sapui5/blob/master/SmartField.view.xml
&lt; smartField:SmartField value="{Price}" id="idPriceObjectNumber" contextEditable="false"&gt;
	&lt; smartField:controlProposal&gt;
		<smartfield:controlproposal controltype="ObjectNumber">		</smartfield:controlproposal>
	&lt; /smartField:controlProposal&gt;
&lt; /smartField:SmartField&gt;

ObjectStatus

ObjectStatus нужен для отображения какого-либо статуса.
Посмотрим на примере:

/SmartField_sapui5/blob/master/SmartField.view.xml
&lt; smartField:SmartField value="{Status}" id="idStatusNoIcon"&gt;
	&lt; smartField:controlProposal&gt;
		&lt; smartField:ControlProposal&gt;			&lt; smartField:objectStatus&gt;
				<smartfield:objectstatus criticality="{StatusValueState}" criticalityrepresentationtype="WithoutIcon">
				</smartfield:objectstatus>
			&lt; /smartField:objectStatus&gt;
		&lt; /smartField:ControlProposal&gt;
	&lt; /smartField:controlProposal&gt;
&lt; /smartField:SmartField&gt;

Свойство criticalityRepresentationType=»WithoutIcon» выводит статус без иконки, уберем свойство, появиться иконка:

  • Если {StatusValueState} = 3:
  • Если {StatusValueState} = 2:
  • Если {StatusValueState} = 1:
  • Если {StatusValueState} любое другое значение:
    objectstatus smart control

Дата (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
    &lt; smartField:SmartField value="{CreationDate}" id="idCreationDateLong"&gt;
    	&lt; smartField:customData&gt;
    		&lt; core:CustomData key="dateFormatSettings" value='\{"style":"long"\}' /&gt;
    	&lt; /smartField:customData&gt;
    &lt; /smartField:SmartField&gt;
  • Вывод даты используя шаблон (pattern):
    /SmartField_sapui5/blob/master/SmartField.view.xml
    &lt; smartField:SmartField value="{CreationDate}" id="idCreationDateCustomPattern"&gt;
    	&lt; smartField:customData&gt;
    		&lt; core:CustomData key="dateFormatSettings" value='\{"pattern":"yyyy-MM-dd"\}' /&gt;
    	&lt; /smartField:customData&gt;
    &lt; /smartField:SmartField&gt;

Обратите внимание на описание {CreationDate} в метаданных, а именно на свойство sap:display-format=»Date»:

/SmartField_sapui5/blob/master/mockserver/metadata.xml
<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» отсутствует. В результате получается иной вывод даты:
date smart controls

Умное поле со справкой

Посмотрим на поле цены:
smart controls help value
Рядом с полем есть небольшой элемент, позволяющий организовать поиск по какой-либо справочной информации. В данном примере реализован поиск по валютам.
Посмотрим как это сделано:

/SmartField_sapui5/blob/master/SmartField.view.xml
&lt; f:label&gt;
	&lt; smartField:SmartLabel labelFor="idPrice" /&gt;
&lt; /f:label&gt;
&lt; smartField:SmartField value="{Price}" id="idPrice"/&gt;

< smartfield:smartlabel labelFor=»idPrice»>< /smartfield:smartlabel> — вывели название поля (Цена).
< smartfield:smartfield value=»{Price}» id=»idPrice»>< /smartfield:smartfield> — выводим само поле со справочным элементом.
Откроем метаданные и посмотрим, как описан {Price}:

/SmartField_sapui5/blob/master/mockserver/metadata.xml
<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:

/SmartField_sapui5/blob/master/mockserver/metadata.xml
&lt; EntityType Name="VL_SH_H_TCURC" sap:content-version="1"&gt;
	&lt; Key&gt;
		&lt; PropertyRef Name="WAERS" /&gt;
	&lt; /Key&gt;
	&lt; Property Name="WAERS" Type="Edm.String" Nullable="false"
		MaxLength="4" sap:display-format="UpperCase" sap:text="KTEXT"
		sap:label="Код валюты (Currency Code)" /&gt;
	&lt; Property Name="KTEXT" Type="Edm.String" MaxLength="25"
		sap:label="Описание (Description)" /&gt;
&lt; /EntityType&gt;&lt; EntityContainer Name="com.sap.GL.zrha_Entities"
m:IsDefaultEntityContainer="true" sap:supported-formats="atom json xlsx"&gt;
	<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>
&lt; /EntityContainer&gt;&lt; Annotations Target="com.sap.GL.zrha.Product/CurrencyCode" xmlns="http://docs.oasis-open.org/odata/ns/edm"&gt;
	&lt; Annotation Term="com.sap.vocabularies.Common.v1.ValueList"&gt;
		&lt; Record&gt;
			&lt; PropertyValue Property="Label" String="Currencies" /&gt;
			&lt; PropertyValue Property="CollectionPath" String="VL_SH_H_TCURC" /&gt;
			&lt; PropertyValue Property="SearchSupported" Bool="true" /&gt;
			&lt; PropertyValue Property="Parameters"&gt;
				&lt; Collection&gt;
					&lt; Record Type="com.sap.vocabularies.Common.v1.ValueListParameterInOut"&gt;
						&lt; PropertyValue Property="LocalDataProperty" PropertyPath="CurrencyCode" /&gt;
						&lt; PropertyValue Property="ValueListProperty" String="WAERS" /&gt;
					&lt; /Record&gt;
					&lt; Record Type="com.sap.vocabularies.Common.v1.ValueListParameterDisplayOnly"&gt;
						&lt; PropertyValue Property="ValueListProperty" String="KTEXT" /&gt;
					&lt; /Record&gt;
				&lt; /Collection&gt;
			&lt; /PropertyValue&gt;
		&lt; /Record&gt;
	&lt; /Annotation&gt;
&lt; /Annotations&gt;

Похожим образом реализован и выпадающий список с категориями.
Откройте пример (https://github.com/kannade/SmartField_sapui5), поэкспериментируйте, там нет ничего сложного!
Помимо умных полей есть еще и

Разбирать их в рамках данного поста мы не будем, но основной подход остается тот же.
Больше примеров с 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/.