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/
Related
I am trying to find the best way to bind items to a textfield in my extjs project. I downloaded the data into a store with one record in the controller. How would I bind to this textfield from the one record? I would preferably bind in the view, not in the controller
You should read this guide to understand better what binding is
The best solution for you is bind the record on the viewmodel of the view, so:
textfield.setBind({
value:'{myRec.valueToRefer}'
})
viewmodel.set('myRec',record.getData());
If you want, you can also use a form to handle this, using form.loadRecord and giving to the textfield a name..
A tip:
set inside the viewmodel a value to null:
data:{
myRec:null
}
Set your record in the viewmodel after setting the bind to the textfield.
Other tip:
If you can, avoid using setBind and prefer to set the binding directly on textfield creation:
//WILL WORK BUT YOU CAN AVOID IT
textfield.setBind({
value:'{myRec.valueToBind}'
})
//YES
var textfield=Ext.create({
xtype:'textfield',
bind:{
value:'{myRec.valueToBind}'
}
});
Refer to Sencha documentation also
You can use bind config to bind the data or any other config for ExtJS component.
Bind setting this config option adds or removes data bindings for other configs.
For example, to bind the title config:
var panel = Ext.create({
xtype: 'panel',
bind: {
title: 'Hello {user.name}'
}
});
To dynamically add bindings:
panel.setBind({
title: 'Greetings {user.name}!'
});
To remove bindings:
panel.setBind({
title: null
});
In this FIDDLE, I have created a demo for biding. I hope this will help/guide you to achieve you requirement.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
//defining Store
Ext.define('Store', {
extend: 'Ext.data.Store',
alias: 'store.gridstore',
autoLoad: true,
fields: ['name', 'email', 'phone'],
proxy: {
type: 'ajax',
url: 'data1.json',
reader: {
type: 'json',
rootProperty: ''
}
}
});
//defining view model
Ext.define('MyViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.myvm',
data: {
formdata: null
},
stores: {
gridstore: {
type: 'gridstore'
}
}
});
//Controller
Ext.define('MyViewController', {
extend: 'Ext.app.ViewController',
alias: 'controller.myview',
onGridItemClick: function (grid, record) {
//Bind the form data for CLICKED record
this.getViewModel().set('formdata', record)
}
});
//creating panel with GRID and FORM
Ext.create({
xtype: 'panel',
controller: 'myview',
title: 'Binding Example',
renderTo: Ext.getBody(),
viewModel: {
type: 'myvm'
},
layout: 'vbox',
items: [{
xtype: 'grid',
flex: 1,
width: '100%',
bind: '{gridstore}',
columns: [{
text: 'Name',
dataIndex: 'name'
}, {
text: 'Email',
dataIndex: 'email',
flex: 1
}, {
text: 'Phone',
dataIndex: 'phone'
}],
listeners: {
itemclick: 'onGridItemClick'
}
}, {
xtype: 'form',
flex: 1,
width: '100%',
defaults: {
anchor: '100%'
},
title: 'Bind this form on Grid item Click',
bodyPadding:15,
margin: '20 0 0 0',
// The fields
defaultType: 'textfield',
items: [{
fieldLabel: 'Name',
name: 'first',
allowBlank: false,
bind: '{formdata.name}'
}, {
fieldLabel: 'Email',
name: 'email',
allowBlank: false,
bind: '{formdata.email}'
}, {
fieldLabel: 'Phone',
name: 'phone',
allowBlank: false,
bind: '{formdata.phone}'
}]
}]
});
}
});
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']
I have a problem with ExtJS modern toolkit's Form component.
I create a form with no buttons (you can test it in sencha fiddle). The only button is in the titlebar and it isn't working at the moment.
The problem is :
Form submission on pressing Enter. My form is empty, default method is POST, but my page is reloading when I press Enter while the focus is on any of my fields. Url address string in browser complemented form field names, but the form's method is POST.
Ext.create('Ext.form.Panel', {
renderTo: Ext.getBody(),
requires: [
'Ext.form.FieldSet',
'Ext.field.Text',
'Ext.field.TextArea',
'Ext.TitleBar'
],
items: [{
xtype: 'titlebar',
docked: 'top',
title: 'Searching',
items: [{
iconCls: 'fa fa-search',
iconAlign: 'right',
text: 'Search',
align: 'right',
handler: function() {
//
}
}]
}, {
xtype: 'fieldset',
border: false,
shadow: 'true',
defaults: {
value: ''
},
items: [{
xtype: 'numberfield',
label: 'Some ID',
allowBlank: true,
name: 'id'
},
{
xtype: 'textfield',
label: 'Some Article',
name: 'article'
}
]
}]
});
How to prevent page reloading?
I've never seen this behaviour in ExtJS form's by default.
Just replace id with something else could be Id in field name, it is conflicting with Ext id property
{
xtype: 'numberfield',
label: 'Some ID',
allowBlank: true,
name: 'Id'
},
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
hi i just learning ext js few months, I want to create a GUI like http://loianegroner.com/wp-content/uploads/2012/05/extjs4-mvc-grid-binded-form-loiane.jpg . when an item is clicked will fill the form . any suggestion how to make it??
Update
This is my code, But Grid no bind to form when item click on grid, What is wrong?
Controller: Detail.js
Ext.define('UserApp.controller.Detail', {
extend: 'Ext.app.Controller',
stores: ['User'],
models: ['User'],
views: ['user.Detail','user.listDetail'],
refs: [{
ref: 'Detail',
selector: 'form'
}],
init: function() {
this.control({
'listDetail': {
selectionchange: this.gridSelectionChange,
viewready: this.onViewReady
}
});
},
gridSelectionChange: function(model, records) {
if (records[0]) {
console.log('clicked item');
this.getDetail().getForm().loadRecord(records[0]);
}
},
onViewReady: function(grid) {
grid.getSelectionModel().select(0);
}
});
Model:User.js
Ext.define('UserApp.model.User', {
extend: 'Ext.data.Model',
idProperty: 'userID',
fields: [
{name: 'userID', type: 'int'},
{name: 'name'},
{name: 'lastname'},
{name: 'age', type: 'int'},
]
});
View : Detail.js// form show data item click on grid
Ext.define('UserApp.view.user.Detail' ,{
extend: 'Ext.form.FieldSet',
alias : 'widget.Detail',
margin: '0 0 0 10',
title:'Company details',
defaults: {
width: 240,
labelWidth: 90
},
defaultType: 'textfield',
items: [{
fieldLabel: 'userID',
name: 'userID'
},{
fieldLabel: 'Nama',
name: 'name'
},{
fieldLabel: 'lastname',
name: 'lastname'
},{
fieldLabel: 'age',
name: 'age'
}]
});
View: listDetail.js// Show grid data
Ext.define('UserApp.view.user.listDetail' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.listDetail',
// id:'userID2',
store: 'User',
title : 'Users',
dockedItems: [{
xtype: 'pagingtoolbar',
store: 'User',
dock: 'bottom',
displayInfo: true
}],
initComponent: function() {
this.columns = [
{
header: 'ID',
dataIndex: 'userID',
flex: 1
},
{
header: 'Name',
dataIndex: 'name',
flex: 1
},
// {header: 'Last Name', dataIndex: 'lastname', flex: 1},
// {header: 'Age', dataIndex: 'age', flex: 1}
];
this.callParent(arguments);
}
});
Thisis straight out of Sencha docs. The first stop for you would be to gotrough this example and study it line by line:
http://docs.sencha.com/extjs/4.2.2/#!/example/grid/binding-with-classes.html
Then you can take a look at the exact code that rendered the image you included in your question:
http://docs.sencha.com/extjs/4.2.2/extjs-build/examples/build/KitchenSink/ext-theme-neptune/#form-grid