I'm using dgrid 1.2.1 OnDemandGrid, and with it have tried both dstore 1.1.1 and 1.1.2 (Rest, SimpleQuery, Trackable). It seems no matter what I try I am unable to get the virtual scrolling to work.
My store is defined as:
seStore = new declare([Rest, SimpleQuery, Trackable])({
target: appUrl + "api/GET_ITEMS",
idProperty: "SID",
sortParam: "sort",
useRangeHeaders: true
});
Defined with the store is a method for the sorting and filtering:
seStore.getSECollection = function (sortFieldName, desc) {
var sFilter = {};
if (sArea != "") {
sFilter.AREA = sArea;
}
var coll = seStore.filter(sFilter).sort({ property: sortFieldName, descending: desc });
return coll;
}
Grid:
// Create a Grid instance
seGrid = new (declare([OnDemandGrid, Selection, DijitRegistry, Selector, Keyboard, Editor, ColumnHider, ColumnResizer, ColumnReorder]))({
id: "seGrid",
idProperty: "SID",
cellNavigation: true,
columns: seColumns,
collection: seStore.getSECollection("SID", true),
region: 'center',
selectionMode: "multiple",
keepScrollPosition: true,
query: { responseType: "json" },
getBeforePut: false,
farOffRemoval: Infinity, // larger than total height of data; never remove rows
minRowsPerPage: 25, // request more data at a time
maxRowsPerPage: 50,
pagingMethod: 'throttleDelayed',
queryRowsOverlap: 0,
//loadingMessage: "Loading data...",
noDataMessage: "No results found.",
showFooter: true
});
And backend REST service response provides the correct response where rItems is an array of items from my database query and rTotal is the total number of items in the database for this query:
HttpResponseMessage rm = new HttpResponseMessage(HttpStatusCode.OK);
string dgrJsonResults = Newtonsoft.Json.JsonConvert.SerializeObject(rItems, Formatting.None);
rm.Content = new StringContent(dgrJsonResults, System.Text.Encoding.UTF8);
rm.Content.Headers.ContentRange = new ContentRangeHeaderValue((long)start, (long)count, rTotal) { Unit = "items" };
The grid initally loads correctly with the first 25 items requested, but after this initial request once I scroll down to the bottom (item 25), a request to get the next range of data is not fired.
Can someone please help point me in the right direction?
Related
I'm trying to restore table header order from local storage, but it doesn't work for a header from ajax response.
var table = new Tabulator("#example-table", {
placeholder: "No Data Available", //display message to user on empty table
movableColumns: true, //enable user movable columns
persistence: {
columns: true,
},
ajaxURL: "/ajax/showall", //ajax URL
persistenceWriterFunc: function (id, type, data) {
//id - tables persistence id
//type - type of data being persisted ("sort", "filter", "group", "page" or "columns")
//data - array or object of data
if (Array.isArray(data) && data.length) {
// array does not exist, is not an array, or is empty
// ⇒ do not attempt to process array
console.log('do not save empty array');
localStorage.setItem(id + "-" + type, JSON.stringify(data));
};
},
persistenceReaderFunc: function (id, type) {
//id - tables persistence id
//type - type of data being persisted ("sort", "filter", "group", "page" or "columns")
return data ? JSON.parse(data) : false;
},
ajaxResponse: function (url, params, response) {
this.setColumns(response.header);
return response.data;
}
});
Is there some way to do this?
I was trying to use tableBuilding: function() etc, but nothing works.
I don't want to send ajax query just to get a table header.
There is no need to do any of this manually, you enable the persistence module it will do all this for you automatically as long as you have the persistent columns option enabled
var table = new Tabulator("#example-table", {
persistence:{
columns: true, //persist columns
}
});
See the Persistence Documentation for more information.
Any time the columns are set by your ajax response they will automatically update the local storage options.
You only need to use the persistenceWriterFunc and persistenceReaderFunc options if you are trying to replace the inbuilt storage options, which it does not appear you need to do here
I'm very new to ExtJS and wanted to achieve the following:
I have a model with data something like this:
{
"Account_Enabled": true,
"Requirements_gathered": true,
"work_done": false,
"deadlines": {
"Account_Enabled": true,
"Requirements_gathered": false
}
}
There are no multiple rows. Only a single row returned from the database.
I want to display the data in a grid with three columns
Column1: The name of the column
Column2: A checkbox that shows whether the value is true or false
Column3: A checkbox that shows whether the column name present in "deadlines" or not
Ex:
Account_Enabled True True
Requirements_Gathered True False
work_done False Undefined(Checkbox need to be disabled)
Basically, i need to convert that single row into three columns.
Also, i need to the update the store when the user checks/uncheks the checkboxes
May i know if there is any way to achieve this via ExtJS grids? or is there any better idea?
Thanks in advance
There is no direct way to bind your json response in the format you mention to the grid store.
What you need to do is to manipulate the response the match grid columns required.
Check this working example ExtJs Fiddle
//Your Original Response
let response = '{"Account_Enabled": true, "Requirements_gathered": true, "work_done": false, "deadlines": {"Account_Enabled": true, "Requirements_gathered": false}}';
// Convert your response to object
let jsonDecode = Ext.decode(response);
//This function to convert your response to match grid store
let dataConvert = function(jsonObj){
//Returned array object
let data = [];
// To get Object of deadlines and know if the property exist or not
let availableData = jsonObj.deadlines
//Loop throw object property
for(var objProperty in jsonObj){
//Ignore deadlines property
if(objProperty=="deadlines"){
continue;
}
//Adding the object to the array "objPropery" will return the property name
//"jsonObj[objProperty]" will return the value of property if it is true or flase
//"availableData[objProperty]" will return the value if exist in availableData
data.push({colName:objProperty,isReqGathered:jsonObj[objProperty],isWorkDone:availableData[objProperty]})
}
return data
}
let gridStore = Ext.create('Ext.data.Store', {
storeId: 'gridStoreId',
fields: ['colName', 'isReqGathered', 'isWorkDone'],
data: dataConvert(jsonDecode)
});
Ext.create('Ext.grid.Panel', {
title: 'Test Store Filter',
width: 500,
height: 400,
renderTo: Ext.getBody(),
store: gridStore,
columns: [{
dataIndex: 'colName',
text: 'colName'
}, {
dataIndex: 'isReqGathered',
text: 'isReqGathered'
}, {
dataIndex: 'isWorkDone',
text: 'isWorkDone'
}]
})
I'm having trouble binding my JavaScript kendo ui grid to model data from an action method. All the examples i see are mostly MVC wrappers and the JavaScript examples are all different and none seem to work for me.
Here is where i'm at below.
I did a generic test with static data that works.
var dataSource_Test = new kendo.data.DataSource({
data: [{ LeagueDetailGroupId: "15", GroupName: "Best Team 5"}]
});
Here is the datasource object im trying to create with the controller action:
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "#Url.Action("LeagueDetailGroup_Read", "Configuration")?_leagueTypeId=" + leagueTypeId,
// i have tried all kinds of variants here, and not sure what to put
// my action method is returning json using kendo's DataSourceResult method
//contentType: "application/json",
type: "POST"
//dataType: "odata"
},
schema: {
data: "Data", // seen this in examples, dunno what it does
total: "Total", // seen this in examples, dunno what it does
model: {
id: "LeagueDetailGroupId",
fields: {
LeagueDetailGroupId: { editable: false, nullable: true },
GroupName: { validation: { required: true } }
}
}
},
// i seen this is an example from telerik but dont understand the use case for it
parameterMap: function (data, operation) {
// this prints no data before i even start so its a moot point configuring it from products to my stuff at this moment
// but not sure what todo here of if i need this anyways
console.log(data);
if (operation != "read") {
// post the products so the ASP.NET DefaultModelBinder will understand them
var result = {};
for (var i = 0; i < data.models.length; i++) {
var product = data.models[i];
for (var member in product) {
result["products[" + i + "]." + member] = product[member];
}
}
return result;
} else {
return JSON.stringify(data)
}
}
}
});
Here is the grid which works ok with the generic static datasouce object.
var grid = $("#leagueEdit_ldg_grid").kendoGrid({
dataSource: dataSource,
sortable: true,
pageable: true,
autobind: false,
//detailInit: leagueEdit_ldg_detailInit,
dataBound: function () {
this.expandRow(this.tbody.find("tr.k-master-row").first());
},
columns: [
{
field: "LeagueDetailGroupId",
title: "Group Id",
width: "110px"
},
{
field: "GroupName",
title: "Group Name",
width: "110px"
}
]
});
Delayed read, autobind set to false.
dataSource.read();
Here is my simplified Controller action. It runs and gets data, and works fine for my MVC wrapper grids.
[Route("LeagueDetailGroup_Read/{_leagueTypeId:int}")]
public ActionResult LeagueDetailGroup_Read([DataSourceRequest]DataSourceRequest request, int _leagueTypeId = -1)
{
DataSourceResult result =
_unitOfWork.FSMDataRepositories.LeagueDetailGroupRepository.Get(
ld => ld.LeagueTypeId == _leagueTypeId
)
.ToDataSourceResult(request,
ld => new LeagueDetailGroupViewModel
{
LeagueDetailGroupId = ld.LeagueDetailGroupId,
LeagueTypeId = ld.LeagueTypeId,
GroupName = ld.GroupName,
DateCreated = ld.DateCreated,
DateLastChanged = ld.DateLastChanged
}
);
// data looks fine here
return Json(result, JsonRequestBehavior.AllowGet);
}
Currently i'm getting this error:
Uncaught TypeError: e.slice is not a function
at init.success (kendo.all.js:6704)
at success (kendo.all.js:6637)
at Object.n.success (kendo.all.js:5616)
at i (jquery-3.1.1.min.js:2)
at Object.fireWith [as resolveWith] (jquery-3.1.1.min.js:2)
at A (jquery-3.1.1.min.js:4)
at XMLHttpRequest.<anonymous> (jquery-3.1.1.min.js:4)
It's hard to know without testing but let me know how this works.
Change your controller so that you are just returning a json string.
Also, try removing your schema and the parameter map, and set your dataType to json:
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "#Url.Action("LeagueDetailGroup_Read", "Configuration")?_leagueTypeId=" + leagueTypeId,
dataType: "json"
}
}
});
For the grid I find simple json data does not usually need a schema/model defined. Kendo is super annoying and hard to debug. Let me know how it goes.
In my experience, an e.slice error happens when you have a record that has a null value in it somewhere. The kendo grid is not really smart enough to deal with this so you either have to make sure your datasource returns empty strings instead of nulls for string fields, or put a client template on the columns that translates a null into an empty string. It's possible that the kendo todatasourceresult made the problem come to light. Note that that is usually the last step before returning your dataset since it can modify the entity queries to give paging, so that you never query more than a single page of data (for ajax grids).
EDIT: ANSWER FOUND
I found the answer in this post. there is a private store config field called remoteSort that is set to true by default, so client-side sorters won't get used unless remoteSort is explicitly set to false.
I'm trying to sort a grid of Features by the number of User Stories in them. I've tried a couple different things. The first was a sorter function in the data Store Configuration:
Ext.create('Rally.data.wsapi.Store',{
model: 'PortfolioItem/Feature',
autoLoad:true,
start: 0,
pageSize: 20,
fetch: ['Name', 'ObjectID', 'Project', 'Release', 'UserStories','State','_ref'],
context://context stuff
filters:[
//filter stuff
],
sorters:[
{
property:'UserStories',
sorterFn: function(o1, o2){
return o1.get('UserStories').Count - o2.get('UserStories').Count;
}
}
],
listeners: //listener stuff
But this always returned nothing. (when the sorter was not included, i did get back all the Correct Features, but I could not sort the the number of user stories per Feature).
I also tried adding a sorter to the column in the grid, as seen in this post:
xtype: 'rallygrid',
width:'50%',
height:400,
scroll:'vertical',
columnCfgs: [
{
text:'Stories',
dataIndex:'UserStories',
xtype:'numbercolumn',
sortable:true,
doSort: function(direction){
var ds = this.up('grid').getStore();
var field = this.getSortParam();
console.log(ds, field, direction);
ds.sort({
property: field,
direction:direction,
sorterFn: function(us1, us2){
return (direction=='ASC'? 1 : -1) * (us1.get(field).Count - us2.get(field).Count);
}
});
},
width:'20%',
renderer:function(us){
return us.Count;
}
}
]
But I was having the same issues that the person in the other thread was having, where nothing was getting sorted.
I was running into this error when using the grid reconfigure method.
TypeError: overHeader is undefined [Break On This Error]
This is the Error i saw at ext-dev.js (overHeader.isOnLeftEdge(e))
and the warnings are showing up :
Ext.grid.header.Container attempted to reuse an existing id h1
The code snippet is :
initComponent: function () {
var searchGrid=this;
searchGrid.plugins = [ Ext.create('Ext.ux.grid.HeaderFilter'), Ext.create('Irm.grid.GridResetView')];
searchGrid.columns = [{
header: '',
dataIndex: '',
sortable: false,
menuDisabled: true,
hideable: false,
draggable: false,
width: 25,
tdCls : 'grid-cell-wordwrap',
componentCls: 'auto-test-search-result-grid-header-cart-icon',
renderer: function (value, metaData, record) {
var returnValue;
returnValue = 'my return value';
return returnValue;
}
},{
header : '<span data-qtip="'+searchGrid.translate('search.gridHeadAsset')+'">'+
searchGrid. translate('search.gridHeadAsset')+'</span>',
dataIndex : 'assetType',
sortable : true,
hideable: false,
draggable : false,
width : 90,
componentCls : 'auto-test-search-result-grid-header-asset-type',
tdCls : 'grid-cell-wordwrap',
renderer : function (value, metaData, record) {
var assetType = value,
boxContents = '',
returnValue;
returnValue = 'adfasf';
return returnValue;
} // this is how its declare in the view
var myGrid = this.getSearchGrid(); // this is general grid which
var myStore = this.getRetrievalItemsStore(); // this is attached to the store from where it brings the data
myGrid.reconfigure(myStore,filterColumns); // filter colums are the new set of columns i want to set to the grid.
can any one please let me know why this is happening?
I really Appreciate your help..this is happening in ext js 4.07.
EDIT :
Found the problem
This problem happens when the grid declaration is in one file and we are using columns for reconfiguration. if we see we are sending an array of columns, but reconfiguration needs an array of objects , i.e the configuration at the declaration time. Use another variable to send the raw config to the new file or make sure ur declaration of grid is on the same page as the reconfig method.
Please correct me if am wrong.
Glad if this helps anyone.