SAPUI5 Strange data binding behaviour - sapui5

It's pretty silly problem but I have no idea why is it happening. I heve this in my controller:
this.getView().setModel(this.placesModel, "myCity");
then I set the data with Ajax request to my express RESTFull app and in View.xml
<List items="{path: 'myCity>/people'}">
<CustomListItem>
<VBox>
<Title text="Person:"/>
<Label text="{myCity>/people/name}"/>
<Label text="{myCity>/people/age}"/>
</VBox>
</CustomListItem>
</List>
I have object myCity with few properties. One of them is object people which is array of objects. When I try to list them like that I can see that all my people get listed but without corresponding name and age. Also I find it hard to understend when to use > when / when when >/.

Basic binding syntax with model name is {(model_name)>(path_to_property)}, if you don't have a model name (default model) you need to specify only {path_to_property}.
The initial slash (/) is needed if you don't have a contextbinding. In your case you have contextbinding set on List, so you don't need to use the slash.
Updated code:
<List items="{path: 'myCity>/people'}">
<CustomListItem>
<VBox>
<Title text="Person:"/>
<Label text="{myCity>name}"/>
<Label text="{myCity>age}"/>
</VBox>
</CustomListItem>
</List>
For more information refer to Binding Path.

Related

MultiComboxBox within a table closes after selection

I have tried to resolve the problem for quite sometime but have not been successful.
Inside a table, I have a sap.m.MultiComBox. The drop down in the multicombobox closes after selecting the first value. If not inside the table, the multicombobox works fine as expected (popover does not close). One additional behavior I observed is that if I don't have the selectedKeys bound, then it works fine.
Any reasons or suggestions?
<Table
growing="true"
items="{employee>/EmployeeCollection}">
<columns>
<Column width="10%" />
<Column width="55%" />
<Column width="35%"/>
</columns>
<ColumnListItem>
<Image id="image" src="{employee>dataURI}" class="sapOB_Assign_Usercircle" />
<Text text="{employee>Name}" class="tableText" />
<VBox>
<MultiComboBox id="mcb1"
selectedKeys="{employee>roles}"
items="{
path: 'roles>/BusinessRoles',
templateShareable: false
}">
<core:Item key="{roles>id}" text="{roles>name}" />
</MultiComboBox>
<HBox />
</VBox>
</ColumnListItem>
</Table>
You must be using UI5 version 1.66 or below with growing="true" on the Table. In that case, the dropdown closes immediately after the selection due to a focus loss caused by rerendering of the list item (Its DOM element being rewritten completely). The rerendering itself is caused by two-way bound selectedKeys which explains why it "works" if the property is not bound.
Normally, two-way binding should not be used together with growing. According to the API reference:
Note: Growing must not be used together with two-way binding.
But it's still unclear whether the above constraint is still valid today (See issue #3013).
In order to keep two-way binding with growing="true", add the attribute key* to the list binding info:
<Table
growing="true"
items="{
path: 'employee>/EmployeeCollection',
key: 'employeeId'
}"
>
Here is a working example: https://jsbin.com/ciyosir/edit?js,output. As you can see, the dropdown is kept open even after selection because the list item is not rerendered thanks to the extended change detection.
Additionally, I'd suggest to upgrade to the latest stable UI5 version in order to benefit from many controls having migrated to the new semantic rendering.
* The key awaits a property name from the model of which the value is unique. For more information, see topic Extended Change Detection.

UploadCollection instantUpload="false" when Embedded in List

I am using sap.m.UploadCollection to manage files selected by the user and upload to the server. I want the user to select all the required files then press a 'Save' button to upload all the files at one time. Thus I have set instantUpload to false. This UploadCollection is a part of the items in a sap.m.List. When the user selects a file from the file system an upload is automatically performed (not desired). If I use the same UploadCollection definition outside of the List it does not upload immediately. I need to get it working properly inside the list.
Code Snippet:
<List
items="{ path: 'submittal>/submission', templateShareable: true }">
<layoutData>
<layout:GridData span="XL12 L12 M12 S12"/>
</layoutData>
<items>
<CustomListItem>
<Panel headerText="Round # {submittal>roundId}" expandable="true" expanded="true">
<forms:SimpleForm layout="ResponsiveGridLayout" editable="true">
<UploadCollection
noDataText="No documents on file"
items="{path : 'submittal>documents', templateShareable : false}"
mode="SingleSelectMaster"
uploadEnabled="true"
uploadButtonInvisible="false"
uploadUrl="OptionController?optionId=JS002&action=submittalUpload"
instantUpload="false"
multiple="true"
beforeUploadStarts="submittalBeforeUpload"
uploadComplete="submittalUploadComplete"
selectionChange="documentSelected">
<layoutData>
<layout:GridData span="XL6 L8 M10 S12" linebreakXL="true" linebreakL="true" linebreakM="true" linebreakS="true" />
</layoutData>
<items>
<UploadCollectionItem
documentId="{submittal>id}"
fileName="{submittal>name}"
mimeType="{submittal>typeName}"
selected="{submittal>selected}"
visibleEdit="false"
enableDelete="true"
deletePress="documentDelete">
<attributes>
<ObjectAttribute title="File size" text="{ path: 'submittal>size', formatter: '.formatFileSize' }" />
</attributes>
</UploadCollectionItem>
</items>
</UploadCollection>
</forms:SimpleForm>
</Panel>
</CustomListItem>
</items>
</List>
UI5 Version: 1.78.1
Any help would be appreciated.
Thank you
It is not recommended to use UploadCollection directly inside List, Table, etc. but there is a simple workaround.
Just put a sap.m.Button into sap.m.List instead of using directly sap.m.UploadCollection. Then define fragment with a sap.m.Dialog that has sap.m.UploadCollection inside. In a button press event callback you just bind a row context into a dialog so you'll be able to show correct uploaded files (if there are any).
You can also design a button in your list in a way that you use attachment icon as an icon property and a number (counter) in a text property indicating how many files have been already uploaded.
It would be confusing for an end user to see list items and then another items (files) from UploadCollection inside one or more list items..

sap.m.ObjectListItem: Need to keep whitespace (tabs) in title

<ObjectListItem
title="{i18n>uBOMItem}: {Item} Component: {ComponentDesc}"
number="{ComponentNo}"
>
I am using sap.m.ObjectListItem. While binding, I need tab space between {Item} & {ComponentDesc}.
E.g. like \t
Currently, sap.m.ObjectListItem does not support rendering whitespace for title.
And I agree with alexP's answer that it's not clean to combine multiple labels ("{i18n>uBOMItem}:" and "Component:") into one.
That being said; if it's really necessary to do so, however, you'll need to extend ObjectListItem.
Example: https://embed.plnkr.co/WaMaP4wqMevsjMxX
Internally, ObjectListItem renders its title from sap.m.Text. The Text control has a public property called renderWhiteSpaceapi which we can use to allow tabs to be rendered.
ObjectListItem is only for one value. In your case it's better to use CustomListItem.
<CustomListItem>
<HBox width="100%">
<VBox>
<Label emphasized="true" text="{i18n>uBOMItem}: {Item}" />
</VBox>
<VBox class="sapUiSmallMarginBegin">
<Label emphasized="true" text="Component: {ComponentDesc}" />
</VBox>
<VBox width="50%" justifyContent="End">
<ObjectNumber number="{ComponentNo}" />
</VBox>
</HBox>
</CustomListItem>
It's not clean to output two data bindings from your model in one label, text or similar. You should split the output. In case of an i18n label and a data binding in one control i would make a exception.

SAPUI5: ObjectAttribute Wrap Text

I am attempting to display a wrapped long text in an ObjectAttribute in an SAP UI5 application:
<List id="__listObjectAttributes" noDataText="Drop list items here" headerText="Shipping Information" items="{Shipments}">
<items>
<ObjectListItem id="__listItemShipments" title="{ShipmentTxt}">
<attributes>
<ObjectAttribute id="__attributeShipmentId" title="Shipment #" text="{Id}"/>
<ObjectAttribute id="__attributeShipmentCode" title="Shipment Code" text="{ShipCd}"/>
<ObjectAttribute id="__attributeShipmentLongText" title="Long Text" text="{LongText}" binding="{ShipmentLongText}"/>
</attributes>
</ObjectListItem>
</items>
</List>
The problem is, when the list is displayed the text is truncated instead of wrapped. I've been looking for ways to wrap the text in an ObjectAttribute, but to no avail.
I have found articles that say both "you can do it" and "you can't do it".
Possible: https://archive.sap.com/discussions/thread/3589475
Not possible: https://experience.sap.com/fiori-design-web/object-list-item/
If it is not possible to add this information to an ObjectAttribute, does anyone know a way to display the same information in a list that will accept wrapped text?
Solution
#Ran Hassid's answer was correct! Using a CustomListItem in combination with a SimpleForm was the best solution. Here is the code I ended up going with:
<List id="__listObjectAttributes" noDataText="Drop list items here" headerText="Shipping Information" items="{Shipments}">
<items>
<CustomListItem id="__listItemShipments">
<content>
<form:SimpleForm id="__formShipmentList" editable="true" layout="GridLayout" labelMinWidth="100">
<form:content>
<!--Id-->
<Label id="__labelShipmentId" text="Id"/>
<Text id="__textShipmentId" text="{Id}"/>
<!--Shipment Code-->
<Label id="__labelShipmentCode" text="Shipment Code"/>
<Text id="__textShipmentCode" text="{ShipCd}"/>
<!--Long text-->
<Label id="__labelShipmentLongText" text="LongText"/>
<Text id="__textShipmentLongText" text="{Longtext}" binding="{ShipmentLongText}"/>
</form:content>
</form:SimpleForm>
</content>
</CustomListItem>
</items>
</List>
Then I added the sap.ui.layout.form to the mvc:View to simplify the code:
<mvc:View xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" xmlns:semantic="sap.m.semantic" xmlns:form="sap.ui.layout.form" controllerName="shipments.controller.ShipmentDetail">
I think that even if it is possible (I assume via css changes and so on) it is not recommended because it is not part of the ObjectAttribute interface. In order to achieve the same effect you can do one of the following:
Use CustomListItem instead of ObjectListItem and inside the content of it wrap a SimpleForm. The simple form layout should be grid layout because you want to position text next to the title in the same row. In the Text control you can put as longest string as you want and also control on the wrapping of it. So your code should look something like that (I didn't use binding but I assume you will know what to do in your code)
<List noDataText="Drop list items here" id="__list0">
<items>
<CustomListItem type="Navigation" id="__item1">
<content>
<sap.ui.layout.form:SimpleForm xmlns:sap.ui.layout.form="sap.ui.layout.form" xmlns:sap.ui.core="sap.ui.core" editable="true" layout="GridLayout" id="__form0" labelMinWidth="100">
<sap.ui.layout.form:content>
<sap.ui.core:Title text="Title" id="__title0" />
<Label text="Long Text" id="__label1" />
<Text text="Very long text with\nmultiple lines" />
<Label text="Other text" id="__label2" />
<Text text="Some text goes here" />
</sap.ui.layout.form:content>
</sap.ui.layout.form:SimpleForm>
</content>
</CustomListItem>
</items>
</List>
The second option is to use CustomListItem but with VBOX + HBOX. so you have a VBOX which wrap HBOX's and inside each HBOX you put title next to the text.
I recommend to go with the first approach because it's much more clear and responsive.
Good luck.
I would recommend using basic CSS to solve this issue.
XML-View:
...
<ObjectAttribute text="{aVeryLongText}" class="objectAttributeWrapper" />
...
CSS:
.objectAttributeWrapper * {
white-space: pre-line !important;
word-wrap: break-word !important;
}
This will even work if there are changes on the sap.m.ObjectAttribute Interface, since this CSS-Selector grabs all children of the element which we assigned the CSS class to.
Speaking from my experience this was a quick and stable solution. I had to extend a legacy app, where replacing the whole control would result in me needing to rewrite a whole controller.
Works like a charm and didnt break since 1.71.50

In SAPUI5, how use sap.m.Image with UseMap and get the clicked location?

I'm writing here after a couple of hours of reading everything available on-line, including SAPUI5 Explored Apps, API, etcs.
I need to use Image with Maps to define and capture different clickable areas in an image.
SAPUI5 explored says there is an UseMap parameter, but don't provide enough info or example. I've tried and can't map and get the clicked location.
The API offers sap.m.ImageHelper, with one parameter to use maps. But it also lacks example or enough documentation.
Finally, I'm aware that there's some examples on-line using sap.ui.commons. But I couldn't find any example using sap.m
Anyone has a real working example of this?
Thank you!
Regards,
Douglas
The sap.m.Image useMap property simply adds a useMap property to the element. However you need to define a map element with the same name as in the useMap property along with the regions.
You could use the HTML control from the sap.ui.core library to add a HTML map element to the page.
<Image src="img/someImage.jpg"
width="200px"
useMap="regions"
>
</Image>
<core:HTML content='<map name="regions">
<area shape="rect" coords="0,0,82,126" href="link1.html" alt="Link 1">
<area shape="rect" coords="90,90, 158,103" href="link2.htm" alt="Link 2">
</map>'>
</core:HTML>
You don't necessarily have to revert to a stringified version of your map coding.
Here's how you can provide a map as the useMap parameter for a sap.m.image by referencing the html namespace (Note the declaration xmlns:html="http://www.w3.org/1999/xhtml" at the top):
<mvc:View controllerName="xy.controller.Master" xmlns="sap.m" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" >
<App>
<pages>
<Page title="{i18n>title}">
<content>
<Image src="img/Blume.PNG" densityAware="false" width="" useMap="Map">
<layoutData>
<FlexItemData growFactor="1"/>
</layoutData>
</Image>
<html:map name="Map" id="Map">
<html:area alt="" title="" href="www.google.de" shape="poly" coords="384,505,444,507,444,528,390,527"/>
<html:area alt="" title="" href="www.google.de" shape="poly" coords="426,582,494,583,494,636,426,632"/>
</html:map>
</content>
</Page>
</pages>
</App>
</mvc:View>
Credits: https://answers.sap.com/questions/290270/how-use-sapmimage-with-usemap-and-get-the-clicked.html