PDA

View Full Version : Conforming to Common Practices


thephatp
08-28-2008, 07:48 PM
Hi Everyone,

I'm very much a newbie to ExtJS, and I've gone through a LOT of the tutorials, API Documentation, the non-API documentation, etc. However, I've become very frustrated with myself that I'm not really getting how all of it works.

I'm not new to OOP or Javascript, but I am new at OOP with Javascript, to a point. I have created "classes" before, but never to the complication of those in ExtJS.

I really want to learn how to use the libraries the right way, as I am in the middle of a huge project, and I could really use a LOT of this stuff. However, I don't understand how some of the examples work together. I'm trying to do something that I considered pretty darn basic, and I cannot figure it out for the life of me.

This is what I'm trying to do:

I'd like to create a TabPanel that has 3 different tabs, each containing a different DataGrid. That's simple enough...I got that to work. However, I now want to add a panel just below the TabPanel to display row details when a user clicks on a row in one (any) of the DataGrids. However, I only want one Panel for this, not three separate ones (like combining each grid with it's own details Panel in every tab of the TabPanel). In fact, I may want to change the location of this details Panel at a later point, so it can't be attached to the DataGrids or the TabPanel.

Sounds simple enough to me, but I can't seem to figure it out. I've spent tons of time pouring through the various examples and documentation, trying to learn it the right way. I may be able to find a way to get it to work eventually, but since I'm going to be adding Tabs later and possibly sending data from clicks to different Panels on the page, I'd really like to learn it the correct way and use "class" structures for the objects.

I don't completely understand the superclass constructor calling (scope) in relation to the objects being created. Also, I don't understand how to connect the different pieces together. I don't understand what the `items:` config property actually expects--I started thinking I could pass it two objects, say my DataGrid, and then say another Panel, but that has never worked. And finally, I don't understand how to display the objects on the page without using the "renderTo" config option, even though I've seen examples that accomplish this. As an aside, I don't want the whole page to be a panel, so I don't want to use a ViewPort.

I can post code if needed. Currently, I have the code broken up in 4 JS files: 3 of them are the 3 DataGrids I'm using, then the final one is for the TabPanel that contains the DataGrids. All of them use the Ext.onReady() function, which I know is not good, but I can't get around.


So, does anyone have an example of what I'm trying to accomplish that either (1) Is documented inline with the code explaining details to a newbie level; or (2) Is pretty obvious what is going on?

I really apologize for the ignorance, but I've been working on this for about a week now, and my progress has come to a halt.

Thanks in advance for any help/advice/direction/etc.

Chad

evant
08-28-2008, 08:05 PM
You ask a fair amount of questions, so I'll probably only cover some of this:


I don't completely understand the superclass constructor calling (scope) in relation to the objects being created.


Scope in javascript is different to that in other languages. In javascript you can pass the scope around, for example:


O1 = Ext.extend(Object,
{
method: function()
{
this.name = 'foo';
alert(this.name);
}
}
);

O2 = Ext.extend(Object,
{
method: function()
{
this.name = 'bar';
alert(this.name);
}
}
);

var o1 = new O1();
var o2 = new O2();

o1.method.call(o2);



Also, I don't understand how to connect the different pieces together. I don't understand what the `items:` config property actually expects


Ext works with a container/layout architecture, in a very short summary:
1) Containers can contain other components.
2) Each container can have a layout specified.
3) The layout is responsible for rendering child items of the container.

As such, the items will differ depending on what type of layout you're using (for example, if you're using a border layout you can't have any more than 5 components in the layout). At it's most basic though, items should contain a series of components, whatever is appropriate for your layout. Also note that Container extends Component, so this allows for nesting (Viewport can contain a border layout, the center region can contain a tab panel which has one tab containing a grid).


And finally, I don't understand how to display the objects on the page without using the "renderTo" config option, even though I've seen examples that accomplish this.


You only ever use renderTo on your outermost container (often times this is usually a view port, so renderTo isn't required in that case). All other items should be managed via the container model, either through specify items configuration, or through using the add(), remove() and doLayout() methods on the container.

evant
08-28-2008, 08:07 PM
In regards to your actual question, I'd lay it out something like:


Viewport
Center Region -> Tab Panel
Each Tab will contain a grid here, use the selectionchange event on the grids selection model to make changes to the details panel
South Region -> Details Panel

thephatp
08-28-2008, 08:21 PM
Thanks for the fast response. I did see the scope example in the documentation very similar to what you show above. As mostly an application programmer, passing scope around is a very foreign concept, and I think I'm getting lost trying to follow it all.

I imagined something like what you said about Containers "containing" other components, I'm just not getting how.

Lets say I want to get the Panel layout first--a TabPanel with a single tab, and a Panel that exists just below the TabPanel just as you described in your second post--BUT, say I can't use a ViewPort. I'd imagine this as an outer container, say MainContent or MainPanel to keep both of these items, but...

First question: What is MainPanel if it is not a ViewPort? It it an Ext.Panel object? Is it some other Ext object? Something else?

Second question: How do I associate the myTabPanel and DetailsPanel with the MainPanel? (IOW, how do I hand "MainPanel" my two objects and have it control them?)

Sorry for such basic questions...I'm hoping a light-bulb goes off in my head soon.

mjlecomte
08-28-2008, 08:27 PM
If you haven't looked yet, I'd reference the grid data binding examples, the feedviewer example, and on Saki's site www.extjs.eu, the components communication example. Basically sounds like you want to couple the various "legos" loosely.

Also have a gander at this one if you haven't looked at it yet:
http://extjs.com/learn/Manual:Component:Extending_Ext_Components

evant
08-28-2008, 08:29 PM
Your code could look something like:


Ext.onReady(function()
{
var ct = new Ext.Container(
{
autoEl: {},
height: 600,
width: 600,
renderTo: document.body,
layout: 'border',
items:
[
{
xtype: 'tabpanel',
region: 'center',
activeTab: 0,
items:
[
{title: 'tab1', html: 'tab1'},
{title: 'tab2', html: 'tab2'},
{title: 'tab3', html: 'tab3'}
]
},
{
title: 'Details',
height: 200,
region: 'south',
html: 'Details panel',
split: true
}
]
}
);
}
);

mjlecomte
08-28-2008, 08:39 PM
For your layout questions, be sure to have a look at the layout browser example.

You can get references to other components using Ext.getCmp('theIDyouGiveYourComponent') and then manually perform actions, but I think what you're after is component communication using observer pattern whereby you can fire events and have your other components subscribe or listen for those events (that's what those examples I pointed you towards tend to do).

Edit: Saki has yet another tutorial in the wiki about event firing, etc. and explains the why etc either in the tutorial or his blog (http://blog.extjs.eu/know-how/events-explained/).

thephatp
08-28-2008, 08:46 PM
For your layout questions, be sure to have a look at the layout browser example.

You can get references to other components using Ext.getCmp('theIDyouGiveYourComponent') and then manually perform actions, but I think what you're after is component communication using observer pattern whereby you can fire events and have your other components subscribe or listen for those events (that's what those examples I pointed you towards tend to do).

Edit: Saki has yet another tutorial in the wiki about event firing, etc. and explains the why etc either in the tutorial or his blog (http://blog.extjs.eu/know-how/events-explained/).

Yes, that is exactly what I want to do. I have looked at the Feed Viewer (http://www.yui-ext.com/deploy/dev/examples/feed-viewer/view.html) for quite a while now, but it's been really hard to follow because of my lack of understanding. But I will definitely take a look at the examples you spoke of.

thephatp
08-28-2008, 08:48 PM
Your code could look something like:


Ext.onReady(function()
{
var ct = new Ext.Container(
{
autoEl: {},
height: 600,
width: 600,
renderTo: document.body,
layout: 'border',
items:
[
{
xtype: 'tabpanel',
region: 'center',
activeTab: 0,
items:
[
{title: 'tab1', html: 'tab1'},
{title: 'tab2', html: 'tab2'},
{title: 'tab3', html: 'tab3'}
]
},
{
title: 'Details',
height: 200,
region: 'south',
html: 'Details panel',
split: true
}
]
}
);
}
);


Ok, great, this is exactly what I was thinking (and tried, but with Ext.Panel instead of Ext.Contain).

But now, if I've created the two items (xType: TabPanel, and then Details area) as objects, how do I list those two things in the items section?

I've tried using "items: myGrid, myDetailsPanel" but that didn't work. Is there something else I have to do?

Thanks again for all the help!

mjlecomte
08-28-2008, 08:57 PM
don't forget items is expecting an array

thephatp
08-29-2008, 02:57 PM
Ok, so I took a look at some of Saki's examples, and I'm trying to modify it slightly and test it. I know the JsonStore and the Columns are correct, because they are an exact copy from a different Grid test that I did that worked (not using Ext.extend).

Could someone take a look here and tell me what I'm doing wrong? Firebug gives no errors, but my page doesn't show anything at all.



// init globals
Ext.ns('Example');
Ext.BLANK_IMAGE_URL = ExtDir + '/resources/images/default/s.gif';

/**
* @class Example.Grid
* @extends Ext.grid.GridPanel
*/
Example.Grid = Ext.extend(Ext.grid.GridPanel, {

// configurables
border:false

// {{{
,initComponent:function() {

// pre-configure the grid
Ext.apply(this, {

// store
store:new Ext.data.JsonStore({
url: reportPage_SimpleView
, root: 'rows'
, fields: [
{name:'Col1' , type:'string'}
, {name:'Col2' , type:'string'}
, {name:'Col3' , type:'date', dateFormat: 'Y-m-d H:i:s'}
, {name:'Col4' , type:'string'}
, {name:'Col5' , type:'string'}
, {name:'Col6' , type:'bool'}
, {name:'Col7' , type:'bool'}
]
})

// column model
,columns:[
{header: 'Col1' , width: 230, sortable: true, dataIndex: 'Col1'}
, {header: 'Col2' , width: 400, sortable: true, dataIndex: 'Col2'}
, {header: 'Col3' , width: 130, sortable: true, dataIndex: 'Col3', renderer: Ext.util.Format.dateRenderer('Y-m-d H:i:s')}
, {header: 'Col4' , width: 90, sortable: true, dataIndex: 'Col4'}
, {header: 'Col5' , width: 90, sortable: true, dataIndex: 'Col5'}
]

// force fit
,viewConfig:{forceFit:true}

}); // eo apply

// call parent
Example.Grid.superclass.initComponent.apply(this, arguments);

} // eo function initComponent
// }}}
// {{{
,onRender:function() {
// call parent
Example.Grid.superclass.onRender.apply(this, arguments);

// load store
this.store.load();
}

}); // eo extend

// register xtype
Ext.reg('examplegrid', Example.Grid);


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

// initialize
Ext.QuickTips.init();

var container = new Ext.Container({
title: 'Testing GridPanel'
, items:[{xtype:'examplegrid', id:'one2many-grid'}]
, height: 800
, width: 1000
, renderTo: 'content'
})

container.show();


}); // eo function onReady

// eof

thephatp
08-29-2008, 05:18 PM
Nevermind, I figured out what I was doing wrong. Mis-typed something in the include. ;)