I have a ExtJS grid with a store mapped to it.
The JSON response for the store contains 20 fields, but I have mapped only 10 fields in the store. Is it possible for me to obtain the other 10 fields without me having to map them in the store or is it necessary for me to map all the fields to the store. Doing this on row select event of the grid. As for the code, I am able to create the grid, map the store, fire the event and even get the record for the selected row with the mapped 10 field.
Any suggestions ??
As requested by Shekhar :
Store definition
Ext.define('gdoc.store.PrintPaperStore', {
extend: 'Ext.data.Store',
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: true,
storeId: 'PrintPaperStore',
proxy: {
type: 'ajax',
url: 'urlToRetrieveTheJSON',
reader: {
type: 'json',
root: 'root'
}
},
fields: [{
mapping: 'value',
name: 'value'
},
{
mapping: 'display',
name: 'display'
}
]
}, cfg)]);
}
});
The JSON Response :
{
"root": [{
"value": "COATED115",
"display": "Coated recycled paper (115gms)",
"description": "Good quality",
"extra": "EXTRA INFO"
}, {
"value": "COATED135",
"display": "Coated recycled paper (135gms)",
"description": "Good quality"
}, {
"value": "OFFSET",
"display": "Offset recycled paper (80gms)",
"description": "Good quality",
"extra": "EXTRA INFO"
}, {
"value": "OTHER",
"display": "Other paper (client to order)",
"description": "Good quality",
"extra": "EXTRA INFO"
}]
}
As you can see I have mapped only value and display from the JSON response in the store.
Is it possible for me to retrieve values of description and extra without me having to map them in the store.
You can access the .raw property on the model, which will contain the raw JSON from the reader.
No. The model, or store, must set all the fields you want to have available from the JSON data.
I'm confused as to why you don't want to map the extra fields? It's it purely time saving and hoping there was a quicker way to get access to the data? Or are you expecting the fields names to be dynamic?
If it's the dynamic reason, take a look at this post for a solution. Dynamic model with ExtJS 4
Related
I am new to KTDatatable in Metronic.
I am trying to use server side pagination in Metronic dashboard, and I am parsing the data in a KTDatatable, but I can't find a way to parse the returned data from the API and to view number of pages and each page URL.
The code that I was able to write so far is:
data: {
type: 'remote',
source: {
read: {
url: dataURL,
method: 'GET',
contentType: 'application/json',
map: function(data) {
var cards = data.cards.data;
var currentPage = data.cards.current_page;
var lastPage = data.cards.last_page;
return cards;
}
},
},
pageSize: 10,
serverPaging: true,
},
In this code I was able to get the first ten records but:
1- I wasn't able to parse them the way I want in the table.
2- I wasn't able to show the pages number nor calling the API for the second page or the (x) page I want.
These are the things I want to do.
Thanks in advance.
You can go back to the end of the KT-Datatable documentation to find most of answers you want KT-Datable documentation, but I am gonna explain more hoping it will be more clear.
So the returned value from the API (Json) should look have two main objects meta and data, and it looks something like this:
{
"meta": {
"sort": "desc",
"field": "IssueName",
"page": 1,
"pages": 2,
"perpage": "10",
"total": 11
},
"data": [
{
"IssueName": "******",
"CardNumber": "******"
},
{
"IssueName": "******",
"CardNumber": "******"
}
]
}
And after getting the values of the response from the API you should only return the data object to be parsed by the datatable so the map function should look something like this:
map: function(data) {
return data.data;
}
and it will process the meta data itself.
To parse the data into the columns you should use the same key name of the data in column definition array, so in my example I used it like this:
columns: [
{
field: 'IssueName',
title: columnsTitles.issue,
type: 'string',
},
{
field: 'CardNumber',
title: columnsTitles.card_number,
type: 'string',
},
]
And every time the datatable calls the API it will send more data that will help you give the right response, the data will be on a shape of an array (The field name should be the same as the key):
[
"pagination" => array:4 [
"page" => "1"
"pages" => "2"
"perpage" => "10"
"total" => "11"
],
"sort" => array:2 [
"field" => "IssueName"
"sort" => "desc"
],
]
The sent data is related with the pagination and sorting type you have to get from the API, and you can also add filters and they will be stored in the array in the "query" field, and you can handle them in the backend.
I cannot find any info if there is any limitations for dojo treegrid JSON store. Here is my simple store. It works perfect but fails if it has thousands of items. So is there a limit for number of items or childItems? Or is there a limit for JSON object size?
{
"identifier": "id",
"label": "name",
"items": [
{
"id": "id1",
"type": "year",
"year": "2018",
"childItems": [
{
"id": "id0",
"projname": "Project 1"
},
{
.....
}
]
},
{
.....
}
]
}
Dojo treegrid mostly shows this error message when it finds multiple items with the same id, so you want to make sure all "id" attributes in your "items" list have unique value. In my test setup I was able to load more than 20000 rows so most probably you have malformed data. Supply following option to grid to log any fetch related errors:
onFetchError: function(err, req){
console.log(err);
}
Hope it helps.
I have a Kendo grid where I'm trying to add a delete feature. My datasource looks like:
var datasource = new kendo.data.DataSource({
transport: {
read: {
url: Router.action("Admin", "GetScansForMailItem", { mailItemIdnt: detailinit.data.MailItemIdnt }),
dataType: "json"
},
destroy: {
url: Router.action("Admin", "DeleteScan"),
type: "post"
}
},
model: {
id: "ScanIdnt",
fields: {
ScanIdnt: {editable: false, nullable: false}
}
},
pageSize: 5
});
I added the model part because this answer, however it made no difference.
The actual grid looks like:
.kendoGrid({
dataSource: datasource
scrollable: false,
sortable: true,
pageable: true,
editable: "inline",
columns: [{
field: "ScanIdnt",
title: "Scan ID"
}, {
field: "CreatedDate",
title: "Created",
template: "#= kendo.parseDate(CreatedDate, 'yyyy/MM/dd') #"
}, {
field: "ScanDocumentRelativePath",
title: "File Path",
template: "<a href='/CAMP/Admin/Download?scanIdnt=#= ScanIdnt #'>#= ScanDocumentRelativePath.substring(1) #</a>"
}, {
field: "ScanUserIdnt",
title: "Scanned By"
},{
command: "destroy",
title: ""
}]
});
Strangely, clicking the delete button removes the from the gird on the UI, but there is absolutely no Ajax call is made the the destroy URL. I can't seem to figure out why. Any ideas?
EDIT I'd like to point out that this grid is in fact a nested grid inside of another grid (like here) I discovered that the parent grid handles actually makes a call, but to the wrong function. For some reason, it clicking delete on a to level item calls the read function of the nested grid, however, the nested grids do nothing
Figured it out (sorta). While I think there were many issues with my code and the grid, It seems that when it came down to it, Kendo didn't like how I had my data.
In the Kendo docs related to hierarchical grids, the data for the child grid is stored in a field of the data for the parent. For example, given the following JSON:
"ParentItems": [
{
"Id": 12345 ,
"Name": "Test1",
"ChildItems": [
{"Id": 1, "Name": "Test"},
{"Id": 2, "Name": "Test"}
]
},
{
"Id": 12346 ,
"Name": "Test2",
"ChildItems": [
{"Id": 1, "Name": "Test"},
{"Id": 2, "Name": "Test"}
]
}
]
In the parent grid, each ParentItem would display it's respective ChildItems in the child grid.
On the other hand, I was pulling both data sets separately. Basically, I pulled the ParentItems like:
"ParentItems": [
{
"Id": 12345,
"Name" : "Test1"
},
{
"Id": 12346,
"Name" : "Test2"
}
]
And then made a second request to pull the child items, based on the parent's id.
"ChildItems": [
{"Id": 1, "Name": "Test", "ParentId": "12345"},
{"Id": 2, "Name": "Test", "ParentId": "12345"}
]
I was able to modify the server side code to serve the data like in the very first example and managed to get things working. The specific document that helped me out can be found here
I'm looking at this template to build a web application: https://js.devexpress.com/Demos/WidgetsGallery/Demo/PivotGrid/FieldChooser/AngularJS/Light/
In the example there are static data. I have to retrieve them from the server. So, I wrote this:
$scope.testData = [];
$scope.pivotGridDataSource = new DevExpress.data.PivotGridDataSource({
fields: [{
caption: "Nome",
dataField: "fullName",
area: "row"
}, {
caption: "Country",
dataField: "country",
area: "column"
}, {
caption: "Count",
dataField: "countOne",
dataType: "number",
summaryType: "sum",
area: "data"
}],
store: $scope.testData
});
$scope.pivotGridOptions = {
allowSortingBySummary: true,
allowSorting: true,
allowFiltering: true,
showBorders: true,
dataSource: $scope.pivotGridDataSource,
fieldChooser: {
enabled: false
}
},
$scope.fieldChooserOptions = {
dataSource: $scope.pivotGridDataSource,
texts: {
allFields: "All",
columnFields: "Columns",
dataFields: "Data",
rowFields: "Rows",
filterFields: "Filter"
},
width: 400,
height: 400,
bindingOptions: {
layout: "layout"
}
};
// Now I call the server to retrieve data
$scope.getTestData = () => {
$scope.testData.length = 0;
result.forEach(e => {
$scope.testData.push(e);
);
$scope.pivotGridDataSource.reload();
}
$scope.getTestData();
The problem is that when the data are loaded, in the Fields below it shows just the fields written at the beginning (so the name, the count and the country). But I saw in the demo that it should be display ALL parameters of the object.
For example, if the object is so structured:
{ "name": "Test1", "country": "Germany", "creationDate": "xxx", "surname": "yyy" }
So, I expect that in the fields there should be ALL parameters, so name, country, creationDate, surname. So, I did this at the beginning:
I changed $scope.testData = [] into:
$scope.testData = [{ "name": "", "country": "", "creationDate": "", "surname": "" }]
so the component will preparare all fields. And this works. But what if the server gives me back an Object that has another parameters? How can I display them?
I tried so after the calling and before the reload():
let fields = $scope.pivotGridDataSource.fields();
let newField = {
llowExpandAll: false,
allowFiltering: true,
allowSorting: true,
allowSortingBySummary: true,
caption: "This is a new field",
dataField: "newField",
dataType: "string",
displayFolder: "",
index: fields.length
}
$scope.pivotGridDataSource.fields().push(newField);
$scope.pivotGridDataSource.reload();
But it doesn't work yet. Worse, it does not even initialize the Pivot.
The fieldChooser uses the store fields, in this case $scope.testData fields, in your code I see your store is first declared (as null or with some format as you described) and then you have a function to fill it.
I don't know how your code looks and why you create your store that way, but that is basically your problem (the flow).
In the sample code the flow is:
Store with data (static in this case)
PivotGridDataSource
FieldChooser
In your code the flow is:
Store (empty)
PivotGridDataSource
FieldChooser
Store (fill) --> at this point your FieldChooser has been initialized with the fields of the empty version of your store so not much to do (in Jquery you could re-create your object, you dan do it using Jquery within AngularJs see a simple code sample here and below)
$('#chartContainer').dxChart('instance').dispose();
$('#chartContainer').dxPieChart({
...
});
To avoid all of this you can just use the DevExpress.data.CustomStore and your flow will be basically identical to the demo.
I'm binding a JS KendoUI dropdownlist to JSON (not using a model) which recently has been changed by adding a named array to the object (in efforts to format the JSON for a Kendo TreeView control). This broke a few things of course. The original JSON format looked like this (an array of objects):
[
{
"COLUMN_NAME": "OBJECTID",
"DATA_TYPE": "esriFieldTypeOID",
"CATEGORY": "Feature Data"
},
{
"COLUMN_NAME": "Brand",
"DATA_TYPE": "esriFieldTypeString",
"CATEGORY": "Feature Data"
},...
]
now it looks like this (an object with a named array, with objects):
{
"Hydrant": [
{
"COLUMN_NAME": "OBJECTID",
"DATA_TYPE": "esriFieldTypeOID",
"CATEGORY": "Feature Data"
},
{
"COLUMN_NAME": "Brand",
"DATA_TYPE": "esriFieldTypeString",
"CATEGORY": "Feature Data"
},...
],
"DisplayField": "Description",
"DefaultField" : "HydrantID"
}
I assumed I could simply define the schema to "Hydrant" or set the dataText/ValueFields to "Hydrant.COLUMN_NAME" but no luck. What am I overlooking? I am binding this JSON format response to a dropdownlist using the "COLUMN_NAME" to populate it.
bonus: how could I use the "DefaultField" to set the default selection in the dropdownlist?
Thanks in advance!
You can use the schema.data field of the DataSource configuration to identify the field from the response to use for its data:
schema: { data: 'Hydrant' }