I'm just started working with Ext js a week ago, and I would like to ask for help on how to make a relationship between two grid panel, I have the first panel to display categories and the second for sub-categories, so I want to : when I click on a category, it displays its subcategories in the second grid panel, and a message "please select a category if none is selected, for now I'm just displaying all subcategories in the second panel, here my code :
Ext.onReady(function() {
Ext.define('categorie', {
extend: 'Ext.data.Model',
fields: [
{name: 'id_categorie', type: 'string'},
{name: 'lib_categorie', type: 'string'},
],
idProperty: 'id_categorie'
});
Ext.define('sub-categorie', {
extend: 'Ext.data.Model',
fields: [
{name: 'id_sub-categorie', type: 'string'},
{name: 'lib_sub-categorie', type: 'string'},
{name: 'id_categorie', type: 'string' },
],
associations: [
{ type: 'belongsTo', model: 'categorie', primaryKey: 'id_sub-categorie', foreignKey: 'id_categorie' }
],
});
var categorieStore = Ext.create('Ext.data.Store', {
model: 'categorie',
pageSize : 15,
proxy: {
type: 'ajax',
url: 'ajax.php?mode=getCategories',
reader: {
type: 'json',
root: 'categories'
}
},
timeout : 90000,
extraParams : {
start : 0,
limit : 20
},
sorters: [ {
property : 'lib_categorie',
direction : 'ASC'
} ],
remoteSort : true,
autoDestroy : true,
simpleSortMode : true,
autoLoad: true
});
var subCategoriesStore = Ext.create('Ext.data.Store', {
model: 'sub-categorie',
pageSize : 15,
proxy: {
type: 'ajax',
url: 'ajax.php?mode=getSubCategories',
reader: {
type: 'json',
root: 'sub-categories'
}
},
timeout : 90000, // 90 secondes
extraParams : {
start : 0,
limit : 20
},
sorters: [ {
property : 'lib_sub-categorie',
direction : 'ASC'
} ],
remoteSort : true,
autoDestroy : true,
simpleSortMode : true,
autoLoad: true
});
var CategoriePanel = Ext.create('Ext.grid.Panel',{
title: 'Categories',
renderTo: 'categories_grid',
store: categorieStore,
columns: [
{
header : I18N.msgID,
tooltip : I18N.msgID,
align : 'left',
text: 'ID',
flex: 50,
dataIndex: 'id_categorie'
},
{
header : I18N.msgLib,
tooltip : I18N.msgLib,
align : 'left',
text: 'Lib',
flex: 50,
dataIndex: 'lib_categorie'
},
],
width: 400,
});
var subCategoriePanel = Ext.create('Ext.grid.Panel',{
title: 'subCategories',
renderTo: 'subcategories_grid',
store: subCategoriesStore,
columns: [
{
header : I18N.msgIDs,
tooltip : I18N.msgIDs,
align : 'left',
text: 'IDs',
flex: 50,
dataIndex: 'id_sub-categorie'
},
{
header : I18N.msgLibs,
tooltip : I18N.msgLibs,
align : 'left',
text: 'Libs',
flex: 50,
dataIndex: 'lib_sub-categorie'
},
],
width: 400,
});
You must add a listener to your categories grid:
listeners: {
itemclick: function ( this, record, item, index, e, eOpts ) {
// Select your catergory, find subcategories and load subcategories in your subcategories grid
}
}
Related
I'm trying to filter my JSON that has value of 32 for privilege field. I've tried multiple ways of filtering it but still it's returning me all rows instead the filtered ones.
Ext.onReady(function () {
// create the data store
var store = new Ext.data.Store({
url: url,
reader: new Ext.data.JsonReader({
root: 'keys',
idProperty: 'key',
fields: ['key', 'name']
}),
autoLoad: true
});
store.filter({
property: 'privileges',
value: 32,
type: 'int',
exactMatch: true
});
//create the Grid
var grid = new Ext.grid.GridPanel({
store: store,
columns: [
{
id :'name',
header : 'Name',
width : 500,
sortable : true,
dataIndex: 'name'
},
{
header : 'Key',
width : 500,
sortable : false,
dataIndex: 'key'
},
{
header : 'Regenerate',
width : 300,
dataIndex: ''
}
],
stripeRows: true,
height: 350,
title: 'Administrator Keys'
});
grid.render('restApiKeyContent');
});
Current my JSON is as below
{
"id": "abc123",
"name": "Test",
"queue": "test",
"expire": "2118-11-27T02:05:15.546778Z",
"keys": [
{
"key": "64654asdsad1sd1",
"customer": "Test Customer",
"externalUser": "123213",
"name": "Jenna Testing API Key 1",
"privileges": 31
},
{
"key": "7c5362f98f084ae7b76b8484f660fdcf",
"customer": "Test Customer",
"externalUser": "123213",
"name": "Jenna Testing API Key 1",
"privileges": 16
}
}
Appreciate if someone can guide me on how to filter JSON by a specific field which has the Keys as root?
This may help you. Add privileges field in JSONReader and filter store after store is loaded:
Ext.onReady(function () {
// create the data store
var store = new Ext.data.Store({
url: 'filter-store-extjs3.json',
reader: new Ext.data.JsonReader({
root: 'keys',
idProperty: 'key',
fields: ['key', 'name', 'privileges']
}),
autoLoad: true,
listeners: {
load: function() {
store.filter('privileges', '16', true, true);
}
}
});
var grid = new Ext.grid.GridPanel({
renderTo: Ext.getBody(),
store: store,
columns: [
{
id :'name',
header : 'Name',
width : 500,
sortable : true,
dataIndex: 'name'
},
{
header : 'Key',
width : 500,
sortable : false,
dataIndex: 'key'
},
{
header : 'Regenerate',
width : 300,
dataIndex: ''
}
],
stripeRows: true,
height: 350,
title: 'Administrator Keys'
});
});
I have a grid with a pagination. When I set a filter, the ajax request is successfully executed, the json return value looks fine and the filtered rows appear in my grid.
But the Loading... popup won't disappear and Firebug reports an error in ext-all-debug.js: TypeError: data is null (Line 134684). The code at that point is:
data = store.getData();
items = data.items; // error
I've checked my JS several times, but I can't find the problem.
Unfortunately I can't create a fiddle, since I use remote filtering. So here's the script:
Ext.onReady (function () {
Ext.define('FooModel', {
extend: 'Ext.data.Model',
fields: [
{ name: 'myId', type: 'int' },
{ name: 'myDate', type: 'date', dateFormat: 'Y-m-d H:i:s' },
{ name: 'myString', type: 'string' },
{ name: 'myFilename', type: 'string' },
{ name: 'myUser', type: 'string' }
]
});
Ext.define('FooStore', {
extend: 'Ext.data.Store',
model: 'FooModel',
autoLoad: true,
autoDestroy: true,
proxy: {
type: 'ajax',
url: 'test.php',
reader: {
type: 'json',
rootProperty: 'import_files',
messageProperty: 'error',
}
},
remoteFilter: true,
remoteSort: true,
sorters: [{
property: 'myId',
direction: 'ASC'
}],
pageSize: 5
});
var theFooStore = new FooStore();
theFooStore.load({
callback: function(records, operation, success) {
if(!success) {
Ext.Msg.alert('Error', operation.getError());
}
}
});
Ext.define('FooGrid', {
extend: 'Ext.grid.Panel',
xtype: 'grid-filtering',
requires: [ 'Ext.grid.filters.Filters' ],
width: 1000,
height: 700,
renderTo: 'content',
plugins: 'gridfilters',
emptyText: 'No Matching Records',
loadMask: true,
stateful: true,
store: theFooStore,
defaultListenerScope: true,
columns: [
{ dataIndex: 'myId', text: 'My Id', filter: 'number' },
{ xtype: 'datecolumn', dataIndex: 'myDate', text: 'My Date', renderer: Ext.util.Format.dateRenderer('d.m.Y'), filter: true },
{ dataIndex: 'myString', text: 'My String', filter: 'list' },
{ dataIndex: 'myFilename', text: 'My Filename',
renderer: function(value, meta, record) {
return Ext.String.format('{1}', record.data.myId, value);
},
filter: {
type: 'string',
itemDefaults: { emptyText: 'Search for...' }
}
},
{
dataIndex: 'myUser', text: 'My User',
filter: {
type: 'string',
itemDefaults: { emptyText: 'Search for...' }
}
},
],
dockedItems: [{
xtype: 'pagingtoolbar',
store: theFooStore,
dock: 'bottom',
displayInfo: true
}]
});
new FooGrid();
});
And here's a sample json return value:
{
"success" : true,
"total" : 19,
"import_files" : [{
"myId" : "1",
"myFilename" : "foo bar.xlsx",
"myDate" : "2015-05-19 13:23:21",
"myUser" : "ABC",
"myString" : "Lorem ipsum"
},
...
]
}
Has someone experienced the same issue? What could it cause?
Just my luck. Found the answer shortly after posting the question.
Deleting the filter: 'list' option at my My String column is the solution.
I want to get an infinite scrolling grid with extjs4 and a c# backend... i am setting the proxy api in my controller..
My Model:
Ext.define('appname.model.training.course.TrainingRequirementList', {
extend: 'Ext.data.Model',
idProperty: 'ID',
fields: [
{ name: 'ID', type: 'int', convert: null },
{ name: 'EmployeeName', type: 'string' },
{ name: 'Description', type: 'string' },
{ name: 'StatusText', type: 'string' },
{ name: 'Status', type: 'int' },
{ name: 'Priority', type: 'string' },
{ name: 'Date', type: 'string' },
{ name: 'Cost', type: 'string' },
{ name: 'CanApprove', type: 'bool' },
{ name: 'CanRequest', type: 'bool' },
{ name: 'ConfirmStatus', type: 'string' },
{ name: 'PlanId', type: 'int'}
]
});
My Grid:
{
xtype: 'gridpanel',
flex: 1,
padding: '0 10 10 10',
minHeight: 200,
verticalScroller: {
xtype: 'paginggridscroller'
},
store: {
model: 'appname.model.training.course.TrainingRequirementList',
pageSize: 200,
autoLoad: true,
buffered: true,
remoteSort: true,
sorters: {
property: 'Date',
direction: 'DESC'
},
proxy: {
type: 'direct',
extraParams: {
total: 50000
},
reader: {
type: 'json',
root: 'ID',
totalProperty: 'TotalCount'
},
simpleSortMode: true
}
},
columns:
[{
text: Lang.Main.Employeee,
dataIndex: 'EmployeeName',
flex: 1,
filterable: true
},
{
text: Lang.Main.Course,
dataIndex: 'Description',
flex: 1,
filterable: true
},
{
text: Lang.Main.Status,
dataIndex: 'StatusText',
flex: 1,
filterable: true
},
{
text: Lang.Main.Priority,
dataIndex: 'Priority',
flex: 1
},
{
text: Lang.Main.Date,
dataIndex: 'Date',
flex: 1
},
{
text: Lang.Main.Cost,
dataIndex: 'Cost',
flex: 1,
filterable: true
},
{
text: Lang.Main.Actions,
flex: 1,
align: 'center',
xtype: 'actioncolumn',
width: 50,
items: [{
icon: 'Design/icons/cog_edit.png',
tooltip: Lang.Main.Open,
handler: function (grid, rowIndex, colIndex, item) {
this.onGridOpen(grid.getStore().getAt(rowIndex));
}
}]
}],
selModel: { mode: 'MULTI', selType: 'checkboxmodel' },
}
setting proxy in controoler:
view.grid.getStore().setProxy({
type: 'direct',
model: 'appname.model.training.course.TrainingRequirementList',
api: { read: SCT.Service.Training.Plan.GetFilteredRequirements },
extraParams: { total: 50000 },
reader: {
type: 'json',
root: 'ID',
totalProperty: 'TotalCount'
},
simpleSortMode: true
});
additional information about my view:
Ext.define('appname.view.training.course.TrainingRequirements',
{
extend: 'Ext.panel.Panel',
require: [ 'Ext.grid.PagingScroller'],
My grid is only loading the first 200 rows and the scrollbar is only as big as it would be for 200 rows.. :/ ...
the server response with entries like this:
{"ID":99,"PlanId":23,"firstname":"name","lastname":"name","Comment":"","Status":3,"ConfirmType":0,"Priority":"entry","DesiredDate":null,"StartDate":new Date(1354107600000),"ActualCost":180,"EstimatedCost":0,"row":201,"TotalCount":8568,"EmployeeName":"some, name","Description":"","StatusText":"state","Date":"28.11.2012","Cost":"EUR 180"}
what am i missing???
UPDATE
When i scroll down the script is loading the second page also.. still nothing more...
if you ned more information dont hesitate to ask
Does your server include the correct TotalCount value in the response?
Edit:
According to your reader's configuration, your server should answer with data formatted this way (of course your response should also be valid JSON, here Javascript is used for illustration):
{
// total property at the root level of response object
TotalCount: 8568,
// root for items data, configured as "ID" in your reader (you should probably
// change that to something like "records" or "data" to better express meaning)
ID: [
// individual fields data
{ID: 1, EmployeeName: 'Foo', ...},
{ID: 2, EmployeeName: 'Bar', ...},
...
]
// if you had, for example, a successProperty, it would go here too
,success: true
}
In your case, it seems that your TotalCount is mixed in every item data?
You're right about the implementation on the server side: it should simply be the total number of records, so something like COUNT(*) in the database.
One more thing: new Date(1354107600000) is not valid JSON. You should use a string and cast it to a date once the JSON has been decoded. For example, in your model, your could configure the field type to have Ext handle this for your: {name: 'Date', type: 'date', format: 'd.m.Y'}.
Ext.require([
'Ext.grid.*',
'Ext.data.*',
'Ext.panel.*'
]);
Ext.onReady(function(){
Ext.define('ImageModel', {
extend: 'Ext.data.Model',
fields: ['name', 'url', {name:'size', type: 'float'}, {name:'lastmod', type:'date', dateFormat:'timestamp'}]
});
var store = Ext.create('Ext.data.JsonStore', {
model: 'ImageModel',
proxy: {
type: 'ajax',
url: 'get-images.php',
reader: {
type: 'json',
root: 'images'
}
}
});
store.load();
var listView = Ext.create('Ext.grid.Panel', {
width:425,
height:250,
collapsible:true,
title:'Simple ListView <i>(0 items selected)</i>',
renderTo: Ext.getBody(),
store: store,
multiSelect: true,
viewConfig: {
emptyText: 'No images to display'
},
columns: [{
text: 'File',
flex: 50,
dataIndex: 'name'
},{
text: 'Last Modified',
xtype: 'datecolumn',
format: 'm-d h:i a',
flex: 35,
dataIndex: 'lastmod'
},{
text: 'Size',
dataIndex: 'size',
tpl: '{size:fileSize}',
align: 'right',
flex: 15,
cls: 'listview-filesize'
}]
});
// little bit of feedback
listView.on('selectionchange', function(view, nodes){
var l = nodes.length;
var s = l != 1 ? 's' : '';
listView.setTitle('Simple ListView <i>('+l+' item'+s+' selected)</i>');
});
});
i have create 2 panel, one is left panel,second is right panel.
the list view are created in the left panel,and the right panel will read the page showimage.php
list view are display file detail,when user select the list view will passing the file name as a parameter "name" to showimage.php, and the right panel will show the image by name are passed from list view select event.(actually the name field are stored file's ID)
Question
1)how to create the select list view event,when select a list view passing parameter name to showimage.php,and right panel refresh the page and display the image.
//===========================LIST VIEW===============================
Ext.define('ImageModel', {
extend: 'Ext.data.Model',
fields: ['PicID', 'PicUploadedDateTime','PicData']
});
var ImgStore = Ext.create('Ext.data.JsonStore', {
model: 'ImageModel',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'get-image.php',
baseParams: { //here you can define params you want to be sent on each request from this store
mainid: 'value1',
startdate: 'value2',
enddate: 'value3'
},
reader: {
type: 'json',
root: 'images'
}
}
});
var listView = Ext.create('Ext.grid.Panel', {
region: 'west',
id : 'imagelist',
title: 'Select Image',
width: 200,
split: true,
collapsible: true,
floatable: false,
title:'Select Image',
store: ImgStore,
multiSelect: false,
viewConfig: {
emptyText: 'No images to display'
},
columns: [
{
text: 'Date Time Uploaded',
//xtype: 'datecolumn',
//format: 'Y-m-d H:i:s',
flex: 65,
width: 100,
dataIndex: 'PicUploadedDateTime'
}]
});
function hexToBase64(str) {
return btoa(String.fromCharCode.apply(null, str.replace(/\r|\n/g, "").replace(/([\da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" ")));
}
listView.on('selectionchange', function(view, nodes){
/*
var nodeIdDisplay = "";
for(var i = 0; i < nodes.length; i++)
{
if(nodeIdDisplay.length > 0)
nodeIdDisplay += ",";
nodeIdDisplay += nodes[i].get("PicID");
}
*/
if (nodes[0].get("PicID") > 0){
//alert(nodes[0].get("PicData"));
image=Ext.getCmp('displayimage');
image.setSrc("data:image/jpeg;base64,"+hexToBase64(nodes[0].get("PicData")));
//console.log(nodes[0].get("PicData"));
}
});
this code method is post to the get-image.php,and get all the image in store and then,
list view on select change event get the image id and display the image on type : 'image' component
I was creating Tree Panel similar to TreeGrid example with drag'n'drop. The only problem is that items are correctly shown in tree panel in Firefox browser whereas in Chromium tree grid is empty. How's that possible?
JSON data sent to server:
{"text":".","children": [
{
"id":null,
"name":"en",
"visible":false,
"expanded":true,
"leaf":false,
"children":{
"id":5,
"name":"/",
"visible":false,
"expanded":true,
"leaf":true,
"children":[]
}
}]
}
Model
Ext.define('Example.model.WebTreeItem', {
extend: 'Ext.data.Model',
idProperty: 'id',
fields: [
{name: 'id', type: 'int', defaultValue: 0},
{name: 'visible', type: 'boolean' },
{name: 'name', type: 'string' }
]
});
Store
Ext.define('Example.store.WebTreeItems', {
extend: 'Ext.data.TreeStore',
model: 'Example.model.WebTreeItem',
autoLoad: true,
proxy: {
type: 'ajax',
api: {
read : 'getlist.json'
},
reader: {
type: 'json'
}
}
});
View
Ext.define('Example.view.webitem.Tree', {
extend: 'Ext.tree.Panel',
alias : 'widget.webtreeitem',
title : 'Web items',
store: 'WebTreeItems',
rootVisible: false,
multiSelect: true,
singleExpand: false,
collapsible: true,
selModel: Ext.create('Ext.selection.CheckboxModel'),
height: 800,
renderTo: 'webstructure-tree',
columns: [{
xtype: 'treecolumn',
text: 'Name',
flex: 2,
sortable: true,
dataIndex: 'name'
},{
xtype: 'booleancolumn',
text: 'Visible',
flex: 1,
dataIndex: 'visible',
sortable: false
}],
viewConfig: {
plugins: {
ptype: 'treeviewdragdrop'
}
}]
});
Dependencies are loaded automatically using
Ext.Loader.setConfig({enabled:true});
Ext.application({
...
});
Any suggestion will be highly appreciated.
Well I thought that I was sending aforementioned JSON, but in fact I was sending something like this (quoted response with escaped quotes) and Chromium couldn't read it correctly
"{\"text\":\".\",\"children\": [
{
\"id\":null,
\"name\":\"en\",
\"visible\":false,
\"expanded\":true,
\"leaf\":false,
\"children\":{
\"id\":5,
\"name\":\"/\",
\"visible\":false,
\"expanded\":true,
\"leaf\":true,
\"children\":[]
}
}]
}"