ExtJS columns renderer, row count and setLoading - javascript

I have a grid.Panel, it is hidden by default. When I show it, it renders 100 lines and performs the function renderer, but if you call refresh() for this table, it will render only 49 lines, what do these numbers depend on and how to change them? Also wondering if there is an event when the lines are rendered to cause setLoading(false)?
grid.Panel:
extend: 'Ext.grid.Panel',
alias: 'widget.commongrid',
controller: 'commongrid-controller',
viewModel: {
type: 'commongrid-model'
},
viewConfig: {
enableTextSelection: true
},
enableColumnMove: false,
columns: [],
bind: {
store: '{commonDetailStore}'
},
createGrid: function (columns, data) {
var ctrl = this.getController();
ctrl.createGrid(columns, data);
}
Controller code:
createGrid: function (columns, data) {
var me = this,
view = me.getView(),
vm = me.getViewModel(),
store = vm.getStore('commonDetailStore');
columns = me.generateColumn(columns);
view.reconfigure(columns);
store.loadData(data);
},
generateColumn: function (columns) {
return Ext.Array.map(columns, function (column, index) {
return {
'dataIndex': column,
'text': column,
'width': 150,
'sortable': false,
'resizable': true,
'menuDisabled': true,
'renderer': 'onCommonDetailedGridColumnRenderer'
};
});
}
grid.Model:
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.commongrid-model',
stores: {
commonDetailStore: {
autoLoad: true,
proxy: {
type: 'localstorage'
},
fields: []
}
}

Related

How to overide extJS grid filter

I am creating a new project in that I am using Grid.
Here is my grid.
Ext.define('myProj.view.base.grid.myGrid', {
extend: 'Ext.grid.Panel',
alias: 'widget.myGrid',
controller: 'myProj-controller-base-grid-myGridcontroller',
requires: [
"myProj.controller.base.grid.myGridcontroller",
'Ext.grid.feature.Grouping',
'Ext.grid.plugin.BufferedRenderer',
'Ext.grid.filters.Filters',
],
mixins: ['Deft.mixin.Injectable'],
inject: ["gridStore"],
config: {
gridStore: null,
},
emptyText : "No data available",
plugins: {
gridfilters: true
},
overflowY: 'auto',
width:'100%',
stripeRows: false,
columnLines: false,
selModel: {
selType: 'checkboxmodel',
mode: 'SINGLE',
allowDeselect: true
},
initComponent: function () {
let _this=this;
Ext.apply(this, {
store: this.getListGridStore(),
});
this.callParent(arguments);
}
});
Now I want to overideto my filter. I have writtent my override code I am looking many examples but I am not geeting how to connect these two codes. ANy help will be usefull.
The overide code which I wanted to place here look like this.
Ext.override(Ext.grid.filters.filter.List, {
createMenuItems: function (store) {
debugger;
}
});
I believe the override works but the createMenuItems function is not called.
Did you define the filter for each column? Like in the code example shown here.
{
dataIndex: 'rating',
text: 'Rating',
width: 75,
filter: {
type: 'list',
value: 5
}
}

After adding an entry to the tree, it is not displayed. Extjs

The application displays the tree.
Records are added using the 'rowediting' plugins.
In the controller, by clicking on the "Create" button, an event is triggered.
...
onAddChild: function(el) {
var grid = el.up('treepanel'),
sel = grid.getSelectionModel().getSelection()[0],
store = grid.getStore();
store.suspendAutoSync()
var child = sel.appendChild({
text: '',
leaf: true
});
sel.expand()
grid.getView().editingPlugin.startEdit(child);
store.resumeAutoSync();
},
...
The plugin itself looks like this:
plugins: [{
ptype: 'rowediting',
clicksToMoveEditor: 1,
autoCancel: false,
listeners: {
afteredit: function (editor, context, eOpts) {
context.store.reload();
},
canceledit: function (editor, context, eOpts) {
context.store.reload();
},
beforeedit: function (editor, context) {
return !context.record.isRoot();
}
}
}],
Store:
Ext.define('Survey.store.QuestionTreeStore', {
extend: 'Ext.data.TreeStore',
model: 'Survey.model.QuestionTree',
autoLoad: true,
autoSync: true,
//storeId: 'QuestionTree',
proxy: {
type: 'ajax',
noCache: false,
api: {
create: urlRoot + 'Create',
update: urlRoot + 'Update',
destroy: urlRoot + 'Destroy',
read: urlRoot + 'Read'
},
The problem is that adding a record happens, but at the same time it is not displayed in the tree, I need to refresh the page so that the record would appear.
How to make a new entry immediately appear in the tree?
Thank

Problems loading the storage in the renderer for the combobox field

My field looks like this:
...
{
xtype: 'gridcolumn',
text: 'MyField',
dataIndex: 'contragent',
editor: {
xtype: 'combobox',
allowBlank: false,
displayField:'name',
valueField:'id',
queryMode:'remote',
store: Ext.data.StoreManager.get('ContrAgents')
},
renderer: function(value, metaData, record, rowIndex, colIndex, store, view) {
store_ca = Ext.data.StoreManager.get('ContrAgents');
if (record.data.contragent != ''){
store_ca.load();
var contr = store_ca.getById(record.data.contragent);
//indexInStore = store_ca.findExact('id', value);
console.log(contr);
return contr.data.name;
}
}
},
...
Store 'ContrAgents' looks like this:
Ext.define('BookApp.store.ContrAgents', {
extend: 'Ext.data.Store',
model: 'BookApp.model.ContrAgents',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'app/data/Contragents.json'
}
});
The problem is that the name of the required field is not returned (contr.data.name), contr is null.
Apparently the store does not have time to load, in this case I need to load it, but store_ca.load () does not bring results.
How to load the store correctly to use
store_ca.getById (record.data.contragent); to return the name of the field?
I'm not entirely sure why you would need to use a store to populate the value in the grid's cell, because you could always just send the text value through the grid's store as opposed to the id.
You probably have a good reason for doing it, so I've revisited the fiddle and implemented it accordingly. You should be able to check it out here
The changes
../app/store/ContrAgents.js
Ext.define('Fiddle.store.ContrAgents', {
extend: 'Ext.data.Store',
model: 'Fiddle.model.ContrAgents',
autoLoad: false,
proxy: {
type: 'ajax',
url: 'Contragents.json'
}
});
../app/store/ListViewStore.js
Ext.define('Fiddle.store.ListViewStore', {
extend: 'Ext.data.Store',
model: 'Fiddle.model.ListViewModel',
autoLoad: false,
proxy: {
type: 'ajax',
url: 'List.json'
}
});
../app/view/ListView.js
Ext.define('Fiddle.view.ListView' ,{
extend: 'Ext.grid.Panel',
alias: 'widget.booklist',
itemId: 'BookList',
store: 'ListViewStore',
xtype: 'listview',
plugins: 'gridfilters',
initComponent: function() {
var me = this;
// Pin an instance of the store on this grid
me.myContrAgents = Ext.data.StoreManager.lookup('ContrAgents');
// Manually load the 'ContrAgents' first
me.myContrAgents.load(function(records, operation, success) {
// Now load the 'ListViewStore' store
me.getStore().load();
});
me.columns = [
{
header: 'ID',
dataIndex: 'id',
sortable: true,
width: 35
},
{
text: 'Контрагент',
dataIndex: 'contragent',
renderer: function(value, metaData, record, rowIndex, colIndex, store, view) {
if (value > 0) {
if (rec = me.myContrAgents.findRecord('id', value)) {
return rec.get('name');
}
}
return '';
}
}
];
me.callParent(arguments);
}
});
Data/List.json
"data" : [
{"id": 1, "contragent": "2"},
{"id": 2, "contragent": "3"},
{"id": 3, "contragent": "4"}
]
You are trying to query the store before it's data is actually populated. You want to avoid loading the store for each time the renderer event is triggered.
The Ext.data.Store->load function is asynchronous
See docs
store.load({
scope: this,
callback: function(records, operation, success) {
// the operation object
// contains all of the details of the load operation
console.log(records);
}
});
Change your implementation to this and test if it works
renderer: function(value, metaData, record, rowIndex, colIndex, store, view) {
store_ca = Ext.data.StoreManager.get('ContrAgents');
if (record.data.contragent != ''){
store_ca.load(function(records, operation, success) {
console.log('loaded records');
var contr = store_ca.getById(record.data.contragent);
indexInStore = store_ca.findExact('id', value);
console.log({
contr: contr,
indexInStore: indexInStore
});
});
// Not sure what you are trying to return here
// return contr.data.name;
}
}
Remote Combo in ExtJS Grid Example
I found a good example for what you are trying to accomplish here with a combo dropdown in a grid with a remote store, check out this post (you might have to register for free but the solution is worth it and I won't plagiarise it here)
Grid with combo edit widget with binding
Perhaps this could help...
Ext.define('Fiddle.view.ListView' ,{
extend: 'Ext.grid.Panel',
alias: 'widget.booklist',
itemId: 'BookList',
store: 'ListViewStore',
xtype: 'listview',
plugins: ['cellediting','gridfilters'],
initComponent: function() {
this.columns = [
{
header: 'ID',
dataIndex: 'id',
sortable: true,
width: 35
},
{
text: 'Контрагент',
width: 150,
xtype: 'widgetcolumn',
dataIndex: 'contragent',
widget: {
xtype: 'combo',
bind: '{record.contragent}',
allowBlank: false,
displayField: 'name',
valueField: 'id',
store: Ext.data.StoreManager.lookup('ContrAgents')
}
}
];
this.callParent(arguments);
}
});

How to get scope of store in grid

I wrote my Ajax in init component and I am getting all the require data in this.store.
But I am not getting scope of store in grid where i defined. Since I am closing the bracket of Ajax Success I am not. what is the correct way to do.
My Code is :
initComponent: function() {
this.fields = [];
this.columns = [];
this.data = [];
this.store = [];
Ext.Ajax.request({
url: 'XML/1Cohart.xml',
scope: this,
timeout: global_constants.TIMEOUT,
method: "GET",
disableCaching: true,
failure: function(response) {
utils.showOKErrorMsg(sdisMsg.ajaxRequestFailed);
},
success: function(response) {
var datas = response.responseXML;
Ext.each(datas.getElementsByTagName("HEADER"), function(header) {
this.buildField(header);
this.buildColumn(header);
}, this);
Ext.each(datas.getElementsByTagName("G"), function (columnData) {
this.buildData(columnData);
this.fieldLength = this.fields.length;
this.record = [];
for (i = 0; i < this.fieldLength; i++) {
//debugger;
var fieldName = this.fields[i].name
this.record[i] = columnData.getAttribute(fieldName);
}
this.data.push(this.record);
}, this);
this.store = new Ext.data.ArrayStore({
fields : this.fields
});
this.store.loadData(this.data); // Getting correct data in this.store
},
});
In same init component in east panel i defined grid. for which column is coming but store is not getting.
Grid code is
{
xtype: 'panel',
region: "east",
header: true,
collapsible: true,
autoScroll: true,
//columnWidth: 0.5,
width: "30%",
hideBorders: true,
split: true,
items: [{
xtype: 'panel',
title: "Search Result",
height:500,
items: [{
xtype: 'grid',
itemid: 'ABC_GRID',
store : this.store,
autoHeight: true,
sm: new Ext.grid.CheckboxSelectionModel({singleSelect:true}),
frame: true,
columns : this.columns,
}]
}]
After loading the data in this.store get the grid and reconfigure its store
Ext.ComponentQuery.query("#ABC_GRID")[0].reconfigure(this.store);
For ExtJs 3
We need use Ext.getCmp() as Ext.ComponentQuery.query is not supported. Need to define id property of grid as id:ABC_GRID.
Ext.getCmp("ABC_GRID").reconfigure(this.store)
Rather than calling This.store you can call grid.getview().getStore(), you will get the store of the grid where you want to load the data.

ExtJS TaskRunner

I'm still in the learning process with EXTJS and any help would be much appreciated.
The goal for me is to load data into a grid where one cell needs to have the value incremented every minute. From my research using the TaskRunner function is the way to go but can't figure out where to put it and how to use it. My assumption is that it needs to go into the model or the controller but I'm not sure. In my simple project I'm using the MVC architecture.
Currently my gird works as expected. It reads in a file does a date conversion that produces a minute value. It's that minute value that I need to increment.
The code below is a sample TaskRunner snippit that I'm working with, right or wrong I don't know yet.
var runner = new Ext.util.TaskRunner();
var task = runner.newTask({
run: store.each(function (item)
{
var incReq = item.get('request') + 1;
item.set('request', incReq);
}),
interval: 60000 // 1-minute interval
});
task.start();
Model:
Ext.define("myApp.model.ActionItem", {
extend : "Ext.data.Model",
fields : [
{
name: 'pri',
type: 'int'
},
{
name: 'request',
type: 'int',
defaultValue: 0,
convert : function(v, model) {
return Math.round((new Date() - new Date(v)) / 60000);
}
}
]
});
Controller:
Ext.define("myApp.controller.HomeController", {
extend: "Ext.app.Controller",
id: "HomeController",
refs: [
{ ref: "ActionItemsGrid", selector: "[xtype=actionitemgrid]" },
{ ref: "DetailsPanel", selector: "[xtype=actionitemdetails]" }
],
pri: "",
models: ["ActionItem"],
stores: ["myActionStore"],
views:
[
"home.ActionItemDetailsPanel",
"home.ActionItemGrid",
"home.HomeScreen"
],
init: function () {
this.control({
"#homescreen": {
beforerender: this.loadActionItems
},
"ActionItemsGrid": {
itemclick: this.displayDetails
}
});
},
displayDetails: function (model, record) {
this.getDetailsPanel().loadRecord(record);
},
loadActionItems: function () {
var store = Ext.getStore("myActionStore");
store.load();
this.getActionItemsGrid().reconfigure(store);
}
});
View:
Ext.define("myApp.view.home.ActionItemGrid", {
extend: "Ext.grid.Panel",
xtype: "actionitemgrid",
resizable: true,
multiSelect: false,
enableDragDrop : false,
store: null,
columns:
[
{ header: "Pri", dataIndex: "pri", sortable: false, autoSizeColumn: true},
{ header: "Req", dataIndex: "request", sortable: false, autoSizeColumn: true}
],
viewConfig:
{
listeners: {
refresh: function(dataview) {
Ext.each(dataview.panel.columns, function(column) {
if (column.autoSizeColumn === true)
column.autoSize();
})
}
}
}
});
Sample JSON File:
{
"actionitems" : [
{
"pri": 1,
"request": "2014-12-30T03:52:48.516Z"
},
{
"pri": 2,
"request": "2014-12-29T05:02:48.516Z"
}
]
}
You have error in code which creates task - you should provide function to run configuration property, not result of invocation. Try this:
var runner = new Ext.util.TaskRunner();
var task = runner.newTask({
run: function() {
store.each(function (item)
{
var incReq = item.get('request') + 1;
item.set('request', incReq);
})
},
interval: 60000 // 1-minute interval
});
task.start();
You can put that code in loadActionItems method.

Categories

Resources