So, I'm having problem with adding a simple toolbar with buttons to my grid. At first I create a grid like this:
Ext.define('MyApp.view.user.List', {
extend: 'Ext.grid.Panel',
alias: 'widget.userlist',
title: 'All Users',
store: 'Users',
initComponent: function() {
this.columns = [
{header: 'login', dataIndex: 'login', flex: 1},
{header: 'password', dataIndex: 'password', flex: 1},
{header: 'name', dataIndex: 'name', flex: 1},
{header: 'email', dataIndex: 'email', flex: 1},
{header: 'phone', dataIndex: 'phone', flex: 1}
];
this.callParent(arguments);
}
});
It works fine, I got my grid. But now I need to add toolbar with buttons on it, which will do CRUD operations with grid entries. So I added this piece of code:
...
store: 'Users',
items: [{
xtype: 'toolbar',
items: [{
text: 'Добавить',
action: 'create'
},
{
text: 'Редактировать',
action: 'update'
},
{
text: 'Удалить',
action: 'destroy'
}
]
}
],
...
But that doesn't seem to change anything at all. I still can see only plain grid in my browser, so question is what am I doing wrong?
The whole code of this View now looks like that:
Ext.define('MyApp.view.user.List', {
extend: 'Ext.grid.Panel',
alias: 'widget.userlist',
title: 'All Users',
store: 'Users',
items: [{
xtype: 'toolbar',
items: [{
text: 'Добавить',
action: 'create'
},
{
text: 'Редактировать',
action: 'update'
},
{
text: 'Удалить',
action: 'destroy'
}
]
}
],
initComponent: function() {
this.columns = [
{header: 'login', dataIndex: 'login', flex: 1},
{header: 'password', dataIndex: 'password', flex: 1},
{header: 'name', dataIndex: 'name', flex: 1},
{header: 'email', dataIndex: 'email', flex: 1},
{header: 'phone', dataIndex: 'phone', flex: 1}
];
this.callParent(arguments);
}
});
What do I need to change/add to get it working?
You need to specify the toolbar configuration inside initComponent only. See the following.
this.dockedItems = [{
xtype: 'toolbar',
dock: 'top',
items: [{
text: 'Добавить',
action: 'create'
}, {
text: 'Редактировать',
action: 'update'
}, {
text: 'Удалить',
action: 'destroy'
}]
}
];
See if this can help you.
Change your definition:
Ext.define('MyApp.view.user.List', {
extend: 'Ext.grid.Panel',
alias: 'widget.userlist',
title: 'All Users',
store: 'Users',
tbar: [{
text: 'Добавить',
action: 'create'
}]
// .....
});
Better way to structure your component:
Ext.define('MyApp.view.user.List', {
extend: 'Ext.grid.Panel',
alias: 'widget.userlist',
title: 'All Users',
initComponent: function () {
var me = this;
var store = Ext.storeMgr.lookup('Users');
Ext.applyIf(me, {
store: store,
columns: [
{header: 'login', dataIndex: 'login', flex: 1},
{header: 'password', dataIndex: 'password', flex: 1},
{header: 'name', dataIndex: 'name', flex: 1},
{header: 'email', dataIndex: 'email', flex: 1},
{header: 'phone', dataIndex: 'phone', flex: 1}
],
dockedItems: [{
xtype: 'tbar',
dock: 'top',
items: [
{
text: 'Добавить',
action: 'create'
},
{
text: 'Редактировать',
action: 'update'
},
{
text: 'Удалить',
action: 'destroy'
}]
}]
});
me.callParent(arguments);
// could be something like this to load the store
me.on('afterrender', function() {
me.getStore().loadPage(1);
} , me);
}
});
Related
Here's an EXTJS rowexpander implementation
http://jsfiddle.net/Litote0707/xPpf2/
When you expand it, you can see the price.
Instead of price, can I show another custom grid something like this?
Ext.define('my.app.main.CustomList', {
extend: 'Ext.grid.Panel',
title: 'List in Rowexpander',
store: Ext.data.StoreManager.lookup('myStore'),
columns: [
{ text: 'Name', dataIndex: 'name' },
{ text: 'Email', dataIndex: 'email', flex: 1 },
{ text: 'Phone', dataIndex: 'phone' }
],
height: 200,
width: 400
});
Hello I've problem to selected by value. And the data is from viewmodel. I also search the answer on google but I not found. I am very confusing about it. Please help me.
This is my form:
Ext.define('Sipen.view.items.ItemsForm', {
extend: 'Ext.window.Window',
xtype: 'items-form',
height: 250,
width: 500,
layout: { type: 'fit' },
bind: {title: '{title}'},
modal: true,
items: [
{
xtype: 'form',
reference: 'form',
bodyPadding: 20,
flex: 1,
modelValidation: true,
layout: {
type: 'hbox',
align: 'stretch'
},
items: [
{
xtype: 'fieldcontainer',
flex: 1,
title: 'Item Information',
layout: 'anchor',
defaults: {
anchor: '100%',
xtype: 'textfield',
msgTarget: 'under',
labelWidht: 100,
allowBlank: false
},
items: [
{
xtype: 'hiddenfield',
name: '_id',
bind: '{currentTipe._id}'
},
{
fieldLabel: 'Code',
name: 'item_code',
bind: '{currentItem.item_code}'
},
{
fieldLabel: 'Name',
name: 'item_name',
bind: '{currentItem.item_name}'
},
{
xtype: 'numberfield',
minValue: 1,
fieldLabel: 'Price',
name: 'item_price',
bind: '{currentItem.item_price}'
},
{
xtype: 'combo',
name: 'type',
fieldLabel: 'Type',
valueField: 'type_name',
displayField: 'type_name',
queryMode: 'local',
forceSelection: true,
submitValue: true,
bind: {
value: '{typeItems.type_name}',
store: '{typeItems}',
selection: '{currentItem.type_name}'
}
}
]
}
],
dockedItems: [
{
xtype: 'toolbar',
dock: 'bottom',
ui: 'footer',
layout: {
pack: 'end',
type: 'hbox'
},
items: [
{
xtype: 'button',
text: 'Save',
formBind: true,
listeners: {
click: 'onSave'
}
},
{
xtype: 'button',
text: 'Cancel',
listeners: {
click: 'onCancel'
}
}
]
}
]
}
]
});
Look at xtype 'combo' and I selection data by {currentItem.type_name} and the data is right, but I get error
this Uncaught TypeError: item.getId is not a function.
And this is my view model:
Ext.define('Sipen.view.items.ItemsModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.items-items',
requires: [ 'Sipen.model.Items' ],
stores: {
items: {
model: 'Items',
autoLoad: true
},
typeItems: {
model: 'TypeItems',
autoLoad: true
}
}
});
Sorry for my bad english, but please help me...
============[Fixed]======================
I've found the result in here https://www.sencha.com/forum/showthread.php?302067
So the script should be like this:
{
xtype: 'combo',
name: 'type',
fieldLabel: 'Type',
valueField: 'type_name',
displayField: 'type_name',
queryMode: 'local',
forceSelection: true,
submitValue: true,
bind: {
value: '{typeItems.type_name}',
store: '{typeItems}',
selection: '{currentItem.type_name}'
}
}
I have a button inside ExtJs toolbar as below
Ext.define('Member.view.members.MembersGrid', {
extend: 'Ext.grid.Panel',
alias: 'widget.membersGrid',
id: 'membersGrid',
cls: 'custom-grid',
requires: [],
viewConfig : {
enableTextSelection: true
},
frame: true,
store: '',
//id: 'transGrid',
height: 150,
columns: [
{
xtype: 'rownumberer'
},
{
hidden:true,
width: 10,
dataIndex: 'id',
text: 'id'
},
/*{
width: 100,
//flex: 1,
dataIndex: 'member_number',
text: 'Member Number'
},*/
{
width: 150,
flex: 1,
dataIndex: 'member_names',
text: 'Member Names'
}],
dockedItems: [
{
xtype: 'toolbar',
itemId: 'toptoolbar',
id:'toptoolbar',
flex: 1,
dock: 'top',
items: [
{
xtype: 'button',
text: 'Pin_Reset',
id: 'pinReset',
itemId: 'pinReset',
iconCls: 'pin_reset'
}
]
}
],
initComponent: function() {
Ext.getCmp('pinReset').hidden = true;
this.callParent();
}
});
I want the button to appear hidden after render. I thought Ext.getCmp('pinReset').hidden = true; will do since I have assigned the button an id. Getting the following error 'Cannot set property 'hidden' of undefined' on Chrome developer tools.
Extjs Version: 5.1
initComponent is called before the rendering.So it is not able to find the button.You can use 'afterrender' event instead for this.
Add following code instead of initComponent:
listeners:{
afterrender: function() {
Ext.getCmp('pinReset').hidden = true;
}
}
Working Code:
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.create('Ext.grid.Panel', {
alias: 'widget.membersGrid',
id: 'membersGrid',
cls: 'custom-grid',
renderTo:Ext.getBody(),
requires: [],
viewConfig : {
enableTextSelection: true
},
frame: true,
store: '',
//id: 'transGrid',
height: 150,
columns: [
{
xtype: 'rownumberer'
},
{
hidden:true,
width: 10,
dataIndex: 'id',
text: 'id'
},
/*{
width: 100,
//flex: 1,
dataIndex: 'member_number',
text: 'Member Number'
},*/
{
width: 150,
flex: 1,
dataIndex: 'member_names',
text: 'Member Names'
}],
dockedItems: [
{
xtype: 'toolbar',
itemId: 'toptoolbar',
id:'toptoolbar',
flex: 1,
dock: 'top',
items: [
{
xtype: 'button',
text: 'Pin_Reset',
id: 'pinReset',
itemId: 'pinReset',
iconCls: 'pin_reset'
}
]
}
],
listeners:{
afterrender: function() {
Ext.getCmp('pinReset').hidden = true;
}
}
});
}
});
<link rel="stylesheet" href="https://extjs.cachefly.net/ext-4.1.1-gpl/resources/css/ext-all.css">
<script type="text/javascript" src="https://extjs.cachefly.net/ext-4.1.1-gpl/ext-all-debug.js"></script>
You are using initComponent instead of afterRender in your codesnippet. Is that correct?
I would use the reference-property and use it like this:
items: [
{
xtype: 'button'
reference: 'myButton'
}
]
...
afterRender: function() {
this.lookupReference('myButton').setHidden(true);
this.callParent();
}
I have a grid panel and when the user selects the row and clicks the edit button or dbl clicks the row, I want to send the selected row to the new window. But I am having trouble in sending the data.
Here is my grid panel. (List.js)
Ext.define('MyApp.view.main.List', {
extend: 'Ext.grid.Panel',
xtype: 'mainlist',
require: [ 'MyApp.view.student.StudentForm' ],
title: 'Student Records',
scrollable: true,
margin: 20,
layout: {
type: 'vbox',
align: 'stretch'
},
reference: 'studentGrid',
frame: true,
collapsible: true,
store: 'StudentStore',
collapsible: true,
columns: [
{
text: 'Name',
dataIndex: 'name',
flex: 1
},
{
text: 'Address',
dataIndex: 'address',
flex: 1
},
{
text: 'Phone',
dataIndex: 'phone',
flex: 1
},
{
text: 'Email',
dataIndex: 'email',
flex: 1
},
{
text: 'Faculty',
dataIndex:'faculty',
flex: 1
}
],
dockedItems: [
{
xtype: 'toolbar',
dock: 'top',
items: [
{
xtype: 'button',
text: 'Add',
iconCls: 'fa fa-plus',
listeners: {
click: 'onAdd'
}
},
{
xtype: 'button',
text: 'Edit',
iconCls: 'fa fa-edit',
id: 'editButton',
listeners: {
click: 'onEdit'
}
},
{
xtype: 'button',
text: 'Delete',
iconCls: 'fa fa-trash-o',
bind: {
disabled: '{ !mainlist.selection }'
},
listeners: {
click: 'onDelete'
}
}]
}
],
// toolbar for our store filter field
tbar: [{
xtype: 'textfield',
fieldLabel: 'Search Student',
emptyText: '...type to filter',
width: 300,
listeners: {
change: 'onSearch'
},
triggers: {
clear: {
cls: 'x-form-clear-trigger',
handler: function(){
this.reset();
}
}
}
}]
});
And this my Controller (MainController.js)
createDialog: function(record)
{
if (record)
{
var form = Ext.create('MyApp.view.student.StudentForm');
form.loadRecord(record);
form.show();
}
Ext.create('MyApp.view.student.StudentForm').show();
},
onEdit: function(button, e, options){
var row = button.up('mainlist').getSelection();
debugger;
this.createDialog(row[0]);
},
And here is the pop up window where the data has to be loaded(StudentForm.js)
Ext.define('MyApp.view.student.StudentForm', {
extend: 'Ext.window.Window',
xtype: 'student-form',
height: 400,
width: 500,
layout: {
type: 'fit'
},
reference: 'form',
title: 'Add Student',
closable: true,
modal: true,
items: [{
xtype: 'form',
id : 'formId',
bodyPadding: 5,
modelValidation : true,
layout: {
type: 'vbox',
align: 'stretch'
},
items: [{
xtype: 'fieldset',
flex: 1,
title: 'Student Information',
layout: 'anchor',
defaultType: 'textfield',
defaults: {
anchor: '100%',
msgTarget: 'side'
},
items: [
{
xtype: 'hiddenfield',
name: 'id',
fieldLabel: 'Label'
},
{
fieldLabel: 'Name',
name: 'name'
},
{
fieldLabel: 'Address',
name: 'address'
},
{
fieldLabel: 'Phone',
name: 'phone'
},
{
fieldLabel: 'Email',
name: 'email'
},
{
xtype: 'combo',
fieldLabel: 'Faculty',
name: 'facultyName',
queryMode: 'local',
displayField: 'facultyName',
valueField: 'facultyName',
store: {
fields: ['facultyName'],
data: [{
facultyName: 'computing'
}, {
facultyName: 'multimedia'
}, {
facultyName: 'networking'
}]
}
}
]
}],
dockedItems: [
{
xtype: 'toolbar',
dock: 'bottom',
layout: {
pack: 'end',
type: 'hbox'
},
items: [
{
xtype: 'button',
text: 'Save',
iconCls: 'fa fa-check',
listeners: {
click: 'onSave'
}
},
{
xtype: 'button',
text: 'Cancel',
iconCls: 'fa fa-times',
listeners: {
click: 'onCancel'
}
}
]
}]
}]
});
What am I missing here?Any suggestions?
It says loadRecord() is not a function
Your MyApp.view.student.StudentForm is not actually a form. It is a window, hence there is no loadRecord method.
Instead of form.loadRecord(record); call form.down('form').loadRecord(record).
Remember, it is worth naming things what they are.
Main view file
Ext.define('DemoApp1.view.Main', {
extend: 'Ext.tab.Panel',
xtype: 'main',
requires: [
'Ext.form.FieldSet',
'Ext.field.Text',
'Ext.field.Email',
'Ext.field.Password',
'Ext.field.DatePicker',
'Ext.TitleBar',
'Ext.Button'
],
config: {
tabBarPosition: 'bottom',
items: [
{
xtype: 'container',
title: 'Login',
autoDestroy: false,
layout: {
type: 'vbox',
pack: 'center',
align: 'center'
},
iconCls: 'user',
items: [
// login user
{
xtype: 'fieldset',
id: 'login-user-field-set',
width: 500,
title: 'Login Here!',
items: [
{
xtype: 'emailfield',
label: 'Email',
name: 'user'
},
{
xtype: 'passwordfield',
label: 'Password',
name: 'password'
}
]
},
{
xtype: 'button',
id: 'login-button',
text: 'Login',
ui: 'confirm',
width: 150
}
]
},
{
autoDestroy: false,
xtype: 'container',
title: 'Register',
layout: 'vbox',
scrollable: true,
iconCls: 'add',
items: [
{
xtype: 'titlebar',
title: 'Register New User',
docked: 'top'
},
{
// register new user
xtype: 'fieldset',
id: 'reg-items-field-set',
items: [
{
xtype: 'textfield',
label: 'Email',
allowBlank: false,
name: 'reg_user'
},
{
xtype: 'passwordfield',
label: 'Password',
name: 'reg_password'
},
{
xtype: 'passwordfield',
label: 'Confirm Password',
name: 'reg_cpassword'
},
{
xtype: 'textfield',
label: 'User Name',
name: 'reg_user_name'
},
{
xtype: 'datepickerfield',
picker: {
yearFrom: 1975,
yearTo: 2005
},
label: 'DOB',
name: 'reg_dob'
},
{
xtype: 'selectfield',
label: 'Gender',
name: 'reg_gender',
options: [
{text: 'Male', value: 'male'},
{text: 'Female', value: 'female'}
]
}
]
},
{
xtype: 'container',
layout: {
type: 'hbox',
align: 'center',
pack: 'center'
},
items: [
{
xtype: 'button',
id: 'register-button',
text: 'Register',
ui: 'confirm',
width: 200
},
{
xtype: 'spacer',
width: 50
},
{
xtype: 'button',
id: 'reset-button',
text: 'Reset',
ui: 'decline',
width: 200
}
]
}
]
}
]
}
});
Controller file
Ext.define('DemoApp1.controller.MainController', {
extend: 'Ext.app.Controller',
requires: [
'Ext.form.FieldSet',
'Ext.Button'
],
config: {
refs: {
loginButton: '#login-button',
regFieldSet: '#reg-items-field-set',
regNewUserButton: '#register-button',
regFormResetButton: '#reset-button',
loginUserFieldSet: '#login-user-field-set'
},
control: {
loginButton: {
tap: 'loginButtonTapped'
},
regFormResetButton: {
tap: 'regFormResetButtonTapped'
},
regNewUserButton: {
tap: 'regNewUserButtonTapped'
}
},
loginButtonTapped: function(self, e) {
console.log('loginButtonTapped');
},
regFormResetButtonTapped: function(self, e) {
console.log('regFormResetButtonTapped');
},
regNewUserButtonTapped: function(self, e) {
console.log('regNewUserButtonTapped');
}
}
});
on click on any button it logging the below
Uncaught TypeError: Cannot read property 'apply' of undefined
what wrong in it???
thanks in advance...
Your methods should not go in the config block. loginButtonTapped, regFormResetButtonTapped and regNewUserButtonTapped. They should come out one level into the class definition, because they are class methods, not configurations.