Call Dynamic Table values Onselect from listItems - sapui5

I would like to know if possible to get dynamic table values onSelect from listItems.
controller.js
onPress : function(oEvent){
var oSelectedItem = oEvent.getSource();
var oContext = oSelectedItem.getBindingContext("invoice");
var sPath = oContext.getPath();
var oListItem= this.getView().byId("BoM");
oListItem.bindItems({
path : "invoice>/ProductHeadSet('12345')/ProductHead2BOM",
template : new sap.m.ColumnListItem({
cells: [
new sap.m.Text({
text: "{invoice>Material}"
}),
new sap.m.Text({
text: "{invoice>Component}"
}),
new sap.m.Text({
text: "{invoice>Brand}"
})
]
})
});
}
});
Above is my controller, when i make onPress, i could receive the values from "12345". But when i try to make an dynamic onPress by removing (12345)"invoice>/ProductHeadSet/ProductHead2BOM"". It throws me an error like this "The request URI is invalid. The ProductHeadSet segment refers to an entity set and not to a single entity".
Thanks and Regards.

Your answer is right there
"The request URI is invalid. The ProductHeadSet segment refers to an entity set and not to a single entity".
Int the below code, the number within the brackets help identify which index in the array should be bound to the list.
invoice>/ProductHeadSet('12345')/ProductHead2BOM Without the number, you are trying to bind the entire array to oListItem.
EDIT
This is a little difficult to answer without seeing the model and bindings, But instead of doing path : "invoice>/ProductHeadSet('12345')/ProductHead2BOM"
Do
path : "invoice>"+sPath+"/ProductHead2BOM"

Related

How to concatenate multiple property bindings into one

I have an OData source that gives result rows that contain first_name & last_name.
I want to display these in a table with a column called Full Name.
I'm trying to use a JSView (It seems less kludgy than XML).
I can do a 1:1 binding like this:
var template = new sap.m.ColumnListItem({
// ...,
cells: [
new sap.m.Text({
text: "{first_name}"
})
]
});
But I cannot figure out how to bind / concatenate multiple fields to the Text control, or alternatively how to put multiple Text controls into one cell.
EDIT: This is not the exact same as the other suggested solution because this is for JSView instead of XMLView.
You can just use below format to concatenate the two values using simply binding.
XML
<Text text="{first_name} {last_name}" />
JS
new sap.m.Text({
text: "{first_name} {last_name}"
});
Prerequisite
In order to enable complex binding syntax (aka CompositeBinding), the following bootstrap setting is required:
<script id="sap-ui-bootstrap" src="https://.../resources/sap-ui-core.js"
data-sap-ui-compatversion="edge"
...
>
From: https://stackoverflow.com/a/41554735/5846045
This took me several hours of searching and trial and error, but I finally figured out out to use a formatter callback:
var template = new sap.m.ColumnListItem({
id: "column_template",
type: "Navigation",
visible: true,
cells: [
new sap.m.Text("activity", {
text: {
parts: [
{path: "first_name"},
{path: "last_name"}
],
formatter: function(a,b){
return a+" "+b;
}
}
})
]
});
parts must apparently be an array of objects with a path property. The path value must match the odata source.
These values will then be passed to the formatter callback as arguments.
EDIT: you can also do simple concatenation with a template, but there is a trick - you must add data-sap-ui-compatVersion="edge" to your bootstrap and then the following will work:
new sap.m.Text("activity", {
text: "{first_name} {last_name}"
});

Binding/Displaying OData data in a sap.m.Table control

I'm running into issue binding OData in a table control and I'm hoping one of you experts can spare a millisecond to tell me where I'm screwing up.
I can get the OData info from the backend server - step one is I just want to display it in a table with columns and step two is to present users with a segmented button to enable/disable processing of a countries data. Lets just get the data displayed now.
Here is the OData that is returned from the backed
backend odata
Here is my createContent code - I want to do it in JavaScript:
var oTable = new Table({
height: '100%',
firstVisibleRow: 0,
visibleRowCountMode: sap.ui.table.VisibleRowCountMode.Auto,
selectionMode: sap.ui.table.SelectionMode.None,
selectionBehavior: sap.ui.table.SelectionBehavior.RowOnly
}).addStyleClass('suggCompTableStyle');
var oColName = new sap.ui.table.Column().setLabel('{i18n>txt_countryName}').bindElement("/data>LANDX");
oTable.addColumn(oColName);
var oModel = sap.ui.getCore().getModel();
oModel.callFunction("/getCountryActiveList",
"GET",
{SPRAS: 'E'},
null,
function(oData, oResponse)
{ oTable.setModel( new sap.ui.model.json.JSONModel({data : oData.results}));
oTable.bindRows("/data");
alert("ok"); },
function(oError) {alert("err"); });
/* eslint-enable no-alert */
oTable.placeAt("content");
var oPage = new sap.m.Page({
title: "{i18n>title}",
content: [
oTable
]
});
var app = new sap.m.App("myApp", {
initialPage: "oPage"
});
app.addPage(oPage);
return app;
}/* end createContent function */
My table is created with the correct number of rows but not displaying the column data. I guess I'm confused on how to bind the column data?
Thanks for the assistance.
Steve
The issue is in your binding oTable.bindRows("/data");.
The bindRows method is expecting a row template control of the type sap.ui.table.Row.
You can look into https://sapui5.hana.ondemand.com/#/api/sap.ui.base.ManagedObject/methods/bindAggregation for more information. The bindRows method expects an input parameter equal to the oBindingInfo of the bindAggregation method from the link I above.

Bind Selected Item to Dialog

I am attempting to show data from a table item in the controls of a dialog. Here is a Plunker: https://plnkr.co/edit/MPHT17Hf4xNj3ZuuNXMd?p=preview
And here is the code specifically which gets the item data and sets it in the 'detailItem' JSONModel:
onItemPress: function(evt) {
var me = this;
var view = me.getView();
var item = evt.getSource().getBindingContext('list').getObject();
view.getModel('detailItem').setData(item);
var dlg = new sap.m.Dialog({
title: 'Edit Item',
type: 'Message',
content: [
new sap.m.VBox({
items: [
new sap.m.Label({
text: 'Section'
}),
new sap.m.Input({
value: '{detailItem>sectionId}'
}),
new sap.m.Label({
text: 'Cost'
}),
new sap.m.Input({
value: '{detailItem>costId}'
})
]
})
],
beginButton: new sap.m.Button({
text: 'Ok',
press: function() {
dlg.close();
}
}),
endButton: new sap.m.Button({
text: 'Cancel',
press: function() {
dlg.close();
}
}),
afterClose: function() {
dlg.destroy();
}
}).open();
}
The Plunker is pretty straight forward. Basically, I want to select an item in the table, open a dialog with a couple input fields allowing the data to be edited. I am trying to bind the input fields to the selected item by setting the data for the 'detailItem' model and attempting to bind the value property of the input fields to the respective data element.
Here is a working example (forked from yours): embed.plnkr.co/ictpCHG0R3H3jtsCmHKW.
The approach with the relative binding syntax was alright. We don't, however, need a second model, so replace {detailItem> with {list> in your dialog. Then, we can set the given binding context (from the selected item) to the dialog so that the relative bindings inside the dialog can be resolved:
dialog.setBindingContext(item.getBindingContext("list"), "list")
But that alone isn't enough. The dialog still won't display the selected data because it's not a descendant of the view and thus the "list" model is unknown to it.
One way to solve this problem is to add the dialog to the dependents aggregation of the view or any other control in the view. By this, the model will be propagated to the dialog. And as a bonus effect, it will be destroyed together when the principal control gets destroyed:
Special aggregation dependents is connected to the lifecycle management and databinding, but not rendered automatically and can be used for popups or other dependent controls or elements. This allows the definition of popup controls in declarative views and enables propagation of model and context information to them. [src]
Since all controls provide the aggregation <dependents>, you can also move the dialog definition from the controller to the view.

Uncaught TypeError: sap.ui.layout.form.SimpleForm is not a constructor

I am sorry to ask this silly question but when I am initializing the simple form layout , I am getting "Uncaught TypeError: sap.ui.layout.form.SimpleForm is not a constructor" . I am using below mentioned code :
// Add a Pagebar
var oBar = new sap.m.Bar("idFOBar", {
contentLeft: new sap.m.Button("idFOBackButton", {
icon: "sap-icon://nav-back",
press: function(){
app.back();
}
})
});
// Simple form
var oButton = new sap.m.Button({text: "Press"});
var oSimpleform = new sap.ui.layout.form.SimpleForm({
title:"Elements with Simple Form Layout",
content:[oButton]
});
var oPage = new sap.m.Page({
title: "Find Order",
content: [oBar,oSimpleform]
});
return oPage;
I remember I implemented forms before with the same code. I am not able to understand what is wrong here ?
Regards,
MS
The problem seems to be, that the class sap.ui.layout.form.SimpleForm cannot be found, so you cannot use it as a constructor.
It seems to work when you add sap.ui.layout to your sap-ui-core.js-bootstrap (jsbin).
Another option is to call $.sap.require("sap.ui.layout.form.SimpleForm"); to specifically load the SimpleForm-class.

Get ColumnListItem index sapui5

How can I get index of pressed ColumnListItem? I want to get and pass to controller method.
View code:
var oTable = new sap.m.Table({
id: "Countries",
mode: sap.m.ListMode.None,
columns: [ new sap.m.Column({
width: "1em",
header: new sap.m.Label({
text: "Name"
})
})
]
});
var template = new sap.m.ColumnListItem({
id: "first_template",
type: "Navigation",
visible: true,
selected: true,
cells: [ new sap.m.Label({
text: "{name}"
})
],
press: [oController.pressListMethod]
});
oTable.bindItems("/eventos", template, null, null);
oPage.addContent(oTable);
Controller code:
pressListMethod: function(index){
var oData = sap.ui.getCore().getModel().getProperty("/eventos/"+index+"/name");
alert(oData);
}
You shouldn´t rely on the index since the index in the table can differ from the index in your model (e.g. due to filtering and sorting).
You can read the bindingContext of the pressed ListItem like this:
pressListMethod: function(event){
var bindingContext = event.getSource().getBindingContext();
}
The bindingContext is an artificial object containing the related model and a path of the object within the model.
You can then read properties of your object like this:
var name = bindingContext.getProperty("name");
To get the whole object you can do it like this:
var myObject = bindingContext.getObject();
To get exact value of product
SelectedRowContext.getObject('PRODUCT_ID')
To get Name of product
SelectedRowContext.getObject('NAME')