Please suggest. Table binding does not work.
Model Data and may change:
{ "TestCloudEnvRO": [ { "pipelineName": "RP1", "cycles": [ "cy1", "cycle1", "RP1cy2", "cyc2", "crCycle" ] }, { "pipelineName": "RP2", "cycles": [ "BP1-c2", "bp2-cy" ] }, { "pipelineName": "RPlocal", "cycles": [ "cyclelocal" ] }, { "pipelineName": "rp1234", "cycles": [ "cyclert" ] }, { "pipelineName": "RPTEST", "cycles": [ "BPTEST1" ] }, { "pipelineName": "rp123", "cycles": [ "cytr" ] } ] }
View
<Table id="idtrlAllPipelines" alternateRowColors="true">
<columns>
<Column demandPopin="true" minScreenWidth="Tablet">
<Text text="Release Pipeline Cycles"/>
</Column>
</columns>
Controller
var oTemplate = new sap.m.ColumnListItem({ cells: [ new sap.m.Text({ text: "{getHist>pipelineName}" }) ] }); this.byId("idtrlAllPipelines").setModel(oModelEnv, "getHist");
this.byId("idtrlAllPipelines").bindAggregation("items", { path: "getHist>/TestCloudEnvRO", template: oTemplate, templateShareable: true } );
It does not load any items in the table.
But this works at View. I have to replace this with /TestCloudEnvRO with selected key of Icon tab filter, so the above should work. Please suggest.
<Table items="{path: 'getHist>/TestCloudEnvRO'}" id="idtrlAllPipelines" alternateRowColors="true">
For the binding you suggested, your dataset may need to be modified a bit in order to achieve the requirement. PFB the code.
Controller
loadDataSet: function () {
var oMasterModel = this.getView().getModel("oMasterModel");
var oDataSet = [{
"IconTabName": "Env1",
"Table": [{
"name": "Person1",
"runs": ["10", "20"]
}, {
"name": "Person2",
"runs": ["0", "2"]
}]
}, {
"IconTabName": "Env2",
"Table": [{
"name": "Person3",
"runs": ["5", "25"]
}, {
"name": "Person4",
"runs": ["20", "12"]
}]
}];
oMasterModel.setData({
allFilters: oDataSet
});
oMasterModel.refresh(true);
}
View
<IconTabBar items="{oMasterModel>/allFilters}">
<items>
<IconTabFilter text="{oMasterModel>IconTabName}">
<Table items="{oMasterModel>Table}">
<columns>
<Column>
<Label text="Name"/>
</Column>
<Column >
<Label text="Runs"/>
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Text text="{oMasterModel>name}"/>
<Select items="{oMasterModel>runs}">
<core:Item text="{oMasterModel>}"/>
</Select>
</cells>
</ColumnListItem>
</items>
</Table>
</IconTabFilter>
</items>
</IconTabBar>
Related
<mvc:View xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
xmlns:core="sap.ui.core"
controllerName="z.controller.Main">
<Page id="page" title="ComboBox" >
<content>
<ComboBox name="Drop-down List" id="box0" items="{/country}">
<items >
<core:Item key="{Key}" text="{Name}" id="item0"/>
</items>
</ComboBox>
</content>
<Button text="Change" press="onChange"/>
</Page>
</mvc:View>
model1.json
{
"country": [{
"Key": "IN",
"Name": "India"
},
{
"Key": "US",
"Name": "USA"
},{
"Key": "UK",
"Name": "United Kingdom"
}]
}
model2.json
{
"country2": [{
"Key": "BD",
"Name": "Bangladesh"
},
{
"Key": "CA",
"Name": "Canada"
},{
"Key": "FR",
"Name": "France"
}]
}
Main.controller.js
sap.ui.define([
'sap/ui/core/mvc/Controller',
"sap/ui/model/json/JSONModel",
"z/models/model"
], function(Controller,JSONModel, localModel) {
'use strict';
return Controller.extend("z.controller.Main",{
onInit: function(){
var oModel = localModel.createJSONModel("models/data/model1.json");
sap.ui.getCore().setModel(oModel);
var oModel2 = localModel.createJSONModel("models/data/model2.json");
sap.ui.getCore().setModel(oModel2, "model2");
},
onChange: function(){
}
})
});
controller.js
sap.ui.define([
'sap/ui/core/mvc/Controller',
"sap/ui/model/json/JSONModel"
], function(Controller,JSONModel) {
'use strict';
return {
createJSONModel: function(filePath){
var oModel = new JSONModel();
oModel.loadData(filePath);
return oModel;
}
}
});
I have two JSON models and building a combo list using aggregation binding(items="{/country}") by reading data from model1. I am trying to fill the same Combolist by reading the data from the model2 on a button press event.
You can switch the model by using it as a prefix model2> (as you have defined in the Main.controller.js in the onInit method) in the binding path:
onChange: function() {
var oComboBox = this.getView().byId("box0");
oComboBox.bindItems("model2>/country2", {
template: this.getView().byId("item0")
});
}
And change the aggregation from items to dependents.
<ComboBox name="Drop-down List" id="box0" items="{/country}">
<dependents>
<core:Item key="{Key}" text="{Name}" id="item0"/>
</dependents>
</ComboBox>
I read the documentation https://sapui5.hana.ondemand.com/#/entity/sap.m.Select/sample/sap.m.sample.Select/code and I wanted to created a selector in my code.
I carefully follow the documentation but the text isn't display.
In my XML file:
<Select
selectedKey="{test>/SelectedProduct}"
items="{
path: 'test>/ProductCollection',
sorter: { path: 'Name' }
}">
<core:Item key="{test>/SelectedProduct/ProductId}" text="{test>/SelectedProduct/Name}" />
</Select>
in my controller file:
var oData = {
"SelectedProduct": "HT-1001",
"SelectedProduct2": "HT-1001",
"SelectedProduct3": "HT-1001",
"ProductCollection": [
{
"ProductId": "HT-1000",
"Name": "Notebook Basic 15"
},
{
"ProductId": "HT-1001",
"Name": "Notebook Basic 17"
},
{
"ProductId": "HT-1002",
"Name": "Notebook Basic 18"
},
{
"ProductId": "HT-1002",
"Name": "Notebook Basic 18"
},
{
"ProductId": "HT-1002",
"Name": "Notebook Basic 18"
}
],
"Editable": true,
"Enabled": true
};
var oModel = new JSONModel(oData);
this.getView().setModel(oModel, "test");
It doesn't display me the text but it display me the number of elements of my array.
I also tried:
<Select
selectedKey="{test>/SelectedProduct}"
items="{
path: 'test>/ProductCollection',
sorter: { path: 'Name' }
}">
<core:Item key="{test>/ProductCollection/ProductId}" text="{test>/ProductCollection/Name}" />
</Select>
And:
<Select
selectedKey="{test>/SelectedProduct}"
items="{
path: 'test>/ProductCollection',
sorter: { path: 'Name' }
}">
<core:Item key="{test>/ProductCollection.ProductId}" text="{test>/ProductCollection.Name}" />
</Select>
Why this solution doesn't work as expected ?
No need for ProductCollection in Item binding path. The item path is already set to ProductCollection in Select.
<core:Item key="{test>ProductId}" text="{test>Name}" />
I want to display a chart (sap.viz.ui5.controls.VizFrame) that visualizes data from an OData Service. However, the data of the service has to be manipulated. See the example below:
Main.view.xml
<mvc:View controllerName="demo.chart.controller.Main" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m">
<Shell id="shell">
<App id="app">
<pages>
<Page id="page" title="Chart Demo">
<content></content>
</Page>
</pages>
</App>
</Shell>
</mvc:View>
Chart.fragment.xml
<c:FragmentDefinition xmlns:c="sap.ui.core" xmlns:viz="sap.viz.ui5.controls" xmlns:viz.data="sap.viz.ui5.data"
xmlns:viz.feeds="sap.viz.ui5.controls.common.feeds">
<viz:VizFrame uiConfig="{applicationSet:'fiori'}" vizType='donut'>
<viz:dataset>
<viz.data:FlattenedDataset data="{manipulatedData>/}">
<viz.data:dimensions>
<viz.data:DimensionDefinition name="Gender" value="{manipulatedData>gender}"/>
</viz.data:dimensions>
<viz.data:measures>
<viz.data:MeasureDefinition name="Amount" value="{manipulatedData>amount}"/>
</viz.data:measures>
</viz.data:FlattenedDataset>
</viz:dataset>
<viz:feeds>
<viz.feeds:FeedItem uid="color" type="Dimension" values="Gender"/>
<viz.feeds:FeedItem uid="size" type="Measure" values="Amount"/>
</viz:feeds>
</viz:VizFrame>
</c:FragmentDefinition>
Main.controller.js
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel",
"sap/ui/core/Fragment"
], function (Controller, JSONModel, Fragment) {
"use strict";
return Controller.extend("demo.chart.controller.Main", {
onInit: function () {
const mDefault = this.getOwnerComponent().getModel();
const mManipulatedData = new JSONModel([{
gender: "F",
amount: 0
}, {
gender: "M",
amount: 0
}, {
gender: "X",
amount: 12
}]);
this.getView().setModel(mManipulatedData, "manipulatedData");
console.log(this.getView().getModel("manipulatedData"));
mDefault.read("/ContactSet", {
success: oData => {
const aManipulatedData = mManipulatedData.getData();
oData.results.forEach(entry => {
aManipulatedData.forEach(type => {
if (entry.Sex === type.gender) {
type.amount++
}
})
});
Fragment.load({
name: "demo.chart.view.Chart",
controller: this
}).then(oFragment => {
this.getView().addDependent(oFragment);
this.byId("page").addContent(oFragment);
});
}
})
}
});
});
Structure of the service (GWSAMPLE_BASIC/ContactSet)
{
"d": {
"results": [
{
"__metadata": {
"id": "https://sapes5.sapdevcenter.com/sap/opu/odata/IWBEP/GWSAMPLE_BASIC/ContactSet(guid'0050568c-901d-1eda-bcae-e8394de7e116')",
"uri": "https://sapes5.sapdevcenter.com/sap/opu/odata/IWBEP/GWSAMPLE_BASIC/ContactSet(guid'0050568c-901d-1eda-bcae-e8394de7e116')",
"type": "GWSAMPLE_BASIC.Contact"
},
"Address": {
"__metadata": {
"type": "GWSAMPLE_BASIC.CT_Address"
},
"City": "Walldorf",
"PostalCode": "69190",
"Street": "Robert-Koch-Straße",
"Building": "1",
"Country": "DE",
"AddressType": "02"
},
"ContactGuid": "0050568c-901d-1eda-bcae-e8394de7e116",
"BusinessPartnerID": "0100000000",
"Title": "",
"FirstName": "Karl",
"MiddleName": "",
"LastName": "Müller",
"Nickname": "",
"Initials": "",
"Sex": "M",
"PhoneNumber": "0622734567",
"FaxNumber": "0622734004",
"EmailAddress": "do.not.reply#sap.com",
"Language": "EN",
"DateOfBirth": null,
"ToBusinessPartner": {
"__deferred": {
"uri": "https://sapes5.sapdevcenter.com/sap/opu/odata/IWBEP/GWSAMPLE_BASIC/ContactSet(guid'0050568c-901d-1eda-bcae-e8394de7e116')/ToBusinessPartner"
}
}
}
]
}
}
So, as you can see, I'm only interested in the aggregated values of the Sex property. My current solution is to loop through all the entries of the entity set and increase the property in a custom JSON model. This is not only very inperformant because you do the heavy-lifting on the client side, it also requires you to know all the possible values for the data displayed in the chart right away. Is there a way to do this with OData queries or do I have to create a new entity set with the comulated data in my SAP system?
OData should be able to count and group, as described in this quesiton: OData v4 groupby with $count
But I doubt your SAP OData Service will, most of the time, those services do not implement the full OData specification.
You can improve your js by not using two nested for loops but something like this:
mGender = {};
oData.results.forEach(entry => {
if (!mGender[entry.Sex])
{mGender[entry.Sex] = 0
}
mGender[entry.Sex]++
});
Is there a way to render the sap.f.Card control dynamically with an XML view? With aggregation binding maybe? I only used aggregation binding with lists and tables so far...
I need to render some cards dynamically on a main view but I want to stay with the MVC concept. That's why I don't prefer to render the cards in the controller. My Card is also very complex and has multiple controls in it. (Text, Status Indicator, Progress Indicator, etc.)
Is there a way of implementing that?
In Fiori, Cards are usually rendered within sap.f.GridContainer (In fact, it was initially called sap.f.CardContainer).
Just like with Tables and Lists, you can bind <items> to the GridContainer too with the Card as a template control:
<f:GridContainer xmlns:f="sap.f"
width="100%"
snapToRow="true"
items="{
path: '/myCardItems',
templateShareable: false
}">
<f:layout>
<f:GridContainerSettings rowSize="84px" columnSize="84px" gap="8px" />
</f:layout>
<f:layoutXS>
<f:GridContainerSettings rowSize="70px" columnSize="70px" gap="8px" />
</f:layoutXS>
<f:items>
<f:Card> <!-- template -->
<f:header>
<card:Header xmlns:card="sap.f.cards" title="{title}" />
</f:header>
<f:layoutData>
<f:GridContainerItemLayoutData minRows="..." columns="..." />
</f:layoutData>
</f:Card>
</f:items>
</f:GridContainer>
The above snippet is from the Demo Kit sample that has an aggregation binding.
You can achieve it using the Grid layout withcontent aggregation
view.xml
<core:View
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
xmlns:l="sap.ui.layout"
xmlns:fc="sap.f"
xmlns:card="sap.f.cards"
controllerName="path.Main"
xmlns:html="http://www.w3.org/1999/xhtml">
<Page title="Main" class="sapUiContentPadding">
<content>
<!-- Cards data binding -->
<l:Grid containerQuery="true" id="cardsGrid" defaultSpan="XL2 L4" class="gridProgressIndicator" hSpacing="0" content="{/cards}">
<fc:Card class="sapUiMediumMargin" width="300px">
<fc:header>
<card:Header
title="{title}"
subtitle="{subTitle}"
iconSrc="{icon}"/>
</fc:header>
<fc:content>
<VBox
height="115px"
class="sapUiSmallMargin"
justifyContent="SpaceBetween">
<HBox justifyContent="SpaceBetween">
<ComboBox
width="120px"
placeholder="To City"
items="{items}">
<core:Item key="{key}" text="{text}" />
</ComboBox>
<ComboBox
width="120px"
placeholder="To City"
items="{items}">
<core:Item key="{key}" text="{text}" />
</ComboBox>
</HBox>
<HBox justifyContent="SpaceBetween">
<DatePicker width="186px" placeholder="Choose Date ..."/>
<Button text="Book" press="onBookPress" type="Emphasized" />
</HBox>
</VBox>
</fc:content>
</fc:Card>
</l:Grid>
</content>
</Page>
</core:View>
controller.js
bindCardsGrid: function() {
var rowData = [
{ "title": "Title 1", "subTitle": "SubTitle 1", "icon": "sap-icon://menu2", "items": [{ "key": "CV1", "text": "CV1"}, { "key": "CV2", "text": "CV2"}, { "key": "CV3", "text": "CV3"},{ "key": "CV4", "text": "CV4"}]},
{ "title": "Title 2", "subTitle": "SubTitle 2", "icon": "sap-icon://add-contact", "items": [{ "key": "CV1", "text": "CV1"}, { "key": "CV2", "text": "CV2"}, { "key": "CV3", "text": "CV3"},{ "key": "CV4", "text": "CV4"}]},
{ "title": "Title 3", "subTitle": "SubTitle 3", "icon": "sap-icon://business-objects-experience", "items": [{ "key": "CV1", "text": "CV1"}, { "key": "CV2", "text": "CV2"}, { "key": "CV3", "text": "CV3"},{ "key": "CV4", "text": "CV4"}]},
{ "title": "Title 4", "subTitle": "SubTitle 4", "icon": "sap-icon://process", "items": [{ "key": "CV1", "text": "CV1"}, { "key": "CV2", "text": "CV2"}, { "key": "CV3", "text": "CV3"},{ "key": "CV4", "text": "CV4"}]}
];
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData({ "cards": rowData });
this.getView().setModel(oModel);
},
output
I am an intern working with SAP UI5, and I am having difficulties accessing the data in my JSON file to a table
My JSON data is in the format as so (This is a snippet):
[
{
"id": 0,
"name": "<UNKNOWN>",
"area": "core",
"cmakeComponents": [
{
"id": "RemoteSupportDaemon",
"name": "RemoteSupportDaemon"
}
],
......
},
{
........
}
]
I am trying to load my JSON files from the manifest.json file as so:
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "opensap_DashAnalytics.i18n.i18n"
}
},
"data": {
"type": "sap.ui.model.json.JSONModel",
"uri": "model/component_XXX.json"
},
"component": {
"type": "sap.ui.model.json.JSONModel",
"uri": "model/component_SSS.json"
}
}
And I am trying to use that data in my view to make a table with:
<!--sap.m.table-->
<Table
id="idTable"
items= "{path:'{data>/}',
mode: 'sap.ui.model.BindingMode.OneWay'}"
.....
>
<headerToolbar>
<Toolbar>
<Title text="Orange"/>
</Toolbar>
</headerToolbar>
<columns>
<Column>
<Text text="Component" />
</Column>
<Column>
<Text text="Number of failed Tests" />
</Column>
<Column>
<Text text="Number of Bugs" />
</Column>
<Column>
<Text text="Total Tests" />
</Column>
<Column>
<Text text="Pass/Fail Ratio" />
</Column>
</columns>
<items>
<ColumnListItem
press= "onItemSelected"
type= "Navigation">
<cells>
<ObjectListItem title="{data>name}"/>
</cells>
.........
.........
</ColumnListItem>
</items>
</Table>
When I run my code, my table displays NO DATA
I have an assumption that the problem has to deal with how I am writing my path variable, or something related.
I was wondering if there were anyone who would be familiar with this problem that could help me.
You have a wrong syntax in table 'items' aggregation
<Table
id="idTable"
items= "{path:'data>/',
mode: 'sap.ui.model.BindingMode.OneWay'}"
>
Furthermore, remember that the number of cells should be the same to the number of columns to work properly
<cells>
<ObjectListItem title="{data>name}"/>
<ObjectListItem title="{data>otherProperty1}"/>
<ObjectListItem title="{data>otherProperty2}"/>
<ObjectListItem title="{data>otherProperty3}"/>
<ObjectListItem title="{data>otherProperty4}"/>
</cells>