I have ExtJS application and I want to implement displaying total number of records in the header.
ViewModel:
Ext.define('AppName.view.main.MainModel', {
extend: 'Ext.app.ViewModel',
// ...
stores: {
users: Ext.create("AppName.store.UsersStore")
}
});
Binding to view
Ext.define('AppName.view.main.UsersPanel', {
extend: 'Ext.panel.Panel',
// ...
items:[{
bind : {
title : 'Users ({users.data.length})'
},
items: [{
listeners : {
cellclick : 'OnSelectUser'
},
xtype: 'grid', columns: [
{ text: 'Full Name', dataIndex: 'fullName', flex: 2},
{ text: 'Address', dataIndex: 'address', flex: 1},
{ text: 'Sex', dataIndex: 'sex', flex: 1},
{ text: 'Date Of Birth', dataIndex: 'dob', flex: 1}
],
bind: '{users}'
}]
}]
});
And this works after first loading of records to Store by code
OnSearchButtonClick: function () {
var me = this,
usersStore = me.getViewModel().get('users');
usersStore.load();
}
But when I remove records from store by code
var me = this,
usersStore = me.getViewModel().get('users');
usersStore.loadData([], false);
or by
usersStore.removeAll()
then only table is cleared but not header.
So I have a question: how can I bind store size?
try with sync on the store after removing records.
usersStore.removeAll();
usersStore.sync();
sometimes binding not refresh binded components because new or removed records are not synched in the store
Related
friends!
I have a grid, with a widget column. I get the data for the store from the server.
I get different templates for each row and try to set these templates in my widget. However, I am not able to display the data in the templates.
Here is my example fiddle https://fiddle.sencha.com/#fiddle/3j41&view/editor
I expect the second column to display data with different templates. Instead of data I see {testName}.
In the third column everything works, but it's static data
Can you help me understand what's wrong?
My result:
My store:
var store = Ext.create('Ext.data.Store', {
fields: ['name', 'tplConfig'],
data: [{
name: 'Test 1',
tplConfig: {
tplBody: '<div><b>Name:</b> {testName}</div> <div>any text</div>',
tplData: {
testName: 'Alex'
}
}
} ]
});
My grid:
{
xtype: 'grid',
title: 'Widget Column Demo',
store: store,
columns: [
.....
{
xtype: 'widgetcolumn',
text: 'Dynamic',
width: 120,
dataIndex: 'tplConfig',
widget: {
xtype: 'component',
tpl: '{tplBody}',
//data: '{tplData}' //it's not working
}
}
.......
]
}
You can use renderer:
{
xtype: 'gridcolumn',
text: 'Dynamic',
width: 120,
dataIndex: 'tplConfig',
renderer: function(tplConfig) {
var t = new Ext.Template(tplConfig.tplBody);
return t.apply(tplConfig.tplData);
}
}
or as a 1 liner:
return new Ext.Template(tplConfig.tplBody).apply(tplConfig.tplData);
To binding between a grid and a form I use something like:
viewModel: {
type: 'viewermodel'
},
items: [{
xtype: 'grid',
title: 'Grid: click on the grid rows',
itemId:'myGridItemId',
flex: 1.2,
margin: '0 10 0 0',
bind:{
store:'{mystore}',
selection:'{users}'
},
columns: [
{ text: 'Name', dataIndex: 'name', flex:0.5 },
{ text: 'Email', dataIndex: 'email', flex: 1 },
{ text: 'Cars', dataIndex: 'cars', flex: 1 }
]
},
FIDDLE: https://fiddle.sencha.com/#fiddle/1is6&view/editor
Problem: the store is not in a viewmodel but in the store's app folder (App.store.MyStore).
Is there any way, in this case, of binding selection: '{users}' from record grid to form fields? Something like:
store:'MyStore',
bind:{
selection:'{users}'
},
You need to add MyStore to your application's store config.
Here's the updated fiddle. You'll see in Ext.application I've added stores: ['MyStore']
Ext.define('MyApp.view.MyVehicleGridPanel', {
extend: 'Ext.grid.Panel',
alias: 'widget.mygrid',
header: false,
store: UserStore,
multiSelect: false,
columns: [
{
xtype: 'gridcolumn',
dataIndex: '_id',
text: 'Vehicle ID'
},
{
xtype: 'gridcolumn',
width: 126,
dataIndex: 'Plat_No',
text: 'Plat Number'
},
{
xtype: 'gridcolumn',
width: 200,
dataIndex: 'Name',
text: 'Added By'
}
]
})
i dont have any id declare in the gridpanel, because it will used in dynamicly,
so, i m using alias to find my grid component like below code
var grid = Ext.ComponentQuery.query('mygrid');
console.log( Ext.ComponentQuery.query('mygrid') );
if (grid.getSelectionModel().hasSelection()) { //error at here
var row = grid.getSelectionModel().getSelection()[0];
console.log(row.get('Plat_No'));
};
But, firebug return error with TypeError: grid.getSelectionModel is not a function
any other way to find my gridpanel component?
Ext.ComponentQuery.query() returns an array of matched Components from within the passed root object.
So if you have only one mygrid component in your application, you can get your grid like this:
var grid = Ext.ComponentQuery.query('mygrid')[0];
I am trying to bind a grid data to a form in extjs. when i click on a grid row, the details should be populated in form. Can i do that in a simple way without using MVC. I have wrote the below code. help me further. Thank you
// JavaScript Document
Ext.require('Ext.data.Store');
Ext.require('Ext.grid.Panel');
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [ 'id','name', 'email', 'phone' ]
});
Ext.onReady(function() {
var userStore = Ext.create('Ext.data.Store', {
model: 'User',
data: [
{ id: '1', name: 'srb', email: 'srb#gmail.com', phone: '555-111-1224' },
{ id: '2', name: 'srv', email: 'srv#gmail.com', phone: '555-222-1254' }
]
});
Ext.create('Ext.grid.Panel', {
renderTo: Ext.getBody(),
store: userStore,
width: 400,
title: 'All Users',
columns: [
{
text: 'Id',
dataIndex: 'id' ,
flex: 1
},
{
text: 'Name',
dataIndex: 'name',
flex: 2
},
{
text: 'Email Address',
flex: 3,
dataIndex: 'email',
},
{
text: 'Phone Number',
flex: 2,
dataIndex: 'phone'
}
],
listeners : {
itemclick: function(dv, record, item, index, e) {
var nm= record.get('name');
}
},
});
Ext.create('Ext.form.FieldSet',{
renderTo: Ext.getBody(),
margin: '0 0 0 10',
title:'User details',
defaults: {
width: 240,
labelWidth: 90
},
defaultType: 'textfield',
items: [{
fieldLabel: 'Id',
name: 'id'
},{
fieldLabel: 'Name',
name: 'name'
},{
fieldLabel: 'Email Id',
name: 'email'
},{
fieldLabel: 'Phone Number',
name: 'phone'
}]
});
});
Use Ext.form.Panel instead of Ext.form.FieldSet. Field set is more of a decorating container. The form panel provides support for loading / saving data from the form, etc.
Then you need a way to access your form panel in your click event. The absolute simplest is to set an id on the form, and use Ext.getCmp to get a ref to the form. Since you've already got the record there, you can just use the loadRecord method of the form panel.
And you'll be done! Be happy to have named your model & form fields the same ;)
The final call in the event listener will look like this:
Ext.getCmp('myForm').loadRecord(record);
what version of extjs are you using?
you don't seem to have a form defined or instantiated.
in your grid's itemclick event handler, you need to get a reference to the form, and call form.loadRecord with the passed in record (2nd argument):
itemclick: function(dv, record, item, index, e) {
var form = getAReferenceToTheFormObject();
form.loadRecord(record);
}
example:
http://jsfiddle.net/4TSDu/74/
I'm trying to set values for the components in a form panel and below is my code.
Form Panel with grid:
Ext.define('MyApp.view.MyForm', {
extend: 'Ext.form.Panel',
height: 436,
width: 754,
layout: {
columns: 4,
type: 'table'
},
bodyPadding: 10,
title: 'My Form',
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [
{
xtype: 'displayfield',
colspan: 4,
fieldLabel: '',
value: 'Display Field'
},
{
xtype: 'displayfield',
colspan: 2,
margin: '0 50 0 0 ',
fieldLabel: 'Age',
labelAlign: 'top',
value: 'Display Field'
},
{
xtype: 'displayfield',
colspan: 2,
fieldLabel: 'Country',
labelAlign: 'top',
value: 'Display Field'
},
{
xtype: 'gridpanel',
colspan: 4,
header: false,
title: 'My Grid Panel',
store: 'MyJsonStore',
columns: [
{
xtype: 'gridcolumn',
dataIndex: 'DeptName',
text: 'Dept Name'
},
{
xtype: 'gridcolumn',
dataIndex: 'DeptId',
text: 'Dept ID'
}
]
}
]
});
me.callParent(arguments);
}
});
Models:
Ext.define('MyApp.model.EmpModel', {
extend: 'Ext.data.Model',
uses: [
'MyApp.model.DeptModel'
],
fields: [
{
name: 'Name'
},
{
name: 'Age'
},
{
name: 'Country'
},
{
name: 'Dept'
}
],
hasMany: {
associationKey: 'Dept',
model: 'MyApp.model.DeptModel'
}
});
Ext.define('MyApp.model.DeptModel', {
extend: 'Ext.data.Model',
uses: [
'MyApp.model.EmpModel'
],
fields: [
{
name: 'DeptName'
},
{
name: 'DeptId'
}
],
belongsTo: {
associationKey: 'Dept',
model: 'MyApp.model.EmpModel'
}
});
Store:
Ext.define('MyApp.store.MyJsonStore', {
extend: 'Ext.data.Store',
requires: [
'MyApp.model.EmpModel'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
model: 'MyApp.model.EmpModel',
storeId: 'MyJsonStore',
data: {
EmpDet: [
{
EmpName: 'Kart',
Age: '29',
Dept: [
{
DeptName: 'Dev',
DeptId: '1000'
}
]
}
]
},
proxy: {
type: 'ajax',
url: 'data/empDet.json',
reader: {
type: 'json'
}
}
}, cfg)]);
}
});
Json data:
{
"EmpDet": [
{
"EmpName": "Kart",
"Age": "29",
"Dept": [
{
"DeptName": "Dev",
"DeptId": "1000"
}
]
}
]
}
Questions:
1) I had left the value of the component as "Display Field" itself because if I remove this value the width of the grid below decreases. I feel this is because of the table layout and colspans. Is there any other best way to display labels without any alignment change on value load.
2) I'm trying to set the value for the display field. I tried to do it with the afterrender event but the problem is that it throws a undefined error at Ext.getStore('MyJsonStore').getAt(0). I found that this works fine if I write the same in the click event of a button. So, I feel that the store is not loaded when I try the afterrender event of the displayfield (autoload for store is set to true). Is there an alternative for afterrender event of a component. Also, Is there a way to set all the field values at a stretch instead of setting every component one by one?
3) Also I find it difficult to do the association properly. I'm using Sencha Architect 2.2 and when I go the data index of the grid, I'm not able to get the "DeptName" and "DeptId" in the dropdown.
Please help.
For the question number 2, I want to suggest the below way. I hope it works for you.
My solution:
You can set the display fields values when the store is loaded. So you can use load event of store as below:
yourStoe.on('load',function()
{
//set display field values here
});