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" -->
<!-- *********************************** -->
< f:FormElement >
	< f:label >
		< smartField:SmartLabel labelFor="idProductId" />	< /f:label >
	< smartField:SmartField value="{ProductId}" id="idProductId" />< /f:FormElement >

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

/SmartField_sapui5/blob/master/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!

Запустим пример:
smart control read only

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

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

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

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

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

Смотрим метаданные:

/SmartField_sapui5/blob/master/mockserver/metadata.xml
<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) ссылку на почту.

Подобным образом отображаются поля:

Полный обзор различных вариаций 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
< 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:

boolean fields

ObjectNumber

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

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

ObjectStatus

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

/SmartField_sapui5/blob/master/SmartField.view.xml
< 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} любое другое значение:
    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
    < 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»:

/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
< 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}:

/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
< 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), поэкспериментируйте, там нет ничего сложного!

Помимо умных полей есть еще и

Разбирать их в рамках данного поста мы не будем, но основной подход остается тот же.

Больше примеров с 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/.