Dojo grid nested json - json

I'd like to have a dojo grid which connects to a server url which outputs the following json :
{identifier : "id"
items : [ { id: "1", name: "John", university : { name: "XXX", address: "YYY" } }].
Basically I have a nested json. I would like to represent the university name and University address as separate columns in the grid.
I tried using the dojox.grid.DataGrid object and creating a gird layout, but do not know how to refer to the nested elments and university.name and university.address don't seem to work.
I am using dojo 1.6.1.
Does anybody have any pointers?
This is the js code I use :
dojo.require("dojox.grid.DataGrid");
dojo.require("dojo.data.ItemFileReadStore");
dojo.addOnLoad(function(){
// our test data store for this example:
var jsonStore = new dojo.data.ItemFileReadStore({
url: '/MainDeployer/ajax/users/get.json'
});
var layoutUsers = [
[{
field: "name",
name: "Name",
width: 10
},
{
field: "university.name",
name: "University Name",
width: 10
},
{
field: "university.address",
name: "University Address",
width: 'auto'
}]];
// create a new grid:
var grid = new dojox.grid.DataGrid({
query: {},
store: jsonStore,
clientSort: true,
rowSelector: '20px',
structure: layoutUsers
},
document.createElement('div'));
dojo.byId("usersTable").appendChild(grid.domNode);
grid.startup();
});
Thanks,
Cristian

What kind of store are you using? Have a look at the dojo.data.ItemFileReadStore documentation, there is an example with a situation like yours:
http://dojotoolkit.org/reference-guide/dojo/data/ItemFileReadStore.html#item-structure
This would help you fetching all the items with a single call to the method "fetch". If for some reasons it doesn't work due to the different json structure, you can continue using ItemFileReadStore , and create a function that loops over all the objects in your json and uses the loadItem method for adding items one by one in this way (it's not beautiful but it works):
var myData = {"items" : []};
var myStore = new dojo.data.ItemFileWriteStore({data: myData});
var myLayout = [{
field: 'name',
name: 'Name',
width: '200px'
},
{
field: 'universityName',
name: 'University Name',
width: '100px'
},
{
field: 'universityAddress',
name: 'University Address',
width: '60px'
}];
var myGrid;
dojo.addOnLoad(function(){
myGrid = new dojox.grid.DataGrid({
store: myStore,
structure: myLayout
}, document.createElement('div'));
dojo.byId("myGridContainer").appendChild(myGrid.domNode);
myGrid.startup();
dojo.xhrGet({
url: myURL,
handleAs: "json",
headers: {
"Content-Type": "application/json; charset=uft-8",
"Accept" : "application/json"
},
load: function(responseObject, ioArgs) {
myList = responseObject;
dojo.forEach(myList.items, function(element) {
myStore.newItem({"name": element.name,
"universityName": element.university.name,
"universityAddress": element.university.address});
});
})
});
}

se a formatter:
var nameFormatter = function(value, rowIdx){
return value.name;
};
var addressFormatter = function(value, rowIdx){
return value.address;
};
var layoutUsers = [
[{
field: "name",
name: "Name",
width: 10
},
{
field: "university",
name: "University Name",
width: 10,
formatter: nameFormatter
},
{
field: "university",
name: "University Address",
width: 'auto',
formatter: addressFormatter
}]];

Related

SAPUI5 aggregation of tables doesn't work

I'm new to SAPUI5 and I'm trying to aggregate some JSON data before displaying in a column chart.
Here are some lines of my code:
var xsodataURL = 'That is my URL to my xsodata';
var oModelBU = new sap.ui.model.odata.ODataModel(xsodataURL, false);
oModelBU.bindList('/PM_PROJECT', false, {
select: 'PMBudget, PMActual, PMEAC'
});
var oDatasetBU = new sap.viz.ui5.data.FlattenedDataset({
dimensions: [{
axis: 1,
name: 'ProgramID: Overall Result',
value: ''
}],
measures: [
[{
name: 'Budget',
value: '{PMBudget}'
}, {
name: 'Actual',
value: '{PMActual}'
}, {
name: 'EAC',
value: '{PMEAC}'
}]
],
data: {
path: '/PM_PROJECT'
}
});
var oChartBU = new sap.viz.ui5.Column({
width: '100%',
height: calcChartHeight,
legendGroup: {
layout: {
position: 'bottom'
}
},
plotArea: {
colorPalette : d3.scale.category20().range()
},
title: {
visible: true,
text: 'Budget use in mEUR',
alignment: 'left'
},
dataset: oDatasetBU
});
oChartBU.setModel(oModelBU);
Actually everything works fine, but the application just display the JSON data of the last item in my xsodata. That's why I tried to aggregate the data in the xsodata file like:
"PM_SHOWCASE"."PM_PROJECT" aggregates always(SUM of "PMBudget", SUM of "PMActual", SUM of "PMEAC");
But that doesnt work - does anyone know, how I can display ALL data aggregated as SUM of the table "PM_PROJECTS"? Thanks in advance!
Have a great day, Arne.

Extjs create form items with json store

I have created a form panel view and I will create some form items iside this panel. The communication to the store, controller and model works fine but how can I create the items in the view?
Json array (retrieved from external service):
{
"data": [
{
"name": "ff",
"xtype": "textfield",
"allowBlank": false,
"fieldLabel": "labelText1"
},
{
"name": "fsdsdf",
"xtype": "textfield",
"allowBlank": false,
"fieldLabel": "labelText2"
}
],
"msg": "Unknown",
"success": true
}
Store:
Ext.define('myApp.store.Forms', {
extend: 'Ext.data.Store',
alias: 'store.Form',
model: 'myApp.view.FormModel',
constructor: function(config) {
var me = this;
config = config || {};
me.callParent([Ext.apply({
autoLoad: true,
proxy: {
type: 'ajax',
url: 'url_to_service',
reader: {
type: 'json',
rootProperty: 'data',
successProperty : 'success'
}
},
storeId: 'formStore'
}, config)]);
// console.error("store loaded");
// console.info(me);
}
});
model
Ext.define('myApp.view.FormModel', {
extend: 'Ext.data.Model',
data: {
name: 'myApp'
}
});
Controller
Ext.define('myApp.view.FormController', {
extend: 'Ext.app.ViewController',
alias: 'controller.form',
init: function(application) {
var store = new myApp.store.Forms();
store.on("metachange", metaChanged, this);
function metaChanged(store, meta) {
var grid = Ext.ComponentQuery.query('form')[0];
grid.fireEvent('metaChanged', store, meta);
};
this.control({
"form": {
metaChanged: this.handleStoreMetaChange
}
});
},
handleStoreMetaChange: function(store, meta) {
var form = Ext.ComponentQuery.query('form')[0];
form.reconfigure(store, meta.data);
}
});
At least the view where I want to create the items from the store.
Ext.define('myApp.view.Form', {
extend: 'Ext.form.Panel',
xtype: 'form',
controller: "form",
viewModel: {
type: "form"
},
title: 'form',
bodyPadding: 10,
autoScroll: true,
defaults: {
anchor: '100%',
labelWidth: 100
},
// How can I add form items here?
});
Within your view you'll need to create a function that matches the form.reconfigure(store, meta.data) call you are making in your controller.
And in that function you can call the form's add function to add items to the form. As you are already supplying the xtype and configuration parameters in the data structure each item can be passed to the add function as it. It would look something like the below code...
reconfigure: function(store, data) {
var me = this;
Ext.each(data, function(item, index) {
me.add(item);
});
}
I have knocked together an Example Fiddle that shows this working. I just mocked out the loading of the data and 'metachange' event as it was easier to get the demo working.

Web API Odata not returning correct metadata

I'm using OData v4 with Web API to communicate with my AngularJS web application.
More specifically I'm trying to display my data using Kendo UI Grid.
My problem is, that my Web API does not return the correct metadata, resulting in Kendos datasource not being able to display the data.
I'm doing paging, and to do that I need the "count" property in my response for Kendo UI Grid datasource to be able work properly.
The response I'm expecting the Web API should look something like this:
http://docs.oasis-open.org/odata/odata-json-format/v4.0/errata02/os/odata-json-format-v4.0-errata02-os-complete.html#_Toc403940644
However, the result I'm seeing in the response is:
{
"#odata.context":"http://localhost:1983/odata/$metadata#TestReports","value":[
{
"Id":1,"Name":"Test Testesen","Purpose":"Kendo UI Grid Test","Type":"Rumraket","ReportedDate":"2015-02-04T10:03:59.4173323+01:00"
},{
"Id":2,"Name":"Gunner Testesen","Purpose":"OData Web API Test","Type":"Sutsko","ReportedDate":"2015-02-04T10:03:59.4173323+01:00"
},{
"Id":3,"Name":"Bertram Didriksen","Purpose":"Server Paging Test","Type":"Flyver","ReportedDate":"2015-02-04T10:03:59.4173323+01:00"
},{
"Id":4,"Name":"Oluf Petersen","Purpose":"Test","Type":"B\u00e5d","ReportedDate":"2015-02-04T10:03:59.4173323+01:00"
},{
"Id":5,"Name":"Alfred Butler","Purpose":"Opvartning","Type":"Batmobil","ReportedDate":"2015-02-04T10:03:59.4173323+01:00"
}
]
}
My code for retrieving the data is:
$scope.pendingReports = {
dataSource: {
type: "odata",
transport: {
read: {
beforeSend: function (req) {
req.setRequestHeader('Accept', 'application/json;odata=fullmetadata');
},
url: "/odata/TestReports",
dataType: "odata"
},
parameterMap: function (options, type) {
var paramMap = kendo.data.transports.odata.parameterMap(options);
console.log(paramMap);
delete paramMap.$inlinecount; // <-- remove inlinecount parameter
delete paramMap.$format; // <-- remove format parameter
console.log(paramMap);
return paramMap;
}
},
schema: {
data: function (data) {
return data; // <-- The result is just the data, it doesn't need to be unpacked.
},
total: function (data) {
return data.length; // <-- The total items count is the data length, there is no .Count to unpack.
}
},
pageSize: 5,
serverPaging: true,
serverSorting: true
},
sortable: true,
pageable: true,
dataBound: function () {
this.expandRow(this.tbody.find("tr.k-master-row").first());
},
columns: [
{
field: "Name",
title: "Navn"
}, {
field: "ReportedDate",
title: "Indberetet den"
}, {
field: "Purpose",
title: "Formål"
}, {
field: "Type",
title: "Type"
}, {
field: "options",
title: "Muligheder"
}
]
};
My WebApiConfig class is corrently like this:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Formatters.InsertRange(0, ODataMediaTypeFormatters.Create());
config.MapODataServiceRoute(
routeName: "odata",
routePrefix: "odata",
model: GetModel()
);
}
public static Microsoft.OData.Edm.IEdmModel GetModel()
{
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<TestReport>("TestReports");
return builder.GetEdmModel();
}
}
Does anyone have any suggestions on how I get the Web API to return the correct metadata?
Apparently Kendo UI Grid is not supporting OData v4.
The fix was to modify the parameterMap of the Kendo datasource, and tell it to use $count instead of $inlinecount.
Besides that I had to tell the schema to read "#odata.count" as the "total" value.
After I edited the before posted code to the ode below, I got the correct data in my response:
$scope.pendingReports = {
dataSource: {
type: "odata",
transport: {
read: {
beforeSend: function (req) {
req.setRequestHeader('Accept', 'application/json;odata=fullmetadata');
},
url: "/odata/TestReports",
dataType: "json"
},
parameterMap: function (options, type) {
var d = kendo.data.transports.odata.parameterMap(options);
delete d.$inlinecount; // <-- remove inlinecount parameter
d.$count = true;
return d;
}
},
schema: {
data: function (data) {
return data.value; // <-- The result is just the data, it doesn't need to be unpacked.
},
total: function (data) {
return data['#odata.count']; // <-- The total items count is the data length, there is no .Count to unpack.
}
},
pageSize: 5,
serverPaging: true,
serverSorting: true
},
sortable: true,
pageable: true,
dataBound: function () {
this.expandRow(this.tbody.find("tr.k-master-row").first());
},
columns: [
{
field: "Name",
title: "Navn"
}, {
field: "ReportedDate",
title: "Indberetet den"
}, {
field: "Purpose",
title: "Formål"
}, {
field: "Type",
title: "Type"
}, {
field: "options",
title: "Muligheder"
}
]
};

Kendo UI Grid with object ID translation

I'm trying to make a grid with KendoUI with external data via JSON (php+mysql engine) from TABLE A and one of columns of these data, get text labels from another TABLE B.
Example, data are: idPermission=1, user_id=1, business_unit_id=1, permission=10
The user_id=1 I want get from another table (Users) their names, 1=John Doe, 2=Martin Brown.
I want to see "John Doe" instead id 1 in the visualization of grid, and "Martin Brown" instead id 2. When inline (or popup) editing of the records I've already reached the target, and I've a select box with the names and not the ids!
Here is my code:
<script>
$(function() {
var crudServiceBaseUrl = "http://localhost/ajax/";
var dataTable = "UsersPermissions";
// This is the datasource of the grid
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: crudServiceBaseUrl + "table_action.php?op=R&tbl="+dataTable,
dataType: "json"
},
update: {
url: crudServiceBaseUrl + "table_action.php?op=U&tbl="+dataTable,
type: "POST"
},
destroy: {
url: crudServiceBaseUrl + "table_action.php?op=D&tbl="+dataTable,
type: "POST"
},
create: {
url: crudServiceBaseUrl + "table_action.php?op=C&tbl="+dataTable,
type: "POST"
}
},
batch: true,
pageSize: 10,
schema: {
model: {
id: "idPermission",
fields: {
idPermission: { editable: false, nullable: true },
user_id: { validation: { required: true } },
business_unit_id: {},
permission: { validation: { required: true } },
}
}
}
});
// This is the datasource of the user_id column
usersSource = new kendo.data.DataSource({
transport: {
read: {
url: crudServiceBaseUrl + "table_action.php?op=R&tbl=Users",
dataType: "json"
}
},
batch: true,
schema: {
model: {
id: "idUser",
fields: {
idUser: {},
email: {},
password: {},
name: {},
last_login: {},
status: {}
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
pageable: true,
sortable: {
mode: "single",
allowUnsort: false
},
reorderable: true,
resizable: true,
scrollable: false,
toolbar: ["create"],
columns: [
{
field: "user_id",
editor: function (container, options) { // This is where you can set other control types for the field.
$('<input name="' + options.field + '"/>').appendTo(container).kendoComboBox({
dataSource: usersSource,
dataValueField: "idUser",
dataTextField: "name",
});
},
title: "ID Utente"
},
{ field: "business_unit_id", title: "Business Unit"},
{ field: "permission", title: "Permission"},
{ command: ["edit", "destroy"], width: "230px"}],
editable: "inline"
});
});
</script>
How I can make the same thing I've done in editing mode, in view mode?
For achieving that you have to first edit the query of the read operation seeing your sample data it must be like this
SELECT a.idPermission, b.name, a.business_unit_id, a.permission
FROM TABLE_A AS a
JOIN TABLE_B(users) AS B ON a.user_id=b.user_id;
json encode the data and send to client
and in your kendo grid change column user_id to name
I know you were asking about the HTML/JavaScript way, but using MVC, this is a good, alternative way to do it:
http://decisivedata.net/kendo-ui-grid-and-entity-framework-code-first-foreign-key-fields/

Sencha Touch 1.1.1 nested JSON Store load

Hi guys I hope someone can help me with this I´m really stuck although it´s some damned beginner question that has already been answered and I assure you I read all of the answer Posts but still can´t get it to work.
I´m using Sencha Touch 1.1.1 and try to get this Store loaded with nested JSON data. Here´s the code:
Ext.regModel("UserData", {
hasMany : [{
name : "id",
type : "integer",
},{
name : "username",
type : "string",
},{
name : "password",
type : "string",
}]
});
var userdata =
{"users": [
{
"id": 16,
"username": "bla#bla.com",
"password": "bla",
}, {
"id": 17,
"username": "bla#bla.com",
"password": "bla",
}
]
};
var myStore = new Ext.data.Store({
model : 'UserData',
data : userdata,
proxy : {
type : 'ajax',
reader : {
type : 'json',
root : 'users' // not working
}
}
});
var myList = new Ext.List ({
fullscreen : true,
store : myStore,
grouped : false,
itemTpl : '<div>{username}</div>'
});
Returns Uncaught Type Error: Arguments list has wrong type. When I rewrite the JSON with an outer Array wrapper, it works, but with wrong root (not users) I definitly saw examples where this worked with the root:'' value.
var userdata =
[ {"users": [
{
"id": 16,
"username": "bla#bla.com",
"password": "bla",
}, {
"id": 17,
"username": "bla#bla.com",
"password": "bla",
}
]
} ];
What am I missing?
If I am not mistaken, in your "UserData" model, it should be fields instead of hasMany.
And try putting your json data in a separate json file and locate the path in your store's proxy.
var myStore = new Ext.data.Store({
model: 'UserData',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'test.json',
reader: {
type: 'json',
root: 'users'
}
}
});
I tested it and it's working fine here. Here is my full code.
Ext.regModel("UserData", {
fields: [
{name: 'id', type:'int'},
{name: 'username', type:'string'},
{name: 'password', type:'string'}
]
});
var myStore = new Ext.data.Store({
model: 'UserData',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'test.json',
reader: {
type: 'json',
root: 'users'
}
}
});
var app = new Ext.Application({
name: 'TestApp',
useLoadMask: true,
launch: function() {
TestApp.views.listToolbar = new Ext.Toolbar({
title: 'Foo Bar',
layout: 'hbox'
});
TestApp.views.list = new Ext.List({
id: 'list',
store: myStore,
emptyText: 'Nothing',
itemTpl: '<div class="username">{username}</div>',
});
TestApp.views.container = new Ext.Panel({
layout: 'fit',
html: 'this is the container',
dockedItems: [TestApp.views.listToolbar],
items: [TestApp.views.list]
});
TestApp.views.viewport = new Ext.Panel({
fullscreen: true,
layout: 'card',
cardAnimation: 'slide',
items: [
TestApp.views.container
]
});
}
});