Skip to content

Instantly share code, notes, and snippets.

@ricma

ricma/.gitignore Secret

Last active January 3, 2016 20:49
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Embed
What would you like to do?
Creating different views on Models in SAPUI5 (see http://scn.sap.com/thread/3486587) Is it possible to transpose the data of a model in order to get the data more appropriate to a certain control? Here: The first table shows all persons. the second table should show all phone numbers and then the persons attached to them.
// Some example data of persons having various telephone numbers
// Note: Some of the persons have the same number
var oPersonData = {
"persons": [
{"name": "Sonja Software", "phones": ["12345", "54321"]},
{"name": "Conrad Coder", "phones": []},
{"name": "Mike Mailinglist", "phones": ["6789"]},
{"name": "Hugo Hacker", "phones": ["54321"]}]};
// Function makePhoneList is a copy of function transposeData
// (see exampleTransposed.js).
function makePhoneList(oPersonList) {
// we first sort all numbers into a map to have every number exactly
// once
var mPhones = {};
jQuery.map(oPersonList["persons"], function(oPerson, iIdx) {
var aPhones = oPerson.phones || [];
jQuery.map(oPerson.phones, function(sPhone, iIdx2) {
mPhones[sPhone] = mPhones[sPhone] || {"number": sPhone};
mPhones[sPhone]["persons"] = mPhones[sPhone]["persons"] || [];
mPhones[sPhone]["persons"].push(oPerson.name);
});
});
// Change the map to a list of values -- the keys are part of the
// items under `number`.
var aPhones = [];
jQuery.each(mPhones, function(sNumber, oPhone) {
aPhones.push(oPhone)});
return {"phones": aPhones};
}
// Function makePersonList is a copy of function makePhoneList.
function makePersonList(oPhoneList) {
// we first sort all persons into a map to have every person exactly
// once
var mPersons = {};
jQuery.map(oPhoneList["phones"], function(oPhone, iIdx) {
var aPersons = oPhone.persons || [];
jQuery.map(oPhone.persons, function(sPerson, iIdx2) {
mPersons[sPerson] = mPersons[sPerson] || {"name": sPerson};
mPersons[sPerson]["phones"] = mPersons[sPerson]["phones"] || [];
mPersons[sPerson]["phones"].push(oPhone.number);
});
});
// Change the map to a list of values -- the keys are part of the
// items under `number`.
var aPersons = [];
jQuery.each(mPersons, function(sNumber, oPerson) {
aPersons.push(oPerson)});
return {"persons": aPersons};
}
// Structure oPhoneData contains a unique list of telephone numbers and their
// associated persons. Structure oPhoneData is a transposition of structure
// oPersonData.
var oPhoneData = makePhoneList(oPersonData);
// set the person model
var oPersonModel = new sap.ui.model.json.JSONModel();
oPersonModel.setData(oPersonData);
// set the phone model
var oPhoneModel = new sap.ui.model.json.JSONModel();
oPhoneModel.setData(oPhoneData);
// create some controls to show the data
// This shows the persons and their telephone numbers
var oPersonTable = new sap.ui.table.Table();
oPersonTable.bindRows("personModel>/persons");
function personModelChanged(oControlEvent) {
oPhoneData = makePhoneList(oPersonData);
oPhoneModel.setData(oPhoneData);
}
oPersonTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: "Name"}),
template: new sap.ui.commons.TextField({
value: "{personModel>name}",
change: personModelChanged})}));
oPersonTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: "Phone Numbers"}),
template: new sap.ui.commons.DropdownBox().bindItems(
"personModel>phones",
new sap.ui.core.ListItem({
text: "{personModel>}"}))}));
// set the model of the control
oPersonTable.setModel(oPersonModel, "personModel");
oPersonTable.placeAt("content");
// create some controls to show the data
// This shows the telephone numbers and their persons
var oPhoneTable = new sap.ui.table.Table();
oPhoneTable.bindRows("phoneModel>/phones");
function phoneModelChanged(oControlEvent) {
oPersonData = makePersonList(oPhoneData);
oPersonModel.setData(oPersonData);
}
oPhoneTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: "Phone Number"}),
template: new sap.ui.commons.TextField({
value: "{phoneModel>number}",
change: phoneModelChanged})}));
oPhoneTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: "Names"}),
template: new sap.ui.commons.DropdownBox().bindItems(
"phoneModel>persons",
new sap.ui.core.ListItem({
text: "{phoneModel>}"}))}));
// set the model of the control
oPhoneTable.setModel(oPhoneModel, "phoneModel");
oPhoneTable.placeAt("content");
// Create a table showing all numbers
// set the model
var oModelTransposed = new sap.ui.model.json.JSONModel();
// --------------------------------------------------
// FIXME: I manually transpose the data here
// This has drawbacks: The data is duplicated and might get out of
// sync!
function transposeData(oData) {
// we first sort all numbers into a map to have every number exactly
// once
var mPhones = {};
jQuery.map(oData["persons"], function(oPerson, iIdx) {
var aPhones = oPerson.phones || [];
jQuery.map(oPerson.phones, function(sPhone, iIdx2) {
mPhones[sPhone] = mPhones[sPhone] || {"number": sPhone};
mPhones[sPhone]["persons"] = mPhones[sPhone]["persons"] || [];
mPhones[sPhone]["persons"].push({
"name": oPerson.name});
});
});
// Change the map to a list of values -- the keys are part of the
// items under `number`.
var aPhones = [];
jQuery.each(mPhones, function(sNumber, oData) {
aPhones.push(oData)});
return {"phones": aPhones};
}
// Question: Is their a way to use a view onto the original data?
// Especially: If this model is changed by some control the change
// should also be set in the `originalModel` (For example by changeing
// one of the names in the upper table the lower table should change
// accordingly)
oModelTransposed.setData(transposeData(oData));
oData = oModelTransposed.getData();
// --------------------------------------------------
// create some controls to show the data
// This shows the persons and their telephone numbers
var oTableTransposed = new sap.ui.table.Table();
oTableTransposed.bindRows("transposedModel>/phones");
var oColumnNamesT = new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: "Name"}),
template: new sap.ui.commons.DropdownBox().bindItems(
"transposedModel>persons",
new sap.ui.core.ListItem({
text: "{transposedModel>name}"}))});
oTableTransposed.addColumn(oColumnNamesT);
var oColumnNumbersT = new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: "Phone numbers"}),
template: new sap.ui.commons.TextField({
value: "{transposedModel>number}"})});
oTableTransposed.addColumn(oColumnNumbersT);
// set the model of the control
oTableTransposed.setModel(oModelTransposed, "transposedModel");
oTableTransposed.placeAt("content");
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
<title>Transform models to get transposed / concatenated data</title>
<script id="sap-ui-bootstrap"
src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_goldreflection"
data-sap-ui-libs="sap.ui.commons,sap.ui.table"></script>
<script type="text/javascript" src="example.js">
</script>
<!--
<script type="text/javascript" src="exampleTransposed.js">
</script>
-->
</head>
<body class="sapUiBody">
<div id="content"></div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment