SAPUI5 Multimodel Binding - model-binding

I have a problem with multimodel binding.
In init function of controller i set JSON model in ui.core
var oModel = new sap.ui.model.json.JSONModel(data1);
sap.ui.getCore().setModel(oModel, "model1");
in View I have a template of ColumnListItem and I bind it in a table
var template = new sap.m.ColumnListItem({
id: "first_template",
type: "Navigation",
type : sap.m.ListType.Active,
visible: true,
selected: true,
cells: [ new sap.m.Label({
text: "{name}"
})
],
press: [oController.pressListMethod]
});
oTable.bindItems("model1>/events", template, null, null);
oPage.addContent(oTable);
With simple Model it work's rigth but in Multimodel table only gets the number of items but not the properties of the model. Any solution ?

You need to use the model name in the template, too:
var template = new sap.m.ColumnListItem({
id: "first_template",
type: "Navigation",
type : sap.m.ListType.Active,
visible: true,
selected: true,
cells: [
new sap.m.Label({
text: "{model1>name}" // No leading "/" here since the binding is relative to the aggregation binding below
})
],
press: oController.pressListMethod
});
oTable.bindItems("model1>/events", template);
oPage.addContent(oTable);

Related

UI5 OData Search Help not displaying values

this is the odata response i am getting:
my desired result would be a search help that displays the "TypRolle", "RolleNr" and "RolleOri" columns of the odata response. But right now i am stuck at trying to just display one of them, the "TypRolle" one.
this is what my search help looks like right now:
As you can see, no values are being displayed.
Here is my valueHelpRequest method:
var roletypeUrl = "my odata url";
var attModel = new sap.ui.model.json.JSONModel();
var link = this.getView().byId("roletype"); // roletype input field
var oDataModel = new sap.ui.model.odata.v2.ODataModel(roletypeUrl, {
json: true,
loadMetadataAsync: true
});
oDataModel.read("/ZshNsiAgr01xxlEinzelTypSet", {
success: function(oData, response) {
attModel.setData(oData);
var oValueHelpDialog = new sap.m.Popover({
title: "Rollentyp auswählen",
footer: [new sap.m.Button({
text: "Ok"
})]
});
oValueHelpDialog.openBy(link);
var oItemTemplate = new sap.m.StandardListItem({
title: "test",
description: "{TypRolle}"
});
var oHelpTable = new sap.m.Table({
width: "300pt",
columns: [
new sap.m.Column({
header: [
new sap.m.Label({
text: "Rollentyp"
})
]
})
],
items: {
path: "/results",
template: oItemTemplate
},
items: [
new sap.m.ColumnListItem({
cells: [
new sap.m.Text({
text: "{TypRolle}"
})
]
})
]
})
oHelpTable.setModel(attModel);
oValueHelpDialog.addContent(oHelpTable);
I am very thankful for any kind of suggestion and look forward to your answers :)
If you have to do it with JSON model ... here it is
]
})
]
})
oHelpTable.bindAggregation("items", "/results", new sap.m.ColumnListItem({
cells: [
new sap.m.Text({
text: "{TypRolle}"
})
]
}));
oHelpTable.setModel(attModel);
oValueHelpDialog.addContent(oHelpTable);
Or else you can directly bind to your default OData model as well and it can fetch the data automatically without you writing the read

Bind children of children in SAPUI5 table

I have this model from my oData service:
{
"entity": [
{
"valueA": "ABC",
"valueB": "DEF",
"childL1": [
{
"valueC": "GHI",
"valueD": "JKL"
},
{
"valueC": "MNO",
"valueD": "PQR"
}
]
},
{
"valueA": "ABC",
"valueB": "DEF",
"childL1": [
{
"valueC": "GHI",
"valueD": "JKL"
},
{
"valueC": "MNO",
"valueD": "PQR"
}
]
}
]
}
Notice that for each 'child' in my 'entity' set, there's also an array of possible 'childL1'.
I have table in UI5 and I bound the data in the controller by:
this.myTable.bindAggregation('items', {path: /entity, template: this.oTemplate});
This works but the table displays:
Child1
Child2
However, what I want to do is:
/0/ChildL1/0
/0/ChildL1/0
/1/ChildL1/0
/1/ChildL1/0
So, to do that, I can do:
this.myTable.bindAggregation('items', {path: /entity/childL1, template: this.oTemplate});
The result would be as expected. However, I need to also display valueA in my table. Since my binding is at child1, I won't be able to get /entity/n/valueA.
What possible solution can I do for this? Is there a way to backtrack provided that childL1 has a 'key'? Or can I get entity then display childL1 in the table?
Since you haven't mentioned table control like which control you are using - sap.ui.table.Table or sap.m.Table. In case of "sap.ui.table.Table" you can bind the individual column like below
oTable.addColumn(new sap.ui.table.Column({
label : new sap.m.Label({
text : " "
}),
template : new sap.m.Text({
maxLines : 1
}).bindProperty("text", "valueA"),
}));
oTable.addColumn(new sap.ui.table.Column({
label : new sap.m.Label({
text : " "
}),
template : new sap.m.Text({
maxLines : 1
}).bindProperty("text", "childL1/valueC"),
}));
Like this you can add any no. of columns with different path but their parent path should alsways be same and then at last you can bind your main path to table rows like this-
oTable.bindAggregation("rows", {
path : "/entity"
});
and in case of sap.m.Table you can do it like this-
new sap.m.Table({ items:{
path:"/entity",
template: new sap.m.ColumnListItem({
cells:[
new sap.m.Text({
text:"{valueA}"
}),
new sap.m.Text({
text: "{childL1/valueC}"
})
]
})
}
})

creating dynamic table with data from odata service in ui5

I'm a complete newb on sap ui5.
I'm trying to generating a table on my webpage generated in sap web ide.
The data for this table is a .json file accessed via odata service.
I've come this far:
oModel is generated:
function initModel() {
var sUrl = "/sap/opu/odata/sap/ZGWS_someService/CollectionSet?$format=json";
var oModel = new sap.ui.model.odata.ODataModel(sUrl, true);
sap.ui.getCore().setModel(oModel);
}
now I want to generate a table on my html site with the data in the .json file.
So I have to create columns based on the properties of the items and then filling the rows with the current data.
.json looks like this:
{
"d": {
"results": [
{
"property1": "123",
"property2": "346"
},
{
"property1": "123",
"property2": "555"
}
I have no solution for this yet - can you help me out?
greetz,
simon
I created the table in the controller and sorted the data via lodash.
Is that good practice?
var oTable = this.byId("table");
oTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({
text: "Info1"
}),
sortProperty: "INTST",
template: new sap.ui.commons.TextView().bindProperty("text", "key")
}));
oTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({
text: "Count"
}),
template: new sap.ui.commons.TextView().bindProperty("text", "value")
}));
$
.ajax({
url: '/.../ServiceSet',
jsonpCallback: 'getJSON',
contentType: "application/json",
dataType: 'json',
success: function(data, textStatus, jqXHR) {
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData(data);
sap.ui.getCore().setModel(oModel);
//Create a model and bind the table rows to this model
//Get the forecastday array table from txt_forecast object
var aData = oModel.getProperty("/d/results");
var aData2 = _.countBy(_.map(aData, function(d) {
return d.VALUE;
}));
var aData3 = Object.keys(aData2).sort().map(key => ({
key,
value: aData2[key]
}));
oModel.setData({
modelData: aData3
});
oTable.setModel(oModel);
}
});
oTable.bindAggregation("rows", {
path: "/modelData"
});

In MVC 3, how do I refresh kendo grid in a partial view after I select a row in another partial view Kendo Grid?

I have a view with 3 partial views. The first partial view has a Kendo grid and when you select a row in the grid it populates and displays the 2nd partial view which has another kendo grid. It also populates and displays the 3rd partial view with another grid.
If I select a row in the 2nd kendo grid, i want it to insert data into the database table that the 3rd grid is using and I want it to refresh that 3rd grid with the new data.
I also have a custom button(retire) in the 3rd grid on each row that will also need to update that same grid by removing the item that was retired.
Can anyone help me set this up? Should I be using 3 partial views?
I guess you are using partial views to load each grid and it's data, that will work but you will have to refresh the entire page when a row is selected on the second grid in order to fill the third grid.
However Kendo Grid to a remote data source works well for this, you can then ignore loading the data into the grids within your partial views and use a bit of jQuery to ask the third grid to update on change event.
I find it much faster to fill grids with data via Ajax then when the page loads - but I have lots of data!
I have a grid updating for a person search which updates every time the search textbox changes
Grid defined as:-
$("#PersonSearch").kendoGrid({
columns: [
{ title: "Organisation", field: "cn", encoded: true },
{ title: "First name", field: "fn", encoded: true },
{ title: "Last name", field: "ln", encoded: true },
{ title: "Type", field: "pt", encoded: true },
{ title: "Date of birth", field: "db", encoded: true, format: "{0:dd/MM/yy}" },
{ title: "NHS number", field: "nn", encoded: true }
],
//sortable: { mode: "multiple" },
change: function () {
var selected = this.select()
data = this.dataSource.getByUid(selected.data("uid"));
if (data.url != "") {
.... do anything on a row being selected
}
else {
this.clearSelection();
}
},
filterable: false,
scrollable: { virtual: true },
sortable: true,
selectable: true,
groupable: false,
height: 480,
dataSource: {
transport: { read: { url: "../Person/PeopleRead/", type: "POST" } },
pageSize: 100,
serverPaging: true,
serverSorting: true,
sort: [
{ field: "cn", dir: "asc" },
{ field: "ln", dir: "asc" },
{ field: "fn", dir: "asc" },
],
serverFiltering: true,
serverGrouping: true,
serverAggregates: true,
type: "aspnetmvc-ajax",
filter: [],
schema: {
data: "Data", total: "Total", errors: "Errors",
model: {
id: "cID",
fields: {
db: { type: "date", defaultValue: null }
}
}
}
}
});
I trigger the Grid to fill with more data when the search box is changed :-
$('#GenericSearchString').keyup(function () {
// get a reference to the grid widget
var grid = $("#PersonSearch").data("kendoGrid");
// refreshes the grid
grid.refresh();
grid.dataSource.transport.options.read.url = "../Person/PeopleRead/" + $(this).val();
grid.dataSource.fetch();
});
On the server side in the Person controller I have a method PeopleRead :-
[HttpPost]
public ActionResult PeopleRead(String id, [DataSourceRequest]DataSourceRequest request)
{
WebCacheController Cache = ViewBag.Cache;
if (id == null) id = "";
string urlBase = Url.Content("~/");
var PeopleList = from c in db.Connections
where c.Person.Firstname.Contains(id) || c.Person.LastName.Contains(id)
select new
{
oID = c.Organisation.OrganisationID,
connID = c.ConnectionID,
cn = c.Organisation.Name,
fn = c.Person.Firstname,
pt =
(
c.Type == ModelEnums.ConnectionTypes.Customer ? "Customer" :
c.Type == ModelEnums.ConnectionTypes.Owner ? "Owner" :
c.Type == ModelEnums.ConnectionTypes.Service_User ? "Service user" :
c.Type == ModelEnums.ConnectionTypes.Worker ? "Worker" :
c.Type == ModelEnums.ConnectionTypes.Profile ? "Profile" : "Unknown"
),
url =
(
c.Type == ModelEnums.ConnectionTypes.Customer ? "" :
c.Type == ModelEnums.ConnectionTypes.Owner ? "" :
c.Type == ModelEnums.ConnectionTypes.Service_User ? urlBase + "ServiceUser/Details/" :
c.Type == ModelEnums.ConnectionTypes.Worker ? urlBase + "Worker/Details/" :
c.Type == ModelEnums.ConnectionTypes.Profile ? "" : ""
),
ln = c.Person.LastName,
nn = c.Person.NHSNumber,
db = c.Person.DateOfBirth
};
DataSourceResult result = PeopleList.ToDataSourceResult(request);
return Json(result);
}
Sorry the example is a bit off topic, but I though better to have working code as an example.
In your case the change: of the second grid would change the grid3.dataSource.transport.options.read.url and then do a grid3.dataSource.fetch();
I have to include the reference kendo.mvc along with many more on the mvc project as well as a link to kendo.aspnetmvc.min.js in the cshtml.

kendo ui grid not showing data

I am trying to get this basic kendo ui with expandable rows working:
<div id="grid"></div>
<script type="text/javascript">
$(function () {
$("#grid").kendoGrid({
columns: [
{
field: "ProductId",
title: "ProductId"
}
],
dataSource: {
type: "json",
transport: {
read: '#Url.Action("GetData1", "MockForms")'
}
},
height: 450,
sortable: true,
pageable: true,
detailTemplate: "<h2 style='background-color: yellow;'>Expanded!</h2>",
detailExpand: function (e) {
this.collapseRow(this.tbody.find(' > tr.k-master-row').not(e.masterRow));
}
});
});
</script>
The json is generated like this:
public ActionResult GetData1([DataSourceRequest] DataSourceRequest request)
{
var list = new List<Product>
{
new Product {ProductId = 1, ProductType = "SomeType 1", Name = "Name 1", Created = DateTime.UtcNow},
new Product {ProductId = 1, ProductType = "SomeType 2", Name = "Name 2", Created = DateTime.UtcNow},
new Product {ProductId = 1, ProductType = "SomeType 3", Name = "Name 3", Created = DateTime.UtcNow}
};
return Json(list.AsQueryable().ToDataSourceResult(request));
}
and seems to be send OK (according to firebug). However, nothing is bound (there are no javascript errors). Any ideas?
PS:
OnaBai's 2nd comment helped me to get this to work. I changed:
return Json(list.AsQueryable().ToDataSourceResult(request));
=>
return Json(list);
which produces this JSON:
[{"ProductId":1,"ProductType":"SomeType 1","Name":"Name 1","Created":"\/Date(1371022051570)\/"},{"ProductId":1,"ProductType":"SomeType 2","Name":"Name 2","Created":"\/Date(1371022051570)\/"},{"ProductId":1,"ProductType":"SomeType 3","Name":"Name 3","Created":"\/Date(1371022051570)\/"}]
Still I would like to use:
return Json(list.AsQueryable().ToDataSourceResult(request));
as this will eventually make paging and sorting easier. It currently produces:
{"Data":[{"ProductId":1,"ProductType":"SomeType 1","Name":"Name 1","Created":"\/Date(1371022186643)\/"},{"ProductId":1,"ProductType":"SomeType 2","Name":"Name 2","Created":"\/Date(1371022186648)\/"},{"ProductId":1,"ProductType":"SomeType 3","Name":"Name 3","Created":"\/Date(1371022186648)\/"}],"Total":3,"AggregateResults":null,"Errors":null}
I tried to use:
field: "Data.ProductId",
instead of:
field: "ProductId",
in the JavaScript code with no avail.
If you want to use ToDataSourceResult you should use the ASP.NET MVC wrappers. More info is available in the documentation: http://docs.kendoui.com/getting-started/using-kendo-with/aspnet-mvc/helpers/grid/ajax-binding

Resources