I am trying to get a really basic tree grid working but all I get is an empty panel.
I copied the json string from a working treepanel example and added the date and filename myself for the extra grids.
So calling the bits root and children worked for a basic panel (i had it working when it only had the field text and was directly in the store. So i presumed it would work for a tree grid.
After searching I found that a treestore doesn't have a data config it had to be moved to the proxy. Now I just have empty date and filename columns.
so here is my model
Ext.define('Coda.common.repository.model.RepositoryMaintModel',{
extend: 'Ext.data.Model',
fields: [
{name: 'date', type: 'string'},
{name: 'filename', type: 'string'},
{name: 'text', type: 'string'},
{name: 'iconCls' , type: 'string', defaultValue: 'treenode-no-icon'},
{name: 'expanded' , type: 'boolean', defaultValue: true, persist: false},
{name: 'index' , type: 'int'}
]
});
and here is my view
Ext.define('view.RepositoryMaintView', {
extend: 'U4.panel.Panel',
requires: ['Ext.layout.container.HBox',
'model.RepositoryMaintModel',
'Ext.tree.Panel'],
EVENT_DOWNLOAD: 'download',
layout: 'hbox',
constructor: function (config) {
var me = this;
me.addEvents(
/**
* #event download
* #param {view.RepositoryMaintView} when pressing the download button
*/
me.EVENT_DOWNLOAD
);
var data = {root: {
expanded: true,
root: [
{ text: "detention",date:'10-01-2013', filename:'boo.txt', leaf: true },
{ text: "homework",date:'10-01-2013', filename:'boo.txt', expanded: true,
root: [
{ text: "book report",date:'10-01-2013', filename:'boo.txt', leaf: true },
{ text: "algebra",date:'10-01-2013', filename:'boo.txt', leaf: true}
] },
{ text: "buy lottery tickets",date:'10-01-2013', filename:'boo.txt', leaf: true }
]
}};
var store = Ext.create('Ext.data.TreeStore', {
model: 'blah.blah.model.RepositoryMaintModel',
// data: data, <-- remove from here
proxy: {
type: 'memory',
data: data, // <-- place here
reader: {
type: 'json',
root: 'root'
}
},
folderSort: true
});
var center = Ext.create('Ext.tree.Panel',{
title: 'Folders Companies Items',
//region: 'center',
width: 1000,
height: 200,
collapsible: false,
useArrows: true,
rootVisible: false,
store: store,
multiSelect: true,
columns: [
{
xtype: 'treecolumn', //this is so we know which column will show the tree
text: 'hmm',
flex: 2,
sortable: true
},{
text: 'Date',
sortable: true,
dataIndex: 'date'
},{
text: 'filename',
sortable: true,
dataIndex: 'filename'
}]
});
me.items = [center];
me.callParent(arguments);
}
});
Related
The total number of rows is correctly showing in pagination but Pagination is not updating the view when the next button is clicked.
I'm new to Sencha. In Mysql, I'm returning all rows. So that I can limit in client side. If I limit the rows in backend, I cannot have all the rows in client side.
View: List.js
/*** This view is an example list of people.
*/
Ext.define('CRUD.view.main.List', {
extend: 'Ext.grid.Panel',
xtype: 'home',
requires: [
'CRUD.store.Personnel'
],
title: 'Heroes',
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
})
],
layout: 'fit',
fullscreen: true,
store: {
type: 'personnel',
},
columns: [
{ text: 'Name', dataIndex: 'name', sortable: true, flex: 1 },
{ text: 'Email', dataIndex: 'email', sortable: true, flex: 1 },
{ text: 'Phone', dataIndex: 'phone', sortable: true, flex: 1 }
],
bbar: {
store: {
type: 'personnel',
},
xtype: 'pagingtoolbar',
displayInfo: true
},
// columns: [
// { text: 'Name', dataIndex: 'name', flex: 1 },
// { text: 'Email', dataIndex: 'email', flex: 1 },
// { text: 'Phone', dataIndex: 'phone', flex: 1 }
// ],
listeners: {
select: 'onItemSelected',
},
});
Store: Personnel.js
Ext.define('CRUD.store.Personnel', {
extend: 'Ext.data.Store',
alias: 'store.personnel',
model: 'CRUD.model.User',
id: 'list',
fields: [
'name', 'email', 'phone'
],
// data: [
// { name: 'Jean Luc', email: "jeanluc.picard#enterprise.com", phone: "555-111-1111" },
// { name: 'Worf', email: "worf.moghsson#enterprise.com", phone: "555-222-2222" },
// { name: 'Deanna', email: "deanna.troi#enterprise.com", phone: "555-333-3333" },
// { name: 'Data', email: "mr.data#enterprise.com", phone: "555-444-4444" }
// ],
autoLoad: {
start: 0,
limit: itemsPerPage
},
buffered: true,
pageSize: itemsPerPage,
remoteSort: true,
proxy: {
type: 'jsonp', //cross domain calls - json parser
url: 'http://localhost:8080/list',
enablePaging: true,
reader: {
type: 'json',
totalProperty: 'total'
},
},
// proxy: {
// type: 'memory',
// reader: {
// type: 'json',
// }
// },
});
bbar: {
store: {
type: 'personnel',
},
xtype: 'pagingtoolbar',
displayInfo: true
},
I have removed store inside bbar and it works. Thanks for being cooperative.
The way you're using the store, ExtJS will do a request every time you change the page, sending the page number parameter to the URL set to the store.
If you want to do client-side pagination using ExtJS, you must set your store's proxy type to memory, load your data into the store and then ExtJS Grid will handle pagination as you expect.
Do an Ext.Ajax.Request like that:
Ext.Ajax.request({
url: 'http://localhost:8080/list',
success: function(response) {
dataStore.setProxy({
type: "memory",
enablePaging: true,
data: Ext.JSON.decode(response.responseText) //here you need to adapt to your response structure
});
dataStore.load();
}
});
For cross domain, you can make a call to Ext.data.JsonP.request() method and process the response as shown in the code below:
Ext.data.JsonP.request({
url: 'data1.json',
success: function (response) {
var myData = [];
Ext.Array.forEach(response.data, function (item) {
myData.push({
name: item.name,
email: item.email,
phone: item.phone
});
});
store.setProxy({
type: "memory",
enablePaging: true,
data: myData
});
store.load();
}
});
Check this fiddle for complete working example.
I'm unsuccessful in getting binding associations working in the admin dashboard template (with the desired behavior of selecting a record from a combobox and pulling up associated records in a grid).
My main viewModel is defined as:
Ext.define('Admin.view.main.MainModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.main',
stores: {
patients: {
model: 'md_registry.model.Patient',
autoLoad: true
}
}
});
I added a leaf node to Pages in NavigationTree.js:
{
text: 'Pages',
iconCls: 'x-fa fa-leanpub',
expanded: false,
selectable: false,
//routeId: 'pages-parent',
//id: 'pages-parent',
children: [
{
text: 'Proc',
iconCls: 'x-fa fa-send',
rowCls: 'nav-tree-badge nav-tree-badge-hot',
viewType: 'procedure',
leaf: true
}]
}
With the procedure view being:
Ext.define('Admin.view.pages.Procedure', {
extend: 'Ext.panel.Panel',
xtype: 'procedure',
requires: [
'Ext.panel.Panel',
'Admin.model.Patient',
'Admin.model.Procedure'
//'Admin.model.Diagnosis'
],
anchor : '100% -1',
referenceHolder: true,
width: 1000,
height: 1000,
referenceHolder: true,
layout: {
type: 'hbox',
align: 'stretch'
},
viewModel: 'main',
session: {},
items: [
// https://www.sencha.com/forum/showthread.php?299301-Bind-combobox-displayField-value-to-displayfield
{
xtype: 'fieldset',
layout: 'anchor',
items: [{
xtype: 'combobox',
listeners : {
select : function() {
console.log(arguments)
console.log(arguments[1].data.birth_date)
console.log(arguments[1].data.first_name)
console.log(arguments[1].data.last_name)
console.log(arguments[1].data.sex)
}
},
bind: {
store: '{patients}'
},
reference: 'patientCombo',
publishes: 'id',
fieldLabel: 'Patient Search',
displayField: 'mrn',
//anchor: '-',
// We're forcing the query to run every time by setting minChars to 0
// (default is 4)
minChars: 2,
queryParam: '0',
queryMode: 'local',
typeAhead: true,
// https://www.sencha.com/forum/showthread.php?156505-Local-combobox-with-any-match-filter
doQuery: function(queryString, forceAll) {
this.expand();
this.store.clearFilter(!forceAll);
if (!forceAll) {
this.store.filter(this.displayField, new RegExp(Ext.String.escapeRegex(queryString), 'i'));
}
}
}, {
// https://www.sencha.com/forum/showthread.php?299301-Bind-combobox-displayField-value-to-displayfield
xtype: 'displayfield',
fieldLabel: 'Selected Patient',
bind: {
html: '<p>Name: <b>{patientCombo.selection.first_name}, ' +
'{patientCombo.selection.last_name} </b></p>' +
'<p>Sex: {patientCombo.selection.sex}</p>' +
'<p>Birthdate: {patientCombo.selection.birth_date}</p>'
}
}]
},
{
title: 'Procedures',
xtype: 'grid',
bind: '{patientCombo.selection.procedures}',
flex: 1,
margin: '0 0 0 10',
columns: [{
text: 'Procedure Date', dataIndex: 'proc_date', flex: 1
}, {
text: 'Procedure', dataIndex: 'proc_name', flex: 1
}],
plugins: [{
ptype: 'rowexpander',
rowBodyTpl : new Ext.XTemplate(
'<p><b>Proc Name Orig:</b> {proc_name_orig}</p>',
'<p><b>Proc Code:</b> {proc_code}</p>',
'<p><b>Proc Code Type:</b> {proc_code_type}</p>')
}],
viewConfig: {
emptyText: 'No procedures',
deferEmptyText: false
}
}]
});
My Patient and Procedure models are simply:
Ext.define('Admin.model.Procedure', {
extend: 'Ext.data.Model',
idProperty: 'id',
fields: [
//{ name: 'id', type: 'string' },
{ name: 'proc_code', type: 'string' },
{ name: 'proc_name', type: 'string' },
{ name: 'proc_code_type', type: 'string' },
{ name: 'proc_name_orig', type: 'string' },
{ name: 'proc_date', type: 'date', format: 'Y-m-d' },
{
name: 'patient_id',
type: 'string',
reference: {
parent: 'Admin.model.Patient',
//type: 'md_registry.model.Patient',
inverse: 'procedures',
autoLoad: false
}
}
],
proxy: {
type: 'rest',
url: 'http://127.0.0.1:5000/procedureview/api/read',
reader: {
type: 'json',
rootProperty: ''
}
}
});
and
Ext.define('Admin.model.Patient', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.proxy.Rest'
],
fields: [
{ name: 'id', type: 'string' },
{ name: 'mrn', type: 'string' },
{ name: 'birth_date', type: 'date', format: 'Y-m-d' },
{ name: 'sex', type: 'string' },
{ name: 'first_name', type: 'string' },
{ name: 'last_name', type: 'string' }
],
proxy: {
type: 'ajax',
url: 'http://127.0.0.1:5000/patientview/api/read',
reader: {
type: 'json',
rootProperty: ''
}
}
});
respectively.
The data for my Patients store are getting loaded into the combobox just fine, but when I select an item from the combo list it is not firing off the call to grab the associated procedures data (see image: .
However, the binding associations work as expected with Side Navigation Tabs (see image: , and show up within the object prototype chain, as expected... see
(whereas for the admin dashboard, the associations are empty).
I cannot for the life of me get these working in the Admin Dashboard. I noticed a tool called the bind inspector, but I am running the GPL version of the SDK, so I do not have access to this. Beyond this, I cannot figure out a way to debug why the binding association is not working in the admin dashboard, but otherwise works perfectly well in Side Navigation Tabs.
I would set up a Fiddle, but I have no idea how to do it using the Admin Template.
I just figured it out. It was a namespace issue.
My reference in the procedure model should be:
reference: {
parent: 'Patient',
inverse: 'procedures',
autoLoad: false
}
Voila, all the associated data get loaded as expected!
I'm using ExtJS 6.0.1 and want to drag items from a grid over a tree so I can change some category values into the grid records.
But on drop event I get this error: "TypeError: path is undefined". The error is returned by the function ensureVisible from Ext.tree Panel class, first line.
var foldersStore = Ext.create("Ext.data.TreeStore",{
storeId: 'foldersTreeStore',
proxy: {
type: 'ajax',
url: 'categories/tree.json'
},
autoLoad: true
});
var foldersTree = Ext.create("Ext.tree.Panel",{
title: 'Categories',
hideHeaders: true,
renderTo: 'folders-tree',
rootVisible: false,
allowDeselect: true,
store: foldersStore,
droppedRecords: undefined,
viewConfig: {
plugins: {
ptype: 'treeviewdragdrop',
dragText: 'Drag and drop to reorganize',
dropGroup: 'bkmDDGroup',
appendOnly: true
},
listeners: {
beforedrop: function(node, data, overModel, dropPos, opts) {
this.droppedRecords = data.records;
data.records = [];
console.log(this.droppedRecords);
},
drop: function(node, data, overModel, dropPos, opts) {
console.log(arguments);
}
}
}
});
var filesStore = Ext.create("Ext.data.Store",{
storeId:'filesTableStore',
fields:[
{name: 'eid', type:'string'},
{name: 'fileName', type:'string'},
{name: 'createdAt', type:'string'},
{name: 'mimeType', type:'string'},
{name: 'version', type:'string'},
{name: 'size', type:'int'},
{name: 'creator', type:'string'},
{name: 'modifier', type:'string'},
{name: 'status', type:'string'},
{name: 'tmpId'}
],
proxy: {
type: 'ajax',
url: 'documents/list.json',
reader: {
type: 'json',
rootProperty: "list"
}
},
autoLoad: true
});
var filesTable = Ext.create("Ext.grid.Panel",{
store: filesStore,
title:'Files',
selModel: {
mode: "MULTI",
allowDeselect: true
},
columns:[
{
text:'File Name',
flex:1,
dataIndex:'fileName'
},{
text:'Created By',
flex:1,
dataIndex:'creator'
},{
text:'Mime Type',
width: 150,
dataIndex:'mimeType'
},{
text:'Size',
width: 100,
dataIndex:'size'
},{
text:'Version',
width: 80,
dataIndex: 'version'
},{
text:'Status',
width: 100,
dataIndex:'status'
},{
text:'Created At',
width:150,
dataIndex:'createdAt'
}],
renderTo:'files-table',
height:UI.getContentHeight("#files-table"),
viewConfig: {
plugins: {
ptype: 'gridviewdragdrop',
dragText: 'Drag and drop to reorganize',
dragGroup: 'bkmDDGroup'
}
}
});
From my point of view looks like I've forgot some config, still don't have any idea yet. Even if I have a single console.log line in drop event, the error remains the same.
Any clues will be much appreciated.
Thanks
In the beforedrop listener you are deleting the records you've selected:
data.records = []
Instead you must prepare that records to drop into TreePanel where data model differs from the grid.
Link to the realization
My Simplified Store:
Ext.define('PT.store.DealTree', {
extend: 'Ext.data.TreeStore',
proxy: {
type: 'rest',
url: '/dealTree',
reader: { type: 'json', root: 'children', successProperty: 'success' },
},
root: { name: 'children', expanded: true }
})
My Simplified Grid:
Ext.define('PT.view.deal.DealSelectionGrid', {
extend: 'Ext.tree.Panel',
alias: 'widget.dealSelectionGrid',
rootVisible: false,
fields: ['text', 'date'],
store: 'DealTree',
columns: [
{ xtype: 'treecolumn', text: 'Deal', dataIndex: 'text' },
{ xtype: 'datecolumn', text: 'Date', dataIndex: 'date' }
]
});
Example of simplified response:
[ { text: 'aNode',
id: 522f7dd2323544c424000034,
leaf: true,
date: '2013/10/10' } ]
nothing appears in the Date column, yet the text, leaf, id all work perfectly. I'm clearly missing something. Currently, I'm not using a model because each level is a different model, which isn't supported by default - hence I let ExtJS add all the NodeInterface decoration for me.
The fields configuration goes into the store, not the tree component.
For example, your code is showing the date with this store:
Ext.define('PT.store.DealTree', {
extend: 'Ext.data.TreeStore',
proxy: {
type: 'rest',
url: '/dealTree',
reader: { type: 'json', root: 'children', successProperty: 'success' }
},
// fields option here!
fields: ['text', 'date'],
root: {
name: 'children',
expanded: true,
children: [{
text: 'aNode',
id: '522f7dd2323544c424000034',
leaf: true,
date: '2013/10/10'
}]
}
});
For some reason, this configuration of an ExtJS4 grid won't update. When you click on a cell, change a value, it hits the create URL, not the update URL, as defined in the proxy and observed with Firebug in FF4. Strangely, the datachanged event fires after loading the store when the page starts, but not after data has actually changed. Also, the grid send all rows to the create URL.
Can anyone tell me what I am doing wrong?
Ext.onReady(function() {
Ext.BLANK_IMAGE_URL = '/images/extjs4/s.gif';
Ext.tip.QuickTipManager.init();
//Ext.state.Manager.setProvider(Ext.create('Ext.state.CookieProvider'));
Ext.define('VendorError', {
extend: 'Ext.data.Model',
fields: [
{name: 'UnexpSrvID', type: 'int'},
{name: 'VendorID', type: 'int'},
{name: 'VendorName', type: 'string'},
{name: 'VndActID', type: 'int'},
{name: 'VndActNb', type: 'string'},
{name: 'InvoiceID', type: 'int'},
{name: 'VInvNb', type: 'string'},
{name: 'VInvRcptDt', type: 'date', dateFormat: 'Y-m-d' },
{name: 'InvDate', type: 'date', dateFormat: 'Y-m-d' },
{name: 'CodeSpecifier', type: 'string'},
{name: 'Recurrence', type: 'string'},
{name: 'ClientID', type: 'int'},
{name: 'ClientName', type: 'string'},
{name: 'LocID', type: 'int'},
{name: 'LocName', type: 'string'},
{name: 'RecentLocStatus', type: 'string'},
{name: 'RecentLocStatusDate', type: 'date', dateFormat: 'Y-m-d' },
{name: 'UnexpCost', type: 'float'},
{name: 'ConfirmedAmt', type: 'float'},
{name: 'StaffID', type: 'int'},
{name: 'NetworkID', type: 'string'},
{name: 'UnexpStatCode', type: 'string'}
],
proxy: {
type: 'ajax',
simpleSortMode: true,
api: {
read: '/internal/viewVERext_json.asp',
create: '/internal/viewVERext_create.asp',
update: '/internal/viewVERext_update.asp',
destroy: '/internal/viewVERext_destroy.asp'
},
reader: {
type: 'json',
totalProperty: 'total',
successProperty: 'success',
messageProperty: 'message',
root: 'data'
},
writer: {
type: 'json',
writeAllFields: false,
allowSingle: false,
root: 'data'
},
listeners: {
exception: function(proxy, response, operation){
Ext.MessageBox.show({
title: 'REMOTE EXCEPTION',
msg: operation.getError(),
icon: Ext.MessageBox.ERROR,
buttons: Ext.Msg.OK
});
}
}
}
});
var store = Ext.create('Ext.data.Store', {
model: 'VendorError',
autoLoad: true,
autoSync: true,
pageSize: 20,
remoteSort: true,
listeners: {
// write: function(proxy, operation){
// if (operation.action == 'destroy') {
// main.child('#form').setActiveRecord(null);
// }
// Ext.example.msg(operation.action, operation.resultSet.message);
// }
datachanged: function() {
var report = "";
store.each(
function(rec) {
report = report + rec.dirty + '/';
}
)
alert(report);
}
}
});
// create the Grid
var grid = Ext.create('Ext.grid.Panel', {
store: store,
//stateful: true,
//stateId: 'stateGrid',
columns: [
{ text : 'Vendor',
dataIndex: 'VendorName',
flex : 1
},
{ text : 'Account',
dataIndex: 'VndActNb'
},
{ text : 'Invoice',
dataIndex: 'VInvNb'
},
{ text : 'Invoiced',
dataIndex: 'InvDate',
xtype : 'datecolumn',
align : 'center'
},
{ text : 'Receipted',
dataIndex: 'VInvRcptDt',
xtype : 'datecolumn',
align : 'center'
},
{ text : 'Description',
dataIndex: 'CodeSpecifier'
},
{ text : 'Client',
dataIndex: 'ClientName'
},
{ text : 'Location',
dataIndex: 'LocName'
},
{ text : 'LStatus',
dataIndex: 'RecentLocStatus',
align : 'center'
},
{ text : 'Credit',
dataIndex: 'UnexpCost',
tdCls : 'colyellow',
renderer : Ext.util.Format.usMoney,
align : 'right',
field : { xtype:'textfield', allowBlank:false }
},
{ text : 'Confirmed',
dataIndex: 'ConfirmedAmt',
tdCls : 'colyellow',
renderer : Ext.util.Format.usMoney,
align : 'right',
field : { xtype:'textfield', allowBlank:false }
},
{ text : 'Recurrence',
dataIndex: 'Recurrence',
tdCls : 'colyellow',
align : 'center',
field : {
xtype : 'combobox',
typeAhead: true,
triggerAction: 'all',
selectOnTab: true,
store: [
['once','once'],['1st','1st'],['2nd+','2nd+']
],
lazyRender: true
}
},
{ text : 'CStatus',
dataIndex: 'UnexpStatCode',
tdCls : 'colyellow',
align : 'center',
field : {
xtype : 'combobox',
typeAhead: true,
triggerAction: 'all',
selectOnTab: true,
store: [
<%=cstat_grid%>
],
lazyRender: true
}
},
{ text : 'Owner',
dataIndex: 'NetworkID',
tdCls : 'colyellow',
field : {
xtype : 'combobox',
typeAhead: true,
triggerAction: 'all',
selectOnTab: true,
store: [
<%=staff_grid%>
],
lazyRender: true
}
}
],
layout: 'fit',
height: 500,
renderTo: 'theGrid',
selType: 'cellmodel',
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
})
],
dockedItems: [
{ xtype: 'pagingtoolbar',
store: store,
dock: 'bottom',
displayInfo: true
},
{ xtype: 'toolbar',
dock: 'top',
items: [
{ xtype:'button',
text: 'IsDirty()',
handler: function() {
var report = "";
store.each(
function(rec) {
report = report + rec.dirty + '/';
}
)
alert(report);
}
}
]
}
],
viewConfig: {
stripeRows: true
}
});
Ext.EventManager.onWindowResize(grid.doLayout, grid);
});
Turns out the issue is that records added into the grid are detected as "not new" by the value of a unique id field. A kind poster on the Sencha forums pointed me to this.
By default, this field in the model is expected to have a name of 'id'. So, you must either provide a model with a field of 'id', which my model above did not have, or you must override the default column by using the idProperty property of Ext.data.Model. I simply renamed the UnexpSrvId column to id. And, lo and behold, we send updates to update() instead of create().
This is not obvious from the API docs, as many things unfortunately are in this powerful framework.
Because your grid is using the CellEdit mixin you can add a listener to the grid which will commit the changes to your record after editing. So in your grid, add the listeners config option defined as follows...
listeners: {
edit : function(e) {
e.record.commit();
}
}
EDIT: I think you're using the wrong syntax on your proxy... you can only define a reader and writer (by the looks of things)...
Ed Spencer's article on Proxies
ExtJS 4 API Entry on Proxies