Hierarchial JSON model and UI5 - sapui5

I am creating a demo application with JSON data and UI5. The idea (in a nutshell) is provide various information views for a selected item. I am using IconTabBar control. I have created an example scenario so (hopefully) I can explain the problem more clearly.
1.IconTabBar's first tab has list of employees and user can select one by selecting a radio button on the left
2.This takes the user to the next tab that displays say, sales view. The user can click on any tab and move to the respective view.
3.User can modify the information in any view. If the users forgets or ignores to Save the data, the tab color is set to Red.
4.User can Save the data.
5.Some of the views have information in master detail format.
The problem(s) I am facing are:-
1.How to filter the model data based on the item selected in the table?
2.How to update the filtered data and set back to model?
3.I also would like to know whether the data is structured correctly
I am using following code to update the binding path after company is selected. The GREP function is not returning correct values for proposals. It returns ONLY 1 proposal for E001 whereas it should return 2. It doesn't work properly for orders either. I am not sure whether the data is structured correctly.
var oModel_Data = oJSONDataModel.getData();
var oView_Data = oViewDataModel.getData();
var aModelData = oModel_Data[sSelected_Key];
var aViewData = oView_Data[sSelected_Key];
aViewData = jQuery.grep(aModelData, function(data, index) {
return data.id === sSelected_id
})[0];
oView_Data[sSelected_Key]=aViewData;
oViewDataModel.setData(oView_Data);
oViewDataModel.refresh(true);
I am using following code to check whether user has changed data.
var oView_Data = oViewDataModel.getData();
var oModel_Data = oJSONDataModel.getData();
var aViewData = oView_Data[in_sKey];
var aModelData = oModel_Data[in_sKey];
aModelData.forEach(function(item, index, array) {
var valueView = aViewData;
if (item.id === sSelected_id){
//The code here need to consider complex(nested) data types
//Thus it should check type of not only valueView and item
//but also their each and every child elements
/*---------Temporary Solution---------------------*/
var sViewValue = JSON.stringify(valueView);
var sItem = JSON.stringify(item);
var bSameData = sViewValue === sItem;
if (bSameData==true){
flag_data_changed=false;
}else{
return flag_data_changed=true;
}
}
});
My json model is as below.
{
"employees": [
{"id":"E0001" ,
"name":"Alec Stewert"
},
{"id":"E0002" ,
"name":"Debra Manning"
}
],
"sales": [
{"id":"E0001" ,
"sale_q1":"10000",
"sale_q2":"3000",
"sale_q3":"8000",
"sale_q4":"2000"
},
{"id":"E0002" ,
"sale_q1":"8000",
"sale_q2":"3000",
"sale_q3":"7000",
"sale_q4":"5000"
}
],
"proposal":[
{"id":"E0001",
"fi_q":"Q2",
"value":"12000",
"customer":"6000"
},
{ "id":"E0001",
"fi_q":"Q2",
"value":"8000",
"customer":"2300"
}
],
"key_orders": [
{"id":"E0001",
"order_hdr":
[
{"id":"O0001",
"fi_q":"Q1",
"value":"2000",
"customer":"2000"
},
{"id":"O0002",
"fi_q":"Q1",
"value":"2000",
"customer":"2000"
}
],
"order_dtl":[
{
"id":"O0001",
"itm":"Item X",
"Qty":"100",
"rate":"20"
}
]
},
{"id":"E0002",
"order_hdr":
[
{"id":"O0011",
"fi_q":"Q1",
"value":"2000",
"customer":"5000"
},
{"id":"O0012",
"fi_q":"Q1",
"value":"1000",
"customer":"5000"
}
],
"order_dtl":[
{
"id":"O00011",
"itm":"Item Z",
"Qty":"200",
"rate":"10"
}
]
}
]
}
I have investigated online and in SAP Help but failed to understand what needs to be done. Any help is appreciated.

1.How to filter the model data based on the item selected in the table?
If you prepare the JSONModel you can use the Filter
2.How to update the filtered data and set back to model?
If you bind the table to the JSONModel, by default the JSNOModel is 2 way binding so any edited data will be in the JSONModel
3.I also would like to know whether the data is structured correctly
Go through the Example of the Table So you will get an idea of the Model and binding model to the Table

Related

UI5: get path for new object in model

I often have some kind of master-detail situation where i try to use a single model for both master and detail view.
The detail page is bound directly to an element in the list with .bindElement(path) when you select an item in the list. The path is available from the binding context. Everyone is happy:
//click handler for list item:
var context = this.getBindingContext();
oDetailPage.bindElement(context.getPath());
oApp.toDetail(oDetailPage);
The challenge is when the list page has an "add" button. I create a new object and put that into the model. But how do I find the path? i have no context:
//click handler for "add" button
var newStuff = {
propA: "foo",
propB: 13
};
oModel.setData(oModel.getData().concat(newStuff));
oDetailPage.bindElement(/* What??? */);
oApp.toDetail(oDetailPage);
I've searched for a .findPath(newStuff) method but no such thing exists
Hi, unfortunatly I am unable to test this but I think this should work
The binding path is pretty much pointer to a specific entry in a collection. The path value does depend on a couple of variables, such as how your model is structured.
For example, if the Model data looks like this :
{"results" : [
{propA: "foo",
propB: 13
},
{propA: "ber",
propB: 14
}]
}
And you concat
{propA: "newItem",
propB: 15
}
I believe you binding path would be
"/results/2"
You can also, find the most recent index with something like
this.getModel("yourModel").getObject("results").length;
Edit -
Unless I miss understand your quesitons, your new entry should be at the end of the model.
here are 2 cases
//click handler for "add" button
var newStuff = {
propA: "foo",
propB: 13
};
// case 1: root of model data is an array
var oData = oModel.getProperty("/");
oData.push(newStuff);
oDetailPage.bindElement("/" + oData.length - 1);
// case 2: we appends to /results
var oData = oModel.getProperty("/results");
oData.push(newStuff);
oDetailPage.bindElement("/results/" + oData.length - 1);

Need to show how much data (In precentage) filled in mongoDb collection

I am using MongoDB for storing data in my application. I need to show the user how much data they filled using percentage.
For example: I have USER collection. In this collection i have several fields. Once the user enter data in their profile. I need to show how much percentage of data they filled in their profile.
In my application. I am using MongoDb and loopback frame work. I didn't defined any property in models.
How to solve this problem.Please help!!
You can add properties in you user model and define percentage against that or you can define one object property like the below mentioned
Suppose you have a User model and in it is settings property, of type object
Settings object will gave 10 keys. 1 keys is 10% then 10 keys filled is
100%. So just check whether user have filled the desired setting and mark a percentage.
so your model will be like
{
"name": "Member",
"base": "User",
"properties": {
"email": {
"type": "string"
},
"settings": {
"type": "object"
}
}
}
and inside your code retrieve the settings object and loop through it to make your percentage
Member.findById(your_id, function(err, usr){
if(!err){
var percentage_completed = 0;
Object.keys(usr.settings).map(function(pro){
if( usr.settings[pro] != "" ){
percentage_completed+=10;
}
})
}
})
I hope this will serve your purpose.

BlackBerry Cascades: How do i load data into a ListView

Hello I have a simmiliar question as this one:
BlackBerry 10 Cascades: How do I load data into a DropDown?
The only thing i want to know is how to do this with a ListView instead of a dropdown?
Thanks in advance!
The ListView displays data from a DataModel which is an abstract data type. Which specific type of data model you use depends on the source of your data. You place your data in the appropriate data model then assign the data model to the ListView.
To load data into a dropdown, instead of a listview, use this code:
DropDown {
id: dropdown
attachedObjects: [
ComponentDefinition {
id: compDefDD
Option {
description: "your default value for each Option"
}
},
DataSource {
id: dropDownDataSource
// Load the data from an SQL database, based on a specific query
source: "asset:///database.sql
query: "select * from <yourtable>"
onDataLoaded: {
//the method is the code above
for (var i = 0; i < data.length; i ++) {
var option = compDefDD.createObject();
option.text = data[i].SQLcolumn1;
option.value = data[i].SQLcolumn2;
dropdown.add(option);
}
}
onError: {
console.debug(errorMessage + " : " + errorType);
}
}
]
onCreationCompleted: {
dropDownDataSource.load();
}
}
In this example I load data from a sql database. If you use another source of the data see page reference for more details.

Select an item from Dojo Grid's store and display one of its attributes (array of objects) on grid

I have a Dojo EnhancedGrid which uses a data store filled with the following data structure:
[
{ id: 1, desc: "Obj Desc", options: [ { txt: "text", value: 0 }, { obj2 }, { objn } ] },
{ id: 2, ... },
{ id: 3, ... },
{ id: n, ... }
]
Currently I'm doing all this with an auxiliary store...but I believe this is far from a good approach to the problem, it's too ugly and doesn't work really well with edition (because I have to send changes from one store to another).
Instead of displaying all this objects at the same time, I wanted to select just one object (using its id) and display its options objects on grid. At the same time, the changes on grid should make effect on store, to be able to save them later.
Is it possible to query the grid's store, in order to display just one object? How?
And is it possible to fill the grid with objects list present on "options" attribute?

JQGrid Dynamic Select Data

I have utilised the example code at Example Code at this link
and I have got my grid to show a dynamically constructed select dropdown on add and edit. However when it is just showing the data in the grid it shows the dropdown index instead of its associated data. Is there a way to get the grid to show the data associated with the index instead of the index itself.
e.g. the data on my select could be "0:Hello;1:World"; The drop down on the edit/add window is showing Hello and World and has the correct indexes for them. If the cell has a value of 1 I would expect it to show World in the grid itself but it is showing 1 instead.
Here is the row itself from my grid:
{ name: 'picklist', index: 'picklist', width: 80, sortable: true, editable: true,
edittype: "select", formatter: "select", editrules: { required: true} },
I am filling the dynamic data content in the loadComplete event as follows:
$('#mygrid').setColProp('picklist', { editoptions: { value: picklistdata} });
picklist data is a string of "0:Hello;1:World" type value pairs.
Please can anyone offer any help. I am fairly new to JQGrids so please could you also include examples.
I know you have already solved the problem but I faced the same problem in my project and would like to offer my solution.
First, I declare a custom formatter for my select column (in this case, the 'username' column).
$.extend($.fn.fmatter, {
selectuser: function(cellvalue, options, rowdata) {
var userdata;
$.ajax({
url:'dropdowns/json/user',
async:false,
dataType:'json',
cache:true,
success: function(data) {
userdata = data;
}
});
return typeof cellvalue != 'undefined' ? userdata[cellvalue] : cellvalue ;
}
});
This formatter loads up the mapping of id and user in this case, and returns the username for the particular cellvalue. Then, I set the formatter:'selectuser' option to the column's colModel, and it works.
Of course, this does one json request per row displayed in the grid. I solved this problem by setting 10 seconds of caching to the headers of my json responses, like so:
private function set_caching($seconds_to_cache = 10) {
$ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT";
header("Expires: $ts");
header("Pragma: cache");
header("Cache-Control: max-age=$seconds_to_cache");
}
I know this solution is not perfect, but it was adequate for my application. Cache hits are served by the browser instantly and the grid flows smoothly. Ultimately, I hope the built-in select formatter will be fixed to work with json data.
If you save in jqGrid ids of the select elements and want to show the corresponding textes then you should use formatter:'select' in the colModel (see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:predefined_formatter#formatter_type_select) together with the edittype: "select".
The Usage of stype: 'select' could be also interesting for you if you plan to support data searching.