PDA

View Full Version : How-to create a complete application with Ext-js



Michelangelo
19 Jun 2008, 10:24 AM
Hi all,

I'm new of Extjs. Fantastic web solution.
I have to create a big application and I don't know how to start.

Questions:
1. How can I communicate between object? :-/ how can I get the record passed from the Application.UsersGrid.js to Application.UsersWindow.js and show the data in the form? :-/
2. How can add a toolbar in the Application.UsersWindow.js ? :-/
3. The documentation have no sample inside every method/event/property, is there a place where I can get these information? The tutorials are little application that doesn't use the namespace system.
4. How can I see an example with all the features of the Ext.data.JsonStore ?

The way I started:

I have create 4 files .js


Application.Main.js
Application.Categories.js
Application.UsersGrid.js
Application.UsersWindow.js



Application.Main.js


Ext.namespace('Application');


Ext.BLANK_IMAGE_URL = './ext/resources/images/default/s.gif';
Ext.ns('Application');

// application main entry point
Ext.onReady(function() {

Ext.QuickTips.init();

// code here
var viewport = new Ext.Viewport({
layout:'border',
items:[{
region:'north',
height:28,
items: new Ext.Panel(
{tbar :
[{text: 'Logout'}]
})
},{
region:'center',
layout:'fit',
items: {xtype:'usersgrid'}
},{
region: 'west',
collapsible: true,
title: 'Job Categories',
items: {xtype:'categories'},
width: 300,
autoScroll: true,
split: true
},{
region:'east',
title:'Information',
width:200,
split:true,
collapsible:true
},{
region:'south',
title:'Actions',
height:200,
split:true,
collapsible:true,
collapsed:true

}]
});

}); // eo function onReady
// eof


Application.Categories.js


Ext.namespace("Application");

Ext.extend(
Application.Categories = function(config){
Application.Categories.superclass.constructor.call(this,config);
},

Ext.tree.TreePanel,

{
border:false,
initComponent:function() {
Ext.apply(this, {
loader: new Ext.tree.TreeLoader({
dataUrl:'php/get_categories.php'
}),
root: new Ext.tree.AsyncTreeNode({
expanded: true
}),
rootVisible: false,
listeners: {
click: function(n) {
Ext.Msg.alert('Navigation Tree Click', 'You clicked: "' + n.attributes.text + '"');
}
}
});

this.on('click', function(value){
alert(value);
});


Application.Categories.superclass.initComponent.apply(this, arguments);
} // eo function initComponent

,onRender:function() {

Application.Categories.superclass.onRender.apply(this, arguments);
} // eo function onRender
});

Ext.reg('categories', Application.Categories);


Application.UsersGrid.js


Ext.namespace("Application");

Ext.extend(
Application.UsersGrid = function(config){
Application.UsersGrid.superclass.constructor.call(this,config);
},

Ext.grid.GridPanel,

{
border:false,
initComponent:function() {
this.store = new Ext.data.JsonStore({
url: 'php/get.php',
root: 'records',
totalProperty: 'totalCount',
fields: [
{name:'idpersonal_data', type:'int'},
{name:'public', type:'int'},
{name:'name', type:'string'},
{name:'surname', type:'string'},
{name:'registration_date', type:'date', dateFormat: 'Y-m-d H:i:s'},
{name:'email', type:'string'},
{name:'pac', type:'string'},
{name:'idtongues', type:'int'},
{name:'WE', type:'int'},
{name:'ET', type:'int'},
{name:'OL', type:'int'},
{name:'CS', type:'int'},
{name:'CL', type:'int'},
{name:'CN', type:'int'},
{name:'RF', type:'int'},
{name:'element_translated', type:'int'},
{name:'language_name', type:'string'}
]
});

Ext.apply(this, {
trackMouseOver:false,
autoExpandColumn: 'name',
loadMask: {msg:'Wait a moment, please ...'},

cm: new Ext.grid.ColumnModel([
{header: 'ID', dataIndex: 'idpersonal_data', width: 10, sortable: true},
{header: 'Translator', dataIndex: 'language_name', width: 20, sortable: true},
{header: 'Mode', dataIndex: 'public', width: 15, sortable: true, renderer: function(value) { return (value == 1) ? "Public" : "Private"}},
{header: 'Language', dataIndex: 'idtongues', width: 10, sortable: true, renderer: function(value) { return "<img src=\"images/flags/" + value + ".gif\">";}},
{header: 'First Name', dataIndex: 'name', width: 60, sortable: true},
{header: 'Last Name', dataIndex: 'surname', width: 80, sortable: true},
{header: 'Registration Date', dataIndex: 'registration_date', width: 40, sortable: true, hidden: false, renderer: Ext.util.Format.dateRenderer('d/m/Y H:i:s')},
{header: 'P.A.C.', dataIndex: 'pac', width: 50, renderer: function(value){ return "<a href=\"http://" + value + ".eurocv.eu\" target=\"_blank\">" + value + "</a>"}, hidden: false},
{header: 'Email Address', dataIndex: 'email', width: 80, hidden: false},
{header: 'WE', dataIndex: 'WE', width: 10},
{header: 'ET', dataIndex: 'ET', width: 10},
{header: 'OL', dataIndex: 'OL', width: 10},
{header: 'CS', dataIndex: 'CS', width: 10},
{header: 'CN', dataIndex: 'CN', width: 10},
{header: 'CL', dataIndex: 'CL', width: 10},
{header: 'RF', dataIndex: 'RF', width: 10}
]),

iconCls:'icon-grid',
sm: new Ext.grid.RowSelectionModel({singleSelect:true}),
viewConfig: {
forceFit:true
},

bbar: new Ext.PagingToolbar({
pageSize: 25,
store: this.store,
displayInfo: true,
displayMsg: 'Displaying items {0} - {1} of {2}',
emptyMsg: "No items to display"

})
});

this.on('rowdblclick', function(grid, rowIndex, e){
var record = grid.getStore().getAt(rowIndex);
var userw = new Application.UsersWindow(record);
userw.show();
});

Application.UsersGrid.superclass.initComponent.apply(this, arguments);
} // eo function initComponent

,onRender:function() {
this.store.load({params:{start:0, limit:25}});

Application.UsersGrid.superclass.onRender.apply(this, arguments);
} // eo function onRender
}
);

Ext.reg('usersgrid', Application.UsersGrid);


Application.UsersWindow.js


Ext.namespace("Application");

Ext.extend(
Application.UsersWindow = function(config){
Application.UsersWindow.superclass.constructor.call(this,config);
},

Ext.Window,

{
border:false
,initComponent:function() {

Ext.apply(this, {

labelWidth: 75, // label settings here cascade unless overridden
url:'save-form.php',
title: 'Simple Form',
waitMsgTarget: true,
bodyStyle:'padding:5px',
autoHeight: true,
width: 600,
modal:true,
items: [{
layout:'column',
border:false,
items:[{
columnWidth:.5,
layout: 'form',
border:false,
items: [{
xtype:'textfield',
fieldLabel: 'First Name',s
name: 'name',
anchor:'95%'
}, {
xtype:'textfield',
fieldLabel: 'Last Name',
name: 'surname',
anchor:'95%'
}]
},{
columnWidth:.5,
layout: 'form',
border:false,
items: [{
xtype:'textfield',
fieldLabel: 'Email',
name: 'email',
anchor:'95%'
},{
xtype:'textfield',
fieldLabel: 'PAC',
name: 'pac',
vtype:'string',
anchor:'95%'
}]
}]
},{
xtype:'tabpanel',
plain:true,
activeTab: 0,
height:235,
defaults:{bodyStyle:'padding:10px'},
items:[{
title:'Personal Details',
layout:'form',
defaultType: 'textfield',

items: [{
fieldLabel: 'First Name',
name: 'first',
allowBlank:false,
value: 'Jack'
},{
fieldLabel: 'Last Name',
name: 'last',
value: 'Slocum'
},{
fieldLabel: 'Company',
name: 'company',
value: 'Ext JS'
}, {
fieldLabel: 'Email',
name: 'email',
vtype:'email'
}]
},{
title:'Phone Numbers',
layout:'form',
defaultType: 'textfield',

items: [{
fieldLabel: 'Home',
name: 'home',
value: '(888) 555-1212'
},{
fieldLabel: 'Business',
name: 'business'
},{
fieldLabel: 'Mobile',
name: 'mobile'
},{
fieldLabel: 'Fax',
name: 'fax'
}]
},{
cls:'x-plain',
title:'Biography',
layout:'fit',
items: {
xtype:'htmleditor',
id:'bio2',
fieldLabel:'Biography'
}
}]
}],



buttons:
[
{
text: "Chiudi",
handler: function()
{
this.close();
}
},
{
text: "OK"
}
]


});

Application.UsersWindow.superclass.initComponent.apply(this, arguments);
} // eo function initComponent

,onRender:function() {
this.loadRecord(config);
Application.UsersWindow.superclass.onRender.apply(this, arguments);
} // eo function onRender
}
);
Ext.reg('userswindow', Application.UsersWindow);

mjlecomte
19 Jun 2008, 3:12 PM
Not sure I understand.

You have grid.

You click or double click on grid.

You set up a listener for grid when you click on a row (you need to have row selection model in this case).

So you should end up inside the callback / listener once you have that set up.

Inside the callback I guess you would load the store. Prior to calling for store load you would re-set the url or baseParams or whatever as you need to. Perhaps the store loaded depends on the record from the grid you selected. So you'd examine that record to get whatever data it is that you'd send as baseParams or to change the url to load the store as you see fit.

Have you looked at the examples posted in the tutorials section? There is another example in my signature. It is NOT something that you'd want to copy/paste for your application, but it might be a good reference for learning a few things. I think it shows a few of the things you may be looking for.

I started with ext knowing zero (none) javascript and I'm not a programmer by trade/education. So, don't get discouraged, you'll get it with some time.

I glanced over your code and it looks like you're pretty far along already. From a quick scan I don't see what, if any, problems you're having. Can you be more specific what is wrong?

jay@moduscreate.com
19 Jun 2008, 5:37 PM
that's a lot for someone to digest. Look at using events to transfer data from one component to another. This way they are loosely coupled vs. direct method calls. :)

Michelangelo
19 Jun 2008, 11:38 PM
Not sure I understand.

You have grid.

You click or double click on grid.

You set up a listener for grid when you click on a row (you need to have row selection model in this case).

So you should end up inside the callback / listener once you have that set up.

Inside the callback I guess you would load the store. Prior to calling for store load you would re-set the url or baseParams or whatever as you need to. Perhaps the store loaded depends on the record from the grid you selected. So you'd examine that record to get whatever data it is that you'd send as baseParams or to change the url to load the store as you see fit.

Have you looked at the examples posted in the tutorials section? There is another example in my signature. It is NOT something that you'd want to copy/paste for your application, but it might be a good reference for learning a few things. I think it shows a few of the things you may be looking for.

I started with ext knowing zero (none) javascript and I'm not a programmer by trade/education. So, don't get discouraged, you'll get it with some time.

I glanced over your code and it looks like you're pretty far along already. From a quick scan I don't see what, if any, problems you're having. Can you be more specific what is wrong?

Hi mjlecomte,

thank you for your prompt reply. I am already a developer and I know the "philosophia" of the object modelling but I don't understand how can I found the basics of the ExtJs framework. With basis I mean for basic operation like open a window after a click on a button and load a json code inside a complex window. I need to create an application like this one http://213.251.166.160/~extjs/video2/etb.html but I have found many problem in my way. I have already study your samples.

I have clicked on the row of the grid and an event start:


this.on('rowdblclick', function(grid, rowIndex, e){
var record = grid.getStore().getAt(rowIndex);
var userw = new Application.UsersWindow(record);
userw.show();
});


the "record" variable will be sent to the control Application.UsersWindow, and then in the Application.UsersWindow I have to set the datastore for the form and all its components, right?

Extract from Application.UsersWindow:


items: [{
xtype:'textfield',
fieldLabel: 'First Name',
name: 'name',
value: this.data['name'],
anchor:'95%'
}]


is there a method to set this recordset to the form? Am I wrong way to build it?

Regards,
Michealangelo

Michelangelo
19 Jun 2008, 11:43 PM
that's a lot for someone to digest. Look at using events to transfer data from one component to another. This way they are loosely coupled vs. direct method calls. :)

Hi Garcia,

what is your solution about the problem?

Regards,
Michelangelo

mjlecomte
20 Jun 2008, 4:39 AM
Well, again, just from glancing over, it looks like you're probably 90% of the way there. You might have a look at www.extjs.eu. There is one called recordform that may showcase a way how to work with sending records/forms to another window.

It looks like you create a new window every time you click on the row. Not sure that's a good idea. You might want to create it one time and then reuse (so just hide that window). Again, I think saki's example will prove helpful to see a good way to do it.

It also looks like you're going about a good way to structure/separate your code. Unlike you, I'm not a web developer by trade, I'm still learning myself.

I'd also take note of what jgarcia is suggesting. Basically create your legos (those classes you have) then you can set up listeners / events so your components can communicate with each other. You could have your grid class, your window or form class (just for example) then have your main application manage/monitor the participants. I've tried to separate it one more layer by having your main application be the "view.js" so I could change the view easily and then have another script "onready.js" that serves as application entry point and manager (basically some attempt to separate the view from the logic).

mjlecomte
20 Jun 2008, 4:42 AM
P.S. I had a look at your page. Obviously you have some clue as to what you're doing. Unfortunately I don't speak french, so I didn't get much out of visiting your site.

Last thing I can add is to browse some of the more advanced examples in the demos (feedviewer, data binding, tasks, etc.).

Michelangelo
20 Jun 2008, 6:18 AM
Hi

this is not my page http://213.251.166.160/~extjs/video2/etb.html. It is a project that I have found in this forum.

What are these files at the http://recordform.extjs.eu/ libraries?:
Ext.ux.grid.RecordForm.js
Ext.ux.grid.RowActions.js

Thank you for your suggestions, I don't understand how call a component from another and the javascript light class sometime confuse me.

Yes, I need a clue to attach all the elements and a mentor to learn faster this framework. :)

mjlecomte
20 Jun 2008, 4:48 PM
http://www.extjs.eu is Saki's website. He has many tips, examples, etc, including a blog on ext related stuff.

One of his posted examples (see examples on top menu) is a components communication example. He has put about the least you can put into an example so you can see the theory in practice. There's another example in the ext demos called something like "data binding" (there's a basic and advanced version).