81
Enterprise Web Developer Using the ExtJS Widgets Version 4.0.746 Background Enterprise Web Developer (EWD) includes advanced functionality that allows you to make use of the powerful Javascript widget libraries from ExtJS (http://extjs.com ). By incorporating these widgets into your applications, you'll be able to quickly and easily create Rich Internet Applications. Unlike users of these widget libraries who are forced to hand-craft the required code, you'll be able to let EWD do all the hard work. With EWD you'll be creating in minutes what others will take days or weeks to accomplish. Your web applications will never look the same again! This document is a reference guide to using EWD's ExtJS custom tags. Pre-requisites This guide assumes that you installed EWD (build 746 or later) and have read the eXtc Web Developer Overview, the Installation Guide, Tutorial and Ajax documents. You should also have the main EWD API Guide at hand. You'll also need to install the ExtJS Javascript library files (version 2.2 or later). Full instructions are available at their web site: ExtJS: http://extjs.com Please note the licensing requirements for ExtJS. It is your responsibility to comply with these. Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved 1

Enterprise Web Developer Using the ExtJS Widgets

Embed Size (px)

Citation preview

Page 1: Enterprise Web Developer Using the ExtJS Widgets

Enterprise Web Developer

Using the ExtJS Widgets

Version 4.0.746

Background

Enterprise Web Developer (EWD) includes advanced functionality that allows you tomake use of the powerful Javascript widget libraries from ExtJS (http://extjs.com). Byincorporating these widgets into your applications, you'll be able to quickly and easilycreate Rich Internet Applications. Unlike users of these widget libraries who areforced to hand-craft the required code, you'll be able to let EWD do all the hard work.With EWD you'll be creating in minutes what others will take days or weeks toaccomplish. Your web applications will never look the same again!

This document is a reference guide to using EWD's ExtJS custom tags.

Pre-requisites

This guide assumes that you installed EWD (build 746 or later) and have read theeXtc Web Developer Overview, the Installation Guide, Tutorial and Ajax documents.You should also have the main EWD API Guide at hand.

You'll also need to install the ExtJS Javascript library files (version 2.2 or later). Fullinstructions are available at their web site:

• ExtJS: http://extjs.com

Please note the licensing requirements for ExtJS. It is your responsibility to comply with these.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

1

Page 2: Enterprise Web Developer Using the ExtJS Widgets

EWD's ExtJS Custom Tags

EWD provides a set of custom tags that represent the various ExtJS widgets. TheExtJS custom tags have a prefix of ext: For example:

<ext:grid><ext:tree>

EWD's compiler will convert these into the corresponding Javascript and HTML tagsthat you would otherwise have to write by hand. This approach provides you with amuch simpler and intuitive way of using ExtJS widgets, some of which can be verycomplex and require a lot of advanced Javascript programming.

EWD also automatically handles all the many additional complexities that can occurwhen using ExtJS widgets within an Ajax application, where whole sections ofmarkup containing one set of widgets are replaced with new markup containing newsets of widgets. With EWD you can focus on what you're wanting to do with theExtJS widgets, not how they actually work.

The current version of EWD does not implement the full set of ExtJS widgets, but themain desktop, windowing and layout widgets are available. More widgets will beadded in future builds.

ExtJS widgets are highly configurable via what are known as config options. EWDallows you to apply these config options by mapping them to correspondingly namedattributes within each ExtJS custom tag. Usually EWD will automatically apply a setof sensible defaults for config options that you don't specify. Values for all configoptions can be either string literal values or session variables, for example:

<ext:gridColumn header="#col1Title" width="120" sortable="true" />

The header value will be determined by a session variable named colTitle, denoted by the #character, whilst the width and sortable values use fixed literal values.

This document will not list the various config options for each ExtJS custom tag. Ifyou wish to find out the config options that are available for each custom tag, then youshould refer to the ExtJS API documentation at http://extjs.com/deploy/dev/docs/ forthe ExtJS class created by the EWD custom tag (see Appendix I for mappings).

EWD Configuration

When you install the ExtJS libraries, you'll usually do so by creating a sub-directoryunder your web server's root path into which all the ExtJS resurce files are copied, eg:

C:\Program Files\Apache Group\Apache2\htdocs\ext-2.2

or

/var/www/html/ext-2.2

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

2

Page 3: Enterprise Web Developer Using the ExtJS Widgets

If so, the various ExtJS Javascript files will be referred to, within your web pages, viaa relative URL based on the sub-directory name you chose, eg:

/ext-2.2

EWD provides a simple shortcut for loading the ExtJS Javascript files into yourapplications' pages. After the initial <ewd:config> tag at the top of your EWD pages,simply add:

<ext:config path=”/ext2.2” />

Substitute the path as appropriate to your ExtJS installation.

If you are developing an EWD Ajax application, you'll need this ExtJS configurationtag in only your container page(s). It should not appear in your EWD page fragments.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

3

Page 4: Enterprise Web Developer Using the ExtJS Widgets

How EWD's ExtJS tags map to ExtJS Javascript

EWD's ExtJS custom tags allow you to express ExtJS widgets in terms of nestedXML tags. However, EWD's compiler has to convert the custom tags into theappropriate ExtJS Javascript code. In the main, this is performed as follows:

• Most of the main ExtJS classes have a corresponding EWD Custom Tag, eg:• <ext:Panel> corresponds with Ext.Panel• <ext:ComboBox> corresponds with Ext.form.ComboBox

• Most ExtJS custom tags can be nested inside other ExtJS custom tags (where itmakes sense to do so).

• All the documented config options for an ExtJS class are available as attributes inthe corresponding EWD Custom tag

• Each EWD ExtJS custom tag is compiled into a line of Javascript that instantiatesan instance of the corresponding ExtJS class, eg:

• <ext:panel id="specimenListPanel" border="false" />compiles to:

• var extObjindex463=new Ext.Panel({border:false,id:"specimenListPanel"});

• Unless specifically over-ridden, each child ExtJS tag is added to the items array ofthe corresponding parent ExtJS class. eg:

<ext:panel region="center" id="centerPanel" border="false" > <ext:panel id="trialGridPanel" src="trialSelection.ewd" border="false"/> <ext:panel id="trialSummaryPanel" border="false" /> <ext:panel id="visitGridPanel" border="false" /> <ext:panel id="selectedVisitGridPanel" border="false" /> <ext:panel id="demographicsFormPanel" border="false" /> <ext:panel id="specimenListPanel" border="false" /> </ext:panel>

compiles to:

var extObjindex436=new Ext.Panel({border:false,contentEl:"trialGridPanelDiv",id:"trialGridPanel"});var extObjindex443=new Ext.Panel({border:false,id:"trialSummaryPanel"});var extObjindex448=new Ext.Panel({border:false,id:"visitGridPanel"});var extObjindex453=new Ext.Panel({border:false,id:"selectedVisitGridPanel"});var extObjindex458=new Ext.Panel({border:false,id:"demographicsFormPanel"});var extObjindex463=new Ext.Panel({border:false,id:"specimenListPanel"});var extObjindex429=new Ext.Panel({border:false,id:"centerPanel",items:[extObjindex436,extObjindex443,extObjindex448,extObjindex453,extObjindex458,extObjindex463],region:"center"});

If applicable, you can override the use of the items array and use any other relevantconfig option that takes a collection of object references by using theparentAttribute attribute, eg:

<ext:listeners parentAttribute=”listeners” >

This tells EWD's compiler to add the reference to the ExtJS Listeners object to the listeners config option in the parent tag instead of its items config option.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

4

Page 5: Enterprise Web Developer Using the ExtJS Widgets

This allows you to very simply and easily nest ExtJS widgets (provided it makessense to do so). It also gives you complete control over the widgets and their inter-relationships.

• Some EWD custom tags such as <ext:ewdForm> automatically modify many of itschild EWD ExtJS custom tags, to provide a convenient way of simplifying thetypical use of ExtJS tags.

The principle has been to create a mapping that allows commonly used behaviour tobe packaged up into a small set of interoperating EWD custom tags with a minimumof attributes, whilst allowing the power-user to use any or all of the config optionsfrom within the convenience of EWD's tags.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

5

Page 6: Enterprise Web Developer Using the ExtJS Widgets

ExtJS Layout Widgets: ViewPort

One of the standard layout features provided by ExtJS is the Viewport. This allowsthe browser page to be divided into 5 areas, known as north, south, east, west andcenter. The panels can be initially set to be collapsed and/or with moveable/draggableborders. The Viewport is a good way of making very efficient use of the space withinthe browser page.

The ViewPort creates the outer container within the browser, and Panels are then usedto define the working areas within it. In complex applications, the primary viewportpanels can, themselves, include one or more sub-panels.

Let's create a simple example. First, create a new EWD application sub-directorynamed extjsDemo. Eg if your EWD Application Root Path is c:\ewdApps, create:

c:\ewdApps\extjsDemo

Copy the page definition below and save it in a file named viewportDemo1.ewd in the extjsDemo application directory.

Note: EWD does not currently allow tags to be split across more than one line. Theexample boxes in this document will show some lines wrapped across 2 or morelines. Make sure you reduce these to a single line per tag in your EWD sourcefiles.

You should then have a file:

c:\ewdApps\extjsDemo\viewportDemo1.ewd

<ewd:config isFirstPage="true" /><ext:config path="/ext-2.2" /><html> <head> <title>EWD/Ext-JS Viewport & Layout Demo</title> </head> <body> <ext:viewport layout="border"> <ext:panel region="north" el="myNorthRegion" autoHeight="true" border="false"margins="0 0 1 0" /> <ext:panel region="west" title="West Region" collapsed="true" collapsible="true" split="true"width="500" minWidth="200" /> <ext:panel region="east" title="East Region" collapsed="true" collapsible="true" split="true"width="450" minWidth="250" /> <ext:panel region="center" title="Center Region" /> <ext:panel region="south" title="South Region" collapsed="true" collapsible="true"split="true" height="250" minHeight="100" /> </ext:viewport> <div id="myNorthRegion" style="text-align:center">This is the North Panel</div> </body></html>

Compile this page to the technology of your choice, eg:

d compileAll^%zewdAPI(“extjsDemo”,,”php”)Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

6

Page 7: Enterprise Web Developer Using the ExtJS Widgets

The first time you compile this page you should compile the complete application toensure that EWD generates all the additional supporting pages. Thereafter you canjust recompile the page on its own using:

d compilePage^%zewdAPI(“extjsDemo”,”viewportDemo1”,,”php”)

If you've installed and configured everything properly, when you run this page in abrowser, you should see something like the following:

If you click on the arrowed tabs on the west, east and south panels, they should eachslide into view. You can then drag their borders around or collapse them again byclicking the arrowed tabs again.

Note the way the North panel contents has been defined in a separate <div> tag, and isreferenced using the el attribute. In fact, contentEl is the recommended attribute touse, but this will produce a white panel whereas el produces the blue one. Try it andsee!

Currently, of course, there's nothing in any of the other panels, so let's rectify that!

Let's create a simple page fragment that we'll use as content for each of the panels.Copy and paste the following fragment definition into a file and save it in theextjsDemo directory as panelContent1.ewd.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

7

Page 8: Enterprise Web Developer Using the ExtJS Widgets

<ewd:config isFirstPage="false" pageType="ajax" /><span style="background-color:#ffffff;">Hello world!</span>

Now add a src attribute referring to this fragment to the east, west, south and centerpanels:

<ewd:config isFirstPage="true" /><ext:config path="/ext-2.2" /><html> <head> <title>EWD/Ext-JS Viewport & Layout Demo</title> </head> <body> <ext:viewport layout="border"> <ext:panel region="north" el="myNorthRegion" autoHeight="true" border="false"margins="0 0 1 0" /> <ext:panel region="west" src="panelContent1.ewd" title="West Region" collapsed="true"collapsible="true" split="true" width="500" minWidth="200" /> <ext:panel region="east" src="panelContent1.ewd" title="East Region" collapsed="true"collapsible="true" split="true" width="450" minWidth="250" /> <ext:panel region="center" src="panelContent1.ewd" title="Center Region" /> <ext:panel region="south" src="panelContent1.ewd" title="South Region" collapsed="true"collapsible="true" split="true" height="250" minHeight="100" /> </ext:viewport> <div id="myNorthRegion" style="text-align:center">This is the North Panel</div> </body></html>

Recompile the entire application:

d compileAll^%zewdAPI(“extjsDemo”,,”php”)

and reload viewportDemo1 in your browser. Each of the panels should now containthe text Hello world!

You're now ready to extend this into a fully-fledged Ajax application. First, simplycopy the panelContent1.ewd file to create separately named fragments, eg:

• panelContentEast.ewd• panelContentWest.ewd• panelContentCenter.ewd• panelContentSouth.ewd

Next add a unique id attribute to the <span> tag in each of these fragments, eg inpanelContentEast.ewd:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

8

Page 9: Enterprise Web Developer Using the ExtJS Widgets

<ewd:config isFirstPage="false" pageType="ajax" /><span id="myEastPanel" style="background-color:#ffffff;"> Initial text in the East Panel</span>

Finally change the references in the src attributes to the respective fragments, eg:

<ext:viewport layout="border"> <ext:panel region="north" el="myNorthRegion" autoHeight="true" border="false"margins="0 0 1 0" /> <ext:panel region="west" src="panelContentWest.ewd" title="West Region" collapsed="true"collapsible="true" split="true" width="500" minWidth="200" /> <ext:panel region="east" src="panelContentEast.ewd" title="East Region" collapsed="true"collapsible="true" split="true" width="450" minWidth="250" /> <ext:panel region="center" src="panelContentCenter.ewd" title="Center Region" /> <ext:panel region="south" src="panelContentSouth.ewd" title="South Region"collapsed="true" collapsible="true" split="true" height="250" minHeight="100" /> </ext:viewport>

Recompile the extjsDemo application and refresh your browser. You should see thedifferent content in each of the panels. The cool thing is that you've now also loaded aunique target id into the top of each of the panels, so you can now start delivering newfragments into each specific panel in response to user-generated events. Because thisis actually just one physical browser page, an event in one panel can cause a fragmentto be targetted into the same or any other panel.

Let's try this out. Your main container page (viewportDemo1.ewd) should now belooking like this:

<ewd:config isFirstPage="true" /><ext:config path="/ext-2.2" /><html> <head> <title>EWD/Ext-JS Viewport & Layout Demo</title> </head> <body> <ext:viewport layout="border"> <ext:panel region="north" el="myNorthRegion" autoHeight="true" border="false"margins="0 0 1 0" /> <ext:panel region="west" src="panelContentWest.ewd" title="West Region" collapsed="true"collapsible="true" split="true" width="500" minWidth="200" /> <ext:panel region="east" src="panelContentEast.ewd" title="East Region" collapsed="true"collapsible="true" split="true" width="450" minWidth="250" /> <ext:panel region="center" src="panelContentCenter.ewd" title="Center Region" /> <ext:panel region="south" src="panelContentSouth.ewd" title="South Region"collapsed="true" collapsible="true" split="true" height="250" minHeight="100" /> </ext:viewport> <div id="myNorthRegion" style="text-align:center">This is the North Panel</div> </body></html>

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

9

Page 10: Enterprise Web Developer Using the ExtJS Widgets

and your fragment named panelContentEast.ewd should currently contain:

<ewd:config isFirstPage="false" pageType="ajax" /><span id="myEastPanel" style="background-color:#ffffff;"> Initial text in the East Panel</span>

Note the target id this will introduce into the container page: myEastPanel

Now change your fragment named panelContentCenter.ewd to contain:

<ewd:config isFirstPage="false" pageType="ajax" />

<script language="javascript"> function changeLeftPanel() { ewd.ajaxRequest("panelContentEast2","myEastPanel") ; }</script>

<span id="myCenterPanel" style="background-color:#ffffff;"> <input type="button" value="Click me!" onclick="changeLeftPanel()" /></span>

Let's examine what this fragment will do: when the button in this fragment is clicked,it will trigger the javascript function changeLeftPanel(), causing a fragment namedpanelContentEast2.ewd to be fetched and targetted in the id that was originally sentinto the East panel by the fragment panelContentEast.ewd.

So let's now finally create the fragment panelContentEast2.ewd:

<ewd:config isFirstPage="false" pageType="ajax" /><span> Look! The content in the East Panel has been changed!</span>

Recompile the extjsDemo application and refresh the browser. If you slide the Eastpanel open, you should see the following:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

10

Page 11: Enterprise Web Developer Using the ExtJS Widgets

Now click the button in the Center panel. The content in the East panel shouldchange:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

11

Page 12: Enterprise Web Developer Using the ExtJS Widgets

Your ExtJS Viewport is now ready to provide a framework for a complete Ajaxapplication!

Extending the Viewport: Tabs

ExtJS allows you to add tabbed panels to your Viewport. Let's add some to the centerpanel.

First, edit the main viewportDemo1.ewd page, and change the center panel tag from:

<ext:panel region="center" src="panelContentCenter.ewd" title="Center Region" />

to:

<ext:tabPanel region="center" > <ext:Panel title="Panel 1" closable="false" src="panelContentCenter.ewd" active="true" /> <ext:Panel title="Panel 2" closable="false" fragmentOnSelect="panelContentCenter2.ewd" /> </ext:tabPanel>

What's going to happen is that the second tab won't load its content fragment until thetab is clicked. We'll need to create that fragment, as a file namedpanelContentCenter2.ewd:

<ewd:config isFirstPage="false" pageType="ajax" />

<span id=”myTab2”> This is the second tabbed panel in the center region!</span>

Once again, we'll seed a targetId (in this case myTab2) into the second tab pane, so wecan use this for targetting later fragments into the panel.

Try recompiling the extjsDemo application and refresh the browser again. This timeyou should see the following:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

12

Page 13: Enterprise Web Developer Using the ExtJS Widgets

The panel for Tab 1 is displayed (using the content from fragmentpanelContentCenter.ewd) because its active attribute was set to true:

<ext:tab title="Panel 1" closable="false" src="panelContentCenter.ewd" active="true" />

Click the tab named Panel 2 and you should see the second tab appear with itscontents fetched from the fragment panelContentCenter2.ewd.

You can now add as many tabs as you like to any of the panels in the viewport.

Extending the Viewport: Accordion Panes

Another great feature you can add to your viewport is accordion panes. These allowlots of information to be stacked up into a pile of panels, with only one visible at anyone time. You can slide each panel into view simply by clicking its title bar or button.

EWD makes it easy to add accordion panes. Let's add some to the West panel.

First, edit the main viewportDemo1.ewd page, and change the west panel tag from:

<ext:panel region="west" src="panelContent1.ewd" title="West Region" collapsed="true"collapsible="true" split="true" width="500" minWidth="200" />

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

13

Page 14: Enterprise Web Developer Using the ExtJS Widgets

to:

<ext:accordionPanel region="west" title="West Region" collapsed="true" collapsible="true"split="true" width="500" minWidth="200"> <ext:Panel id="pane1" border="false" title="Accordion Panel 1"src="accordionContent1.ewd" /> <ext:Panel id="pane2" border="false" title="Accordion Panel 2"src="accordionContent2.ewd" /> </ext:accordionPanel>

Now we'll create the two content fragments:

accordionContent1.ewd:

<ewd:config isFirstPage="false" pageType="ajax" />

<span id="myAccordionPane1"> This is the first accordion panel</span>

accordionContent2.ewd:

<ewd:config isFirstPage="false" pageType="ajax" />

<span id="myAccordionPane2"> This is the second accordion panel</span>

Try recompiling the extjsDemo application and refresh the browser again. If you slideopen the West panel, you should see the following:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

14

Page 15: Enterprise Web Developer Using the ExtJS Widgets

Click on the button at the right-hand side of the Accordion Panel 2 title banner and itwill slide open, replacing the first one.

Because we added unique ids to each of the content fragments, we can now targetthese accordion panels with Ajax page fragments!

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

15

Page 16: Enterprise Web Developer Using the ExtJS Widgets

ExtJS Layout Widgets: Toolbar & Menus

Another set of layout widgets provided by ExtJS allows you to add a toolbar to the topof your page (or panel), to which you can add buttons and drop-down menus.

Once again, EWD makes it very quick and easy to use these widgets.

First, create a new EWD page named toolbarDemo.ewd in your extjsDemo directory,containing the following:

<ewd:config isFirstPage="true"><ext:config path="/ext-2.2" debug="true"/>

<html><head><title>Toolbar Demo</title></head><body> <ext:toolbar id="myToolbar" autorender="true" />

<div id="myContent">This is a demo of the ExtJS Toolbar and Menus</div>

</body></html>

Compile using, eg:

d compileAll^%zewdAPI(“extjsDemo”,,”php”)

Load this page into a browser and you should see the text:

This is a demo of the ExtJS Toolbar and Menus

underneath a very thin blue line. This thin blue line is the taskbar which, because itdoesn't yet contain anything, is barely visible (Note: the EWD-specific attributeautoRender=”true” tells EWD to add a <div> tag to the page that is used as therendering point for the toolbar. If you next the <ext:toolbar> tag inside any type ofPanel tag, it will automatically render itself into the Panel).

We'll now add a menu button to this. Replace the line:

<ext:toolbar id="myToolbar" autorender="true" />

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

16

Page 17: Enterprise Web Developer Using the ExtJS Widgets

with:

<ext:toolbar id="myToolbar" autorender="true"> <ext:toolBarButton text="Example Menu" /></ext:toolbar>

Recompile toolbarDemo.ewd using, eg:

d compilePage^%zewdAPI(“extjsDemo”,”toolbarDemo”,,”php”)

and refresh your browser. You should now see the toolbar properly, complete withthe menu option. When you roll your mouse over the menu option, it will appear as abutton:

Clicking the menu option won't have any effect right now. Now let's add a couple ofmenu options to it.

<ext:toolbar id="myToolbar" autorender="true"> <ext:toolBarButton text="Example Menu"> <ext:menu> <ext:menuItem text="First Option" /> <ext:menuItem text="Second Option" /> </ext:menu> </ext:toolBarButton></ext:toolbar>

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

17

Page 18: Enterprise Web Developer Using the ExtJS Widgets

Recompile the page and refresh your browser. Now when you click the menu button,a drop-down panel with the two menu options will appear.

Now let's add an event handler to the options so that we can trigger events when theyare clicked:

<ext:toolbar id="myToolbar" autorender="true"> <ext:toolBarButton text="Example Menu"> <ext:menu> <ext:menuItem id="opt1" text="First Option" onselect="Ext.Msg.alert('Menu Action','Youselected: ' + item.id + ': ' + item.text);" /> <ext:menuItem id="opt2" text="Second Option" onselect="Ext.Msg.alert('Menu Action','Youselected: ' + item.id + ': ' + item.text);" /> </ext:menu> </ext:toolBarButton></ext:toolbar>

Notice that the object item is available to your event handler and its two properties idand text return the values of the corresponding attributes for the menu item that wasclicked by the user. In this simple example we're just generating an alert, displayingwhich menu option was clicked. Notice that in this example we're making use of theExtJS alert which allows you to specify a message heading and automatically greysthe background. We could, of course, used a standard Javascript alert().

Recompile the page and refresh the browser. Now you should get an alert when youclick a menu option.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

18

Page 19: Enterprise Web Developer Using the ExtJS Widgets

It's now a simple step to use this menu to drive some Ajax behaviour. For example,we could add a Javascript functionto the EWD page:

<script language="javascript"> function mySelectHandler(item) { if (item.id == "opt1") { ewd.ajaxRequest("toolbarContent1","myContent") ; } if (item.text == "Second Option") { ewd.ajaxRequest("toolbarContent2","myContent") ; } } </script>

Next, change the event handlers in the <ext:menuItem> tags:

<ext:toolbar id="myToolbar" autorender="true"> <ext:toolBarButton text="Example Menu"> <ext:menu> <ext:menuItem id="opt1" text="First Option" onselect="mySelectHandler(item) " /> <ext:menuItem id="opt2" text="Second Option" onselect="mySelectHandler(item) " /> </ext:menu> </ext:toolBarButton></ext:toolbar>

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

19

Page 20: Enterprise Web Developer Using the ExtJS Widgets

And now create the two fragments:

toolbarContent1.ewd:

<ewd:config isFirstPage="false" pageType="ajax" />

<span> Here is the first option content!</span>

toolbarContent2.ewd:

<ewd:config isFirstPage="false" pageType="ajax" />

<span> Here is the second option content!</span>

Recompile the extjsDemo application and refresh the browser. Now when you click amenu option, the content below the toolbar is replaced with that of the correspondingfragment. Of course we could have targetted any id within the browser page.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

20

Page 21: Enterprise Web Developer Using the ExtJS Widgets

Multi-level Menus

EWD makes it easy to have multi-level drop-down menus of any depth you like.Simply use nested <ext:menuOption> tags, using the nesting to reflect the menuhierarchy you require, eg:

<ext:toolbar id="myToolbar" autorender="true"> <ext:toolBarButton text="Example Menu"> <ext:menu> <ext:menuItem id="opt1" text="First Option" onselect="mySelectHandler(item)" /> <ext:menuItem id="opt2" text="Second Option" onselect="mySelectHandler(item)" /> <ext:menuItem id="opt3" text="Third Option" onselect="mySelectHandler(item)"> <ext:menu> <ext:menuItem id="opt3a" text="Option 3a" onselect="mySelectHandler(item)" /> <ext:menuItem id="opt3b" text="Option 3b" onselect="mySelectHandler(item)"> <ext:menu> <ext:menuItem id="opt3b1" text="Option 3b-1" onselect="mySelectHandler(item)" /> <ext:menuItem id="opt3b2" text="Option 3b-2" onselect="mySelectHandler(item)" /> </ext:menu> </ext:menuItem> <ext:menuItem id="opt3c" text="Option 3c" onselect="mySelectHandler(item)" /> <ext:menuItem id="opt3d" text="Option 3d" onselect="mySelectHandler(item)"> <ext:menu> <ext:menuItem id="opt3d1" text="Option 3d-1" onselect="mySelectHandler(item)" /> <ext:menuItem id="opt3d2" text="Option 3d-2" onselect="mySelectHandler(item)" /> <ext:menuItem id="opt3d3" text="Option 3d-3" onselect="mySelectHandler(item)" /> </ext:menu> </ext:menuItem> </ext:menu> </ext:menuItem> <ext:menuItem id="opt4" text="Fourth Option" onselect="mySelectHandler(item)" /> </ext:menu> </ext:toolBarButton></ext:toolbar>

This will generate the following menu in the browser:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

21

Page 22: Enterprise Web Developer Using the ExtJS Widgets

Checkbox Menu Options

ExtJS also allows you to have menu options that you can check, firing an event whenyou do so. Once again, EWD makes this easy to use. Use the <ext:checkItem> taginstead and use a different event handler: onCheck. The onCheck handler worksidentically to the onSelect handler, but the item object includes a checked property toallow your method to perform the correct actions depending on whether the checkboxwas checked or unchecked by the user. For example:

<ext:checkItem id="opt3d4" text="I like EWD" oncheck="alert('Checked the menu item: ' +item.text + '; checked=' + item.checked);" />

Menu Separators and Heading Titles

You can very easily add separator bars to split up logical groups of menu options bysimply using the <ext:menuSeparator /> tag, eg:

<ext:toolbar id="myToolbar" autorender="true"> <ext:toolBarButton text="Example Menu"> <ext:menu> <ext:menuItem id="opt1" text="First Option" onselect="mySelectHandler(item)" /> <ext:menuSeparator /> <ext:menuItem id="opt2" text="Second Option" onselect="mySelectHandler(item)" /> <ext:menuItem id="opt3" text="Third Option" onselect="mySelectHandler(item)"> <ext:menu> <ext:menuItem id="opt3a" text="Option 3a" onselect="mySelectHandler(item)" /> <ext:menuItem id="opt3b" text="Option 3b" onselect="mySelectHandler(item)"> <ext:menu> <ext:menuItem id="opt3b1" text="Option 3b-1" onselect="mySelectHandler(item)" /> <ext:menuItem id="opt3b2" text="Option 3b-2" onselect="mySelectHandler(item)" /> </ext:menu> </ext:menuItem> <ext:menuItem id="opt3c" text="Option 3c" onselect="mySelectHandler(item)" /> <ext:menuItem id="opt3d" text="Option 3d" onselect="mySelectHandler(item)"> <ext:menu> <ext:menuItem id="opt3d1" text="Option 3d-1" onselect="mySelectHandler(item)" /> <ext:menuItem id="opt3d2" text="Option 3d-2" onselect="mySelectHandler(item)" /> <ext:checkItem id="opt3d3" text="Option 3d-3" oncheck="alert(1)"onselect="mySelectHandler(item)" /> <ext:checkItem id="opt3d4" text="I like EWD" oncheck="alert('Checked the menu item: '+ item.text + '; checked=' + item.checked);" /> </ext:menu> </ext:menuItem> </ext:menu> </ext:menuItem> <ext:menuSeparator /> <ext:menuItem id="opt4" text="Fourth Option" onselect="mySelectHandler(item)" /> </ext:menu> </ext:toolBarButton></ext:toolbar>

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

22

Page 23: Enterprise Web Developer Using the ExtJS Widgets

Alternatively (or additionally) you can use the <ext:menuTextItem> tag to create atext heading that acts as a title and separator between blocks of menu options, eg:

<ext:toolbar id="myToolbar" autorender="true"> <ext:toolBarButton text="Example Menu"> <ext:menu> <ext:menuItem id="opt1" text="First Option" onselect="mySelectHandler(item)" /> <ext:menuTextItem text="Normal Options" /> <ext:menuSeparator /> <ext:menuItem id="opt2" text="Second Option" onselect="mySelectHandler(item)" /> <ext:menuItem id="opt3" text="Third Option" onselect="mySelectHandler(item)"> <ext:menu> <ext:menuItem id="opt3a" text="Option 3a" onselect="mySelectHandler(item)" /> <ext:menuItem id="opt3b" text="Option 3b" onselect="mySelectHandler(item)"> <ext:menu> <ext:menuItem id="opt3b1" text="Option 3b-1" onselect="mySelectHandler(item)" /> <ext:menuItem id="opt3b2" text="Option 3b-2" onselect="mySelectHandler(item)" /> </ext:menu> </ext:menuItem> <ext:menuItem id="opt3c" text="Option 3c" onselect="mySelectHandler(item)" /> <ext:menuItem id="opt3d" text="Option 3d" onselect="mySelectHandler(item)"> <ext:menu> <ext:menuItem id="opt3d1" text="Option 3d-1" onselect="mySelectHandler(item)" /> <ext:menuItem id="opt3d2" text="Option 3d-2" onselect="mySelectHandler(item)" /> <ext:checkItem id="opt3d3" text="Option 3d-3" oncheck="alert(1)"onselect="mySelectHandler(item)" /> <ext:checkItem id="opt3d4" text="I like EWD" oncheck="alert('Checked the menu item: '+ item.text + '; checked=' + item.checked);" /> </ext:menu> </ext:menuItem> </ext:menu> </ext:menuItem> <ext:menuTextItem text="Special Options" /> <ext:menuItem id="opt4" text="Fourth Option" onselect="mySelectHandler(item)" /> </ext:menu> </ext:toolBarButton></ext:toolbar>

Simple Toolbar Buttons

A toolbar button doesn't have to have a menu attached to it: it can be a simple buttonwith an associated event hander. For example:

<ext:toolBarButton text="Hide Help" id="hideHelpBtn" pressed="true" onclick="hideHelp(item)">

By using the pressed attribute, you can make the button stand out as a properlyrendered button on the toolbar without you having to hover over it.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

23

Page 24: Enterprise Web Developer Using the ExtJS Widgets

Make sure your event handler passes the variable item, as shown above. Thisprovides a pointer to the button object. So, for example, you could immediately hidethe button and show another instead using:

function hideHelp(item) { item.hide() ; Ext.getCmp('showHelpBtn').show(); }

Note the use of Ext.getCmp() which is how you get a pointer to another ExtJScomponent via its id.

Of course your event handler could also be used to trigger the fetch of another EWDfragment into a targetId, eg.

function getHelp(item) { item.hide() ; Ext.getCmp('HelpPanel').show(); ewd.ajaxRequest(“helpDetails”,”helpDiv”) ; }

Other Toolbar widgets

ExtJS provides a number of other Toolbar widgets that are mapped to equivalentEWD custom tags. These include:

• <ext:toolbarFill />This pushes all subsequent toolbar widgets to the right. It has no attributes.

• <ext:toolbarSpacer />This adds some space between adjacent toolbar widgets. It has no attributes

• <ext:toolbarSeparator />This adds a vertical bar as a separator between adjacent widgets. It has noattributes

• <ext:toolbarTextItem text=”Some text” />This adds a piece of text into the toolbar.

Panels, Toolbars and StatusBars

By using the nestable behaviour of the EWD ExtJS tags, you can put toolbars andstatus bars inside Panel widgets, and panels inside other panels. For example:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

24

Page 25: Enterprise Web Developer Using the ExtJS Widgets

<ext:Panel id="mainPanel" title="Main container Panel" layout="absolute" border="true"frame="false" width="1000" height="600" autoRender="true">

<ext:Panel id="subPanel" title="Panel with Toolbar and Status bar" border="true" x="100"y="100" frame="false" width="500" contentEl="panelContents">

<ext:toolbar id="theToolbar"> <ext:toolBarButton text="Add Site" pressed=”true” onclick="addSite()"/> <ext:toolBarFill /> <ext:toolBarButton text="Test" onclick="testit()"/> </ext:toolbar>

<ext:statusBar id="myStatusBar" defaultText="Current Status OK"> <ext:toolBarButton text="Click Me" onclick="goToMatching(item)"/> <ext:toolBarSeparator /> <ext:toolBarTextItem text="status"/> </ext:statusBar>

</ext:Panel>

<ext:statusBar id="outerStatusBar" defaultText="This is the outer panel" />

</ext:Panel>

<div id="panelContents"> <br /> <p>This is a test panel</p> <p>with its own toolbar and statusbar</p> <br /></div>

This should render as shown below:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

25

Page 26: Enterprise Web Developer Using the ExtJS Widgets

In this example, the outer container panel is rendered using autoRender=”true”, soEWD automatically adds a <div> tag to the page/fragment that will be used as itsrendering anchor point. The inner panel will render itself automatically inside thecontainer panel. By specifying the outer panel as layout=”absolute”, the inner onecan be positioned inside it using the x and y attributes.

By nesting the toolbar and statusbar inside the inner panel, it is rendered with thetoolbar and statusbar. But notice the outer panel also has its own status bar: it's allcontrolled by the level of nesting of the tags.

The contents for the inner panel are obtained, in this example, from a <div> tag thatwe've specified and hard-coded. The contentEl attribute is used to pull this contentinto the panel.

Finally, notice how the statusBar widget can make use of and or all of the varioustoolBar widgets, and notice the use of the pressed=”true” attribute in the first toolbarbutton which makes it visually appear as a button without the need to float yourmouse over it.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

26

Page 27: Enterprise Web Developer Using the ExtJS Widgets

Grids

One of the greatest and most powerful features in ExtJS is its grid widget. Grids canbe either read-only or editable, or a mixture of the two (ie with some columns beingeditable and some being display-only).

EWD makes it very quick and simple to use ExtJS grid widgets.

We'll start with a simple display-only grid. Like many ExtJS widget, the data in a gridis held in a datastore. This is a JSON-based data structure which is delivered to thebrowser from the back-end system. EWD looks after all the JSON-specific aspects ofthe datastore creation and transmission, leaving you just the simple task of specifyingthe array of data that will populate the datastore and hence the grid.

First, let's create a simple page that will display a grid. Copy the contents below into afile named gridDemo.ewd.

<ewd:config isFirstPage="true"><ext:config path="/ext-2.2" />

<html><head> <title>Ext JS Grid Example</title></head><body>

<span><ext:grid datastore="myData" stripeRows="true" autoRender=”true” title="Example Ext/EWDGrid" width="400" frame="true" autoHeight=”true”> <ext:gridColumn header="Company" width="60" sortable="true" tooltip="The company inquestion"/> <ext:gridColumn header="Price" type="float" width="30" sortable="true" /> <ext:gridColumn header="Change" type="float" width="30" sortable="true" /></ext:grid></span>

</body></html>

You define an ExtJS grid using two custom tags:

<ext:grid> This defines the grid container, its dimensions and styling

<ext:gridColumn> This defines each column in the grid, and characteristicssuch as its heading, data type and whether or not it can besorted by clicking the column heading

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

27

Page 28: Enterprise Web Developer Using the ExtJS Widgets

If you compile and run the gridDemo.ewd page, you'll find that you get an InvalidRequest error. This is because we haven't created the datastore named myData that isreferred to in the <ext:grid> tag.

Datastores are the responsibility of the programmer to create, and this is done in theprePageScript. Add a pre-page script to the <ewd:config> tag:

<ewd:config isFirstPage="true" prePageScript="##class(ewd.test).getDemoGridData">

In the example above, we're going to call a Caché class method namedgetDemoGridData in a class named ewd.test. You can change this to use a class ofyour own choice. Here's the source code for the class method:

ClassMethod getDemoGridData(sessid As %String) As %String{s data(1,1)="Apple"s data(1,2)=29.89s data(1,3)="0.24"s data(1,4)="true"s data(2,1)="Ext"s data(2,2)=83.81s data(2,3)="0.28"s data(2,4)="true"s data(3,1)="Google"s data(3,2)=71.72s data(3,3)="0.02"s data(3,4)="false"s data(4,1)="Microsoft"s data(4,2)=52.55s data(4,3)="0.01"s data(4,4)="true"d createGridDatastore^%zewdExtJS(.data,"myData",”r”,sessid)QUIT ""}

In this example we're simply hard-coding values, but in real-world examples thevalues would be fetched from your database. However, the pattern will be the same:

• create a 2-dimensional local array: array(rowNo, colNo) = value

• pass this array into the createGridDatastore function that EWD provides for you.Note the parameter “r”. This specifies that the EWD Session array named myDatais allowed to be read via JSON by the browser. This parameter can be left blank,as “r” is the default.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

28

Page 29: Enterprise Web Developer Using the ExtJS Widgets

The programmer's task is therefore straightforward and intuitive. He/she needs toknow nothing about how the ExtJS grid datastore is structured in JSON terms, norhow it is conveyed to the browser.

Equally, the page designer's task is straightforward and intuitive. Specify the grid andits column structure, and specify the name of the datastore that will populate it.

If you save and compile the class method above (adjusting the reference to it in theprePageScript attribute appropriately), then recompile the gridDemo.ewd page, whenyou reload the browser you should now see the following:

Note the way you can click on the column headings, and how you can drag thecolumns around, and also turn columns on and off. Note that we only opted to display3 of the columns that were available in the datastore. Look at the class method listingabove and notice that the fourth column of data consists of just the values true andfalse, so a good way to represent this data would be with a checkbox. This is quiteeasy but first you will need to load a special Javascript file that you'll find in the EWDdownload zip file: ExtExtensions.js. Place a copy of this file in an appropriate path onyour web server – in this example we'll assume that it is in the root path. Now add thefollowing tag to the <head> section of your page:

<script src="/ExtExtensions.js" type="text/javascript"></script>

Now add the extra column definition:

<ext:gridColumn header="In Stock" renderAs="checkbox" width="30" />

So, simply by specifying the column using renderAs=”checkbox”, EWD will compilein the necessary ExtJS Javascript to use a checkbox for this column,

You can try modifying some of the grid column attributes, add further columns, etc.For details of the available config option attributes, go to the ExtJS API guide athttp://extjs.com/deploy/dev/docs/ and reference:

<ext:grid> Ext/grid/GridPanel<ext:gridColumn> Ext/grid/ColumnModel

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

29

Page 30: Enterprise Web Developer Using the ExtJS Widgets

Editable Grids

EWD and ExtJS also allow you to make a grid editable, so you can use it as a simplespreadsheet-like interface for editing data in your database.

To create an editable grid, use the <ext:editorGridPanel> tag instead of the<ext:grid> tag.

You can make any or all of the columns editable by adding the attribute editAs to the<ext:gridColumn> tags. The value of the editAs attribute specifies the datatype andhence the mechanism and/or widgets that ExtJS will bring into play to allow you toedit the data field. Supported values in EWD are:

• text simple text field allowing any alphanumeric character• number text field allowing only numeric values• checkbox on/off checkbox for boolean values• select drop-down list of possible valid options for the value• date pop-up calendar widget allows simple date entry• textarea automatically expanding textarea box for multi-line text

For example, the following demonstrates how to specify all these types:

<ext:gridColumn header="First Page" editAs="text" width="90" sortable="true" /> <ext:gridColumn header="Timeout (sec)" type="float" editAs="number" width="90"sortable="true" /> <ext:gridColumn header="Fast Symbol Table" editAs="checkbox" width="110" /> <ext:gridColumn header="Namespace" width="120" editAs="select" name="namespace"sortable="true"/> <ext:gridColumn header="Compiled Date" dateFormat="d M Y" editAs="date" width="120" /> <ext:gridColumn header="Notes" editAs="textarea" grow="true" growMax="160" width="120" />

See later for more details on how to handle each of these types.

For now, let's modify our simple gridDemo.ewd page to make the Price columneditable:• change the grid tag to an editorGridPanel tag• add the attribute clicksToEdit="1" to the editorGridPanel. By default you have to

click on a field twice to edit it, but a single click tends to be more intuitive.• change the Price column definition to include editAs=”number” :

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

30

Page 31: Enterprise Web Developer Using the ExtJS Widgets

<ext:editorgridpanel datastore="myData" clicksToEdit="1" stripeRows="true" title="ExampleExt/EWD Grid" width="400" frame="true"> <ext:gridColumn header="Company" width="60" sortable="true" tooltip="The company inquestion"/> <ext:gridColumn header="Price" type="float" width="30" editAs="number" sortable="true" /> <ext:gridColumn header="Change" type="float" width="30" sortable="true" /> <ext:gridColumn header="In Stock" type="bool" renderAs="checkbox" width="30" /></ext:editorgridpanel>

When you recompile the page and refresh the browser, you should find that when youclick on any Price cell, you can now edit the value. Note the way you can only enternumeric characters!

Although you can now change the values, they're only being altered locally. We nowneed to get the new, edited value to the back-end and into the hands of theprogrammer who can validate and process the new, edited value if required.

This is done by adding a validationScript attribute to the <ext:editorGridPanel> tag.

<ext:editorgridpanel datastore="myData" clicksToEdit="1" stripeRows="true" title="ExampleExt/EWD Grid" width="400" frame="true" validationScript=" class(ewd.test).setDemoGridData" >

Note that you must not specify the method using ##class. Make sure you leave outthe two # characters.

You must also give the EWD Session datastore read/write permissions. You do thisby changing the “r” parameter to “rw” in the createGridDatastore() method that youused in the prePageScript, ie.

ClassMethod getDemoGridData(sessid As %String) As %String{s data(1,1)="Apple"s data(1,2)=29.89s data(1,3)="0.24"s data(1,4)="true"s data(2,1)="Ext"s data(2,2)=83.81s data(2,3)="0.28"s data(2,4)="true"s data(3,1)="Google"s data(3,2)=71.72s data(3,3)="0.02"s data(3,4)="false"s data(4,1)="Microsoft"s data(4,2)=52.55s data(4,3)="0.01"

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

31

Page 32: Enterprise Web Developer Using the ExtJS Widgets

s data(4,4)="true"d createGridDatastore^%zewdExtJS(.data,"myData",”rw”,sessid)QUIT ""}

Now, every time an editable grid cell value is changed and you move away from thegrid cell, this method will fire, passing the row number, column number and newvalue to the programmer. Note that the row and column numbers will be the originalvalues for the cell, so it doesn't matter if the user re-sorts the contents or drags thecoumns around.

So let's take a look at a simple example of what the programmer might do in the back-end validationScript method:

ClassMethod setDemoGridData(sessid As %String) As %String{s row=$$getSessionValue^%zewdAPI("extGridRow",sessid)s column=$$getSessionValue^%zewdAPI("extGridColumn",sessid)s value=$$getSessionValue^%zewdAPI("extGridValue",sessid)i value>99 QUIT "Value is too big!"QUIT ""}

When you change a value, EWD instantiates three session variables:

extGridRowextGridColumnextGridValue

The programmer should pick up these values in his/her script and perform anyvalidation. In the example above we're simply ensuring that the value cannot begreater than 99. In the event of a validation error, the programmer simply QUITs,returning an error message string. EWD automatically uses this to bring up an ExtJSalert.

If the value validates OK, the programmer can optionally save the new value. It is theprogrammer's responsibility to ensure that the row and column numbers providehim/her with sufficient information to save the new value back into the correct placein the database.

The modified value does not need to be committed to the database immediately. Themodified values reside in an EWD Session Array, in this case named myData. Whenediting is completed, the programmer can commit all the changed data at once. Forexample, to access the modified EWD Session values for the grid:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

32

Page 33: Enterprise Web Developer Using the ExtJS Widgets

d mergeArrayFromSession^%zewdAPI(.myData,"myData",sessid)

The local array myData is exactly the same format as originally created in thegetDemoGridData() prePageScript method, but now contains the validated editedvalues. Note that any new values that failed validation are not changed in the EWDSession array, eg:

myData(1,1)="Apple"myData(1,2)=29.89myData(1,3)="0.24"myData(1,4)="true"myData(2,1)="Ext"myData(2,2)=23myData(2,3)="0.28"myData(2,4)="true"myData(3,1)="Google"myData(3,2)=44myData(3,3)="0.02"myData(3,4)="false"myData(4,1)="Microsoft"myData(4,2)=76myData(4,3)="0.01"myData(4,4)="true"

You should now be able to modify your demonstration grid to allow any of thecolumns to be edited, eg:

<ext:editorgridpanel datastore="myData" clicksToEdit="1" stripeRows="true" title="ExampleExt/EWD Grid" width="400" frame="true" validationScript=" class(ewd.test).setDemoGridData" <ext:gridColumn header="Company" width="60" sortable="true" tooltip="The company inquestion" editAs=”text” /> <ext:gridColumn header="Price" type="float" width="30" editAs="number" sortable="true" /> <ext:gridColumn header="Change" type="float" width="30" sortable="true" editAs=”number” /> <ext:gridColumn header="In Stock" type="bool" width="30" editAs=”checkbox” /></ext:editorgridpanel >

Custom Error Processing

In the previous example you saw how the user could be given an error Alert messagesimply by QUIT'ing with a non-null value in the validation script, eg:

i value>99 QUIT "Value is too big!"

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

33

Page 34: Enterprise Web Developer Using the ExtJS Widgets

Although this behaviour will be suitable for many situations, there will be occasionswhen you want to define the error notification behaviour yourself. This is quite easy.Simply make the first and last characters of the QUIT returnValue { and }respectively, and you can then put any Javascript you like inside these braces. EWDwill automatically eval() your Javascript instead of bringing up an alert. For example:

i value["x" do QUIT error. s error= "{Ext.Msg.alert('Error','bad value!') ;". s error=error_"editEvent.record.set(editEvent.field,editEvent.originalValue) ;". s error=error_"editEvent.cancel = true ;}"

In fact this example uses the same code that executes behind the scenes if you use thedefault mechanism (QUIT with a simple non-null string), and you should note thecommands that have been used to cancel the edit and return the original value back tothe edited cell.

Invoking an Event Handler that Fires when a Row is Selected

Provided your grid does not contain any editable cells, you can add an event handlerthat will fire when you select a row from the grid. You can fire your own method andEWD passes it all the information you need to handle the data relevant to the rowwithin Javascript or in the Caché back-end (via an Event Broker call).

Simply add the attribute onRowSelect to the <ext:grid> tag. The attribute's value willbe the name of your function, eg

<ext:grid datastore="myData" stripeRows="true" title="Example Ext/EWD Grid" width="400"frame="true" onRowSelect="myFunc">

Your event handler function must have two input parameters:

• currentRecord an Array containing the values for each column in the selected row

• currentRow the row number of the back-end data store that you selected

eg:

<script language="javascript"> function myFunc(currentRecord,currentRow) { alert(currentRecord + ": " + currentRow) ; }</script>

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

34

Page 35: Enterprise Web Developer Using the ExtJS Widgets

If you click the third row in our demo grid, currentRow would have a value of 3 andcurrentRecord would contain:

currentRecord[0] = 2currentRecord[1] = “Google”currentRecord[2] = 71.72currentRecord[3] = 0.02currentRecord[4] = false

Your function can therefore access and use the values for the current row withinJavascript. If you want to return more data from the Caché back-end from within yourfunction, you can make an Event Broker call, eg:

<script language="javascript"> function myFunc(currentRecord,currentRow) { ewd:##class(ewd.test).fetchGridRecord(currentRow) ; alert(myRecord) ; }</script>

This method might look as follows:

ClassMethod fetchGridRecord(currentRow As %Integer, sessid As %String) As %String{ // access data related to the record identified by the currentRow number, eg // here is the data returned to Javascript as a hard-coded array QUIT "myRecord = ['This record',12,34,99,true,'Test value'];"}

In a real example, you'd use the value of currentRow as an index to look up theappropriate information from the Caché database and return one or more values asJavascript statements, or, as above, as a Javascript array.

Alternatively, you might pass the currentRow for use by the prePageScript of an Ajaxfragment that you target somewhere into your page, eg:

<script language="javascript"> function myFunc(currentRecord,currentRow) { var nvp=”rowNo=” + currentRow; ewd.ajaxRequest(“myFragment”,”myTargetId”,nvp) ; }</script>

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

35

Page 36: Enterprise Web Developer Using the ExtJS Widgets

In this example, we're fetching an EWD fragment named myFragment.ewd that willreplace in the innerHTML of the tag whose id is myTargetId. The prePageScript ofmyFragment.ewd will be able to access the number of the selected row by accessingthe Request value named rowNo, eg:

s selectedRowNo = $$getRequestValue^%zewdAPI(“rowNo”,sessid)

Note that you cannot fire the onRowSelect Event Handler if you are using the<ext:editableGridPanel> tag.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

36

Page 37: Enterprise Web Developer Using the ExtJS Widgets

Menu Trees

The ExtJS Tree is another very useful widget. It creates the kind of expandingvertical menu trees that are now a familiar part of graphical user interfaces, eg:

Once again, EWD makes it very quick and easy to create these trees, of any sizeand/or hierarchy depth.

First, create an EWD page named treeDemo.ewd that contains the following:

<ewd:config isFirstPage="true" prePageScript="##class(ewd.test).getDemoTreeData"><ext:config path="/ext-2.2" />

<html><head> <title>Ext JS Tree Example</title></head><body>

<ext:tree datastore="myTreeData" style="overflow:auto;height:300px;width:200px;" text="Cars" />

</body></html>

Like the grid widget, the contents of the tree widget are contained in a JSONdatastore. EWD automates everything for you, reducing the task of the designer todetermining the positioning and basic styling of the tree, as above. The task of theprogrammer is to populate the tree datastore within the prePageScript, in this caseusing a Caché class method named getDemoTreeData(). Create your own version ofthis method containing the following:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

37

Page 38: Enterprise Web Developer Using the ExtJS Widgets

ClassMethod getDemoTreeData(sessid As %String) As %String{s tree(1)="Ford"s tree(2)="Volvo"s tree(3)="Nissan"s tree(4)="Toyota"s tree(5)="Mercedes"s tree(6)="BMW"d createTreeDatastore^%zewdExtJS(.tree,"myTreeData",sessid) QUIT ""}

As you can see, the programmer simply creates a local array containing the menu treeoptions in the order in which they should appear, and then passes this into thecreateTreeDatastore() method that is provided by EWD.

If you save and compile the treeDemo.ewd page and getDemoTreeData() method, andlaunch the compiled version of treeDemo in a browser, you should see the tree:

Now let's add a few more levels to the tree hierarchy. That's very simple to do. Justexpress these using the natural hierarchy provided by the local array structure:

ClassMethod getDemoTreeData(sessid As %String) As %String{s tree(1)="Ford"s tree(1,1)="Focus"s tree(1,1,1)="Petrol"s tree(1,1,2)="Diesel"s tree(1,2)="Mondeo"s tree(1,2,1)="Petrol"s tree(1,2,2)="Diesel"s tree(2)="Volvo"s tree(2,1)="S40"s tree(2,2)="V70"s tree(2,3)="XC90"s tree(3)="Nissan"s tree(3,1)="Micra"s tree(3,2)="Qashqai"s tree(4)="Toyota"

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

38

Page 39: Enterprise Web Developer Using the ExtJS Widgets

s tree(4,1)="Corolla"s tree(4,2)="Prius"s tree(4,3)="Yaris"s tree(4,3,1)="2 door"s tree(4,3,2)="4 door"s tree(5)="Mercedes"s tree(5,1)="SL-Class"s tree(5,1,1)="SLK Roadster"s tree(5,2)="A-Class"s tree(5,3)="E-Class"s tree(6)="BMW"s tree(6,1)="3 Series"s tree(6,1,1)="318"s tree(6,1,2)="320"s tree(6,1,3)="325i"s tree(6,2)="5 Series"d createTreeDatastore^%zewdExtJS(.tree,"myTreeData",sessid) QUIT ""}

Refresh the page in the browser and you'll now see the new version of the tree whichcan be expanded out to reveal all the levels you've defined above.

Now of course we usually want this kind of tree menu so that we can trigger a specificaction depending on the menu option we choose. In the EWD/ExtJS tree, you can addan action automatically to any leaf-node in the tree hierarchy.

Let's create a simple Ajax-style interaction. First, change the treeDemo.ewd page asfollows:

<ewd:config isFirstPage="true" prePageScript="##class(ewd.test).getDemoTreeData"><ext:config path="/ext-2.2" />

<html><head> <title>Ext JS Tree Example</title>

<script language="javascript"> function selectCar(id,value) { var nvp="id=" + id + "&leafValue=" + value ; ewd.ajaxRequest("showCarDetails","carContent",nvp) ; }</script>

</head><body>

<ext:tree datastore="myTreeData" style="overflow:auto;height:300px;width:200px;" text="Cars"onClick="selectCar" />

<hr /><div id="carContent">Details will be shown here</div></body></html>

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

39

Page 40: Enterprise Web Developer Using the ExtJS Widgets

What we've done here is to add an onClick handler to the tree's leaf nodes that willtrigger a Javascript function named selectCar. Notice the interface to this function:

function selectCar(id,value)

EWD ensures that the id and the text value of the leaf node you clicked is passedthrough to the function. The format of the id is the text string extTreeData followedby the hierarchy level, with each level separated with the character, eg:

extTreeData5x1x1

This repesents the leaf node for tree(5,1,1) which was defined as follows:

s tree(5)="Mercedes"s tree(5,1)="SL-Class"s tree(5,1,1)="SLK Roadster"

The id therefore provides sufficient information to determine exactly which node inthe tree was clicked.

Of course, if all the leaf nodes have unique text, the value can be sufficient. In theexample above, the variable value would have a value of “SLK Roadster”.

By passing you both values, you can determine which you need to determine thesubsequent action you want to invoke.

In the example above, we're going to replace the innerHTML of the tag <divid="carContent"> with a fragment named showCarDetails.ewd, to which we're goingto pass two name/value pairs constructed from the id and value.

Now we'll create that fragment. Copy the following into a file namedshowCarDetails.ewd in the extjsDemo directory.

<ewd:config isFirstPage="false" pageType="ajax" prePageScript="##class(ewd.test).getCarDetails"/><span> Car details selected: <?= #carDetails ?></span>

Now we'll create the prePageScript for this fragment:

ClassMethod getCarDetails(sessid As %String) As %String{s id=$$getRequestValue^%zewdAPI("id",sessid)s leafValue=$$getRequestValue^%zewdAPI("leafValue",sessid)d setSessionValue^%zewdAPI("carDetails",id_": "_leafValue,sessid)QUIT ""}

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

40

Page 41: Enterprise Web Developer Using the ExtJS Widgets

We need to do this because the name/value pairs (id and leafValue) are passed as thethird parameter of the ewd.ajaxRequest method, and because this is evaluated at run-time, EWD cannot safely instantiate these extra name/value pairs directly into theEWD Session. So they have to be extracted from the EWD Request. We're thenconcatenating them together and creating a session variable named carDetails. Thiscan then be displayed in the fragment as <?= #carDetails ?>.

So now you have all the building blocks. Compile the new version of treeDemo.ewdand the fragment showCarDetails.ewd, and save and compile the class methodgetCarDetails(). Refresh the compiled version of the treeDemo page and you shouldsee:

Open up one of the menu levels and click a leaf node and you should now seesomething like:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

41

Page 42: Enterprise Web Developer Using the ExtJS Widgets

The fragment has replaced the original text at the bottom of the page with the id andtext value of the selected tree leaf node. You're now ready to adapt this simpleexample into your own Ajax applications!

ExtJS Forms

ExtJS provides a rich set of form field widgets, and once again EWD makes themeasy to use.

You have two choices as a developer:

• use EWD's “raw” tag-based projection of the corresponding ExtJS classes.

• Use EWD's augmented form features which allows you to use most of theautomation that will be familiar to anyone who has used EWD with standardHTML form fields.

This chapter will concentrate on the second choice, so let's start building anEWD/ExtJS form.

First, create a new EWD page named formDemo.ewd in your extjsDemo directory,containing the following:

<ewd:config isFirstPage="true"><ext:config path="/ext-2.2" debug="true"/><html><head><title>Form Demo</title></head><body> <ext:ewdForm> <ext:FormPanel width="100%" frame="true" autorender="true" /> </ext:ewdForm></body></html>

Compile using, eg:

d compileAll^%zewdAPI(“extjsDemo”,,”php”)

Load this page into a browser and you should just see a very thin blue line. This thinblue line is a specific type of Ext Panel (FormPanel) that is designed to contain forms.Because it doesn't yet contain any fields, it is barely visible.

The EWD-specific attribute autoRender=”true” tells EWD to add a <div> tag to thepage that is used as the rendering point for the FormPanel.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

42

Page 43: Enterprise Web Developer Using the ExtJS Widgets

The special EWD tag, <ext:ewdForm>, which provides a container for ExtJS formtags, tells EWD's compiler to add the additional EWD form automation features to thetags it encloses.

Now let's add a simple Text field to the FormPanel. Add a <ext:textField> tag insidethe <ext:formPanel>:

<ewd:config isFirstPage="true"><ext:config path="/ext-2.2" debug="true"/><html><head><title>Form Demo</title></head><body> <ext:ewdForm> <ext:FormPanel width="100%" frame="true" autorender="true"> <ext:textField fieldLabel="First name" name="firstName" value="*" /> </ext:FormPanel> </ext:ewdForm></body></html>

Recompile the page and re-load it into the browser. You should now see the field atthe top of the page:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

43

Page 44: Enterprise Web Developer Using the ExtJS Widgets

Note that unlike HTML form fields, the textField allows you to specify the field labelas part of the tag. However, just as in standard HTML text fields, EWD allows you tospecify a special value of “*” which tells EWD to automatically add the value of acorrespondingly named Session variable. Let's see this in action.

First, add a pre-page script reference to your page by modifying the <ewd:config> tag:

<ewd:config isFirstPage="true" prepageScript=" ##class(ewd.test).getFormDetails">

Next, create the method in your ewd.test class as follows:

ClassMethod getFormDetails(sessid As %String) As %String{d setSessionValue^%zewdAPI("firstName","Rob",sessid)QUIT ""}

Re-compile the ewd.test class, recompile the formDemo.ewd page and reload thecompiled page into the browser. You should now see “Rob” appear in the textField.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

44

Page 45: Enterprise Web Developer Using the ExtJS Widgets

Let's add a second text field:

<ext:ewdForm> <ext:FormPanel width="100%" frame="true" autorender="true"> <ext:textField fieldLabel="First name" name="firstName" value="*" /> <ext:textField fieldLabel="Last name" name="lastName" value="*" /> </ext:FormPanel> </ext:ewdForm>

Now let's slightly modify the pre-page script:

ClassMethod getFormDetails(sessid As %String) As %String{ i $$getSessionValue^%zewdAPI("firstName",sessid)="" { d setSessionValue^%zewdAPI("firstName","Rob",sessid) d setSessionValue^%zewdAPI("lastName","Tweed",sessid) }QUIT ""}

Recompile the class and page. When you reload it into the browser, you should seethe two fields, pre-populated with “Rob” and “Tweed” respectively.

Now let's add a submit button to allow us to submit the edited form field values backto Caché.

<ext:ewdForm> <ext:FormPanel width="100%" frame="true" autorender="true"> <ext:textField fieldLabel="First name" name="firstName" value="*" /> <ext:textField fieldLabel="Last name" name="lastName" value="*" /> <ext:submitButton text="Submit" id="demoFormBtn" action="##class(ewd.test).saveDemoForm" waitMsg="saving data..." nextpage="demoFormPage2" targetId="responseDiv"failMsgTitle="Form Validation Errors" /> </ext:FormPanel> </ext:ewdForm> <div id="responseDiv" />

We've actually added two tags:

• a <ext:submitButton> tag, which is EWD's automation tag for defining a submitbutton.

• a div tag: <div id=”responseDiv” /> which provides the target for the content ofthe fragment demoFormPage2.ewd that has been specified as the nextpage in thesubmit button tag.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

45

Page 46: Enterprise Web Developer Using the ExtJS Widgets

Now add the action script to your ewd.test class:

ClassMethod saveDemoForm(sessid As %String) As %String{ s firstName=$$getSessionValue^%zewdAPI("firstName",sessid) i firstName="" d setFieldError^%zewdExtJS("firstName","A first name must beentered",sessid) s lastName=$$getSessionValue^%zewdAPI("lastName",sessid) i lastName="" d setFieldError^%zewdExtJS("lastName","A last name must beentered",sessid) QUIT ""}

This is somewhat different from a standard EWD form action script in that it shouldalways Quit with a null return value, and each and every form field validation error istrapped and recorded using the special API method setFieldError^%zewdExtJS. Youspecify the field name that is in error, and also specify the error message for that field.

To see how all the things we've added come into play, save and recompile the ewd.testclass and re-compile formDemo.ewd. When you re-load the page into the browser,you should now see the submit button:

Try clicking the submit button. If you've done everything correctly, you should see:

However, you should have also briefly noticed an ExtJS alert window saying “savingdata...” before the “Congratulations” text appeared under the form. That wasbecause, in the <ext:submitButton> tag, we'd specified: waitMsg="saving data...".

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

46

Page 47: Enterprise Web Developer Using the ExtJS Widgets

Now try forcing validation errors. Refresh the page in the browser and then removethe text from both fields before pressing the Submit button. You should now see anExtJS alert window telling you that field validation errors have occurred:

Notice also that the borders of the two fields have been highlighted in red. Click onthe alert window's OK button and now move the mouse over each field. You shouldsee a tooltip come up with the error message we specified for that field:

In the <ext:submitButton> tag we specified: failMsgTitle="Form Validation Errors". Thiswas used to define the title for the ExtJS alert window. By default, the alert windowdisplays the message “Validation error(s) were reported”. If you want to change this,set the value of the special EWD Session variable ewd.form.errorMessage in youraction script, eg:

d setSessionValue^%zewdAPI("ewd.form.errorMessage","It failed!",sessid)

That's the basics of EWD's ExtJS forms now working, but there's lots more we can do.First let's try out the various ExtJS form field types that are supported in EWD.

Add a combo box to the FormPanel in your formDemo.ewd page as follows:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

47

Page 48: Enterprise Web Developer Using the ExtJS Widgets

<ext:ewdForm> <ext:FormPanel width="100%" frame="true" autorender="true"> <ext:textField fieldLabel="First name" name="firstName" value="*" /> <ext:textField fieldLabel="Last name" name="lastName" value="*" /> <ext:comboBox store="#cityList" value="*" fieldLabel="City" typeAhead="true"mode="local" name="city" forceSelection="true" selectOnFocus="true" emptyText="Select aCity.." /> <ext:submitButton text="Submit" id="demoFormBtn" action="##class(ewd.test).saveDemoForm" waitMsg="saving data..." nextpage="demoFormPage2" targetId="responseDiv"failMsgTitle="Form Validation Errors" /> </ext:FormPanel> </ext:ewdForm> <div id="responseDiv" />

Next, modify the pre-page script to instantiate a list of cities, eg:

ClassMethod getFormDetails(sessid As %String) As %String{i $$getSessionValue^%zewdAPI("firstName",sessid)="" {d setSessionValue^%zewdAPI("firstName","Rob",sessid)d setSessionValue^%zewdAPI("lastName","Tweed",sessid)d deleteFromSession^%zewdAPI("cityList",sessid)d appendToComboBoxStore^%zewdExtJS("London","lon","cityList",sessid)d appendToComboBoxStore^%zewdExtJS("New York","nyc","cityList",sessid)d appendToComboBoxStore^%zewdExtJS("Paris","par","cityList",sessid)}QUIT ""}

And finally, modify the validation rules in your action script:

ClassMethod saveDemoForm(sessid As %String) As %String{s firstName=$$getSessionValue^%zewdAPI("firstName",sessid)i firstName="" d setFieldError^%zewdExtJS("firstName","A first name must beentered",sessid)s lastName=$$getSessionValue^%zewdAPI("lastName",sessid)i lastName="" d setFieldError^%zewdExtJS("lastName","A last name must beentered",sessid)s city=$$getSessionValue^%zewdAPI("city",sessid)i city="Select a City.." d setFieldError^%zewdExtJS("city","A city must beentered",sessid)QUIT ""}

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

48

Page 49: Enterprise Web Developer Using the ExtJS Widgets

Save and recompile the ewd.test class and your formDemo.ewd page. Reload the pageinto the browser and now you should see the comboBox. Click on its arrow buttonand you'll see the cities you specified in the pre-page script will pop up. If you don'tselect anything (so you leave “Select a City..” appearing in the combo-box), and clickthe submit button, you should see the combo box highlighted in red. A tooltip shouldpop up when you move your mouse pointer over it, with the error message wespecified in the action script.

Note how the comboBox, being a single-choice device, maps to and from thecorrespondingly named EWD Session variable (in this case city). If you modify thepre-page script to pre-define a value for city, then you'll see that value automaticallyselected when you refresh the page in the browser. For example:

d setSessionValue^%zewdAPI("city","par",sessid)

will cause Paris to be automatically selected.

There's another thing you can do with a comboBox: make a fragment getautomatically requested when an option in the drop-down list is clicked. EWD makesthis easy. Just add a nextpage and targetId attribute, eg:

<ext:comboBox store="#cityList" value="*" fieldLabel="City" nextpage="demoFormPage2"targetId="responseDiv" typeAhead="true" mode="local" name="city" forceSelection="true"selectOnFocus="true" emptyText="Select a City.." />

The selected option will be passed as a Request name/value pair, where the name isthe same as the comboBox name, in this case city. Therefore the pre-page script ofthe nextpage (demoFormPage2.ewd) could determine which option was clicked byaccessing:

s city=$$getRequestValue^%zewdAPI(“city”,sessid)

However, in our example, we'll not use this additional facility – we'll just use thecomboBox as a means of selecting a city prior to clicking the Submit button.

Now let's add a group of radio buttons. Make the following change to the form:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

49

Page 50: Enterprise Web Developer Using the ExtJS Widgets

<ext:ewdForm> <ext:FormPanel width="100%" frame="true" autorender="true"> <ext:textField fieldLabel="First name" name="firstName" value="*" /> <ext:textField fieldLabel="Last name" name="lastName" value="*" /> <ext:comboBox store="#cityList" value="*" fieldLabel="City" typeAhead="true"mode="local" name="city" forceSelection="true" selectOnFocus="true" emptyText="Select aCity.." /> <ext:radioGroup fieldLabel="Sex"> <ext:radio boxLabel="Female" name="sex" inputValue="f" /> <ext:radio boxLabel="Male" name="sex" inputValue="m" /> </ext:radioGroup> <ext:submitButton text="Submit" id="demoFormBtn" action="##class(ewd.test).saveDemoForm" waitMsg="saving data..." nextpage="demoFormPage2" targetId="responseDiv"failMsgTitle="Form Validation Errors" /> </ext:FormPanel> </ext:ewdForm> <div id="responseDiv" />

Add the following line to the pre-page script to pre-select a sex of Male:

d setSessionValue^%zewdAPI("sex","m",sessid)

After recompiling the class and page and reloading the page into the browser, itshould now look as follows:

ExtJS provides number, date and time fields. Let's add an example of each:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

50

Page 51: Enterprise Web Developer Using the ExtJS Widgets

<ext:ewdForm> <ext:FormPanel width="100%" frame="true" autorender="true"> <ext:textField fieldLabel="First name" name="firstName" value="*" /> <ext:textField fieldLabel="Last name" name="lastName" value="*" /> <ext:comboBox store="#cityList" value="*" fieldLabel="City" typeAhead="true"mode="local" name="city" forceSelection="true" selectOnFocus="true" emptyText="Select aCity.." /> <ext:radioGroup fieldLabel="Sex"> <ext:radio boxLabel="Female" name="sex" inputValue="f" /> <ext:radio boxLabel="Male" name="sex" inputValue="m" /> </ext:radioGroup> <ext:numberField fieldLabel="No of tickets" name="tickets" value="*" /> <ext:dateField fieldLabel="Date of Birth" name="dob" value="*" /> <ext:timeField fieldLabel="Departure Time" name="departTime" value="*" /> <ext:submitButton text="Submit" id="demoFormBtn" action="##class(ewd.test).saveDemoForm" waitMsg="saving data..." nextpage="demoFormPage2" targetId="responseDiv"failMsgTitle="Form Validation Errors" /> </ext:FormPanel> </ext:ewdForm> <div id="responseDiv" />

Pre-set values for these in your pre-page script as follows:

d setSessionValue^%zewdAPI("tickets",1,sessid)d setSessionValue^%zewdAPI("dob","08/09/2008",sessid)d setSessionValue^%zewdAPI("departTime","10:40",sessid)

ExtJS Checkboxes are handled similarly to the ExtJS Radio buttons, eg:

<ext:checkboxGroup hideLabel="true"> <ext:checkbox boxLabel="Matching" id="role1" name="roles" inputValue="1" /> <ext:checkbox boxLabel="Query" id="role2" name="roles" inputValue="2" /> <ext:checkbox boxLabel="User Definition" id="role3" name="roles" inputValue="3"/> <ext:checkbox boxLabel="Site Definition" id="role4" name="roles" inputValue="4" /></ext:checkBoxGroup>

Note that the Id of each checkbox item should be unique, but the name of eachcheckbox in a group should be the same. The checkboxes are integrated with theEWD back-end just like standard HTML checkboxes: using the EWD SelectedSession array, eg to pre-check the checkboxes for “Query” and “Site Definition”:

d setCheckboxOn^%zewdAPI("roles",2,sessid)d setCheckboxOn^%zewdAPI("roles",4,sessid)

When the form is submitted, you can check whether a checkbox value was checkedusing:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

51

Page 52: Enterprise Web Developer Using the ExtJS Widgets

if $$isCheckboxOn^%zewdAPI("roles",2,sessid) do something

Alternatively you can merge the selected array into a local one and process itappropriately, eg:

d getCheckboxValues^%zewdAPI(“roles”,.selectedArray,sessid)

ExtJS Textarea fields are defined as follows:

<ext:textarea fieldLabel="Site Description" name="siteDesc" value="*" height="100"width="250" />

Integration with the EWD back-end is the same as the standard HTML textarea. Topre-populate the textarea from your database:

s text(1)=”First line of text”s text(2)=”Second line of text”s text(3)=”Last line”d mergeToTextArea^%zewdAPI(“siteDesc”,.text,sessid)

And to access the text when the form is submitted, transfer it out to a local arraywhich you can then process appropriately, eg:

d mergeFromTextArea^%zewdAPI(“siteDesc”,.text,sessid)

Advanced Form Widgets: ItemSelector

The ExtJS ItemSelector is a drag-and-drop enabled widget that allows the user toselect one or more items from a pre-determined list of options. It is not part of themainstream ExtJS widgets, but is in their experimental ux library. Nevertheless it is afully functional and extremely useful widget which has been made extremely easy touse through an EWD tag: <ext:itemSelector>.

In order to use the ItemSelector, you must make sure that the files ExtExtensions.jsand multiselect.css are loaded into your container page. You'll find these files in the

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

52

Page 53: Enterprise Web Developer Using the ExtJS Widgets

EWD download kit's zip file. For example, if you've saved the files to your web-server's root path, load them into your container page using:

<link rel="stylesheet" type="text/css" href="/multiselect.css"/><script src="/ExtExtensions.js" type="text/javascript"></script>

Now you can add an itemSelector into your <ext:formPanel>, eg:

<ext:itemSelector id="myItemSelector" name="sites" hideLabel="true" msWidth="150" msHeight="120" toLegend="Assigned Sites" fromLegend="Available Sites" fromStore="myStore" fromField="Available" toStore="myToStore"/>

This will appear as follows:

You can use the arrows to move items into the selected panel, or you can drag anddrop them.

You can pre-define the “from” list using a datastore, and, if required, you can alsopre-define the “to” list using a datastore. You'll do this in the pre-page script of thefragment containing the itemSelector, eg:

ClassMethod getUserDefinitionData(sessid As %String) As %String{ for i=1:1:4 s data(i)="Test site "_i d createItemSelectorDatastore^%zewdExtJS(.data,"myStore","rw",sessid) for i=1:1:2 s todata(i)="to site "_i d createItemSelectorDatastore^%zewdExtJS(.todata,"myToStore","rw",sessid) QUIT ""}

As you can see, EWD makes it easy to create the datastores: just create a local arraycontaining the values you want in the list and save it using thecreateItemSelectorDatastore() method.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

53

Page 54: Enterprise Web Developer Using the ExtJS Widgets

When the form is submitted, the selected items in the to list will appear in the EWDRequest using the name you assigned to the ItemSelector: in the example above it willbe saved into the Request variable named sites (Note: the current implementationdoes not automatically save the results from the itemSelector widget into the EWDSession). The selected values are comma-delimited, eg in your form's Action script:

ClassMethod saveFormData(sessid As %String) As %String{ s storeValues=$$getRequestValue^%zewdAPI(“store”,sessid) // If items 2 and 4 had been selected, storeValues = “2,4” QUIT ""}

Laying out Forms

So far we've just used a single column of form fields. We could combine severalfields within a fieldSet. For example:

<ext:ewdForm> <ext:FormPanel width="100%" frame="true" autorender="true"> <ext:fieldSet width="92%" title="Personal Details" autoHeight="true"> <ext:textField fieldLabel="First name" name="firstName" value="*" /> <ext:textField fieldLabel="Last name" name="lastName" value="*" /> </ext:fieldSet> <ext:comboBox store="#cityList" value="*" fieldLabel="City" typeAhead="true"mode="local" name="city" forceSelection="true" selectOnFocus="true" emptyText="Select aCity.." /> <ext:radioGroup fieldLabel="Sex"> <ext:radio boxLabel="Female" name="sex" inputValue="f" /> <ext:radio boxLabel="Male" name="sex" inputValue="m" /> </ext:radioGroup> <ext:numberField fieldLabel="No of tickets" name="tickets" value="*" /> <ext:dateField fieldLabel="Date of Birth" name="dob" value="*" /> <ext:timeField fieldLabel="Departure Time" name="departTime" value="*" /> <ext:submitButton text="Submit" id="demoFormBtn" action="##class(ewd.test).saveDemoForm" waitMsg="saving data..." nextpage="demoFormPage2" targetId="responseDiv"failMsgTitle="Form Validation Errors" /> </ext:FormPanel> </ext:ewdForm> <div id="responseDiv" />

If you recompile the page and reload it into the browser, it should now look like this:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

54

Page 55: Enterprise Web Developer Using the ExtJS Widgets

We could also split the formPanel into two columns by using column Panels. Forexample, suppose we want the following appearance:

We would define this as follows:

<ext:ewdForm> <ext:FormPanel width="100%" frame="true" autorender="true"> <ext:Panel layout="column"> <ext:Panel id="lhs" columnWidth=".5" layout="form"> <ext:fieldSet width="92%" title="Personal Details" autoHeight="true"> <ext:textField fieldLabel="First name" name="firstName" value="*" /> <ext:textField fieldLabel="Last name" name="lastName" value="*" /> </ext:fieldSet> <ext:comboBox store="#cityList" value="*" fieldLabel="City" typeAhead="true"mode="local" name="city" forceSelection="true" selectOnFocus="true" emptyText="Select aCity.." /> <ext:radioGroup fieldLabel="Sex"> <ext:radio boxLabel="Female" name="sex" inputValue="f" /> <ext:radio boxLabel="Male" name="sex" inputValue="m" /> </ext:radioGroup> </ext:Panel>

<ext:Panel id="rhs" columnWidth=".5" layout="form"> <ext:dateField fieldLabel="Date of Birth" name="dob" value="*" /> <ext:fieldSet width="92%" title="Ticket Details" autoHeight="true"> <ext:timeField fieldLabel="Departure Time" name="departTime" value="*" />

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

55

Page 56: Enterprise Web Developer Using the ExtJS Widgets

<ext:numberField fieldLabel="No of tickets" name="tickets" value="*" /> </ext:fieldSet> </ext:Panel> </ext:Panel> <ext:submitButton text="Submit" id="demoFormBtn" action="##class(ewd.test).saveDemoForm" waitMsg="saving data..." nextpage="demoFormPage2" targetId="responseDiv"failMsgTitle="Form Validation Errors" /> </ext:FormPanel> </ext:ewdForm>

You can see from this example how EWD makes it very simple to nest Panels withinPanels to any depth you wish. Each Panel can be given a unique id, so that it can beused as a target for EWD fragments. You can also hide and display panels fromwithin Javascript using:

/* To hide the lhs column */Ext.getCmp('lhs').hide() ;

/* To show the lhs column again*/Ext.getCmp('lhs').show() ;

You can hide and reveal form fields from within Javascript too, by using some pre-built functions that EWD provides for you:

/* To hide the Date of Birth field */EWD.ext.hideField(Ext.getCmp('dob')) ;

/* To show the Date of Birth field again */EWD.ext.showField(Ext.getCmp('dob')) ;

Note that in our example form we haven't assigned an id for any of the fields. In fact,as part of EWD's form automation, you only need to specify either a name or idattribute in a form field. EWD will add the missing attribute, assigning the value ofthe one that is present. So, for example, the Date of Birth field has the attributename=”dob”. EWD will automatically add id=”dob” to the field at compile time.

This means that we can use any of the Javascript methods that identify a form field byits id attribute, without having to explicitly define it.

The net result is that we can use all the sophistication of ExtJS form field widgets, andyet define a form in a very succinct and intuitive way, as shown in the final exampleabove.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

56

Page 57: Enterprise Web Developer Using the ExtJS Widgets

Modal Windows

EWD makes it easy to use ExtJS's modal pop-up windows. Just define a modalwindow object using the <ext:modalWindow> tag and reference it from within thespecial EWD function EWD.ext.openWindow() that can be called from any eventhandler.

For example, a simple scenario is a page that contains a button which, when clicked,triggers the creation of the modal window. Copy the page definition below and save itin a file named ModalWindowDemo1.ewd in the extjsDemo application directory.

<ewd:config isFirstPage="true"><ext:config path="/ext-2.2" />

<html><head><title>Modal Window Demo</title></head><body> <div> <input id="windowBtn" type="button" value="Start Modal window"onclick="EWD.ext.openWindow(theWindow)" /> <ext:modalWindow id="myModalWindow" object="theWindow" title="Demo Modal Window"height="auto" width="300" src="modalWindowContent1" /> </div></body></html>

In this example, the <ext:modalWindow> tag defines an ExtJS modal window objectand instantiates it with a name of theWindow. Normally EWD's compilerautomatically assigns names to the objects it creates from the ExtJS tags, but you canover-ride this behaviour and assign your own object name by using the object=attribute. When you assign your own name, EWD doesn't “var” the object name, soit becomes available globally throughout your page.

As a result, you can refer to and use the object theWindow anywhere in your page, soin this case we're using it in the OnClick event handler of the Button that we'vedefined in the page. To open the modal window, we use the special built-in methodEWD.ext.open() and pass the theWindow object into it.

Note: behind the scenes, EWD ensures that this mechanism cannot be hi-jacked to callup any arbitrary fragment in the modal window. Only the one specified in thepage/fragment definition will be allowed to be displayed in the modal window.

Now let's create the fragment that contains the content for the modal window. Copythe page definition below and save it in a file named modalWindowContent1.ewd inthe extjsDemo application directory:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

57

Page 58: Enterprise Web Developer Using the ExtJS Widgets

<ewd:config pageType="ajax" isFirstPage="false">

<script language="javascript"> function okAction() { /* do something here! */ /* then close the window */ EWD.ext.window.destroy() ; }</script><div> <center> <p>This is a demo of an ExtJS modal window</p> <br /> <ext:button id="OK" text="OK" autoRender="true" handler="okAction()" /> </center></div>

Compile these two pages and load the compiled ModalWindowDemo1 page into yourbrowser. You should see the following:

When you click the button you should see:

If you click the OK button, the modal window will disappear. The destruction of thewindow is done by the line of Javascript:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

58

Page 59: Enterprise Web Developer Using the ExtJS Widgets

EWD.ext.window.destroy() ;

EWD has created the object EWD.ext.window for you which represents the modalwindow widget. The ExtJS destroy() method removes the window.

You can easily add multiple buttons and assign different handlers to them, eg modifymodalWindowContent1.ewd as follows:

<ewd:config pageType="ajax" isFirstPage="false">

<script language="javascript"> function okAction() { /* do something here! */ /* then close the window */ EWD.ext.window.destroy() ; }</script><div> <center> <p>This is a demo of an ExtJS modal window</p> <br /> <ext:button id="OK" text="OK" autoRender="true" handler="okAction()" /> <ext:button id="Cancel" text="Cancel" autoRender="true" handler="EWD.ext.window.destroy()" /> </center></div>

If you save and recompile your pages, you'll now see that the modal window has twobuttons. However, they will be rendered one above the other which doesn't look verygood:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

59

Page 60: Enterprise Web Developer Using the ExtJS Widgets

We can re-arrange these buttons by using the ExtJS renderTo config option for eachbutton, rendering them to two <div> tags that we'll line up by using a table, ie:

<div> <p>This is a demo of an ExtJS modal window</p> <ext:button id="OK" text="OK" renderTo="leftx" handler="okAction()" /> <ext:button id="Cancel" text="Cancel" renderTo="rightx" handler="EWD.ext.window.destroy()"/><table align="center"> <tr> <td id="leftx">&nbsp;</td> <td>&nbsp;</td> <td id="rightx">&nbsp;</td> </tr></table></div>

Now the buttons will line up nicely:

Triggering the opening of a modal window can be done using the event handlers ofany tags. For example, we could have used an ExtJS button:

<ext:button id="ExtButton" text="OK" autoRender="true" onclick="EWD.ext.openWindow(theWindow)" />

Modal Window Forms

One common use of a modal window is to contain a form. Let's examine how this canbe done and controlled. We'll demonstrate this with a simple logon window.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

60

Page 61: Enterprise Web Developer Using the ExtJS Widgets

Copy the page definition below and save it in a file named modalWindow1d.ewd inthe extjsDemo application directory:

<ewd:config isFirstPage="true"><ext:config path="/ext-2.2" />

<html><head><title>Modal Window Demo</title></head><body onload="EWD.ext.openWindow(loginWindow)"> <div id="contentDiv">

<ext:modalWindow id="myModalWindow" closable=”false” object="loginWindow"title="Logon" height="auto" width="300" src="modalWindowContent1d" />

</div></body></html>

There's not much difference in this container page from our previous example:however this time we're using the page's onload event hander to trigger the modalwindow and the modal window content fragment is nowmodalWindowContent1d.ewd which will contain the logon form. We've also giventhe <div> tag that surrounds the button an id of “contentDiv” which we'll later use asa target for a fragment. The idea is that if the user logs in correctly, the login buttonwill disappear, to be replaced with the new fragment contents. The modal window isalso set not to be closable, so there's no way to bypass this modal login dialogue.

Now let's create the login form which will populate the modal window. Copy thepage definition below and save it in a file named modalWindowContent1d.ewd in theextjsDemo application directory:

<ewd:config pageType="ajax" isFirstPage="false">

<span><ext:ewdForm>

<ext:FormPanel width="100%" frame="true" autorender="true"> <ext:textField fieldLabel="Username" name="username" value="" /> <ext:textField fieldLabel="Password" inputType="password" name="password" value="" /> <ext:submitButton id="logonBtn" text="OK" action="##class(ewd.test).logonTest" waitMsg="please wait..."nextpage="modalWindowContent2d" targetId="contentDiv" failMsgTitle="Logon Error" /></ext:FormPanel>

</ext:ewdForm></span>

The <ext:ewdForm> and <ext:FormPanel> tags are described in detail in theprevious chapter on Forms.

We're using two textFields for the username and password, the password defined asinputType=”password” to ensure that it doesn't display the password as you type it.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

61

Page 62: Enterprise Web Developer Using the ExtJS Widgets

We need to use a submit button, which is provided by the <ext:submitButton> tag.Let's look at what the submit button will do when it is clicked:

<ext:submitButton id="logonBtn" text=”OK” action="##class(ewd.test).logonTest" waitMsg="pleasewait..." nextpage="modalWindowContent2d" targetId="contentDiv" failMsgTitle="Logon Error" />

It will post the form contents to the Caché back-end and invoke the action scriptmethod ##class(ewd.test).logonTest which we'll use to validate the username and password.If the validation passes successfully, EWD will return a fragment namedmodalWindowContent2d which will be targetted into the container page's <divid=”contentDiv”> tag. While the posting and validation is taking place, the usershould see an alert message saying “please wait..”.

Let's now look at the action script method ##class(ewd.test).logonTest which you should addto your ewd.test class:

ClassMethod logonTest(sessid As %String) As %String{s username=$$getSessionValue^%zewdAPI("username",sessid)i username'="rob" d setFieldError^%zewdExtJS("username","Invalid login attempt",sessid)s password=$$getSessionValue^%zewdAPI("password",sessid)i password'="rob" d setFieldError^%zewdExtJS("username","Invalid login attempt",sessid)QUIT ""}

For simplicity we've hard-coded the logic to only allow a username and password ofrob and rob respectively, but usually you'd authenticate against some kind of look-uptable in your database. What this method will do is as follows:

• If either or both fields are invalid, it will set a field error that will highlight theusername field. If you roll the mouse over the highlighted field, you'll get an ExtJStooltip saying “Invalid login attempt”.

• If a field error is set, then EWD will also automatically pop up an ExtJS alertwindow telling you that an error occurred. The title of this alert window wasdefined in the <ext:submitButton> using the failMsgTitle="Logon Error" attribute.

OK we're nearly done. The final piece in the jig-saw is the fragment that we'll returnif the user successfully logs in. Copy the page definition below and save it in a filenamed modalWindowContent2d in the extjsDemo application directory:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

62

Page 63: Enterprise Web Developer Using the ExtJS Widgets

<ewd:config pageType="ajax" isFirstPage="false">

<script language="javascript"> EWD.ext.window.destroy() ;</script>

<div> <p>Congratulations! You've successfully logged in!</p></div>

The important thing to note in this fragment is the Javascript section which destroysthe modal window.

That's all the bits we need! Save and compile the pages and the class method. Nowload the container page into your browser. It should look like this:

Now enter an invalid username and password (ie anything other than rob and robrespectively) and click the OK button. You should see the “please wait..” messageappear briefly and then you'll get:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

63

Page 64: Enterprise Web Developer Using the ExtJS Widgets

When you click on the OK button on the alert window, you should now see theusername field highlighted, and if you roll the mouse over it, you'll see:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

64

Page 65: Enterprise Web Developer Using the ExtJS Widgets

Now log in correctly (username=rob and password = rob) and click the OK button.The modal window should now disappear and a success message will replace theoriginal login button:

That's it! You now have a fully working ExtJS modal form window!

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

65

Page 66: Enterprise Web Developer Using the ExtJS Widgets

Adding a Progress Bar

ExtJS has a very cool progress bar widget that EWD makes very easy to use. Here'show to use it.

First, add a <div> tag to your page to provide an anchoring/rendering point for theprogress bar. You may want it centered, in which case you could use a table, eg:

<table border="0" width="100%" style="table-layout:fixed"> <tr> <td width="10%">&nbsp;</td> <td width="80%" id="progbar" align="center"> &nbsp; </td> <td width="10%">&nbsp;</td> </tr> </table>

Now add the progress bar widget anywhere in the page. Initially we'll make it hidden,eg:

<ext:progressBar id="progress" width="300" renderTo="progbar" hidden="true" />

Note how we tell it to render itself into the <div> we created.

The idea is that we'll make the progress bar appear when an appropriate event handlerfires. So in the Javascript function for that event handler, add the following:

function submitTheGrid() { var progBar = Ext.getCmp('progress') ; progBar.show() ; progBar.wait({ interval:200, duration:30000, increment:15, text:'Please wait...' });

You can adjust any of the config options in the progBar.wait() method. The durationdefines the maximum duration that the progress bar will cycle its animation.ProgBar.show() will make the progress bar appear.

So that's the progress bar now on display. How do we turn it off? That's very simple: Ext.getCmp("progress").hide() is the method to use, so we just invoke this at the pointat which we know the task has completed. For example, if the initial event triggersthe fetching of an EWD fragment, then we can use its <ewd:ajaxOnload> block, ie:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

66

Page 67: Enterprise Web Developer Using the ExtJS Widgets

<ewd:ajaxOnload> Ext.getCmp("progress").hide() ;</ewd:ajaxOnload>

EWD doesn't execute the Javascript within the <ewd:ajaxOnLoad> block until thefragment has been loaded into the container page, so this is the perfect place to makethe progress bar disappear!

That's it! You now have a progress bar on your page.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

67

Page 68: Enterprise Web Developer Using the ExtJS Widgets

Advanced Use of EWD's ExtJS Custom Tags

As you've seen, EWD automates most of the day-to-day use of ExtJS widgets thatyou're likely to need, but there may be occasions when you want to take more controlof what's going on. One way, of course, is to hand-craft your own ExtJS Javascript,but you'll find that this is rarely necessary. You can make use of a lot of the “hidden”tags that EWD's compiler uses behind the scenes when converting ExtJS Custom tagsinto the final ExtJS Javascript code, in particular allowing you to define your ownlisteners (the ExtJS equivalent of Event Handlers). You can also harness calls toEWD via ExtJS's own use of the XMLHttpRequest object, and instruct EWD to justsend back a raw stream of Javascript without any of the additional EWD-specific codethat it would normally add.

Adding Listeners

To add your own listener to an EWD/ExtJS tag, you first need to consult the ExtJSAPI manual (http://www.extjs.com/deploy/dev/docs/) to find the specification for thelistener you wish to use. You'll find this in the Public Events section. For example,let's add a click listener to an Ext.Button widget. You'll find this listed in the PublicEvents section as follows:

click : (Button this, EventObject e) Fires when this button is clicked

So this event passes two objects to the Event Handler that you will specify: the currentbutton object and the event object. Now we can add the listener. In fact an ExtJSobject can have multiple listeners, so you specify two nested tags:

• <ext:listeners> This provides the container for the set of listeners that youwant to add to the object.

• <ext:listener> This contains a specific listener.

So let's start with our button:

<ext:button id="myButton" text="Click me" autoRender="true"></ext:button>

Note: you'll need to specify autoRender=”true” if this is a standalone button which isnot nested inside an ExtJS layout widget such as a Panel.

Now add the listeners container tag inside the button tag:

<ext:button id="myButton" text="Click me" autoRender="true"> <ext:listeners> </ext:listeners></ext:button>

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

68

Page 69: Enterprise Web Developer Using the ExtJS Widgets

Now you can add the click listener inside the listeners tag. You specify the name ofthe listener and its parameters in order, using the attributes param1, param2, ...paramn , making sure you match the documented interface, eg:

<ext:button id="myButton" text="Click me" autoRender="true"> <ext:listeners> <ext:listener name="click" param1="buttonObj" param2="event"> <ext:listener> </ext:listeners></ext:button>

Finally, inside the <ext:listener> tag you can specify the Javascript that you want toinvoke when the listener fires, eg:

<ext:button id="myButton" text="Click me" autoRender="true"> <ext:listeners> <ext:listener name="click" param1="buttonObj" param2="event"> alert(buttonObj.id) ; <ext:listener> </ext:listeners></ext:button>

Compile and run your example and you should see the button and when you click it,you'll get an alert window showing the id of the button:

You can add as many individual listeners inside a <ext:listeners> tag.

Direct use of ExtJS XHR Events

If you want to make use of ExtJS's own XMLHttpRequest object interface, but youwant to access the EWD session at the back-end, you can use a special mechanismthat instructs EWD to send a raw stream back to ExtJS without all the extra code andmarkup that EWD will normally add (the additional markup is used by EWD's XHRinterface).

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

69

Page 70: Enterprise Web Developer Using the ExtJS Widgets

To do this, invoke a call to a fragment as usual, but define the fragment somewhatdifferently. You specify the pageType as rawFragment and wrapper the fragment'scontent in the <ewd:rawcontent> tag, eg:

<ewd:config isFirstPage="false" pageType="rawfragment" prepagescript="##class(ewd.test).getAlert"> <ewd:rawcontent>

</ewd:rawcontent>

Inside the rawcontent you can specify any Javascript you like. This can be hard-coded, eg

<ewd:config isFirstPage="false" pageType="rawfragment" prepagescript="##class(ewd.test).getAlert"> <ewd:rawcontent> Ext.Msg.show({ title:'<?= #alertPrompt ?>', msg: '<?= #alertText ?>', buttons: Ext.Msg.OK, icon: Ext.MessageBox.QUESTION }); </ewd:rawcontent>

Or you can generate the entire contents programmatically using an <ewd:execute>tag, eg:

<ewd:config isFirstPage="false" pageType="rawfragment"> <ewd:rawcontent> <ewd:execute method="##class(ewd.test).generateContent" param1="#ewd_sessid" type="procedure" /> </ewd:rawcontent>

Note the way you can pass the EWD Session Id into your method usingparam1=”#ewd_sessid”. The advantage of this latter approach is that you can streamas much generated Javascript content as you like into the ExtJS page – it is not limitedby, for example, the common Caché maximum string length of 32k.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

70

Page 71: Enterprise Web Developer Using the ExtJS Widgets

The EWD/ExtJS Desktop

The techniques and widgets described above allow you to use the ExtJS widgets inconventional web and Ajax applications. However, ExtJS can go one better, andprovide you with a new way of presenting applications, using the ExtJS web desktopwidgets. EWD makes it amazingly simple to make use of these widgets to create yourown, fully functioning web desktop applications.

In order to use the EWD/ExtJS desktop widgets, you'll need to download theadditional customised components from the M/Gateway web site. You'll find these athttp://gradvs2.mgateway.com/main/extjs_desktop.zip Copy the contents into your ExtJS Javascript directories, eg /var/www/html/ext-2.2,maintaining the path structure within the zip file. This will create two newsubdirectories named desktop and images, ie

/ext-2.2/desktop/ext-2.2/images

You can now begin developing a desktop. Let's start with a very simple example.

Create a new file named desktopDemo.ewd in your extjsDemo directory, containingthe following:

<ewd:config isFirstPage="true"><ext:config path="/ext-2.2" />

<html><head><title>EWD/Ext-JS Desktop</title></head><body>

<ext:desktop title="Rob Tweed" iconClass="user" backgroundImage="/ext-2.2/desktop/ewdExtDesktop.jpg"> <ext:window title="Grids" showOnDesktop="true" desktopIcon="/ext-2.2/images/grid48x48.png"iconClass="panel" width="430" height="300" src="gridDemo2.ewd" /> </ext:desktop>

</body></html>

Adjust the image paths according to your ExtJS installation. Compile and run thispage in a browser and you should see the following:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

71

Page 72: Enterprise Web Developer Using the ExtJS Widgets

You have your first web desktop application up and running! Let's take a look at whatthe EWD page defined.

First, the <ext:desktop> tag creates the desktop container and defines the backdropimage to use for your desktop. If you click on the Start button, you'll also see theusername you specified appearing at the top of the start panel.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

72

Page 73: Enterprise Web Developer Using the ExtJS Widgets

Everything else is defined in the <ext:window> tags. In this case we've only defined asingle main window for the desktop which is associated with the single desktop iconnamed Grids. The current version of the desktop also mirrors this in the Start panel.

Let's take a look at the <ext:window> tag we specified:

<ext:window title="Grids" showOnDesktop="true" desktopIcon="/ext-2.2/images/grid48x48.png"iconClass="panel" width="430" height="300" src="gridDemo2.ewd" />

The attributes are as follows:

• title Specifies the text to display on the icon• showOnDesktop Display the icon on the desktop if true• desktopIcon Specifies the image file to use as the desktop icon• iconClass Specifies the class that defines the window image icon in

the Start panel, the taskbar and the window title bar• width the width of the window that will pop up• height the height of the window that will pop up• src the name of the fragment that will populate the window

If you click the Grids icon, a window should pop up with the dimensions youspecified (430 X 300), but it will contain the text Please wait... and you should thensee an Invalid Request error. This is because we haven't yet created the fragment thatwill contain the content for the window. We specified this to be src="gridDemo2.ewd"

We've already created a grid demo page, but that was a complete web page rather thana fragment, but we can quickly adapt it into a fragment. First, copy gridDemo.ewd togridDemo2.ewdEnterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

73

Page 74: Enterprise Web Developer Using the ExtJS Widgets

Next, edit it to contain the following:

<ewd:config isFirstPage="false" pageType="ajax" prePageScript="##class(ewd.test).getDemoGridData">

<span><ext:grid datastore="myData" stripeRows="true" title="Example Ext/EWD Grid" width="400"frame="true" liveUpdate="true" validationScript="class(ewd.test).setDemoGridData"> <ext:gridColumn header="Company" width="60" sortable="true" tooltip="The company inquestion"/> <ext:gridColumn header="Price" type="float" width="30" editAs="number" sortable="true" /> <ext:gridColumn header="Change" type="float" width="30" sortable="true" /> <ext:gridColumn header="In Stock" type="bool" renderAs="checkbox" width="30" /></ext:grid></span>

So now it's just a fragment of markup, without a <head> and <body> section, and itis declared as pageType=”ajax” in the <ewd:config> tag.

Compile this new fragment and it should now work. Reload the main desktop pageand then click the Grids icon (sometimes it takes a few seconds to become activated,particularly in Firefox). You should now see the following:

Now all you need to do is adjust the window and/or grid dimensions and you'll have agreat-looking web desktop application, and all built in just a few minutes!

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

74

Page 75: Enterprise Web Developer Using the ExtJS Widgets

Try adding more desktop icons, and convert some of your other ExtJS examples intofragments to use as contents for your windows. To do this, just add more<ewd:window> tags inside your <ext:desktop> tag in the main container page.

Special Use of Trees in the ExtJS Desktop

Something that is very useful in the desktop environment is to bring up an initialwindow that contains a tree menu. When you click any of the leaf nodes, you want anew window to pop up, but the fragment that populates the window should bedependent on the leaf node you clicked. EWD makes this very simple. First, let's adda new icon to our desktop:

<ext:desktop title="Rob Tweed" iconClass="user" backgroundImage="/ext-2.2/desktop/ewdExtDesktop.jpg"> <ext:window title="Grids" showOnDesktop="true" desktopIcon="/ext-2.2/images/grid48x48.png"iconClass="panel" width="430" height="300" src="gridDemo2.ewd" /> <ext:window title="Tree Demo" showOnDesktop="true" desktopIcon="/ext-2.2/images/about48x48.png" iconClass="panel" width="200" height="200"src="treeDemo2.ewd" /> </ext:desktop>

Now create the treeDemo2.ewd fragment that will populate the pop-up windowcreated when we click the Tree Demo icon:

<ewd:config isFirstPage="true" pageType="ajax" prePageScript="##class(ewd.test).getDemoTreeData2">

<span><ext:tree datastore="myTreeData" style="overflow:auto;height:300px;width:200px;" text="Cars"autoWindow="true" windowWidth="400" windowHeight="300" /> /></span>

This will create a tree menu, but notice the autoWindow, windowWidth andwindowHeight attributes. These cause a new window to open whenever any leaf nodeis clicked. Now we need to define the tree via the prePageScript:

ClassMethod getDemoTreeData2(sessid As %String) As %String{s tree(1)="Ford"_$c(1)_"treeDemoFrag1"s tree(2)="Volvo"_$c(1)_"treeDemoFrag2"s tree(3)="Nissan"_$c(1)_"treeDemoFrag3"d createTreeDatastore^%zewdExtJS(.tree,"myTreeData",sessid) QUIT ""}

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

75

Page 76: Enterprise Web Developer Using the ExtJS Widgets

Notice how we can define a fragment name for each leaf node by setting the secondpiece in each tree node (where the delimiter is ASCII 1) to the name of the requiredfragment. So, in other words, when we click the Ford option, the window that popsup will be populated by a fragment named treeDemoFrag1.ewd.

Now all we need to do is create the three fragments referred to by the prePageScript.Initially let's just create some simple basic content to demonstrate how it will all work:

treeDemoFrag1.ewd:

<ewd:config isFirstPage="false" pageType="ajax" /><span> You selected a Ford!</span>

treeDemoFrag2.ewd:

<ewd:config isFirstPage="false" pageType="ajax" /><span> You selected a Volvo!</span>

treeDemoFrag3.ewd:

<ewd:config isFirstPage="false" pageType="ajax" /><span> You selected a Nissan!</span>

Compile all these pages and when you re-load the main container page in the browser,you should then see the following (the tree window has been dragged to the left forclarity):

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

76

Page 77: Enterprise Web Developer Using the ExtJS Widgets

Now you're all set. You can now modify the three simple fragments and startpopulating the windows with much more complex content.

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

77

Page 78: Enterprise Web Developer Using the ExtJS Widgets

Running Separate EWD Applications in Desktop Windows

A cool trick with the desktop is to use the pop-up windows to act as containers forcompletely self-contained EWD applications (or indeed any other web application).Just load the window with a fragment that contains an <iframe> tag. The <iframe>can then load anything it likes into itself. You now have a complete applicationrunning in a desktop window!

Here's a quick guide to this trick. First add a new icon to your desktop:

<ext:window title="ewdMgr" showOnDesktop="true" desktopIcon="/ext-2.2/images/ewdMgr48x48.png" iconClass="panel" width="800" height="600"src="loadEwdMgr.ewd" />

Now create the fragment named loadEwdMgr.ewd:

<ewd:config isFirstPage="false" pagetype="ajax">

<span><iframe src="/php/ewdMgr/index.php" width="100%" height="100%"frameborder="0"></iframe></span>

You'll probably need to modify the src path for the ewdMgr application for yourenvironment (or use a path to some other existing application).

That's all there is to it! Compile the desktopDemo.ewd and loadEwdMgr.ewd pagesand it should now work:

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

78

Page 79: Enterprise Web Developer Using the ExtJS Widgets

There you go! A complete web desktop application, and all built in a matter of a fewminutes!

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

79

Page 80: Enterprise Web Developer Using the ExtJS Widgets

APPENDIX I

Mapping of EWD ExtJS tags to ExtJS Objects

Tag Name ExtJS Class<ext:button> Ext.Button<ext:checkBox> Ext.form.Checkbox<ext:checkBoxGroup> Ext.form.CheckboxGroup<ext:checkItem> Ext.menu.CheckItem<ext:columnLayout> Ext.layout.ColumnLayout<ext:comboBox> Ext.form.ComboBox<ext:dataArrayReader> Ext.data.ArrayReader<ext:dataArrayReaderRecord> Maps to simple object<ext:dataStore> Ext.data.Store<ext:dateField> Ext.form.DateField<ext:editorGridPanel> Ext.grid.EditorGridPanel<ext:fieldSet> Ext.form.FieldSet<ext:formLabel> Ext.form.Label<ext:formPanel> Ext.form.FormPanel<ext:formSubmit> Maps to simple object<ext:grid> Converted and transformed to <ext:gridPanel><ext:gridCheckColumn> Ext.grid.CheckColumn<ext:gridColumn> Maps to simple object<ext:gridColumnModel> Maps to simple object<ext:gridEditor> Ext.grid.GridEditor<ext:gridPanel> Ext.grid.GridPanel<ext:gridRowExpander> Ext.grid.RowExpander<ext:gridViewConfig> Maps to simple object<ext:hiddenField> Ext.form.HiddenField<ext:itemSelector> Ext.ux.ItemSelector<ext:layoutConfig> Maps to simple object<ext:listeners> Maps to simple object<ext:menu> Ext.menu.Menu<ext:menuItem> Ext.menu.Item<ext:menuSeparator> Ext.menu.Separator<ext:menuTextItem> Ext.menu.TextItem

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

80

Page 81: Enterprise Web Developer Using the ExtJS Widgets

Tag Name ExtJS Class<ext:modalWindow> Maps to simple object<ext:numberField> Ext.form.NumberField<ext:panel> Ext.Panel<ext:progressBar> Ext.ProgressBar<ext:radio> Ext.form.Radio<ext:radioGroup> Ext.form.RadioGroup<ext:statusBar> Ext.StatusBar<ext:store> Maps to simple object<ext:tabPanel> Ext.TabPanel<ext:template> Ext.Template<ext:textarea> Ext.form.TextArea<ext:textField> Ext.form.TextField<ext:timeField> Ext.form.TimeField<ext:toolbar> Ext.Toolbar<ext:toolbarFill> Ext.Toolbar.Fill<ext:toolbarSeparator> Ext.Toolbar.Separator<ext:toolbarSpacer> Ext.Toolbar.Spacer<ext:toolbarTextItem> Ext.Toolbar.TextItem<ext:toolbarButton> Ext.Toolbar.Button<ext:triggerField> Ext.form.TriggerField<ext:viewport> Class Ext.Viewport<ext:window> Class Ext.Window

Enterprise Web Developer : Using the ExtJS Widgets. Version 4.0.746: 08 December 2008. 2008, M/Gateway Developments Ltd. All Rights Reserved

81