PDA

View Full Version : How to get the references of a parent element



shensi
2 Apr 2012, 6:14 AM
Hi,I am new sencha developper, and I am having troubles.

As you can see, I mixed many examples in this screen (layout-browser, treepanel, forms,etc).

I am loading to a store some data from a database (on the left layout). This store contains only id and device labels.

When you select a treestore entry (ie : bwr102.00), I would like to load a tabpanel with forms in it (that's actually working well). But I don't know how to provide to each child tabpanel my id (ie : 15).

In my mind, each time you select a treestore device, I should load associated values.

33457

I found Ext.getCmp, Ext.ComponentManagerView, some examples of getting references...But I don't know how to give to child tabpanel the ID from his parent treeStore ?

Could you help me ?
I am not sure providing examples of my source code will help you to have feedbacks, but there is some pieces of code to illustrate what I have done

My treeStore
// // This treeStore will contain all devices (dynamic content)
var TreeStore = Ext.create('Ext.data.TreeStore', {
id : 'TreeStore',
views:['view_treeStore'],
proxy: {
type: 'rest',
url : 'app.php/users',
reader: {
type: 'json',
root: 'data'
},
writer: {
type: 'json'
}
},
listeners: {
append: function( thisNode, newChildNode, index, eOpts ) {
if( !newChildNode.isRoot() ) {
newChildNode.set('description', newChildNode.get('dID'));
newChildNode.set('leaf', true);
newChildNode.set('text', newChildNode.get('device')+ '-' + newChildNode.get('dID'));
}
}
}
});

The way I add a card-tabs for each treeStore entry

// // Assign the changeLayout function to be called on tree node click.
treePanel.getSelectionModel().on('select', function(selModel, record) {
if (record.get('leaf')) {
//Ext.getCmp('content-panel').layout.setActiveItem(record.getId() + '-panel');
Ext.getCmp('content-panel').layout.setActiveItem('card-tabs-panel');
if (!detailEl) {
var bd = Ext.getCmp('details-panel').body;
bd.update('').setStyle('background','#fff');
detailEl = bd.createChild(); //create default empty div
}
//detailEl.hide().update(Ext.getDom(record.getId() + '-details').innerHTML).slideIn('l', {stopAnimation:true,duration: 200});
}
});


My car-tabs, I found it from the sencha examples

cardTabs: { xtype: 'tabpanel',
id: 'card-tabs-panel',
views:'view-cardTab',
plain: true, //remove the header border
activeTab: 0,
style: 'background-color:#dfe8f6; ',
defaults: {bodyStyle: 'padding:15px'},
items:[{
title: 'Main',
//html: 'This is tab 1 content.'
items: [tabPanel]
}]
}

I would like to know dID inside the tabPanel element !!!
Hope you will understund my needs...Cheers

scottmartin
2 Apr 2012, 9:16 AM
It is generally a good idea to steer away from using hard 'id' fields in your app if possible especially on dynamic items. Have a look at:

http://extjsinaction.com/258

You can use itemId: 'myid' and then grab the component using up/down

MyParent.down('#myid') // items below
MyChild.up('#myPID'); // parent

There is also: Ext.ComponentQuery() to search the Ext.ComponentManager.

Regards,
Scott.

shensi
2 Apr 2012, 10:07 AM
Hey ! First, Thank you very much !

Could you tell me how I get the reference of those :
- MyParent ?
- MyChild ?

Actually, people already have realized this. Do you have a link of an example which illustrates that point ?

Thank you very much for all !
Shensi

scottmartin
2 Apr 2012, 10:52 AM
Try this:




var filterPanel = Ext.create('Ext.panel.Panel', {
itemId: 'panel-filter',
bodyPadding: 5, // Don't want content to crunch against the borders
width: 300,
title: 'Filters',
tbar: [
{
text: 'up/down (xtype)',
handler: function(btn) {
var fp = btn.up('panel'); // xtype
var ds = fp.down('#date-start');
alert(ds.fieldLabel);
}
},
{
text: 'up/down (itemid)',
handler: function(btn) {
var fp = btn.up('#panel-filter'); // itemId
var ds = fp.down('#date-start');
alert(ds.fieldLabel);
}
}
],
items: [{
xtype: 'datefield',
fieldLabel: 'Start date',
itemId: 'date-start'
}, {
xtype: 'datefield',
fieldLabel: 'End date',
itemId: 'date-end'
}],
renderTo: Ext.getBody()
});


Scott.

sskow200
2 Apr 2012, 3:02 PM
Why wouldn't you be using the 'itemclick' event of the tree panel?



var tree = Ext.create('Ext.tree.Panel', {//config omitted}),
tabs = Ext.create('Ext.tab.Panel', {//config omitted

setRecord: function(record) {
//for each tab, load this record?
}
});

tree.on('itemclick', function(view, record, item, idx, evt) {
tabs.setRecord(record);
});




By creating a setRecord function in your tab panel, you can propogate that all the way down to each tab you would like. Each tab can have its own setRecord function as well so you can get custom functionality out of each one (like loading the record into a form or a template). I'm also confused on why you are nesting TabPanels inside TabPanels?

shensi
3 Apr 2012, 7:43 AM
Hi, thank you to for your answer. I am also confused to :-)

Actually, since yesterday I load my dataStore in a slightly different way.
I would like to provide to my child card-tabs an array (yesterday, it was some my store)

PHP side, I return a array('dID', 'device', array_values)
I managed to define it like this :
(I will define dataStore.values in my tabpanel js file. and I will associate this submitted array with a local datastore...)


Ext.define('dataStore.values', {
model: ['deviceModel'],
extend: 'Ext.data.Model',
fields: [
{name: 'sID', type: 'int'},
{name: 'datetime', type: 'string'},
{name: 'device', type: 'string'},
{name: 'source', type: 'string'},
{name: 'type', type: 'string'},
{name: 'value', type: 'string'}
]
});


Ext.define('dataStore', {
model: ['deviceModel'],
extend: 'Ext.data.Model',
fields: [
'dID',
{name: 'device', type: 'string'},
{name: 'device_values', type: 'array'},
]
});


The definition of my treeStore is like this and everything is displayed correctly :


//
// This treeStore will contain all devices (dynamic content)
var treeStore = Ext.create('Ext.data.TreeStore', {
id : 'treeStore',
itemId: 'ii-treeStore',
model: 'dataStore',
proxy: {
type: 'rest',
url : 'app.php/devices',
reader: {
type: 'json',
root: 'data'
},
writer: {
type: 'json'
}
},
listeners: {
append: function( thisNode, newChildNode, index, eOpts ) {
if( !newChildNode.isRoot() ) {
newChildNode.set('leaf', true);
newChildNode.set('text', newChildNode.get('device')+ '-' + newChildNode.get('dID'));
}
}
}
});



//
// Some parameters for the treeStore
treeStore.setRootNode({
text: 'Devices',
leaf: false,
expanded: false
});




// This is another part of the treeStore (static content)
var settingsTreeStore = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
children: [
{
text: 'Settings',
leaf: false,
expanded: true,
children: [
{
text: 'Global Settings',
description:'111',
leaf: true
}, {
text: 'Locations',
description:'222',
leaf: true
}, {
text: 'Groups',
description:'333',
leaf: true
}


]
}
]
}
});




// Graft our userTreeStore into the settingsTreeStore. Note that the call
// to .expand() is what triggers the userTreeStore to load its data.
settingsTreeStore.getRootNode().appendChild(treeStore.getRootNode()).expand();




//
// Go ahead and create the TreePanel now so that we can use it below
var treePanel = Ext.create('Ext.tree.Panel', {
id: 'deviceTreePanel',
itemId: 'ii-treePanel',
title: 'Management panel',
region:'north',
split: true,
height: 560,
minSize: 150,
rootVisible: false,
autoScroll: true,
store: settingsTreeStore
});






I display tabs like this for the moment :



//
// Assign the changeLayout function to be called on tree node click.
treePanel.getSelectionModel().on('select', function(selModel, record) {
if (record.get('leaf')) {
Ext.getCmp('content-panel').layout.setActiveItem('card-tabs-panel');
}
});


So, my question is the same, when I create a new tab associated to an dID, how can I send the reference of array_values to this child tab ?

And for your question :
I'm also confused on why you are nesting TabPanels inside TabPanels?
I'm not sure about my job, I don't see what you mean...
It seems clear for me. And for you ? lol

Regards,
Shensi

sskow200
3 Apr 2012, 7:52 AM
This part doesn't make much sense...



// Assign the changeLayout function to be called on tree node click. treePanel.getSelectionModel().on('select', function(selModel, record) { if (record.get('leaf')) { Ext.getCmp('content-panel').layout.setActiveItem('card-tabs-panel'); } });


you mean...



treePanel.on('select', function(selModel, record) {
if(record.isLeaf()){
Ext.getCmp('content-panel').loadRecord(record);
}
})


I am not understanding why you are wrapping tabpanels inside a card layout. A tabpanel is already inherently a card layout which means you are adding more DOM elements than necessary. Judging by the data, your tabs will always be the same structure and contain the same elements in them, only the data is different depending on the record selected. So, if that is accurate, why not just create a tab panel like so...



var contentPanel = Ext.create('Ext.tab.Panel', {
id: 'content-panel',
//config items omitted
loadRecord: function(record) {
//pseudo-code
//for each of my tabs, load this record...
}
});

shensi
3 Apr 2012, 12:50 PM
Hi, good evening !
I hope this paste code will be the good one...

I finally remove many lines and simplify my js file.
Thanks to you I almost got it.
I was wondering about this parameter : record ? how can I use it ?
I found the console.log function which is very useful with the web console in firefox.
But I still can't access to device_values, and I don't know if my array is initialized correctly ...
I can see bull on the console when I click on elements of the tree.

Thank you for your helps and explanations...
Regards,
Shensi



Ext.Loader.setConfig({enabled: true});


Ext.Loader.setPath('Ext.ux', '../ux');


Ext.require([
'Ext.tip.QuickTipManager',
'Ext.container.Viewport',
'Ext.layout.*',
'Ext.form.Panel',
'Ext.form.Label',
'Ext.grid.*',
'Ext.data.*',
'Ext.tree.*',
'Ext.selection.*',
'Ext.tab.Panel',
'Ext.ux.layout.Center',
'Ext.getCmp.*',
'Ext.ComponentManagerView.*'
]);




var datamodelValue = Ext.define('dataStore.values', {
extend: 'Ext.data.Model',
fields: [
{name: 'sID', type: 'int'},
{name: 'datetime', type: 'string'},
{name: 'device', type: 'string'},
{name: 'source', type: 'string'},
{name: 'type', type: 'string'},
{name: 'value', type: 'string'}
]
});


var datamodel = Ext.define('dataStore', {
extend: 'Ext.data.Model',
fields: [
'dID',
{name: 'device', type: 'string'},
{name: 'device_values', type: 'array'},
]
});


//
// This is the main layout definition.
//
Ext.onReady(function(){


Ext.tip.QuickTipManager.init();


var detailEl;

//
// Main left panel layout
var contentPanel = {
xtype: 'tabpanel',
activeTab: 0,
id: 'content-panel',
itemId: 'ii-contentPanel',
region: 'center',
layout: 'card',
margins: '2 5 5 0',
activeItem: 0,
border: false,
items:[{
title: 'Main',
items: [tabPanel]
},{
title: 'Details',
items: [typesPanel]
},{
title: 'Groupe',
html: 'This is tab 2 content.'
},{
title: 'Actions',
html: 'This is tab 3 content.'
},{
title: 'Graphiques',
html: 'This is tab 4 content.'
},{
title: 'Options',
html: 'This is tab 5 content.'
}],
loadRecord: function(record) {

//var myar = record.('device_values');
var arr = [];
arr = record.get('device_values');
var myarray = Ext.create('Ext.data.Store', {
model: 'dataStore.values',
//storeId: 'usersStore',
data: arr
});

//var myarray = record.get('device_values');
console.log(myarray);
}
};




//
// This treeStore will contain all devices (dynamic content)
var treeStore = Ext.create('Ext.data.TreeStore', {
id : 'TreeStore',
itemId: 'ii-treeStore',
model: 'exoweb.dataStore',
proxy: {
type: 'rest',
url : 'app.php/users',
reader: {
type: 'json',
root: 'data'
},
writer: {
type: 'json'
}
},
listeners: {
append: function( thisNode, newChildNode, index, eOpts ) {
if( !newChildNode.isRoot() ) {
newChildNode.set('leaf', true);
newChildNode.set('text', newChildNode.get('device')+ '-' + newChildNode.get('dID'));
}
}
}
});



//
// Some parameters for the treeStore
treeStore.setRootNode({
text: 'Devices',
leaf: false,
expanded: false
});



// This is another part of the treeStore (static content)
var settingsTreeStore = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
children: [
{
text: 'Settings',
leaf: false,
expanded: true,
children: [
{
text: 'Global Settings',
description:'111',
leaf: true
}, {
text: 'Locations',
description:'222',
leaf: true
}, {
text: 'Groups',
description:'333',
leaf: true
}

]
}
]
}
});




// Graft our userTreeStore into the settingsTreeStore. Note that the call
// to .expand() is what triggers the userTreeStore to load its data.
settingsTreeStore.getRootNode().appendChild(treeStore.getRootNode()).expand();


//
// Go ahead and create the TreePanel now so that we can use it below
var treePanel = Ext.create('Ext.tree.Panel', {
id: 'deviceTreePanel',
itemId: 'ii-treePanel',
title: 'Management panel',
region:'north',
split: true,
height: 560,
minSize: 150,
rootVisible: false,
autoScroll: true,
store: settingsTreeStore
});

//
//
treePanel.on('select', function(selModel, record) {
if(record.isLeaf()){
Ext.getCmp('content-panel').loadRecord(record);
}
})

//
// This is the Details panel that contains the description for each example layout.
var detailsPanel = {
id: 'details-panel',
//views:['view_detailsPanel'],
itemId: 'ii-detailsPanel',
title: 'Details',
region: 'center',
bodyStyle: 'padding-bottom:15px;background:#eee;',
autoScroll: true,
html: '<p class="details-info">When you select a layout from the tree, additional details will display here.</p>'
};



// Finally, build the main layout once all the pieces are ready. This is also a good
// example of putting together a full-screen BorderLayout within a Viewport.
Ext.create('Ext.Viewport', {
layout: 'border',
//views:['view_browser'],
title: 'Ext Layout Browser',
items: [{
xtype: 'box',
id: 'header',
region: 'north',
//html: '<h1>ExoWeb management interface </h1>',
height: 5
},{
layout: 'border',
id: 'layout-browser',
region:'west',
border: false,
split:true,
margins: '2 0 5 5',
width: 275,
minSize: 100,
maxSize: 500,
items: [treePanel, detailsPanel]
},
contentPanel
],
renderTo: Ext.getBody()
});
});

sskow200
3 Apr 2012, 1:30 PM
Your first issue could be that 'array' type is not a valid field type for a model field (See Here (http://docs.sencha.com/ext-js/4-0/#%21/api/Ext.data.Field-cfg-type)). Then I would ask what are you trying to store here? It is not necessary to load all of your device data at this point cause you don't know what the user will be looking at right? If I were you I would utilize the 'activate' event on each tab to load the proper data based on the record id passed to it earlier. It would look something like this...



Ext.define('MyApp.DeviceTab', {
extend: 'Ext.panel.Panel',
alias: 'widget.devicetab',
record: undefined,
url: 'default-data-url.php', //override in subclass / creation config

//more config omitted

initComponent: function() {
this.callParent(arguments);

this.on('activate', this.onActivate, this);
},

onActivate: function() {
var me = this;

if(!Ext.isEmpty(me.record)){
me.loadRecord(me.record);
}
},

loadRecord: function(record) {
var me = this;
me.record = record;

if (me.isActiveTab()){
Ext.Ajax.request({
url: me.url,
params: {id:me.record.get('id')},
success: me.success
});
}
},

success: function(response) {
//override this for each tab to handle response from server
},

isActiveTab: function() {
return this.up('tabpanel').getActiveTab() == this;
}
});

var contentPanel = Ext.create('Ext.tab.Panel', {
id: 'content-panel',
items: [{
xtype: 'devicetab'
title: 'Main',
url: 'main-device-data.url',
success: successFn //you decide
},{
xtype: 'devicetab',
title: 'Group',
url: 'group-device-data.url',
success: successFn //you decide
}],

loadRecord: function(record) {
//for each tab, tab.loadRecord(record)
}
});

var treePanel = Ext.create('Ext.tree.Panel', {//config omitted});
treePanel.on('select', function(selModel, record) {
contentPanel.loadRecord(record);
});

shensi
3 Apr 2012, 1:53 PM
Ok why not ?
I am checking your suggestion right now.
But, I was wondering, in order to minimize the mysql query time :
- Is it better to do one mysql query with all the dataStore in one shot ?
- Is it better to do one mysql query with only Ids in the first time (as i did yesterday in my last post), and do another one each time the user will select one tree entry ?

COuld you describe what I need to do here ?


loadRecord: function(record) {
//for each tab, tab.loadRecord(record)
}

sskow200
3 Apr 2012, 1:56 PM
This is highly application specific. However, in my personal opinion, since you have so many records in your tree, you will never really know if the user will even want most of the other data. So I advise to leave the excess data out until the user requests it via the id of the record in the tree. Those requests should not be very heavy because you are only dealing with a single record, instead of potentially hundreds at a time.

shensi
6 Apr 2012, 7:20 AM
I finaly used your method.

But how can I display my record inside items ?


cardTabs: {
xtype: 'tabpanel',
id: 'card-tabs-panel',
plain: false,
activeTab: 0,
style: 'background-color:#dfe8f6; ',
defaults: {bodyStyle: 'padding:15px'},
//listeners: {
// scope: this,
//},
setRecord: function(record) {
console.log(record);
},
items:[{
title: 'Tab 1',
html: 'This is tab 1 content.'+ record,
},{
title: 'Tab 2',
html: 'This is tab 2 content.'
},{
title: 'Tab 3',
html: 'This is tab 3 content.'
},{
title: 'Tab 4',
html: 'This is tab 4 content.'
},{
title: 'Tab 5',
html: 'This is tab 5 content.'
}]
}


When I try to use record I have this error in firebug :
Uncaught ReferenceError: record is not defined

I will set a more complex form in each tabs and load data through a json proxy with this record ID...
Thank you !

shensi
18 Aug 2012, 12:49 PM
I am sorry to do this for my post but I didn't find a solution...

sskow200 said :




var contentPanel = Ext.create('Ext.tab.Panel', { id: 'content-panel',
//config items omitted
loadRecord: function(record) {
//pseudo-code
//for each of my tabs, load this record...
}
});


I didn't manage to use this record inside the items' tabpanel. The value couldn't be used and I don't know why.

Can anyone give me some help ?
Thank you very much

scottmartin
18 Aug 2012, 1:21 PM
you need to create a form.Panel instead of panel.Panel and then use form.loadRecord() to load the record into the form.



http://docs.sencha.com/ext-js/4-1/#!/api/Ext.form.Panel


Scott.

shensi
19 Aug 2012, 12:54 AM
Hi Scott !

You are brilliant ! It took me half an hour to make it work !

This is the form.panel :


cardForms: { xtype: 'form',
id: 'card-forms-panel',
title: 'Simple Form',
layout: 'anchor',
defaults: {
anchor: '100%'
},
// The fields
defaultType: 'textfield',
items: [{
fieldLabel: 'ID',
name: 'dID',
allowBlank: false
}]
}


And this is the form.panel included into my tabs :


cardTabs2: { xtype: 'tabpanel',
id: 'card-tabs2-forms-panel',
plain: false,
activeTab: 0,
style: 'background-color:#dfe8f6; ',
defaults: {bodyStyle: 'padding:15px'},
items:[{
title: 'Tab 1',
items : [{
xtype: 'form',
id: 'card-tabs2-forms1-panel',
title: 'Form tab1',
layout: 'anchor',
defaults: {
anchor: '100%'
},
defaultType: 'textfield',
items: [{
fieldLabel: 'ID',
name: 'dID',
allowBlank: false
}]
}]
},{
title: 'Tab 2',
html: 'This is tab 2 content.'
},{
title: 'Tab 3',
html: 'This is tab 3 content.'
},{
title: 'Tab 4',
html: 'This is tab 4 content.'
},{
title: 'Tab 5',
html: 'This is tab 5 content.'
}]
}


And this is how I call those panels :


// Assign the changeLayout function to be called on tree node click.
treePanel.getSelectionModel().on('select', function(selModel, record) {
if (record.get('leaf')) {


//Ext.getCmp('content-panel').layout.setActiveItem('card-forms-panel');
//Ext.getCmp('card-forms-panel').getForm().loadRecord(record);



Ext.getCmp('content-panel').layout.setActiveItem('card-tabs2-forms-panel');
Ext.getCmp('card-tabs2-forms1-panel').getForm().loadRecord(record);
}
});


I have an other question... People warn you to use Ext.getCmp component ? Could you tell me what's the risk in my case ?

scottmartin
19 Aug 2012, 8:15 AM
Here is a good video that explains this in detail:
http://vimeo.com/14816550

The basic idea is that to use getCmp, you need to know the id. This usually means that you have assigned an 'id' to your component. This in itself is bad practice.

My new users will create an id, and then wonder why creating a new instance will break things. Two components cannot have the same id. Let the engine create a unique one for you.

You will see many examples that use id and getCmp, but this is to get a quick access to the component for the example, but would not be used in a real application.

It is recommended that you use 'itemId' to provide access to the component.

If you are going to assign an id, it would be assigned to items that you know will only create one instance per app.. ex: viewport. Even in this case, it still not considered good practice.

Scott.

scottmartin
19 Aug 2012, 8:33 AM
Have a look at query for a more updated use of itemId in Ext4:
http://docs.sencha.com/ext-js/4-1/#!/api/Ext.ComponentQuery-method-query

Scott.

shensi
19 Aug 2012, 11:37 AM
Alright ... I got it. So I replaced id by itemId...

Otherwise, I have one other case in which I would like to load a chart ( a Chart example from Ext JS4.1 sample).

How can I load data into a form which is not a form :-)
Because getForm method doesn't work... This a sample of the chart view I use :



{ title: 'Graphs',
//html: 'This is tab 5 content.'
items : [{

xtype: 'chart',
animate: true,
shadow: true,
store: store1,
axes: [{
type: 'Numeric',
position: 'left',
fields: ['data1'],
title: false,
grid: true
}, {
type: 'Category',
position: 'bottom',
fields: ['name'],
title: false
}],
series: [{
type: 'line',
axis: 'left',
gutter: 80,
xField: 'name',
yField: ['data1'],
tips: {
trackMouse: true,
//width: 580,
//height: 170,
layout: 'fit',
items: {
xtype: 'container',
layout: 'hbox',
items: [pieChart, grid]
},
renderer: function(klass, item) {
var storeItem = item.storeItem,
data = [{
name: 'data1',
data: storeItem.get('data1')
}, {
name: 'data2',
data: storeItem.get('data2')
}, {
name: 'data3',
data: storeItem.get('data3')
}, {
name: 'data4',
data: storeItem.get('data4')
}, {
name: 'data5',
data: storeItem.get('data5')
}], i, l, html;

this.setTitle("Information for " + storeItem.get('name'));
pieStore.loadData(data);
gridStore.loadData(data);
grid.setSize(480, 130);
}
}
}]
//----

}]

When I load/display my tab-form-panel, obviously I have got an error :
Uncaught TypeError: Cannot call method 'getForm' of undefined


treePanel.getSelectionModel().on('select', function(selModel, record) {
if (record.get('leaf')) {


//var dID = record.get('dID');
Ext.getCmp('content-panel').layout.setActiveItem('card-tabs2-forms-panel');
Ext.getCmp('card-tabs2-forms1-panel').getForm().loadRecord(record);
Ext.getCmp('card-tabs2-forms2-panel').getForm().loadRecord(record);
Ext.getCmp('card-tabs2-forms3-panel').getForm().loadRecord(record);
Ext.getCmp('card-tabs2-forms4-panel').getForm().loadRecord(record);

// --> This is the chart tab panel
Ext.getCmp('card-tabs2-forms5-panel').getForm().loadRecord(record);
}
});

THANK YOU FOR ALL YOUR HELP !

scottmartin
19 Aug 2012, 1:28 PM
I got it. So I replaced id by itemId...
Good ..


Ext.getCmp('card-tabs2-forms1-panel').getForm()
You can no longer use getCmp, since it needs and id, not itemId

Use:

var t2f1 = Ext.ComponentQuery.query('#card-tabs2-forms1-panel');

You can use just create an array:

var formsArray = tabPanel.query('form');

of .. if you have an itemId for the tabPanel:

var formsArray = Ext.ComponentQuery.query('#myTabPanel > form');

Open the console and have a look around ;)

Scott.