I am a novice in ExtJS and I am trying to include filters in ExTJS grid but I am getting an error like failed loading file "feature.filters". Below is my function for creating Grid and I am invoking this function from another HTML page.
function ExtJSGrid(tableId,headerInfo,data){
Ext.Loader.setConfig({enabled: true});
Ext.Loader.setPath('Ext.ux', 'http://vmxplambardi:19086/teamworks/script/extjs/examples/ux');
Ext.require([
'Ext.grid.*',
'Ext.data.*',
'Ext.ux.grid.FiltersFeature',
'Ext.toolbar.Paging'
]);
var tableId=tableId+"-div";
var fields=[],columns=[],dataIndex='cell';
var filters = {
ftype: 'filters',
local:true,
filters: [{
type: 'string',
dataIndex: 'cell1'
}, {
type: 'string',
dataIndex: 'cell2'
}, {
type: 'string',
dataIndex: 'cell3'
}]
};
document.getElementById(tableId).innerHTML='';
for(var i=1;i<=headerInfo.length;i++)
{
var cellObj={},columnObj={};
cellObj.name=dataIndex+i;
fields.push(cellObj);
columnObj.text=headerInfo[i-1];
columnObj.dataIndex=dataIndex+i;
columns.push(columnObj);
}
var store = Ext.create('Ext.data.ArrayStore', {
fields:fields,
data: data
});
var grid = Ext.create('Ext.grid.Panel', {
store: store,
columns:columns,
width:'100%',
forceFit:true,
features: [filters],
renderTo: tableId
});
}
Please let me know if I am missing anything?
Javascript has no block level scope, so variables defined in the for loop are actually defined at the top of the function (hoisted) and survive the loops. So you are always overwrite the vars.
I've got it working like this:
var filters = {
ftype: 'filters',
// encode and local configuration options defined previously for easier reuse
encode: false, // json encode the filter query
local: true, // defaults to false (remote filtering)
// Filters are most naturally placed in the column definition, but can also be
// added here.
filters: [
{
type: 'boolean',
dataIndex: 'visible' //Just an example
}
]
};
var myFilterGrid = new Ext.create('Ext.ux.LiveSearchGridPanel', {
title: 'someTitle',
selType: 'cellmodel',
store: myStore,
columns:[
{
header: "Column1",
width: 90,
sortable: true,
dataIndex: 'INDEX1',
filterable: true, //<---
filter:{ //<---
type:'string'
}
},
....
{
header: "Another Column",
width: 85,
sortable: true,
dataIndex: 'INDEX2'
}],
features: [filters] //<---
});
And be sure to include
'Ext.ux.grid.FiltersFeature'
Hope this helps!
Related
I am trying to add a GridPanle into a window. For this i have created a model, store and then created a panel and then adding this panel into window.
Facing issue with Panel column Headers.
The below is the code i am using.
function(orderModel, ex112ServiceResponse) {
var tablePopup = null;
var gridPanel = null;
var gridData = [];
var gridStore = null;
// Creation of data model
Ext.define('StudentDataModel', {
extend: 'Ext.data.Model',
fields: [{
name: 'reasonCode',
mapping: 'reasonCode'
},
{
name: 'reasonCodeDescription',
mapping: 'reasonCodeDescription'
},
{
name: 'refField1',
mapping: 'refField1'
},
{
name: 'orderID',
mapping: 'orderID'
},
{
name: 'orderLineID',
mapping: 'orderLineID'
}
]
});
// Store data
//debugger;
debugger;
for (var index = 0; index < ex112ServiceResponse.objectReasonCode.length; index++) {
gridData.push(ex112ServiceResponse.objectReasonCode[index]);
}
gridStore = Ext.create('Ext.data.Store', {
model: 'StudentDataModel',
data: gridData
});
gridPanel = Ext.create('Ext.grid.Panel', {
id: 'gridId',
layout: 'fit'
store: gridStore,
stripeRows: true,
width: 800,
enableColumnMove: true,
enableColumnResize: true,
autoDestroy: true,
columns: [{
header: "SKU/Item Number",
dataIndex: 'refField1',
id: 'refField1',
//flex: .5,
sortable: true,
hideable: true
}, {
header: "Reason Code",
dataIndex: 'reasonCode',
id: 'reasonCode',
//flex: .5, // property defines the amount of space this column is going to take in the grid container with respect to all.
sortable: true, // property to sort grid column data.
hideable: true // property which allows column to be hidden run time on user request.
}, {
header: "Description",
dataIndex: 'reasonCodeDescription',
id: 'reasonCodeDescription',
//flex: 1,
sortable: true,
hideable: false // this column will not be available to be hidden.
},
{
header: "DO :: DO Line",
dataIndex: 'orderLineID',
id: 'doDoLine',
//flex: .5,
sortable: true,
renderer: function(value, metadata, record, rowIndex, colIndex, store) {
debugger;
var do_DOLine = record.raw.orderID + " :: " + record.raw.orderLineID;
return do_DOLine;
}
}
]
});
tablePopup = new Ext.Window({
title: 'Cancellation Reason Codes',
id: 'crcWin'
width: 800,
closeAction: 'close',
plain: true,
autoDestroy: true,
items: [gridPanel]
});
tablePopup.show();
//Table Creation End
}
The issue is when the code create a popup for the first time. Popup looks good. But when i close the popup and clicks on a button in the second time created popup has issue. Column names have been changed.
Popup1:
Popup2:
Your help will be highly appreciated.
The issue is you have provided id to your extjs component and inside of window you have used config
//There is no close action in docs
closeAction: 'close'//Defaults to: 'destroy'
The closeAction to take when the close header tool is clicked:
destroy : remove the window from the DOM and destroy it and all descendant Components. The window will not be available to be redisplayed via the show method.
hide : hide the window by setting visibility to hidden and applying negative offsets. The window will be available to be redisplayed via the show method.
Note: This behavior has changed! setting does affect the close method which will invoke the appropriate closeAction.
Instead of using id you can use itemId.
In this FIDDLE, I have created a demo using your code. I hope this will help/guide you.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
function createWindow() { // Creation of data model
Ext.define('StudentDataModel', {
extend: 'Ext.data.Model',
fields: [{
name: 'reasonCode',
mapping: 'reasonCode'
}, {
name: 'reasonCodeDescription',
mapping: 'reasonCodeDescription'
}, {
name: 'refField1',
mapping: 'refField1'
}, {
name: 'orderID',
mapping: 'orderID'
}, {
name: 'orderLineID',
mapping: 'orderLineID'
}]
});
Ext.create('Ext.data.Store', {
storeId: 'gridStore',
model: 'StudentDataModel',
data: [{
reasonCode: '123',
reasonCodeDescription: 'test test',
refField1: 'it just exammple',
orderID: 1234,
orderID: 12345
}, {
reasonCode: '1231',
reasonCodeDescription: 'test1 test',
refField1: '!it just exammple',
orderID: 12341,
orderID: 123451
}]
});
var gridPanel = Ext.create('Ext.grid.Panel', {
layout: 'fit',
store: 'gridStore',
stripeRows: true,
enableColumnMove: true,
enableColumnResize: true,
autoDestroy: true,
//id: 'gridId',
columns: [{
header: "SKU/Item Number",
dataIndex: 'refField1',
//id: 'refField1',
flex: 1,
sortable: true,
hideable: true
}, {
header: "Reason Code",
dataIndex: 'reasonCode',
// id: 'reasonCode',
flex: 1,
sortable: true, // property to sort grid column data.
hideable: true // property which allows column to be hidden run time on user request.
}, {
header: "Description",
dataIndex: 'reasonCodeDescription',
// id: 'reasonCodeDescription',
flex: 1,
sortable: true,
hideable: false // this column will not be available to be hidden.
}, {
header: "DO :: DO Line",
dataIndex: 'orderLineID',
//id: 'doDoLine',
flex: 1,
sortable: true,
renderer: function (value, metadata, record, rowIndex, colIndex, store) {
var do_DOLine = record.raw.orderID + " :: " + record.raw.orderLineID;
return do_DOLine;
}
}]
});
var tablePopup = new Ext.Window({
title: 'Cancellation Reason Codes',
width: window.innerWidth,
//id: 'crcWin',
plain: true,
modal: true,
autoDestroy: true,
closeAction: 'destroy', //If you want to use hide then you need to be show same window instead of new create
// closeAction: 'close', //https://docs.sencha.com/extjs/4.2.6/#!/api/Ext.window.Window-cfg-closeAction
items: [gridPanel]
});
tablePopup.show();
}
Ext.create('Ext.button.Button', {
text: 'Create window',
renderTo: Ext.getBody(),
handler: createWindow
})
}
});
I'm trying to get the value of a cell in a grid using below. In-fact I'm just trying to print it in the console
console.log(Ext.ComponentQuery.query('gridcolumn[itemId=gridId]')[0].getEditor().getStore().findRecord('description', 'Description'));
Grid Code
Ext.define('Examples.grid.fdGrid', {
extend: 'Ext.grid.Panel',
xtype: foodGrid',
forceNewStore: true,
itemId: 'foodGrid',
height: Ext.getBody().getViewSize().height - 200,
autoload: false,
columns: [
{
text: 'Food Distrib',
xtype: 'gridcolumn',
itemId:'gridId',
dataIndex: 'food_distributor',
flex: 1,
renderer: function(value){
if(Ext.isNumber(value)){
var store = this.getEditor().getStore();
return store.findRecord('foodid',value).get('description');
}
return value;
},
editor: {
xtype: 'combobox',
allowBlank: true,
displayField: "description",
valueField: "foodid",
listeners: {
expand: function () {
var call = this.up('foodgrid[itemId=foodGrid]').getSelectionModel().selection.record.data.networkname.trim();
this.store.clearFilter();
this.store.filter({
property: 'call',
value: call,
exactMatch: true
})
}
},
},
}
});
But i'm getting an error as Uncaught TypeError: Cannot read property 'getEditor' of undefined
What's the error please?
Added the Grid Code part, and the column whose value I want to print.
The editor is created when needed (when the first edit occurs). So when the renderer is first called, the editor is not yet available.
What you want to do from inside your renderer, is to directly access the store, not go through the editor. Then you only need a pre-loaded store to be able to render the grid correctly.
renderer: function(value){
if(Ext.isNumber(value)){
var store =Ext.getStore("MyStore");
return store.findRecord('foodid',value).get('description');
}
return value;
},
editor: {
xtype:'combobox',
store:'MyStore'
Of course, you have to make sure that MyStore is loaded before you render the grid.
One can only guess what you are trying to do there but:
Column doesn't have a selection model of itself. Grid does.
Combobox needs a store.
getEditor may return String OR Object if an editor was set and column is editable
editable is provided by a grid plugin. In other words, specifying a column as being editable and specifying a column editor will not be enough, you also need to provide the grid with the editable plugin.
Some working example:
Ext.define('Examples.grid.fdGrid', {
extend: 'Ext.grid.Panel',
xtype: 'feedGrid',
forceNewStore: true,
itemId: 'foodGrid',
height: Ext.getBody().getViewSize().height - 200,
autoload: false,
selModel: 'cellmodel',
plugins: {
ptype: 'cellediting',
clicksToEdit: 1
},
columns: [
{
text: 'Food Distrib',
xtype: 'gridcolumn',
itemId:'gridId',
dataIndex: 'food_distributor',
flex: 1,
editable: true,
renderer: function(value){
if(Ext.isNumber(value)){
var store = this.getEditor().getStore();
return store.findRecord('foodid',value).get('description');
}
return value;
},
editor: {
xtype: 'combobox',
allowBlank: true,
displayField: "description",
valueField: "foodid",
store: {
fields:['food_distributor', 'description'],
data:[
{
'food_distributor':'a',
foodid:1,
description:'aaaaa'
},
{
'food_distributor':'a',
foodid:2,
description:'bbbbbb'
},
{
'food_distributor':'a',
foodid:3,
description:'aaaaa'
}]
},
listeners: {
expand: function () {
debugger;
var desc = this.up('grid').getSelectionModel().getSelection()[0].get('description').trim();
this.store.clearFilter();
this.store.filter({
property: 'description',
value: desc,
exactMatch: true
})
}
},
},
}
]
});
Ext.create('Examples.grid.fdGrid', {
store: {
fields:['food_distributor', 'description'],
data:[
{
'food_distributor':'a',
foodid:1,
description:'aaaaa'
},
{
'food_distributor':'a',
foodid:2,
description:'bbbbbb'
},
{
'food_distributor':'a',
foodid:3,
description:'aaaaa'
}]
},
renderTo:Ext.getBody()
})
Do you have
var cellEditing = Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
});
Without the plugin the editor doesnt work! and the editor will be undefined when you will try to obtain it
I have a controller and a view and want to push a line from a controller when item is selected.
Where it says onItemSelect: that's where I need to make a call, and don't know how...
Thank you.
controller is this:
Ext.define('Application.controller.ItemController', {
// Extend basic controller object
extend: 'Ext.app.Controller',
// Attach store classes to this controller
stores: ['Items'],
// Attach model classes to this controller
models: ['Item'],
// ..and last but not least - the view classes
views: ['item.List', 'item.Show'],
// Refs parameter defines references to certain
// instances of components pointed by selector
refs: [
{
// Ref determines the name of the automagic
// this.get[ref-goes-here] method that returns
// instance of certain component
ref : 'itemShowDesc',
// Select #item-description component in
// item.Show view
selector: 'itemShow > #item-description'
}
],
// when including the controllers in your application,
// the framework will automatically load the controller
// and call the init method on it
init: function() {
this.control({
'itemList' : {
// Action to be performed on select
select: this.onItemSelect
}
});
},
onItemSelect: function (selModel, selection) {
// Executed only when selection is a leaf
(selection.data.leaf) ? this.getItemShowDesc().addRow(selection.raw.description,'','','','','','') : null;
}
});
and the view is this:
Ext.define('Application.view.item.Show', {
extend: 'Ext.grid.Panel',
alias : 'widget.itemShow',
requires: [
'Ext.selection.CellModel',
'Ext.grid.*',
'Ext.data.*',
'Ext.util.*',
'Ext.form.*',
'Application.model.Item'
],
xtype: 'cell-editing',
title: 'Favorite Books',
frame: true,
initComponent: function() {
this.cellEditing = new Ext.grid.plugin.CellEditing({
clicksToEdit: 1
});
Ext.apply(this, {
width: 680,
height: 350,
plugins: [this.cellEditing],
store: new Ext.data.Store({
// destroy the store if the grid is destroyed
autoDestroy: true,
model: Application.model.Item,
proxy: {
type: 'ajax',
// load remote data using HTTP
url: 'resources/data/grid/books.xml',
// specify a XmlReader (coincides with the XML format of the returned data)
reader: {
type: 'xml',
// records will have a 'plant' tag
record: 'book'
}
},
sorters: [{
property: 'common',
direction:'ASC'
}]
}),
columns: [{
header: 'Book Id',
dataIndex: 'item_id',
width: 100
}, {
header: 'Author',
dataIndex: 'author',
width: 100
}, {
header: 'Title',
dataIndex: 'title',
width: 250
},{
header: 'Description',
dataIndex: 'description',
width: 495
},{
header: 'Price',
dataIndex: 'price',
width: 70,
align: 'right',
renderer: 'usMoney'
},{
xtype: 'actioncolumn',
width: 30,
sortable: false,
menuDisabled: true,
items: [{
icon: 'resources/images/icons/delete.gif',
tooltip: 'Delete Plant',
scope: this,
handler: this.onRemoveClick
}]
}],
selModel: {
selType: 'cellmodel'
}
});
this.callParent();
this.on('afterlayout', this.loadStore, this, {
delay: 1,
single: true
})
},
addRow: function(inItemID,inDisplay,inSex,inAuthor,inTitle,inDescription,inPrice){
// Create a record instance through the ModelManager
var r = Ext.ModelManager.create({
item_id: inItemID,
display: inDisplay,
sex: inSex,
author: inAuthor,
title: inTitle,
description: inDescription,
price: inPrice
}, 'Item');
store.insert(0, r);
cellEditing.startEditByPosition({row: 0, column: 0});
}
,
loadStore: function() {
this.getStore().load({
// store loading is asynchronous, use a load listener or callback to handle results
callback: this.onStoreLoad
});
},
onStoreLoad: function(){
Ext.Msg.show({
title: 'Store Load Callback',
msg: 'Favorites were loaded, data available for processing',
icon: Ext.Msg.INFO,
buttons: Ext.Msg.OK
});
},
onRemoveClick: function(grid, rowIndex){
this.getStore().removeAt(rowIndex);
}
})
Your ref for itemShowDesc is selecting a child component of itemShow. So when you do this.getItemShowDesc().addRow(), you're calling a method on whatever #item-description is, not on the Application.view.item.Show class.
I am trying to edit an information using editor grid. I have three fields, Interview By (combo), Date (date) and Performance (number), I get the date and the performance column, but the combo is not displaying the value initially. But when I click, then it shows the correct value. I am new to extjs and googled it for a solution, but could not find it. Kindly help me with a solution. Thanks in advance.
MY CODE:
initComponent: function() {
this.createTbar();
this.columns = [
{ xtype:'numbercolumn',
hidden:true,
dataIndex:'interview_id',
hideable:false
},
{ xtype: 'gridcolumn',
dataIndex: 'interview_by_employee_id',
header: 'Interview By',
sortable: true,
width: 290,
editor: {
xtype: 'combo',
store: employee_store,
displayField:'employee_first_name',
valueField: 'employee_id',
hiddenName: 'employee_first_name',
hiddenValue: 'employee_id',
mode: 'remote',
triggerAction: 'all',
forceSelection: true,
allowBlank: false ,
editable: false,
listClass : 'x-combo-list-small',
style: 'font:normal 11px tahoma, arial, helvetica, sans-serif'
},
renderer: function(val){
index = employee_store.findExact('employee_id',val);
if (index != -1){
rs = employee_store.getAt(index).data;
return rs.employee_first_name;
}
}
},
{ xtype: 'gridcolumn',
dataIndex: 'interview_date',
header: 'Date',
sortable: true,
readOnly: true,
width: 100,
editor: {
xtype: 'datefield'
}
},
{ xtype: 'numbercolumn',
header: 'Performance',
format:'0',
sortable: true,
width: 100,
align: 'right',
dataIndex: 'interview_performance',
editor: {
xtype: 'numberfield'
}
}
];
candidate_grid_interview.superclass.initComponent.call(this);
}
and the screen shots,
I faced the same problem and found my solution somewhere. Here is a reduced version of what I'm using. I think the key was the renderer property on the column. If your combo uses remote data, it might be loading its content after the grid is done loading - but I'm not sure it will cause the problem you're describing.
Try this concept:
var myStore = new Ext.data.JsonStore({
autoLoad: false,
...
fields: [
{ name: 'myID', type: 'int' },
{ name: 'myName', type: 'string' }
],
listeners: {
load: function () {
// Load my grid data.
},
scope: this
}
});
var myCombo = new Ext.form.ComboBox({
...
displayField: 'myName',
valueField: 'myID',
store: myStore
});
var grid = new Ext.grid.EditorGridPanel({
store: new Ext.data.ArrayStore({
...
fields: [
...
{ name: 'myID', type: 'int' },
...
]
}),
...
cm: new Ext.grid.ColumnModel({
columns: [
...
{
header: 'Header',
dataIndex: 'myID',
editor: myCombo,
renderer: function (value) {
var record = myCombo.findRecord(myCombo.valueField, value);
return record ? record.get(myCombo.displayField) : myCombo.valueNotFoundText;
}
}]
})
});
myStore.load();
Store loading is asynchronous, so it might be loading itself after rendering the grid. I recommend you render your grid within the store onload event. Also, datatypes can be painfull if you don't pay enough attention. Be sure that your grid store and combo store types match.
I am using Extjs4 and I want to apply exactMatch on grid filtering. I am using the newly introduced Grid Filtering feature.I have tried to use exactMatch but it does not work. Here is my sample code:
Ext.define('MyModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'ID', type: 'string'},
{name: 'Title', type: 'string'}
]
});
var store = Ext.create('Ext.data.Store', {
model: 'MyModel',
proxy: {
type: 'ajax',
url: 'myurl',
reader: {
type: 'json'
}
},
sorters: [{
property: 'ID',
direction:'DESC'
}],
autoLoad:true
});
var filters = {
ftype: 'filters',
encode: true,
local: true,
filters: [{
type: 'numeric',
dataIndex: 'ID',
disabled: true
},{
type: 'string',
dataIndex: 'Title',
exactMatch:true
}]
};
var grid = Ext.create('Ext.grid.Panel', {
store: store,
columns: [{
header: 'ID',
dataIndex: 'ID',
width: 20
},{
header: 'List Title',
dataIndex: 'Title',
flex:1
}],
renderTo: 'editor-grid',
width: 700,
height: 400,
frame: true,
features: [filters]
});
Thanks..
It looks like for ExtJS V4.0, you don't have to configure seperate filter options for the grid as they are already included. You can just call the method on the store to filter after the data has been loaded like so:
store.filter("Title", "Bob");
or if you want to do multiple filters like so:
store.filter([
{property: "email", value: "Bob"},
{filterFn: function(item) { return item.get("ID") > 10; }}
]);
The grid's features property can only contain classes that have been extended from the Feature class.
See the Grouping Feature:
Ext.define('Ext.grid.feature.Grouping', {
extend: 'Ext.grid.feature.Feature',
alias: 'feature.grouping'
// More properties and functions...
}
Grouping Feature Usage:
var groupingFeature = Ext.create('Ext.grid.feature.Grouping', {
groupHeaderTpl: 'Group: {name} ({rows.length})', //print the number of items in the group
startCollapsed: true // start all groups collapsed
});
var grid = Ext.create('Ext.grid.Panel', {
features:[groupingFeature]
}