In the last section we have created a component printing out some messages onto the console. Within this section we develop a basic layout for the component. This layout consists of three parts: a header panel displaying some title, a (empty) main panel, and an (empty) input panel.
We show you which hooks you need to provide, in order for the component to be displayed in a running ActionCenter. In the next section we are going to work with the properties of component to configure the header panel, after that we look into how to interact with the server.
We use Ext JS to develop the user interface of the component. Since we do not intend to provide an extensive introduction into EXT JS, we are going to rush through some of this code.
In the last section we have created a simple template for a component. In this section we build upon this template and replace the JavaScript code with a basic layout for our component.
In order to display a component it has to be hooked into an HTML element, the target. Every component should render itself to this target. The following listing shows how to render a panel within the given target.
var panel = new Ext.Panel(); panel.doLayout(); if(target) { //test whether the target is null or undefined var divConfig = { renderTo: target, layout: 'fit', items: [panel] }; //Draw the panel onto the target DivViewportManager.push(new Ext.ux.DivViewport(divConfig));
We create a configuration containing the target for a viewport and use Ext JS to create the viewport. This viewport is then handed over to a DivViewportManager. In some situations the target is undefined or null. Therefore, every component developed for ActionCenters needs to provide a function getPanel returning a panel containing the main GUI of the component. This function is called from outside the component. The following listing shows an implementation of this function:
this.getPanel = function () {//in case the target is not defined or null return panel; }
For our basic layout we use a panel with a fit layout as a wrapper for another panel, the containerPanel, with a border layout. The following listing shows this layout structure.
var panelItems = new Array(); //The container panel uses a border layout ... var containerPanel = new Ext.Panel({ itemId: 'attachmentContainer', layout: 'border', bodyStyle: 'background-color: white;', bodyBorder: false, margins: '1 2 2 2', ctCls: 'x-panel-noborder', items: panelItems }); containerPanel.doLayout(); //... and is placed into a panel with a fit layout var panel = new Ext.Panel({ //why do we need this panel? layout: 'fit', items: [containerPanel] }); panel.doLayout();
As you can see the containerPanel has a property items and a property layout. The property items refers to an array containing some panels. We will fill this array in the following subsection.
A border layout consists of five areas: center, north, east, south, and west. In the attachment component we are going to put the header panel into the Northern region, the input panel into the Southern region, and the main panel into the central location. For each panel we have to provide a property region specifying where to place the panel. The following listing shows the code implementing these three panels. They are placed into the array containing the items of the container panel.
var panelItems = new Array(); var headerPanel = new Ext.Panel({ itemId: 'attachmentHeaderPanel', layout: 'fit', region: 'north', split: false, bodyStyle: 'padding: 0px 10px', margins: '2 2 1 2', html: 'name of the superior contribution' }); panelItems.push(headerPanel); var contentPanel = new Ext.Panel({ itemId: 'attachmentContentPanel', region: 'center', split: true, margins: '1 2 2 2', bodyStyle: 'padding: 0px 10px', html: 'list of attachments' }); panelItems.push(contentPanel); var inputPanel = new Ext.Panel({ itemId: 'attachmentInputPanel', minSize: 20, region: 'south', collapsible: true, //results in an arrow to open and close the input panel split: false, margins: '1 2 2 2', bodyStyle: 'padding: 0px 10px', html: 'input of new files' }); panelItems.push(inputPanel);
The listing at the end of this section shows the complete JavaScript code.
<?xml version="1.0" encoding="UTF-8"?> <ActionCenterElements xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://server.actioncenters.org/svn/AC/actioncenters-xml/ActionCenterElements.xsd"> <!-- xsi:noNamespaceSchemaLocation="http://server.actioncenters.org/svn/AC/actioncenters-xml/ActionCenterElements.xsd"> --> <Component type="Layout_Example"> <js> <code> var Layout_Example = function (superiorContribution, renderer, subrenderers, target) { var panelItems = new Array(); var headerPanel = new Ext.Panel({ itemId: 'attachmentHeaderPanel', layout: 'fit', region: 'north', split: false, bodyStyle: 'padding: 0px 10px', margins: '2 2 1 2', html: 'name of the superior contribution' }); panelItems.push(headerPanel); var contentPanel = new Ext.Panel({ itemId: 'attachmentContentPanel', region: 'center', split: true, margins: '1 2 2 2', bodyStyle: 'padding: 0px 10px', html: 'list of attachments' }); panelItems.push(contentPanel); var inputPanel = new Ext.Panel({ itemId: 'attachmentInputPanel', minSize: 20, region: 'south', collapsible: true, //results in an arrow to open and close the input panel split: false, margins: '1 2 2 2', bodyStyle: 'padding: 0px 10px', html: 'input of new files' }); panelItems.push(inputPanel); var containerPanel = new Ext.Panel({ itemId: 'attachmentContainer', layout: 'border', bodyStyle: 'background-color: white;', bodyBorder: false, margins: '1 2 2 2', ctCls: 'x-panel-noborder', items: panelItems }); containerPanel.doLayout(); var panel = new Ext.Panel({ layout: 'fit', items: [containerPanel] }); panel.doLayout(); this.getPanel = function () {//in case the target is not defined return panel; } if(target) {//test whether the target is null or undefined var divConfig = { renderTo: target, layout: 'fit', items: [panel] }; //Draw the panel onto the target (DivViewportManager is defined in PSS) DivViewportManager.push(new Ext.ux.DivViewport(divConfig)); } }; </code> </js> </Component> </ActionCenterElements>