oData binding to Simple Form - sapui5

I'm creating a read only form that will be used to display a summary of information. I need to send a parameter to the backend first before getting the information but I don't seem to see that parameter is reaching it.
It does reach the entity set but it does not show the parameter. Am I binding correctly?
This is on the controller:
onInit: function() {
var urlEnding = "1000012233";
var oFilterDist = new sap.ui.model.Filter("ID",
sap.ui.model.FilterOperator.EQ, urlEnding);
var summaryText = this.getView().byId("summaryForm");
summaryText.bindElement({
path: "/SummaryScreenSet",
filters: [oFilterDist]
});
}
This is on the View
<VBox class="sapUiSmallMargin" fitContainer="true"
height="100%" width="100%" justifyContent="End"
displayInline="true" id="leftVBox" items="{/SummaryScreenSet}">
<items>
<f:SimpleForm editable="true" layout="ResponsiveGridLayout" id="summaryForm" columnsL="1" columnsXL="1" labelSpanL="5" title="Account Summary" labelSpanM="5">
<f:content>
<Label text="Status" id="__label6" design="Bold" class="sizeText"/>
<ObjectStatus text="{CONTRACT_STATUS}" id="__status6" state="Success" class="boldText"/>
<Label text="Permit Required" id="__label10" design="Bold" class="sizeText"/>
<Text text="{PERMIT_REQD}" id="__text32" wrapping="false" class="sizeText"/>
<Label text="Bill Date | Due Date" id="__label11" design="Bold" class="sizeText"/>
<Text text="{BILL_DATE} | {DUE_DATE}" id="__text33" wrapping="false" class="sizeText"/>
<Label text="Last Estimated Date | Next MR Date" id="__label17" design="Bold" class="sizeText"/>
<Text text="{LAST_PAYMENT_DATE} | {nextMRDate}" id="__text39" wrapping="false" class="sizeText"/>
</f:content>
</f:SimpleForm>
</items>
</VBox>

Going to assume you want a single, specific entry. In that case, what you're looking for is the Entity, not the EntitySet + filter. Coincidentally, here's one I wrote yesterday that works. I've changed the paths and ID's to reflect yours:
var form = this.getView().byId('summaryForm');
form.bindElement({
path: "/SummaryScreenSet('" + urlEnding + "')",
events: {
change: function() {
//triggers on error too I think
form.setBusy(false);
},
dataRequested: function() {
form.setBusy(true);
}
}
});
In that case you don't need the VBOX either, just the form. Don't forget to implement SUMMARYSCREEN_GET_ENTITY or whatever the method is on your DPC_EXT.
Edit: might want to set editable on the form to false, it shrinks the layout to suit text instead of inputs.

Related

Can´t to bind or show data from ModelData.read to form in SapUi5

i have a big trouble that's freaking me out, check it out:
This is my xml for a View, program is divided in two differents Views, first of them, a table with navigation and second one is the details, involved in a form.
<mvc:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" controllerName="Hello_World.Hello_World.controller.View2"
xmlns:html="http://www.w3.org/1999/xhtml" xmlns:form="sap.ui.layout.form">
<App>
<pages>
<Page title="Detalles" showHeader="true">
<Button type="Back" press="patras" tooltip="test"/>
<VBox>
</VBox>
<form:SimpleForm id="formPruebas" maxContainerCols="2" layout="ResponsiveGridLayout" labelSpanL="5" labelSpanM="4" labelSpanS="6" title="Formulario">
<Label text="CustomerID"/>
<Text text="{jsonmodel>CustomerID}"/>
<Label text="CompanyName"/>
<Text text="{CompanyName}"/>
<Label text="ContactTitle" />
<Text text="{ContactTitle}"/>
<Label text="Adress"/>
<Text text="{Adress}"/>
<Label text="City"/>
<Text text="{City}"/>
<Label text="PostalCode"/>
<Text text="{PostalCode}"/>
<Label text="Country" />
<Text text="{i18n>Country}"/>
<Button text="Aceptar" type="Accept">
<layoutData>
<FlexItemData growFactor="1" />
</layoutData>
</Button>
<Button text="Editar" width="100px">
<layoutData>
<FlexItemData growFactor="1" />
</layoutData>
</Button>
</form:SimpleForm>
</Page>
</pages>
</App>
Alright so this is my controller:
onInit: function() {
var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
oRouter.getRoute("View2").attachMatched(this._onRouteMatched, this);
},
_onRouteMatched: function(oEvent) {
var idDevuelto = oEvent.getParameter("arguments").data;
var idCompleto = "/Customers('" + idDevuelto + "')";
//var oForm = this.getView().byId("formPruebas");
var oForm = this.getView().byId("formPruebas");
var serviceUrl = "myurl";
var oModelData = new sap.ui.model.odata.ODataModel(serviceUrl,{
JSON:true,
useBatch: false
});
oModelData.read(idCompleto, {
success: function (oData) {
sap.m.MessageToast.show(oData.CustomerID);
var oModel = new JSONModel(oData.results);
oForm.setModel(oModel.results);
},
error: function (oError) {
sap.m.MessageToast.show("No funca");
}
});
},
However the result is not showing on my view when i run the program, any idea?
PD: I'm pretty noob on sapui5
Finally i found the solution of the problem, if you check the XML code at the beginning of the question , you realize there is not path in Form element.
In mi first view i have a table with id and a PATH which i don't have in the Form so the fastest way i solve it is to put in the XML a slash, an example:
<form:SimpleForm id="formPruebas" maxContainerCols="2" layout="ResponsiveGridLayout" labelSpanL="5" labelSpanM="4" labelSpanS="6" title="Formulario">
<Label text="CustomerID"/>
<Text text="{/CustomerID}"/> // the slash i mean
With that fix, i only do oForm.setModel(oModel) so everything is connected and works
fine, i want to share this information if more people deal with the same error as i did.
Thanks all ideas.

Data Binding from TableSelectDialog to Form

I'm using TableSelectDialog to view some Carrier details. All I need is: If I select any item (row), then all the values from that row should get automatically populated to the form input fields.
In the attached image, if Carrier Name is selected from TableSelectDialog, then the remaining fields should be populated based on that value.
You can achieve the required functionality using the Binding context that you receive from the TableSelcect Dialog.
But for binding context to work properly, both form and the table select dialog should refer to the same Model.
Below is the working code:
VIEW.XML:
Has a Button to trigger the table select dialog.
Has a form.
<l:VerticalLayout class="sapUiContentPadding" width="100%">
<l:content>
<Button class="sapUiSmallMarginBottom" text="Show Table Select Dialog"
press="handleTableSelectDialogPress">
</Button>
<VBox class="sapUiSmallMargin">
<f:SimpleForm id="SimpleFormDisplay354">
<f:content>
<Label text="Supplier Name" />
<Text id="nameText" text="{SupplierName}" />
<Label text="Description" />
<Text text="{Description}" />
<Label text="ProductId" />
<Text text="{ProductId}" />
<Label text="Quantity" />
<Text id="countryText" text="{Quantity}" />
</f:content>
</f:SimpleForm>
</VBox>
</l:content>
</l:VerticalLayout>
Controller:
onInit: function () {
// set explored app's demo model on this sample
var oModel = new JSONModel(jQuery.sap.getModulePath("sap.ui.demo.mock", "/products.json"));
this.getView().setModel(oModel);
},
handleTableSelectDialogPress: function (oEvent) {
if (!this._oDialog) {
this._oDialog = sap.ui.xmlfragment("sap.m.sample.TableSelectDialog.Dialog", this);
}
this.getView().addDependent(this._oDialog);
// toggle compact style
this._oDialog.open();
},
handleClose: function (oEvent) {
var aContexts = oEvent.getParameter("selectedContexts");
if (aContexts && aContexts.length) {
// MessageToast.show("You have chosen " + aContexts.map(function(oContext) { return oContext.getObject().Name; }).join(", "));
this.byId('SimpleFormDisplay354').setBindingContext(aContexts[0]);
}
oEvent.getSource().getBinding("items").filter([]);
}
Now, we also have a Select dialog and on click of any Item we call method : handleClose
In handleClose, we obtain the clicked Item binding context and then tell the form : hey! refer to this context ( which is present in the model). Binding context has a path which tells the form from where to do the relative binding.
Please feel free to contact for more information.

How can I bind a single property of my OData service to a Form?

Will you please tell me how to refer to the first tabular (and single) record?
There is a table with only one record:
<Table items="{WaybillsPlaces}" mode="SingleSelectMaster">
<columns>
<Column hAlign="Center">
<header>
<Text text="Number" />
</header>
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Text text="{CoNumber}" />
</cells>
</ColumnListItem>
</items>
</Table>
How can I read the field of the first record without a table?
<Text text="{WaybillsPlaces[0]/>CoNumber}"/>
I get a table reply, but I do not want to display it in the table - I want to display it in the form in text boxes, so there will always be one line in the response.
<entry>
<id>
http://xxxxx.xxx.local:8000/sap/opu/odata/sap/LOGISTICS_SRV/WaybillsPlaces('4610103052')
</id>
<title type="text">WaybillsPlaces('4610103052')</title>
<updated></updated>
<content type="application/xml">
<m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<d:CoNumber>46101030520001</d:CoNumber>
</m:properties>
</content>
</entry>
EDIT (As #Denis description in the comments):
I have an OData giving me the following entry
<entry>
<id>
http://xxxxx.xxx.local:8000/sap/opu/odata/sap/LOGISTICS_SRV/WaybillsPlaces('4610103052')
</id>
<title type="text">WaybillsPlaces('4610103052')</title>
<updated></updated>
<content type="application/xml">
<m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<d:CoNumber>46101030520001</d:CoNumber>
</m:properties>
</content>
</entry>
How can I bind the CoNumber property with a Input within a From ??
give and ID to your table, get the table in your controller and call its 'getItems()' method. Then get the first object in the returned array:
In your view
<Table id="myTable" items="{WaybillsPlaces}" mode="SingleSelectMaster">
<columns>
<Column hAlign="Center">
<header>
<Text text="Number" />
</header>
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Text text="{CoNumber}" />
</cells>
</ColumnListItem>
</items>
</Table>
In your controller
onCertainEvent(evt){
var oTable = this.getView().byId('myTable');
var oFirstItem = oTable.getItems()[0]; // This is your ColumnListItem object in the first row
var oFirstCellItem = oFirstItem.getCells()[0]; // This is your Text object in the first cell of the first row
var sCellText = oFirstCellItem.getText(); // This is the text string in your first cell of the first row
}
EDIT: bind only the first item in your model
In this case you can do aggregation binding. For aggregation binding you need multiplicity greater than 1. So do property binding in yout ColumnListItem with WaybillsPlaces/0/CoNumber
<Table id="myTable" mode="SingleSelectMaster">
<columns>
<Column hAlign="Center">
<header>
<Text text="Number" />
</header>
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Text text="{WaybillsPlaces/0/CoNumber}" />
</cells>
</ColumnListItem>
</items>
</Table>
EDIT: Data Binding options in certain events
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<meta charset="utf-8">
<title>MVC with XmlView</title>
<!-- Load UI5, select "blue crystal" theme and the "sap.m" control library -->
<script id='sap-ui-bootstrap'
src='https://sapui5.hana.ondemand.com/resources/sap-ui-core.js'
data-sap-ui-theme='sap_bluecrystal'
data-sap-ui-libs='sap.m'
data-sap-ui-xx-bindingSyntax='complex'></script>
<!-- DEFINE RE-USE COMPONENTS - NORMALLY DONE IN SEPARATE FILES -->
<!-- define a new (simple) View type as an XmlView
- using data binding for the Button text
- binding a controller method to the Button's "press" event
- also mixing in some plain HTML
note: typically this would be a standalone file -->
<script id="view1" type="sapui5/xmlview">
<mvc:View
controllerName="my.own.controller"
xmlns:l="sap.ui.layout"
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc"
xmlns:f="sap.ui.layout.form"
xmlns="sap.m">
<Panel headerText="Table Panel">
<Table id="myTable" items="{/WaybillsPlaces}" mode="SingleSelectMaster" select="onRowPressed" updateFinished="onUpdateFinished">
<columns>
<Column hAlign="Center">
<header>
<Text text="Number" />
</header>
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Text text="{CoNumber}" />
</cells>
</ColumnListItem>
</items>
</Table>
</Panel>
<Panel id="Panel1" headerText="onAfterRendering Data Binding">
<Label text="First Item - Property binding:"></Label>
<Input id="Input1"></Input>
<Label text="First Item - Element binding:"></Label>
<Input value="{CoNumber}"></Input>
</Panel>
<Panel id="Panel2" headerText="onUpdateFinished Data Binding">
<Label text="First Item - Property binding:"></Label>
<Input id="Input2"></Input>
<Label text="First Item - Element binding:"></Label>
<Input value="{CoNumber}"></Input>
</Panel>
<Panel id="Panel3" headerText="onRowPressed Data Binding">
<Label text="Selected Item - Property binding:"></Label>
<Input id="Input3"></Input>
<Label text="Selected Item - Element binding:"></Label>
<Input value="{CoNumber}"></Input>
</Panel>
</mvc:View>
</script>
<script>
// define a new (simple) Controller type
sap.ui.controller("my.own.controller", {
onAfterRendering: function(){
var oTable = this.getView().byId('myTable');
var oFirstItem = oTable.getItems()[0]; // This is your ColumnListItem object in the first row
var oFirstCellItem = oFirstItem.getCells()[0]; // This is your Text object in the first cell of the first row
var sFirstItemDataPath = oFirstCellItem.getBindingContext().getPath();
this.getView().byId("Input1").bindProperty("value", sFirstItemDataPath + "/CoNumber");
this.getView().byId("Panel1").bindElement(sFirstItemDataPath);
},
onUpdateFinished: function(oEvent){
var oTable = oEvent.getSource();
var oFirstItem = oTable.getItems()[0]; // This is your ColumnListItem object in the first row
var oFirstCellItem = oFirstItem.getCells()[0]; // This is your Text object in the first cell of the first row
var sFirstItemDataPath = oFirstCellItem.getBindingContext().getPath();
this.getView().byId("Input2").bindProperty("value", sFirstItemDataPath + "/CoNumber");
this.getView().byId("Panel2").bindElement(sFirstItemDataPath);
},
onRowPressed: function(oEvent){
var oFirstItem = oEvent.getParameter("listItem"); // This is the pressed ColumnListItem object
var oFirstCellItem = oFirstItem.getCells()[0]; // This is your Text object in the first cell of the pressed row
var sFirstItemDataPath = oFirstCellItem.getBindingContext().getPath();
this.getView().byId("Input3").bindProperty("value", sFirstItemDataPath + "/CoNumber");
this.getView().byId("Panel3").bindElement(sFirstItemDataPath);
}
});
// instantiate the View
var myView = sap.ui.xmlview({viewContent:jQuery('#view1').html()}); // accessing the HTML inside the script tag above
// create some dummy JSON data
var data = {
WaybillsPlaces: [{
CoNumber: "Item 1",
},{
CoNumber: "Item 2",
},{
CoNumber: "Item 3",
}]
};
// create a Model and assign it to the View
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData(data);
myView.setModel(oModel);
// put the View onto the screen
myView.placeAt('content');
</script>
</head>
<body id='content' class='sapUiBody'>
</body>
</html>
EDIT2: Bind a form input to a certain property in a OData Model
Here I'm gonna use Northwind OData service, for ease of use, but you just need to use your own model. I used the "Customers" entitySet (a.k.a "Customers" DB table), and the "CustomerName" property in this entitySet.
In your case (as per the given OData in the description, you should use the 'WaybillsPlaces' entity and your 'CoNumber' property. If you want to access one specific entry, provide the Key between parenthesis in the binding URL (in your case: WaybillsPlaces('4610103052')).
I highly recommend you to read more about OData binding in UI5 (here and here). In a productive application, please set your OData model in the manifest.json file, to be sure that the $metadata call is done when the application starts, avoiding this way performance and many other issues.
HERE THE SNIPPET

Get bound values from pressed List Item in UI5 controller

I'm a beginner to SAP Fiori (UI5) and trying to retrieve a value from a table made with sap.m.Table in SAP Web IDE. But I don't succeed. Anybody hints on how to get there?
<Table id="table0" items="{/Entity1_Set}">
<ColumnListItem detailPress=".onShowHello" type="DetailAndActive">
<Text id="text5" maxLines="0" text="{Id}" />
<Text id="text6" maxLines="0" text="{field1}" />
<Text id="text7" maxLines="0" text="{field2}" />
<Text id="text8" maxLines="0" text="Euro"/>
</ColumnListItem>
<columns>
<Column id="column0">
<Label id="label0" text="Floor"/>
</Column>
</columns>
</Table>
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/m/MessageToast",
], function(Controller, MessageToast) {
"use strict";
return Controller.extend("QuickStartApplication.controller.View1", {
onShowHello: function(){
MessageToast.show("Hello World!");
},
});
});
In the "hello world"-MessageToast, I would like to display values of the fields in my table.
You can pass parameters in the function, which is called during an event.
Please see also https://sapui5.hana.ondemand.com/#docs/api/symbols/sap.m.ListItemBase.html#event:detailPress
Using these parameters, you can access the bound data.
Please see the following code on how to read the binding context of the ColumnListItem:
detailPress : function(oEventParams){
var oListItem = oEventParams.getSource();
var oBindingContext = oListItem.getBindingContext(); var sSomePropertyValue = oBindingContext.getProperty("<nameOfProperty>"); }
Using .getProperty, you can access your field values.

How can I bin data to table or list in Sapui5

I want to get data from user input and insert that data into a table or list. When the user clicks the insert button, the data will be inserted into the table. If the user clicks the delete button, the selected row will be deleted.
This my home.view.xml:
<Button text="insert" type="Unstyled" press="insContent"></Button>
<Button text="delete" type="Unstyled" press="deleteContent"></Button>
<l:Grid defaultSpan="L12 M12 S12" width="auto">
<l:content>
<f:SimpleForm columnsL="1" columnsM="1" editable="false" emptySpanL="4" emptySpanM="4" id="SimpleForm" labelSpanL="3" labelSpanM="3" layout="ResponsiveGridLayout" maxContainerCols="2" minWidth="1024">
<f:content>
<Label text="Name" id="lname"></Label>
<Input value="" id="iname"></Input>
<Label text="surname" id="lsurname"></Label>
<Input value="" id="isurname"></Input>
</f:content>
</f:SimpleForm>
</l:content>
</l:Grid>
<Table class="nwEpmRefappsShopControlLayout" growing="true" growingScrollToLoad="true" id="catalogTable">
<columns>
<Column demandPopin="true" id="descriptionColumn"></Column>
<Column demandPopin="true" id="descriptionColumn2"></Column>
</columns>
<ColumnListItem class="nwEpmRefappsShopTableItemLayout" id="columnListItem" type="Active" vAlign="Middle">
<cells>
.
.
</cells>
</ColumnListItem>
</Table>
This my home.controller.js:
insContent: function () {
// Get data from input
this.byId("iname").getValue();
this.byId("isurname").getValue();
}
I don't know how to make xml views but maybe this can help you.
First, you need to have a table with a model. For example (oTableData is a sap.m.Table object):
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData({modelData: aData});
oTableData.setModel(oModel);
oTableData.bindItems("/modelData", oRow);
Also you need an array for store data (in index.html).
var aData = [];
For add users you need the following function.
save: function(firstName, lastName) {
// Add object to array
aData.push({firstName: firstName, lastName: lastName});
// Refresh model
var oTableData = sap.ui.getCore().byId(this.createId("table"));
oTableData.getModel().refresh();
}
Finally for delete users you have to add this to the table.
oTableData.setMode(sap.m.ListMode.Delete);
oTableData.attachDelete(function(oEvent) {
var oSelectedItem = oEvent.getParameter("listItem");
var sItemName = oSelectedItem.getBindingContext().getProperty("firstName");
var path = oSelectedItem.getBindingContext().getPath();
path = path.substring(path.lastIndexOf('/') +1);
var model = oSelectedItem.getModel();
var data = model.getProperty('/modelData');
data.splice(parseInt(path), 1);
model.setProperty('/modelData', data);
sap.m.MessageToast.show("Deleted");
});
I make a repository for reference:
https://github.com/aosepulveda/sapui5-model-crud
You can fetch the first and last name using ids after clicking on the insert button. Once you have the values, create an object
var object = {
firstName: user_enteredValue,
lasName: userEnteredSirName
};
Then, insert into your table model, i.e.
table.getModel().getData().push(object);
table.getModel().refresh();
It will update your table with a new row.