Professional Documents
Culture Documents
VERSION 3.2
II
WaveMaker Copyright
4/16/08 WaveMaker Software. All rights reserved. WaveMaker, WaveMaker Visual AJAX Studio, WaveMaker Studio, LiveLayout and the WaveMaker logo are trademarks of WaveMaker Software, which may be registered in some jurisdictions. WaveMaker may have copyrights, trademarks, and other intellectual property rights in and to the contents of this document. This document grants no License to such copyrights, trademarks and other intellectual property rights. All other brands and product names are trademarks or registered trademarks of their respective holders. Information supplied by WaveMaker Software is believed to be accurate and reliable. WaveMaker Software assumes no responsibility for errors in this material. WaveMaker Software reserves the right, without notice, to make changes in product design or specifications.
III
Notices
The following software may be included in WaveMaker. Acegi The end-user documentation included with a redistribution, if any, must include the following acknowledgement: "This product includes software developed by the Acegi Security System for Spring Project (http://acegisecurity.org)." Alternately, this acknowledgement may appear in the software itself, if and wherever such third-party acknowledgements normally appear. The names "Acegi", "Acegi Security System" and "Acegi Security System for Spring" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact ben.alex@acegi.com.au. Ant Apache Ant. Copyright 1999-2006 The Apache Software Foundation. This product includes software developed by The Apache Software Foundation (http://www.apache.org/). This product includes also software developed by: the W3C consortium (http://www.w3c.org) , the SAX project (http://www.saxproject.org) The <sync> task is based on code Copyright (c) 2002, Landmark Graphics Corp that has been kindly donated to the Apache Software Foundation. Apache Commons - beanutils, collections This product includes software developed by The Apache Software Foundation (http://www.apache.org/). Apache Jakarta Commons IO Copyright 2001-2007 The Apache Software Foundation. This product includes software developed by The Apache Software Foundation (http://www.apache.org/). Apache Jakarta Commons FileUpload Copyright 2002-2006 The Apache Software Foundation. This product includes software developed by The Apache Software Foundation (http://www.apache.org/). Apache Jakarta Commons Lang Copyright 2001-2007 The Apache Software Foundation This product includes software developed by The Apache Software Foundation (http://www.apache.org/). Apache Commons Logging Copyright 2003-2007 The Apache Software Foundation. This product includes software developed by The Apache Software Foundation (http://www.apache.org/). JsonView.java The version distributed with WaveMaker is derived from the standard distribution. Source code is available at dev.wavemaker.com. Apache log4j Copyright 2007 The Apache Software Foundation. This product includes software developed at The Apache Software Foundation (http://www.apache.org/). Spring This product includes software developed by the Apache Software Foundation (http://www.apache.org). The end-user documentation included with a redistribution, if any, must include the following acknowledgement: "This product includes software developed by the Spring Framework Project (http://www.springframework.org)." Alternatively, this acknowledgement may appear in the software itself, if and wherever such third-party acknowledgements normally appear. The names "Spring" and "Spring Framework" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact rod.johnson@interface21.com or juergen.hoeller@interface21.com. Tomcat This product includes software developed by The Apache Software Foundation (http://www.apache.org/). Java Management Extensions (JMX) support is provided by the MX4J package, which is open source software. The original software and related information is available at http://mx4j.sourceforge.net. The Windows Installer is built with the Nullsoft Scriptable Install System (NSIS), which is open source software. The original software and related information is available at http://nsis.sourceforge.net. Java compilation software for JSP pages is provided by Eclipse, which is open source software. The original software and related information is available at http://www.eclipse.org. Apache XML Commons Resolver Copyright 2006 The Apache Software Foundation. This product includes software developed at The Apache Software Foundation http://www.apache.org/ . Portions of this code are derived from classes placed in the public domain by Arbortext on 10 Apr 2000. See: http://www.arbortext.com/customer_support/updates_and_technical_notes/catalogs/docs/README.htm XmlSchema This product includes software developed by The Apache Software Foundation (http://www.apache.org/). Please read the different LICENSE files present in the licenses directory of this distribution. Portions Copyright 2006 International Business Machines Corp.
IV
Antlr2 This product includes Antlr2, http://antlr2.org/. Dojo Copyright (c) 2005-2007, The Dojo Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Dojo Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Hibernate This product includes Hibernate. Source code is available at http://www.hibernate.org/. JAXB Distributed under CDDL v1 or GPL v2, a copy of these license is provided with this distribution. The version distributed with WaveMaker is derived from the standard distribution. Source code is available at dev.wavemaker.com. The standard distribution is available at https://jaxb.dev.java.net/. JAX-WS Distributed under CDDL v1 or GPL v2, a copy of these license is provided with this distribution. The standard distribution is available at https://jax-ws.dev.java.net/. JDOM This product includes software developed by the JDOM Project (http://www.jdom.org/)." Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer that follows these conditions in the documentation and/or other materials provided with the distribution. The name "JDOM" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact <request_AT_jdom_DOT_org>. Products derived from this software may not be called "JDOM", nor may "JDOM" appear in their name, without prior written permission from the JDOM Project Management <request_AT_jdom_DOT_org>. In addition, we request (but do not require) that you include in the end-user documentation provided with the redistribution and/or in the software itself an acknowledgement equivalent to the following: "This product includes software developed by the JDOM Project (http://www.jdom.org/)." Alternatively, the acknowledgment may be graphical using the logos available at http://www.jdom.org/images/ logos. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the JDOM Project and was originally created by Jason Hunter <jhunter_AT_jdom_DOT_org> and Brett McLaughlin <brett_AT_jdom_DOT_org>. For more information on the JDOM Project, please see <http://www.jdom.org/>. NSIS The Windows Installer is built with the Nullsoft Scriptable Install System (NSIS), which is open source software. The original software and related information is available at http://nsis.sourceforge.net. HSQLDB Copyright (c) 1995-2000 by the Hypersonic SQL Group. All rights reserved. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Hypersonic SQL Group nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
VI
CONTENTS
.5 5 6 7 7 10 11 12 13 14 15 15 15 17 17 18 19 19 20 21 21
VIII
Common Widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
The Accordion Widget . . . . . . . . . . . . . . . . . . The AutoForm Widget . . . . . . . . . . . . . . . . . . Getting the DataSet . . . . . . . . . . . . . . . Using the DataOutput . . . . . . . . . . . . . . Using AutoForm as a Detail Widget . . . Creating SubForms . . . . . . . . . . . . . . . . AutoForm Properties . . . . . . . . . . . . . . . AutoForm Styles. . . . . . . . . . . . . . . . . . The Bevel Widget . . . . . . . . . . . . . . . . . . . . . Bevel Properties . . . . . . . . . . . . . . . . . . The Button Widget . . . . . . . . . . . . . . . . . . . . . Button Properties . . . . . . . . . . . . . . . . . Button Events . . . . . . . . . . . . . . . . . . . The Content Widget . . . . . . . . . . . . . . . . . . . . How to Use the Content Widget . . . . . . . Content Widget Properties . . . . . . . . . . . The DataGrid Widget . . . . . . . . . . . . . . . . . . . Steps for Creating a DataGrid . . . . . . . . DataGrid Properties . . . . . . . . . . . . . . . Properties for DataGrid Columns . . . . . . Display Types and their Editor Properties Default. . . . . . . . . . . . . . . . . . . . Number . . . . . . . . . . . . . . . . . . . Date . . . . . . . . . . . . . . . . . . . . . Time . . . . . . . . . . . . . . . . . . . . . Date Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Binding to Expressions . . . . . . . Binding to Variables. . . . . . . . . About Pages and Layers . . . . . . . . . . . . . . . Scoping . . . . . . . . . . . . . . . . . . . . . . Loading . . . . . . . . . . . . . . . . . . . . . . Navigation Between Pages and Layers Whole Screen Navigation . . . . . Displaying Subpages . . . . . . . . Tab or Accordion Navigation . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
21 21 21 22 22 23 25 25 26
27 28 28 28 29 29 29 31 31 31 31 32 32 33 33 33 34 34 35 36 36 37 37 37 38 38
IX
Money . . . . . . . . . . . . . . . . . . . . . . . . Link . . . . . . . . . . . . . . . . . . . . . . . . . . RegularExpression . . . . . . . . . . . . . . . . Evaluation . . . . . . . . . . . . . . . . . . . . . DataGrid Events . . . . . . . . . . . . . . . . . . . . . . The Editor Widget . . . . . . . . . . . . . . . . . . . . . . . . . Properties of the Editor Widget. . . . . . . . . . . . Editor Events . . . . . . . . . . . . . . . . . . . . . . . . Display Types and their Editor Properties . . . . Text. . . . . . . . . . . . . . . . . . . . . . . . . . Date . . . . . . . . . . . . . . . . . . . . . . . . . Time . . . . . . . . . . . . . . . . . . . . . . . . . Number . . . . . . . . . . . . . . . . . . . . . . . Currency . . . . . . . . . . . . . . . . . . . . . . Select . . . . . . . . . . . . . . . . . . . . . . . . CheckBox . . . . . . . . . . . . . . . . . . . . . . Radio Button Groups . . . . . . . . . . . . . . TextArea . . . . . . . . . . . . . . . . . . . . . . Slider. . . . . . . . . . . . . . . . . . . . . . . . . Validation . . . . . . . . . . . . . . . . . . . . . . . . . . See Changes as You Type . . . . . . . . . . . . . . . The Label Widget. . . . . . . . . . . . . . . . . . . . . . . . . . Display Types and their Formatting Properties . Number . . . . . . . . . . . . . . . . . . . . . . . Date . . . . . . . . . . . . . . . . . . . . . . . . . Time . . . . . . . . . . . . . . . . . . . . . . . . . Date Time . . . . . . . . . . . . . . . . . . . . . Money . . . . . . . . . . . . . . . . . . . . . . . . Link . . . . . . . . . . . . . . . . . . . . . . . . . . RegularExpression . . . . . . . . . . . . . . . . Evaluation . . . . . . . . . . . . . . . . . . . . . The Layers Widget . . . . . . . . . . . . . . . . . . . . . . . . . Types of Layers . . . . . . . . . . . . . . . . . . . . . . Layers Widget Properties . . . . . . . . . . . . . . . . Layers Widget Events . . . . . . . . . . . . . . . . . . Properties of Each Layer . . . . . . . . . . . . . . . . Events for Each Layer . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
39 39 39 39 40 40 40 42 42 42 43 43 44 44 45 45 46 46 47 47 47 47 49 50 50 50 51 51 51 52 52 52 53 53 54 55 56
The List Widget . . . . . . . . . . . . List Widget Properties . . . List Widget Events . . . . . The Pane Widget . . . . . . . . . . . Pane Widget Properties . . Pane Widget Events . . . . The Panel Widget. . . . . . . . . . . Panel Widget Properties . The Picture Widget. . . . . . . . . . How to Add the Image . . Picture Widget Properties Picture Widget Events . . . The Spacer Widget. . . . . . . . . . Spacer Widget Properties The Splitter Widget . . . . . . . . . Splitter Widget Properties The Tabs Widget . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
56 56 57 57 58 58 59 59 60 60 60 61 61 62 62 62 63 65 65 67 68 68 68 68 69 69 70 70 72 72 74 74 75 75 75
XI
Database Service Operations . . . . . . . . . . . . . . . . . . . . . 76 getCount . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 GetByID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 getList . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 Insert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 Update. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 Delete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 Error or Success? Handling Results from Database Service Operations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 Exporting a Data Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 . 83 . 83 . 84 . 86 . 86 . 87 . 87 . 88 . 88 . 88 . 90 . 90 . 91 . 93 . 94 . 94 . 94 . 95 . 95 101 101
How to Set Up a Log In Page . . . . . . . . . . . . . . . . . . . . . . . . 105 Using the Demo Data Source for Login Data . . . . . . . . . . . . . . 107 Using a Database for Login Data . . . . . . . . . . . . . . . . . . . . . . 107
105
XII
Using LDAP for Login Data . . . . . . . . . . . . . . . . . . . . . . . . . . 108 The Default Login Page. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 The Security Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
111
111 111 111 112 112 112 113 113 113 114 115 117 118 118 119 119 119 120 120 121 121 122 122 123 123 123 124 124 124
117
127
XIII
The Widget Module File . . . . . . . . . . . . . . . . . . . . . Defining Widgets . . . . . . . . . . . . . . . . . . . . . Widget Properties . . . . . . . . . . . . . . . . . . . . . Widget Events . . . . . . . . . . . . . . . . . . . . . . . Expose the Event in the Property Editor . Make the Event Fire. . . . . . . . . . . . . . . Widget Module File Location. . . . . . . . . . . . . . Adding Studio Support for the Widget . . . . . . . . . . . Packages File Location . . . . . . . . . . . . . . . . . Adding Runtime Support for the Widget . . . . . . . . . . lib.js File Location. . . . . . . . . . . . . . . . . . . . . Testing the Widget. . . . . . . . . . . . . . . . . . . . . . . . . Dojo and WaveMaker . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
128 129 130 130 131 131 132 132 133 133 134 134 134
XIV
CHAPTER 1
Overview
This guide helps you get the most out of WaveMaker Visual AJAX Studio (WaveMaker Studio). To learn how to create and run a simple project, its a good idea to start with the WaveMaker Studio Tutorial. This guide contains the following sections: Installing WaveMaker Studio on page 3 Building Pages on page 5 Common Widgets on page 27 Working with Databases on page 65 Working with Services and Operations on page 83 Setting up a User Login Page on page 105 Projects and Project Files on page 111 Customizing WaveMaker Applications with JavaScript on page 117 Creating Custom Widgets on page 127
OVERVIEW
CHAPTER 2
CHAPTER 3
Building Pages
Getting Started With Page Design on page 5 Working with Widgets on page 17 About Pages and Layers on page 21
The WaveMaker Tutorial on page 5 The WaveMaker Studio Page Designer on page 6 Designing Pages In WaveMaker on page 14 Live Layout on page 15
BUILDING PAGES
Design Toolbar on page 7 Palette on page 7 Page Builder on page 10 Model Tree on page 11 Property Editor on page 12 Keyboard Shortcuts on page 13
Design Toolbar
This toolbar provides buttons for common Page Designer functions. The toolbar contains the following buttons:
New Page. Create a new page.
Save Page As. Copy a page to a different page name. The copied page is automatically included in the current project. Toggle Outlined View. The outline toggle button allows you to see your page without the widget outlines (the run-time look, rather than the design-time look). You typically work with the outlines on, then toggle them off to see what the page would look like at run time. Toggle Exploded View. The exploded view puts a bit of padding between all the widgets so that they are easy to select. You can toggle it off and on with this button. The exploded view can obscure widget alignment, so use it only when you need it. Cut. Cut the selected widget. You can then paste the widget into another panel or page. Copy. Copy the selected widget. You can then paste the widget into another panel or page. Paste. Paste a widget that you have copied or cut.
Palette
Located along the left side of the Page Designer, the Palette displays the various types of elements that you can add to your application, such as widgets, gadgets and subpages. To build your pages, drag items from the Palette and drop them in the Page Builder.
BUILDING PAGES
The Palette is organized into logical groups of elements, which are displayed in Accordion boxes. To see what elements are in a particular Accordion box, click on the heading.
WaveMaker provides a large set of page elements and groups, but these are ultimately configurable. You can add your own widgets and gadgets (Creating Custom Widgets on page 127). By default, the Palette contains the following element groups: Common: The top group, called Common contains commonly-used page widgets. All the widgets in the Common group are described in Common Widgets on page 27. All the widgets in the Common group are also included in their logical groups, such as Form Elements or Controls. Form Elements: This group contains elements that you would typically use to create forms. Elements include the AutoForm widget as well as editors pre-configured for currency, date, numbers and so on. Containers and Layout: This group contains elements for page layout. It includes Panels, Spacers, Tabs and so on.
such as a progress bar, a calendar and a tree control. Web Content: This group contains web gadgets, such as a stock gadget, a weather gadget and a YouTube gadget. Static Content: This group contains static content, such as a picture widget and a label widget.
Custom: This group contains an example custom widget. This is where your own custom widgets would also be placed (Creating Custom Widgets on page 127).
10
BUILDING PAGES
This group contains all your project pages other than the one currently displayed in the Page Builder. You can drag a page into the Page Builder to create a sub-page (Displaying Subpages on page 25).
Pages:
Page Builder
The large area in the center of the Page Designer represents the page itself. The top container is called the layoutBox widget. It cannot be removed. Drag widgets from the Palette to add them to the page. In the Page Builder, the outline of the selected widget is highlighted in blue. The name of the selected widget appears in the lower left corner of the Page Builder and the size of the widget (in pixels) is listed to the right of the name.
In the Page Builder, you can display the content with or without outlines and with or without padding:
11
Outlined View. The outline view allows you to see your page without the widget outlines (the run-time look, rather than the design-time look). You typically work with the outlines on, then toggle them off to see what the page would look like at run time. Exploded View. The exploded view puts a bit of padding between all the widgets so that they are easy to select. You can toggle it off and on with this button. The exploded view can obscure widget alignment, so use it only when you need it.
The Design Toolbar includes buttons for toggling the Outlined view and the Exploded view (Design Toolbar on page 7).
Model Tree
The Model Tree is located on the upper right side of the Page Designer.
The Model Tree has the following three tabs: The Widgets tab shows a hierarchical tree of all the widgets in the current page. When you select a widget in this tree, that widget is also selected in the Page Builder. The Components tab shows the components available to your page. The types of components are service calls, navigation components and variables. Each type of component is represented by its own icon. To add a new component, click the appropriate icon at the top of the components tab:
12
BUILDING PAGES
Variable. Create variables to hold data that you can bind to service calls or widgets. You can scope a variable at either the Page or the Project level (Scoping on page 22). Service Call. A Service Call is a way for a WaveMaker application to invoke an action, such as a database query, navigation from one page to another or a custom Java method (Creating a Service Call on page 84). Navigation. An application component that loads a particular Layer or Page (Navigation Between Pages and Layers on page 23). In the case of pages, the Navigation component also stores information about where to display the page.
In the component tree, you can create each component either at the Page level or at the Project level (Scoping on page 22). Click on a component to see its properties in the Property Editor.
The Pages tab shows all the pages in the current project. Double-click on a page in the list to open that page in the Page Designer.
Property Editor
The Property editor is located on the lower right of the Page Designer. The Property Editor has three tabs: Properties: The Properties tab displays the properties of the selected widget or component. Different items have different properties.
13
The Events tab shows all the events for the selected object, if there are any. Styles: The Styles tab allows you to define styles for the selected object. The Styles tab provides two different ways to define styles. You can select pre-existing classes, to define such things as font, font size, color and so on. Or you can click the Custom Styles heading and type in your own custom CSS. For more on either method, see Styling Widgets on page 20.
Events:
Keyboard Shortcuts
You can use the following keyboard shortcuts in the Page Designer.
14
BUILDING PAGES
Description Paste copied widget Copy selected widget Save Change sizeUnits property of selected widget to flex Toggle value of selected widgets box property Switch focus to the parent widget of the currently-selected widget. To force a widget into one of its child containers, hold the <Shift> key while dragging the widget.
To get a widget onto the page, drag it from the Palette and drop it where you want it. The Page Builder always contains a special widget called the layoutBox (The layoutBox on page 15). The layoutBox holds all the other widgets that you drop into the Page Builder. You cannot delete the layoutBox or drag a new one into the Page Builder, but you can set some properties to configure it.
15
Many widgets can be used as containers for other widgets, so you can nest them one inside the other. The panel widget (The Panel Widget on page 59) is a generic container widget that it very useful in structuring widgets on a page. You can set up the panel widget to arrange its contents vertically or horizontally (Arranging Widgets within a Container (Box Property) on page 18). You can also use spacer widgets to adjust the spacing between widgets (The Spacer Widget on page 61). Each widget has its own set of properties that define how it looks and how it behaves. For descriptions of the most common widgets and their properties, see Common Widgets on page 27. For more on using widgets on your page, see Working with Widgets on page 17.
The layoutBox
The layoutBox is the top container for each page. Each page has one and only one layoutBox and you cannot drag a new layoutBox onto the page from the Palette. You can apply padding, margins, backgrounds and other styling to the layoutBox, just as you would to any other container widget. Like other containers, the layoutBox has a box property which you can set to display the contents either horizontally or vertically.
Live Layout
WaveMaker Studios LiveLayout feature allows you to see live data in the Page Designer as you are working with your pages. You can also execute queries in the Query Editor. This allows you to dynamically test run pieces of the application as you assemble it, rather than having to run the whole application.
16
BUILDING PAGES
The following figure shows a page in the Page Builder. This page has a search field and search button, a DataGrid widget that shows the results of the search, and an AutoForm widget that shows details about whatever record is selected in the grid. Notice that this example page shows data in the Page Builder.
If you click a different record in the DataGrid, the AutoForm widget updates to show the new record. LiveLayout allows you to do all this right in the Page Builder, without having to stop and run the application. Heres a an example of you would set up the page shown above to use LiveLayout:
17
1.
In order for Live Layout to work, you must first import your database (Importing a Database on page 65). If you havent already imported a database, do that first. At the top right of WaveMaker Studio, in the Project tabs, click the Live Layout button.
2.
3. 4.
Select the Editor widget in the Page Designer. On the Properties tab, under Editing type in the following value for the displayValue property: a In the Page Designer select the DataGrid widget. On the Properties tab, under Other, click the updateNow button. In the Page Designer select the AutoForm widget. On the Properties tab, under Other, click the updateNow button.
5. 6. 7. 8.
LiveLayout now shows you live data right in the Page Designer. Try clicking different records in your DataGrid. The AutoForm widget automatically updates to show you the new data.
For descriptions of common predefined widgets, see Common Widgets on page 27. For information on creating your own custom widgets, see Creating Custom Widgets on page 127.
Selecting Widgets
If you have trouble selecting a widget in the Page Builder area, select it in the Model Tree.
18
BUILDING PAGES
When you select a widget in the Model Tree, it is automatically selected in the Page Builder.
You can size each child element horizontally, but not vertically. Vertically each element takes up the full height available in the panel. To make a child element shorter than the other child elements, you would need to nest it in another Panel:
19
However, if the box property is set to Top-to-Bottom then the contents are arranged vertically. In this case, each child element expands to fill the full width of the parent Panel.
the size of the widget in the editable dimension, so it corresponds to width or height depending on context.
SizeUnits are the units of measurement for the Size value. SizeUnits can be
expressed in pixels (px), Ems (em), points (pt), or flex values (Flex on page 19). Ems are nearly ideal since the screen-size of an 'em' is proportional to the current font. In other words, if the user has adjusted his font size, objects measured in ems automatically adapt.
Flex
When you set a widgets sizeUnits property to flex, the widget takes up a proportion of the available space in the container. The proportion depends on the value of the size property. If you have two widgets, such as spacers, both with sizeUnits set to flex and size set to one, then they will take up equal amounts of any available space in the parent widget.
20
BUILDING PAGES
Flex values work as a ratio, so if one widget has a flex of 1 and another a flex of 4, the first one will be four times bigger than the second.
Note that widgets that have a non-zero flex, cannot be manually sized because they are automatically sized.
NOTE:
Styling Widgets
Each Widget can be styled by selecting the Styles tab in the Property Editor. The Styles tab offers you two ways to style the widget: you can use Classes or Custom Styles: Classes: To use classes, click to expand the Classes accordion box. Here are predefined classes for displaying each widget. Just click the values you want to use. Custom Styles: To define custom styles, click to expand the Custom Styles accordion box. Here you can type in any valid CSS. For example, you can set values for padding, margins, height and width, background color, font size, and so on. Here are a few simple examples of CSS that you might type directly into this box:
padding: 0 200px; margin: 10px; width: 75%; "background-color: grey; color: white;
Another possibility is to use the Content widget. You can paste your own custom CSS into your project (in the Source > Markup sub-tab) and then apply styles from that directly to your Content Widget (The Content Widget on page 33).
21
In the Binding dialogs, you can choose bind to an editors displayValue or its dataValue. In many cases displayValue and dataValue are the same. They are different for widgets that display a value differently from the way it is stored in the underlying data. The most common case in which the two values are different is for dates and times: displayValue is the readable string (1/02/08) whereas the dataValue is the date in milliseconds that is expected by a service. It is usually best practice to bind to the dataValue. However, when you are binding to another UI element, such as a label, you sometimes need to bind to the displayValue. Setting either the displayValue or dataValue updates the other property.
Binding to Expressions
To bind to an expression, click the Expression tab in the Bind Sources side of the Binding dialog. Type and/or build your expression in the Data Expression area. You can select from the Bind Sources list here as well. By default expressions are considered strings. To have an expression evaluated as a number, begin it with %%. So you'd do %%1.
NOTE: Binding to Variables
You can bind to variables just as you would any other data object. A Variable has a type, so you'd only want to bind that to something that accepts the type. If your Variable is an Actor, for example, you could bind the Actor's lastName to an input's inputValue or a label's content, since these things are strings. We don't currently do type checking.
22
BUILDING PAGES
that you can make service calls that show this group of widgets to a user. (An example of a widget grouping that is not addressable is a panel widget. You can not make a service call to display a particular panel.) To define an addressable group of widgets, you can use pages but you can also use layers. WaveMaker Studio uses the Ajax concept that an application consists not of discrete web pages, but of pages and layers. Both pages and layers are essentially just mechanisms for grouping content and services that you want to present to your users as a unit and that you want to be able to call from a service: Page: A unit of application development in studio. Pages have local scope. They appear in the Dashboard and are accessible on the Design Tab. Once you create a page, it is accessible as a subpage in the Pages section of the Palette. Layer: A widget that allows for multiple widgets to occupy the same area of the screen, in a navigable way. Tabs and Accordion widgets are layers. Layers have no local scope. The widgets they contain are actually part of the containing page scope. So how do you know when to use a Page and when to use a Layer? The first thing to remember is that there is no wrong answer. The main differences between the two for an application developer are Scoping on page 22 and Loading on page 22.
Scoping
The main difference between pages and layers is one of scope. Things scoped at the page level are accessible only on that page. Widgets are scoped to the page they are on. When you use a Layers widget and set up multiple layers, then all the widgets on each layer are available on all the other layers. Similarly, all the service calls youve defined on that page are available on every other layer. In places where you need a lot of interactivity between widgets, its probably more convenient to use layers rather than pages. Service calls and variables can all be scoped either at the project level or at the page level. If you scope a service call or variable the page level, it is accessible only on that page.
Loading
Another difference between pages and layers is how they are loaded in the application. To display a new page, the client asks the server for the content and the server sends it back. A whole new page is loaded, refreshing the state and destroying the existing context.
23
However, a single page can contain multiple layers which can be dynamically revealed or hidden. To show a different layer, you dont need to get it from the server because the client already has it.
24
BUILDING PAGES
This launches the Configure Navigation screen. On this screen you choose whether you want to navigate to a layer or a page:
Layer: If you choose the Layer radio button, a drop-down menu containing all the layers on the current page is enabled. Select a layer from this menu.
If you choose the Page radio button, a drop-down menu containing all the pages in the application is enabled. Select a page from this menu and then choose how you want to display the page. To display a page, you can choose either to use the entire screen, replacing everything in the browser or you can choose to display the page in an existing pane widget.
Page:
25
When youve made all your configuration selections, click the Save button. The new Navigation component now appears in the Components list in the Model Tree and you can call it as you would any other component. For example, you can select the navigation component as the value for a buttons onclick event.
Whole Screen Navigation
If you want to set up a page to display in the whole browser, set up a Navigation component that displays a page and choose the Whole Screen option. When your navigation component is triggered, the page you selected appears in the browser. Note that:
When the page is loaded, you lose any existing context If the page you load has no navigation options, then the users cant get back to where they were. This might or might not be what you want.
Displaying Subpages
The easiest way to display a subpage is to drag it from the Pages section of the Palette and place it where you want it. If you have more than one page in your project, then all the pages in the project effectively become widgets and appear in this section of the Palette. When you drag a page from the Palette and drop it in the Page Builder, you are creating a subpage. The subpage is automatically contained in a pane widget (The Pane Widget on page 57). A pane widget is just a container for a page. The important thing to know about pane widgets is that they are targettable. This means that every pane widget in your application is a
26
BUILDING PAGES
location where you can place a page. When you create a new Navigation component, then all the panes in your project are listed as areas where you can choose to display a page. As weve said, the WaveMaker Studio automatically creates a pane for you when you drag a page from the Palette and drop it in the Page Builder. However, you are also free to drag a Pane widget from the Palette directly. See the section on Pane widgets for more information (The Pane Widget on page 57).
Tab or Accordion Navigation
To set up tab or accordion navigation, you typically use layers, rather than pages. For more information, see The Layers Widget on page 52.
CHAPTER 4
Common Widgets
This section describes the most commonly used widgets and helps you configure them. This section covers all the widgets in the Common section of the Palette. The Accordion Widget on page 27
The AutoForm Widget on page 28 The Bevel Widget on page 31 The Button Widget on page 31 The Content Widget on page 33 The DataGrid Widget on page 34 The Editor Widget on page 40 The Label Widget on page 47 The Layers Widget on page 52 The List Widget on page 56 The Pane Widget on page 57 The Panel Widget on page 59 The Picture Widget on page 60 The Spacer Widget on page 61 The Splitter Widget on page 62 The Tabs Widget on page 63
28
COMMON WIDGETS
29
The DataOutput is available as a binding source, so you can use it as an input to a database service call or in any other way you choose.
Creating SubForms
The AutoForm widget does not generate Editor widgets for lists and substructures in the DataSet. However, you can easily create a subform, by dragging one AutoForm widget into another. When you do this, the dataSetName property for the second (child) AutoForm contains a list of lists and substructures from the first (parent AutoForm. Thus you can very quickly and easily create a SubForm.
AutoForm Properties
AutoForm Common Properties name: the name that WaveMaker Studio uses to reference the widget. This is the name that appears in Model Tree, in the Page Builder, in binding dialogs, and so on; this is also the name you use to reference the widget in code services. binding: defines the DataSet (input data source). Clicking the binding property launches a dialog for defining this DataSet. Alternatively, you can choose a DataSet from the dataSetName property menu. showing: when checked (true), the AutoForm widget is visible to users; when unchecked (false), the widget is hidden. dataSetName: a drop-down menu of obects that you can choose to use as the DataSet (data source) for this AutoForm widget. You can alternatively define a DataSet using the dialog launched by the binding property. AutoForm Display Properties readonly: if checked (true), the Editor widgets in the AutoForm are displayed as output, rather than input, fields. The AutoForm displays as a Detail widget. If unchecked (false), the Editor widgets are input fields and the users can input their own values.
30
specifies the size of the Editor widgets in the AutoForm. You first need to specify the units of size, which you do by setting the editorSizeUnits property. The editorSize property sets a default size for all the Editor widgets in this AutoForm; you can still size each Editor widget individually.
editorSizeUnits: specifies the units in which the editorSize property is measured. The default value is flex. Choices are:
pixels em: text size; adapts automatically to current screen size pt: point (1/72 inch) flex: stretches widget to fill up proportional area of available space (see Setting Widget Size on page 19) captionSize: specifies the size of the caption in each Editor widget. The caption is the label on the widget, the text that the user sees. The value of the caption is specified by the caption property. Before you can set the captionSize, you first need to specify the units of size, which you do by setting the captionUnits property. captionUnits: specifies the units in which the captionSize property is measured. The default value is flex. captionAlign: specifies the horizontal alignment of the caption in each Editor widget. The alignment is relative to the entire available caption area, rather than the entire area of the Editor widget. Possible values are: Right, Left, and Center. captionPosition: specifies the vertical alignment of the caption in each Editor widget. The position is relative to the Editor input (or output) field. Possible values are: Top, Bottom, Left and Right.
px:
AutoForm Layout Properties lock: if checked (true), you cannot add or remove widgets to this container widget. autosize: if checked (true) this property sizes the widget so that it is just big enough for its contents and no bigger. If unchecked (false) the size of the widget is determined by the size property. size: specifies the size of the AutoForm widget. Before you can set the size, you first need to specify the units of size, which you do by setting the sizeUnits property. If the autosize property is checked (true) then the size property cannot be set.
sizeUnits: specifies the units in which the size property is measured. If the autosize property is checked (true) then the sizeUnits property cannot be set. Default value is flex. Choices are:
px: pixels em: text size; adapts automatically to current screen size
31
pt: point (1/72 inch) flex: stretches widget to fill up proportional area of available space (see Setting Widget Size on page 19)
the alignment of the child widgets (any widgets inside the AutoForm widget). Values are Top-to-Bottom or Left-to-Right. See the Arranging Widgets within a Container (Box Property) on page 18 for more information on the box property.
box:
AutoForm Operations Properties autoEditors: automatically add editors based on data clearEditors: clear data from editors deleteEditors: remove all editors from AutoForm clearForm: remove all widgets from AutoForm
AutoForm Styles
AutoForm styles affect both the labels and the data. To change just the labels or just the data, you need to use custom styles.
Bevel Properties
name:
the name that WaveMaker Studio uses to reference the widget. This is the name that appears in Model Tree, in the Page Builder, in binding dialogs, and so on; this is also the name you use to reference the widget in code services.
binding:
not used with the Bevel widget showing: when checked (true), the widget is visible to users; when unchecked (false), the widget is hidden.
32
COMMON WIDGETS
Button Properties
The Button widget has the following properties: Common Properties name: the name that WaveMaker Studio uses to reference the widget. This is the name that appears in Model Tree, in the Page Builder, in binding dialogs, and so on; this is also the name you use to reference the widget in code services. binding: use to dynamically set the value of the caption property or the disabled property. showing: when checked (true), the widget is visible to users; when unchecked (false), the widget is hidden. disabled: when checked (true) the widget can take no inputs. Display Properties caption: the caption is the label on the widget, the text that the user sees. hint: text displayed when the cursor hovers over the button Layout Properties autosize: if checked (true) this property sizes the widget so that it is just big enough for its contents and no bigger. If unchecked (false) the size of the widget is determined by the size property. size: specifies the size of the widget. Before you can set the size, you first need to specify the units of size, which you do by setting the sizeUnits property. If the autosize property is checked (true) then the size property cannot be set. sizeUnits: specifies the units in which the size property is measured. If the autosize property is checked (true) then the sizeUnits property cannot be set. Default value is px. Choices are: px: pixels em: text size; adapts automatically to current screen size pt: point (1/72 inch) flex: stretches widget to fill up proportional area of available space (see Setting Widget Size on page 19)
Button Events
The Button widget provides a single event, the onclick event. This event fires when a user clicks on the button.
33
Open your project. In the Page Designer, drag a Content widget from the Palette onto the page. Click the Source tab along the top of the Page Designer. Several subtabs appear. Click the tab labeled Markup. Delete the single line of sample markup in the text area here. Paste the text from your own CSS markup file into the text area under the Markup tab in the WaveMaker Studio. Save the project. Click on the Design tab to bring up the Page Designer again. Select your Content widget. In the Property Editor, under the Other section, find the property called content. The pull-down menu for this property now contains the IDs in the markup you just added. Select the appropriate ID from the pull-down menu. the project.
10.Save
binding:
use to dynamically set the value of the disabled property. showing: when checked (true), the widget is visible to users; when unchecked (false), the widget is hidden.
disabled:
Layout Properties
34
COMMON WIDGETS
if checked (true) this property sizes the widget so that it is just big enough for its contents and no bigger. If unchecked (false) the size of the widget is determined by the size property. size: specifies the size of the widget. Before you can set the size, you first need to specify the units of size, which you do by setting the sizeUnits property. If the autosize property is checked (true) then the size property cannot be set. sizeUnits: specifies the units in which the size property is measured. If the autosize property is checked (true) then the sizeUnits property cannot be set. Default value is px. Choices are: px: pixels em: text size; adapts automatically to current screen size pt: point (1/72 inch) flex: stretches widget to fill up proportional area of available space (see Setting Widget Size on page 19)
autosize:
Other Properties content: a drop-down menu showing <div> names from the Markup source. Paste your own content into the Markup to define options in this menu. See How to Use the Content Widget on page 33 for more details.
Drag a DataGrid widget onto the Page. Click the binding property. The Binding dialog appears. Under Bind Targets select the dataSet item in the DataGrid. Under Bind Sources, select the object to which you are binding the grid. The object must represent a list. Typically, you will use a service call.
35
5.
Add the columns. You can click autoColumns to have them built for you, or you can add columns manually by clicking the addColumn operation. Use a columns field property to specify a specific field from the Grid binding for that column to display. To size the columns, you can either click autoSize or use the columnWidth property to specify a precise width.
6. 7.
DataGrid Properties
The DataGrid widget has the following properties: Common Properties name: the name that WaveMaker Studio uses to reference the widget. This is the name that appears in Model Tree, in the Page Builder, in binding dialogs, and so on; this is also the name you use to reference the widget in code services. binding: defines the input dataSet for this DataGrid. The dataSet must be a list. Clicking the binding property launches a dialog for defining this input source (Tying Widgets to Data and Services on page 15). showing: when checked (true), the widget is visible to users; when unchecked (false), the widget is hidden. Layout Properties size: specifies the size of the widget. Before you can set the size, you first need to specify the units of size, which you do by setting the sizeUnits property. sizeUnits: specifies the units in which the size property is measured. If the autosize property is checked (true) then the sizeUnits property cannot be set. Default value is flex. Choices are: px: pixels em: text size; adapts automatically to current screen size pt: point (1/72 inch) flex: stretches widget to fill up proportional area of available space (see Setting Widget Size on page 19) DataGrid Operation Properties The DataGrid provides the following operations for configuring the grid: addColumn: allows you to manually add columns one at a time autoColumns: adds a column for each type returned so you dont have do it manually
clearColumns:
36
COMMON WIDGETS updateNow: updates the grid with live data from the service call while
name:
the name that WaveMaker Studio uses to reference the widget. This is the name that appears in Model Tree, in the Page Builder, in binding dialogs, and so on; this is also the name you use to reference the widget in code services. caption: specifies the column heading that is displayed to the user.
Layout Properties autoSize: if checked (true) this property sizes the widget so that it is just big enough for its contents and no bigger. If unchecked (false) the size of the widget is determined by the size property. columnWidth: width of the column as a percentage of the total width of the grid index: order in which the columns are displayed in the grid. Change the index to move columns left or right Data Properties field: select the field you want displayed in the column display: defines the type of format (number, money, date, and so on. ) See the Display Types and their Editor Properties on page 42. format: opens the details property for configuring the format. See the Display Types and their Editor Properties on page 42. Columns Operation Properties The DataGrid columns provide the following operations for configuring the grid: addColumn: adds a new column to the end of the Grid. Use the index property to move the colmn left or right removeColumn: removes the currently selected column
37
Default on page 37 Number on page 37 Date on page 37 Time on page 38 Date Time on page 38 Money on page 39 Link on page 39 RegularExpression on page 39 Evaluation on page 39
Default
Use to display text. No format properties are available for the default display.
Number
Use to display numbers. The digits format property determines the number of decimal places that are displayed in the label. The locale format property represents language code, used for i18n. Based on locale setting, different data may be displayed. Possible values are:nls, de, en, n-au, en-ca, en-gb, es, es-es, fr, it, it-it, js, ko, ko-kr, pt, pt-br, zh, zhcn The round format property can be used to specify that the amount be rounded rather than truncated.
Date
Use to display dates. The datePattern format property determines the format of the date. For example:
MMM-dd-yyy
The formatLength format property determines the style of the displayed date:
- 12/15/2007 medium Dec 15, 2007 long December 15, 2007 full Saturday, December 15, 2007
short
The locale format property represents language code, used for i18n. Based on locale setting, different data may be displayed. Possible values are:nls,
38
COMMON WIDGETS
de, en, n-au, en-ca, en-gb, es, es-es, fr, it, it-it, js, ko, ko-kr, pt, pt-br, zh, zhcn
Time
Use to display times. The timePattern format property determines the format of the date. For example:
HH:mm
The formatLength format property determines the style of the displayed time: short - 4:00 PM medium 4:00:00 PM long 4:00:00 PM Pacific Standard Time full 4:00:00 PM Pacific Standard Time The locale format property represents language code, used for i18n. Based on locale setting, different data may be displayed. Possible values are:nls, de, en, n-au, en-ca, en-gb, es, es-es, fr, it, it-it, js, ko, ko-kr, pt, pt-br, zh, zhcn
Date Time
Use to display date and time. The datePattern format property determines the format of the date. For example:
MMM-dd-yyy
The timePattern format property determines the format of the date. For example:
HH:mm
The formatLength format property determines the style of the displayed date-time: short - 12/15/2007 4:00 PM medium Dec 15, 2007 4:00:00:00 PM long December 15, 20074:00:00 PM Pacific Standard Time
full
The locale format property represents language code, used for i18n. Based on locale setting, different data may be displayed. Possible values are:nls, de, en, n-au, en-ca, en-gb, es, es-es, fr, it, it-it, js, ko, ko-kr, pt, pt-br, zh, zhcn
39
Use to display money. The currency format property specifies the symbol to display before amount. The digits format property determines the number of decimal places that are displayed. The round format property can be used to specify that the amount be rounded rather than truncated. The locale format property represents language code, used for i18n. Based on locale setting, different data may be displayed. Possible values are:nls, de, en, n-au, en-ca, en-gb, es, es-es, fr, it, it-it, js, ko, ko-kr, pt, pt-br, zh, zhcn.
Link
Use to display a URL link. To specify the URL, use the link property in the format property list, rather than the link property in the main Property Editor.
RegularExpression
Use to format a column using a regular expression. Typically, you define a regular expression and replace anything that matches that expression with something else. You define the regular expression in the expression format property and the replacement value in the replace format property. The expression format property specifies the regular expression to use for formatting. For example: (^\d{3}).*(\d{2}).*(\d{4}) The replace format property is used for in-line substitution:
$1-$2-$3
The caseSensitive format property is checked (true) when you want the expression to be case-sensitive. The global format property is checked (true) when you want to keep checking for the regular expression after the first match. It is unchecked (false) when you want to stop after the first match.
Evaluation
40
COMMON WIDGETS
The expression format property takes a dojo.formatter expression. For example, to format numbers using commas, you could use:
dojo.number.format($&)
To trim spaces from beginning and end of a string, you could use:
dojo.trim($&)
DataGrid Events
The following event properties are available for the DataGrid widget: onCellClick: fires when a single cell is clicked onHeaderCellClick: by default, when a user clicks on a header cell, the application performs a sort on the column. You can override by calling a custom service or custom JavaScript triggered on this event onSelected: fires when an entire row is selected onSetColumns: used for custom JavaScript on columnsfires when grid is rendered
binding:
you can use this property (Tying Widgets to Data and Services on page 15) to dynamically set any of the following: disabled if True, no events occur caption label for the input displayValue value as it is shown on the page (Bind to displayValue or dataValue? on page 21) dataValue - value as it appears in database (inherited from the displayValue if not set) readonly - if true, user cannot input to the Editor showing: when checked (true), the widget is visible to users; when unchecked (false), the widget is hidden.
41
Display Properties readonly: if checked (true), the widget is displayed as an output, rather than input, fields. caption: the caption is the label on the widget, the text that the user sees.
specifies the size of the caption in the Editor widget. The value of the caption is specified by the caption property. Before you can set the captionSize, you first need to specify the units of size, which you do by setting the captionUnits property. captionUnits: specifies the units in which the captionSize property is measured. The default value is flex. captionAlign: specifies the horizontal alignment of the caption in the Editor widget. The alignment is relative to the entire available caption area, rather than the entire area of the Editor widget. Possible values are: Right, Left, and Center. captionPosition: specifies the vertical alignment of the caption in the Editor widget. The position is relative to the Editor input (or output) field. Possible values are: Top, Bottom, Left and Right.
captionSize:
Layout Properties size: specifies the size of the widget. Before you can set the size, you first need to specify the units of size, which you do by setting the sizeUnits property. If the autosize property is checked (true) then the size property cannot be set. sizeUnits: specifies the units in which the size property is measured. If the autosize property is checked (true) then the sizeUnits property cannot be set. Default value is px. Choices are: px: pixels em: text size; adapts automatically to current screen size pt: point (1/72 inch) flex: stretches widget to fill up proportional area of available space (see Setting Widget Size on page 19) Editing Properties display: the format in which WaveMaker Studio displays the text. For a full list of types and type properties (see Display Types and their Formatting Properties on page 49). editor: click to display the properties for configuring the selected display type (see Display Types and their Formatting Properties on page 49). displayValue: default display value for the widget.
42
COMMON WIDGETS
Editor Events
The Editor widget has a single event, called onchange. This event fires when the display value of the widget changes. For example, when a user selects a value from a drop-down menu, the display value of that menu changes. You could use the onchange event to call an operation that populates a second drop-down menu.
Use to display text. The following editor properties are available when the display property is set to Text: changeOnKey: if checked (true) the output for the field changes with each character you enter, so you can see changes as you type invalidMessage: message which displays if validation is not met or required field not filled in
password:
Masks the users input with **** promptMessage: when in focus, displays hint to user regExp: a regular expression used for client side validation (Validation on page 47) required: if checked (true), this Editor widget represents a required field and the field cannot be submitted unless the user enters a value.
43
Use to display dates. The Calendar widget is automatically displayed below the date-entry field. Invalid dates in the Calendar are unselectable.
The following editor properties are available when the display property is set to Date: invalidMessage: message which displays if validation is not met or required field not filled in maximum: maximum date range minimum: minimum date range promptMessage: when in focus, displays hint to user required: if checked (true), this Editor widget represents a required field and the field cannot be submitted unless the user enters a value.
Time
Use to display times. The Time widget is automatically displayed below the date-entry field. Invalid dates in the Calendar are unselectable.
44
COMMON WIDGETS
The following editor properties are available when the display property is set to Tme: invalidMessage: message which displays if validation is not met or required field not filled in maximum: maximum time range
minimum:
minimum time range promptMessage: when in focus, displays hint to user required: if checked (true), this Editor widget represents a required field and the field cannot be submitted unless the user enters a value. showMessages: if checked (true) this Editor widget diplays the promp and invalidMessage messages.
Number
Use to display numbers. The following editor properties are available when the display property is set to Number: changeOnKey: if checked (true) the output for the field changes with each character you enter, so you can see changes as you type invalidMessage: message which displays if validation is not met or required field not filled in maximum: maximum time range minimum: minimum time range password: masks the users input with **** places: number of decimal places to show promptMessage: when in focus, displays hint to user regExp: a regular expression used for client side validation (Validation on page 47) required: if checked (true), this Editor widget represents a required field and the field cannot be submitted unless the user enters a value.
Currency
Use to display currency. The following properties are available when the display property is set to Currency: changeOnKey: if checked (true) the output for the field changes with each character you enter, so you can see changes as you type
invalidMessage: maximum:
message which displays if validation is not met or required field not filled in maximum value minimum: minimum value
45
masks the users input with **** places: number of decimal places to show promptMessage: when in focus, displays hint to user regExp: a regular expression used for client side validation (Validation on page 47) required: if checked (true), this Editor widget represents a required field and the field cannot be submitted unless the user enters a value.
Select
Use to make the Editor widget a Select Menu. Select Menus allow the user to select a value from a list of values. In order for this to work, you need to populate the select list with the values. There are two ways to do this. For both you need to deal with the specific editor type properties (the properties available when you click the editor: (details) button). Method One: Enter the values into the options property as comma separated values a, b, c Method Two: Use the binding property to bind the select to a dataSet. If you bind to a dataSet, you must bind to a list (just like for DataGrid). You can use a Service Call or a Variable. Then choose a dataField to show a specific field. Then, for any value output you bind to the editor's displayValue or dataValue. For a select, these will be identical. The following editor properties are available when the displayType is Select: allowNone: adds a blank entry to the list of selectable items binding: allows you to obtain the values for the drop down from a service call or variable dataField: if bound select the column name to be used as the data value for the selection (i.e. StateID) displayField: if bound select the column name of the values to be displayed to the user (i.e. StateName)
options:
manually enter option to be used as both display and data values for the selection required: if checked (true) the user must select an item from the menu
CheckBox
Use the checkBox display type to create a checkbox. The following editor properties are available for the checkBox Editor: dataType: the data type for the checkBox selection value. The data type for this value can be a string, a boolean, or a number.
46
value cannot be null. showMessages: if checked (true) this Editor widget diplays the promp and invalidMessage messages. startChecked: if checked (true) the default value of this checkbox is true (the exact value would depend on the dataType you selected for the checkbox).
To create a group of radio buttons, drag an editor widget onto the page for each radio button you want. Change the value of the display property to RadioButton. By default, the radio buttons are all in the same group. You can also edit the Editor details (the details button for the editor property) and set a name for the radioGroup to limit its scope. To bind to a value associated with a radioGroup, bind to any editor in that group's groupValue property (Tying Widgets to Data and Services on page 15). If multiple radio buttons have same group name, then only one response is allowed per group. Use the RadioButton display type to create a checkbox. The following editor properties are available for the RadioButton Editor: dataType: the data type for the RadioButton selection value. The data type for this value can be a string, a boolean, or a number. radioGroup: type in a group name for this radio button. This will create a sub-group of radio buttons. All radio buttons with the same radioGroup name wil belong to this sub-group. required: if checked (true) the value cannot be null. showMessages: if checked (true) this Editor widget diplays the promp and invalidMessage messages. startChecked: if checked (true) this radio button appears selected by default.
TextArea
When you set the display value of the Editor widget to TextArea, the Editor widget appears as a text area. The following editor properties are available for the TextArea Editor: required: if checked (true) the value cannot be null. showMessages: if checked (true) this Editor widget diplays the prompt and invalidMessage messages.
47
When you set the display value of the Editor widget to Slider, the Editor appears as a slider control that enters a value. Establish the range of slider values by setting the maximum and minimum values for the slider control.
The following editor properties are available for the slider Editor: discreteValues: enter discrete values for the slider as a commadelimited list of numbers maximum: maximum value minimum: minimum value required: if checked (true) the value cannot be null. showMessages: if checked (true) this Editor widget diplays the prompt and invalidMessage messages.
Validation
For validation, click the details button for the editor property. You can type in a regular expression in the regExp field for the editor to validate against. The editors turn yellow and gain the ! triangle when they do not validate. Note that if the required property is checked in Editor (Details), then the field will not validate until you have typed something into it.
48
COMMON WIDGETS
The full list of properties for the Label widget are as follows: Common Properties name: the name that WaveMaker Studio uses to reference the widget. This is the name that appears in Model Tree, in the Page Builder, in binding dialogs, and so on; this is also the name you use to reference the widget in code services. binding: use to dynamically set the value of the caption property, the link property or the disabled property. showing: when checked (true), the widget is visible to users; when unchecked (false), the widget is hidden. disabled: this property is not applicable to the Label widget. Display Properties caption: specifies the caption that is displayed to the user. Layout Properties autosize: if checked (true) this property sizes the widget so that it is just big enough for its contents and no bigger. If unchecked (false) the size of the widget is determined by the size property.
THE LABEL WIDGET size: specifies the size of the widget. Before you can set the size, you first need to specify the units of size, which you do by setting the sizeUnits property. If the autosize property is checked (true) then the size property cannot be set. sizeUnits: specifies the units in which the size property is measured. If the autosize property is checked (true) then the sizeUnits property cannot be set. Default value is px. Choices are: px: pixels em: text size; adapts automatically to current screen size pt: point (1/72 inch) flex: stretches widget to fill up proportional area of available space (see Setting Widget Size on page 19) box: the alignment of the child widgets (any widgets nested inside this widget). Values are Top-to-Bottom or Left-to-Right. See the Arranging Widgets within a Container (Box Property) on page 18 for more information on the box property.
49
Formatting Properties display: the format in which WaveMaker Studio displays the text. For a full list of types and type properties (see Display Types and their Formatting Properties on page 49). format: click to display the properties for configuring the selected display type (see Display Types and their Formatting Properties on page 49). link: links the caption to a URL or Service Call.
50
Use to display numbers. The digits format property determines the number of decimal places that are displayed in the label.
Date
Use to display dates. The datePattern format property determines the format of the date. For example:
MMM-dd-yyy
The formatLength format property determines the style of the displayed date: short - 12/15/2007 medium Dec 15, 2007 long December 15, 2007 full Saturday, December 15, 2007 The locale format property represents language code, used for i18n. Based on locale setting, different data may be displayed. Possible values are:nls, de, en, n-au, en-ca, en-gb, es, es-es, fr, it, it-it, js, ko, ko-kr, pt, pt-br, zh, zhcn
Time
Use to display times. The timePattern format property determines the format of the date. For example:
HH:mm
The formatLength format property determines the style of the displayed time: short - 4:00 PM medium 4:00:00 PM long 4:00:00 PM Pacific Standard Time full 4:00:00 PM Pacific Standard Time The locale format property represents language code, used for i18n. Based on locale setting, different data may be displayed. Possible values are:nls, de, en, n-au, en-ca, en-gb, es, es-es, fr, it, it-it, js, ko, ko-kr, pt, pt-br, zh, zhcn
51
Use to display date and time. The datePattern format property determines the format of the date. For example:
MMM-dd-yyy
The timePattern format property determines the format of the date. For example:
HH:mm
The formatLength format property determines the style of the displayed date-time: short - 12/15/2007 4:00 PM medium Dec 15, 2007 4:00:00:00 PM long December 15, 20074:00:00 PM Pacific Standard Time full Saturday, December 15, 2007 4:00:00 PM Pacific Standard Time The locale format property represents language code, used for i18n. Based on locale setting, different data may be displayed. Possible values are:nls, de, en, n-au, en-ca, en-gb, es, es-es, fr, it, it-it, js, ko, ko-kr, pt, pt-br, zh, zhcn
Money
Use to display money. The currency format property specifies the symbol to display before amount. The digits format property determines the number of decimal places that are displayed. The round format property can be used to specify that the amount be rounded rather than truncated. The locale format property represents language code, used for i18n. Based on locale setting, different data may be displayed. Possible values are:nls, de, en, n-au, en-ca, en-gb, es, es-es, fr, it, it-it, js, ko, ko-kr, pt, pt-br, zh, zhcn
Link
Use to display a URL link. To specify the URL, use the link property in the format property list, rather than the link property in the main Property Editor.
52
Use to format a Label caption using a regular expression. Typically, you define a regular expression and replace anything that matches that expression with something else. You define the regular expression in the expression format property and the replacement value in the replace format property. The expression format property specifies the regular expression to use for formatting. For example: (^\d{3}).*(\d{2}).*(\d{4}) The replace format property is used for in-line substitution:
$1-$2-$3
The caseSensitive format property is checked (true) when you want the expression to be case-sensitive. The global format property is checked (true) when you want to keep checking for the regular expression after the first match. It is unchecked (false) when you want to stop after the first match.
Evaluation
Use to format Label caption value. This is typically used for a Label when the caption is generated through a binding, rather than a constant value entered by the developer. The expression format property takes a dojo.formatter expression. For example, to format numbers using commas, you could use:
dojo.number.format($&)
To trim spaces from beginning and end of the Label caption, you could use:
dojo.trim($&)
53
Types of Layers
The WaveMaker Studio Layers widget provides three different styles. The layersType property allows you to specify which type of layers you want to use. You can easily switch Layers types. Tabs: The tabbed layers style gives each layer a tab. Users can navigate between layers by clicking the relevant tab. Use the title property to set the name on the tab. You can also create tabbed layers with the Tabs widget (The Tabs Widget on page 63). Accordion: The accordion layers style gives each layer an expandable accordion-style display, like the one in the Palette. Use the title property to set the label for the accordion box. You can also create accordion layers with the Accordion widget (The Accordion Widget on page 27). Layers (Default): With the default layers style, only one layer is visible at a time and there is no visual cue about the other layers that exist. Navigation between layers is triggered by events, such as a user clicking a button or link. Once youve created the initial Layers container, you can add new layers using the add operation in the Property Editor. To set up navigation between layers, use the Layer Service (Navigation Between Pages and Layers on page 23).
disabled:
when checked (true), no events occur in this Layers widget (Layers Widget Events on page 54).
Layout Properties autosize: if checked (true) this property sizes the widget so that it is just big enough for its contents and no bigger. If unchecked (false) the size of the widget is determined by the size property.
54
COMMON WIDGETS
the widget. Before you can set the size, you first need to specify the units of size, which you do by setting the sizeUnits property. If the autosize property is checked (true) then the size property cannot be set. sizeUnits: specifies the units in which the size property is measured. If the autosize property is checked (true) then the sizeUnits property cannot be set. Default value is px. Choices are: px: pixels em: text size; adapts automatically to current screen size pt: point (1/72 inch) flex: stretches widget to fill up proportional area of available space (see Setting Widget Size on page 19)
defaultLayer:
Other Properties
specifies which layer to show by default layersType: specifies the type of layers (Types of Layers on page 53)
Operation Properties The Layers widget provides the following operations for configuring the grid: add: automatically adds a new Layer to the layers widget
where newIndex is the index of the layer that will be shown and canChange is a boolean value indicating whether the change is allowed. You can write code to check the new index and set inChangeInfo.canChange = false to disallow the change of layers. For example, suppose you write a JavaScript function called tabLayers1
turbo.declare("Main", turbo.Part, { start: function() { this.tabLayers1Change(); }, canChangeTabs: true,
55
56
COMMON WIDGETS
Operations Each Layer has the following operations that you can use to move between layers in the Page Builder at design time. moveNext: in the Page Builder, use to show the next Layer movePrevious: in the Page Builder, use to show the previous Layer
disabled:
when checked (true), no events occur on this list (List Widget Events on page 57).
Layout Properties autosize: if checked (true) this property sizes the widget so that it is just big enough for its contents and no bigger. If unchecked (false) the size of the widget is determined by the size property.
THE PANE WIDGET size: specifies the size of the widget. Before you can set the size, you first need to specify the units of size, which you do by setting the sizeUnits property. If the autosize property is checked (true) then the size property cannot be set. sizeUnits: specifies the units in which the size property is measured. If the autosize property is checked (true) then the sizeUnits property cannot be set. Default value is px. Choices are: px: pixels em: text size; adapts automatically to current screen size pt: point (1/72 inch) flex: stretches widget to fill up proportional area of available space (see Setting Widget Size on page 19)
57
Other Properties
columnWidths:
widths of each column dataFields: comma-delimited list of in the dataSet for which a column should be displayed. Names are case sensitive. For example:
customerName, contactFirstName, contactLastName
If you leave the dataField property blank, all fields are included in the list. headerVisable: if checked (true) , then headers are displayed; if unchecked, headers are not displayed updateNow: updates the underlying service component and displays the current results in the Page Designer
58
COMMON WIDGETS
WaveMaker Studio automatically creates a pane widget for you when you drag a page from the Palette and drop it into the Page Builder. WaveMaker Studio also automatically generates a name for pane widget, although you are free to change the name. You can target these automatically-generated pane widget when you create a Navigation Component.
NOTE:
59
60
COMMON WIDGETS
flex: stretches widget to fill up proportional area of available space (see Setting Widget Size on page 19) box: the alignment of the child widgets (any widgets inside this widget). Values are Top-to-Bottom or Left-to-Right. See the Arranging Widgets within a Container (Box Property) on page 18 for more information on the box property.
Create an images directory for your project under the webapproot directory Add your image files to the images directory Add a Picture widget to the page. In the Property Editor, set the source property to a relative address from the webapproot directory, such as images/foo.jpg (not the httpstyle forward slashes).
You can also use the Picture widget to create an image link. Specify the image in the source property and the link URL in the link property.
binding:
use to dynamically set the value of the disabled property. showing: when checked (true), the widget is visible to users; when unchecked (false), the widget is hidden. disabled: when checked (true) the widget can take no inputs.
61
Layout Properties autosize: if checked (true) this property sizes the widget so that it is just big enough for its contents and no bigger. If unchecked (false) the size of the widget is determined by the size property. size: specifies the size of the widget. Before you can set the size, you first need to specify the units of size, which you do by setting the sizeUnits property. If the autosize property is checked (true) then the size property cannot be set. sizeUnits: specifies the units in which the size property is measured. If the autosize property is checked (true) then the sizeUnits property cannot be set. Default value is flex. Choices are: px: pixels em: text size; adapts automatically to current screen size pt: point (1/72 inch) flex: stretches widget to fill up proportional area of available space (see Setting Widget Size on page 19) aspect: aspect ratio; can be: h (preserve image horizontally) v (preserve image vertically) none (default) box: the alignment of the child widgets (any widgets inside the widget). Values are Top-to-Bottom or Left-to-Right. See the Arranging Widgets within a Container (Box Property) on page 18 for more information on the box property. Other Properties link: type in a URL to create an image link. When the user clicks on the image, the specified URL loads. Note that this is not where you specify an URL to the image source. Use the source property for that.
62
COMMON WIDGETS
63
the name that WaveMaker Studio uses to reference the widget. This is the name that appears in Model Tree, in the Page Builder, in binding dialogs, and so on; this is also the name you use to reference the widget in code services. binding: not used with the Splitter widget. showing: when checked (true), the widget is visible to users; when unchecked (false), the widget is hidden.
Layout Properties maximum: The maximum value for the Splitters movement. The value -1 (default) specifies unlimitted movement.
minimum:
The minimum value for the Splitters movement. The value -1 (default) specifies unlimitted movement.
64
COMMON WIDGETS
CHAPTER 5
Importing a Database
To use a database in an application, you first need to import it into the project. This import process gives WaveMaker Studio all the connection and authentication information it needs to connect to your database. When you import the database, WaveMaker creates: a Data Model. The Data Model describes all the database tables that you want to be able to access in WaveMaker. The Data Model can also include additional information such as custom queries. WaveMaker Studio stores your database table information and your custom queries as data objects. For more information on these data objects, see Database Objects (Tables and Queries) on page 70. a database Service. A Service is just a group of defined actions, such as a database insert or search action. The database service that WaveMaker creates for you provides the following basic actions, called operations,
66
for interacting with each table in the database: insert, update, delete, getbyID, getList, getCount. For more information on database service operations, see Database Service Operations on page 75. To import a database, follow these steps:
1. 2.
Open the project in which you want to use the database. In the Editor Tabs (across the top left of the WaveMaker Studio) click the Data Model to open the Data Model Editor.
3.
The Data Model Editor appears. The Data Model editor appears. The Data Model editor has an Objects tab and an Import tab. Click the Import tab to open the Import Database screen.
IMPORTING A DATABASE
67
4.
At the top of the screen, in the New Data Model Name field, type in a name for the Data Model. You can just give it the same name as the database or you can use a different name. The name can contain only alphanumeric characters. Below the New Data Model Name field, the screen shows a Username field and a Password field. This is where you type a valid username and password for this database connection. The bottom part of the Import Database screen is an Accordion with two headings: Settings and Advanced Options. Click on the heading to see the configuration fields for that heading. At a minimum, you need to fill out the fields under the Settings heading (Basic Settings on page 67). The Advanced Options might be useful for the advanced user (Advanced Options on page 69). Click the Test Connection button. You should get a Connection Successful message. If the test fails, go back and make sure your settings are correct. Click the Import Database button. WaveMaker Studio begins importing the database (this could take a few minutes). When the import is complete, the Data Model Editor shows you the database objects you have just created (Database Objects (Tables and Queries) on page 70). Save the project.
5.
6.
7.
8.
9.
Basic Settings
The Settings area of the Import Database screen allows you to choose what type of database you want to import and configure the basic required settings. The Settings area is collapsed if the Advanced Options area is expanded. Click on the Settings bar to see the Settings area again. For more on advanced configuration options, see Advanced Options on page 69.
NOTE:
When you choose your database type the Database drop-down menu, the configuration for that type of database appear. The configuration fields are different for the different database types: HSQLDB on page 68 MySQL on page 68 Oracle on page 68 DB2 on page 68 SQL Server on page 69
68
When you import an HSQLDB database, you will need to type the following settings into the Database Connection screen: Database System: The type of database you want to import. Choose HSQLDB.
File:
The location of the HSQLDB database on your file system. For example, if your database file is called cmdb and it is in C:\Program Files\WaveMaker, then you would type in:
C:\Program Files\WaveMaker\Support\Data\cmdb\cmdb
MySQL
When you import a MySQL database, you will need to type the following settings into the Database Connection screen: Database System: The type of database you want to import. Choose MySQL. Host: The network host for the MySQL database. Default value is localhost Port: The port number for the MySQL database. Database: The name of the database instance.
Oracle
When you import an Oracle database, you will need to type the following settings into the Database Connection screen: Database System: The type of database you want to import. Choose Oracle. Host: The network host for the Oracle database. Default value is localhost
The port number for the Oracle database. SID: The Oracle System Identifier that refers to the instance of the Oracle database running on the server. The default is ORCL, which is the default SID that is configured when installing your Oracle database.
Port:
DB2
When you import a DB2 database, you will need to type the following settings into the Database Connection screen: Database System: The type of database you want to import. Choose DB2. Host: The network host for the DB2database. Default value is localhost Port: The port number for the DB2 database.
IMPORTING A DATABASE
69
Database:
SQL Server
When you import a SQL Server database, you will need to type the following settings into the Database Connection screen: Database System: The type of database you want to import. Choose SQLServer. Host: The network host for the SQL Server database. Default value is localhost Port: The port number for the SQL Server database. Database: The name of the database. Instance: The name of the SQL Server instance.
Advanced Options
For advanced users, WaveMaker Studio provides some advanced configuration options. To see these options, click the Advanced Options accordion heading. The following options are available: Connection URL: When you import a database using the standard configuration options on the Import Database screen, WaveMaker Studio creates a JDBC URL for you. This URL is shown here in the Connection URL field. If you know what you are doing and want to change this JDBC URL, you can do it here. Java Package: WaveMaker Studio generates Java classes for you when you import a database. If you want a different Java package name than the default name we generate, type it in here. Table Filter: By default WaveMaker Studio imports all the tables in the database. If you want to import only a subset of the tables, type in a comma-delimited list of regular expressions here. Schema Filter: When you are importing a database that supports schemas, WaveMaker Studio imports only the tables for the default schema. If you want to import tables from other schemas, add the schema names in this field. Driver Class: JDBC driver class name. WaveMaker Studio creates a JAR file for each database that uses a sepcifed dirver. If you want to use a different JAR file for connecting, specify it here (the JAR file must be in the Application Servers class path). Dialect: Specifies the Hibernate dialect for connecting to the database.
70
Tables (Types)
When you import a database, WaveMaker Studio automatically creates data objects, called types, that allow your application to interact with that database. Types are the Java types that represent the tables in your database, including and columns, keys and relationships. To see the tables for a database, click the Data Model Editor tab and then click to expand the objects for that database in the Database Objects list. The tables are listed under the Types heading. In this list, keys are marked with asterisks (*) and relationships are marked as follows: one-to-one or one-to-zero < one-to-many
>
If you select a type in the list, more information about that type appears in the Data Model Viewer on the right.
71
The following table explains the information that is displayed about each column. You can change any of these values and save your changes to the Data Model. Note that this does not change the database that the data model represents. To change the database, you need to export the database.
Primary Key Foreign Key Type Not Null A check box. Checked if the column is a primary key. True or False value. True if the column is a foreign key, false if not. Data type of the column. A check box. Checked if the column can NOT hold a null value. If unchecked, the column value can be null. Maximum column length. Refers to the maximum number of digits used by the selected (numeric) data type. If the column is a primary key, specifies the method of key generation (Key Generation on page 72). If a generator is selected, specifies the parameters for that generator, if any.
Params
Below the columns information, the Data Model editor shows the relationships for the selected table. You can add and delete relationships here.
72
To add a relationship, first create the tables that will be related. Then add a column for the foreign key, select that column, and click on the '+' next to Relationships. Add a name for the relationship and in the Related Type drop down, pick which table you want to reference. Changes you make in the Data Model editor are not automatically made in the database that it represents. In order to change your database, you need to export your Data Model (Exporting a Data Model on page 81).
NOTE: Key Generation
For primary keys, you can use a generator to generate the key values. The Generator field provides the following key generation options:
Generator assigned Description lets the application to assign an identifier to the object before save() is called. This is the default strategy if no <generator> element is specified. supports identity columns in DB2, MySQL, MS SQL Server, Sybase and HypersonicSQL. The returned identifier is of type long, short or int. uses a sequence in DB2, PostgreSQL, Oracle, SAP DB, McKoi or a generator in Interbase. The returned identifier is of type long, short or int picks identity, sequence or hilo depending upon the capabilities of the underlying database
identity sequence
native
If your Generator type requires an input parameter, enter it in the Params column next to the Generator column.
Database Queries
When you import a database, WaveMaker Studio automatically generates a few basic database queries for you. You can use these generated queries as they are, modify them to suit your needs, or create new queries from scratch.
73
To see the database queries for a database, click the Data Model Editor tab and then click to expand the objects for that database in the Database Objects list. The queries are listed under the Queries heading.
If you click one of these queries, it appears in the Query Editor to the right of the Database Objects list.
74
This editor uses the Hibernate Query Language (HQL) which is similar to (but not the same as) SQL. To create a query, you need to fill in the following fields: Query Name: To save your query (so that you can create a service component to call it in your application) you need a query name. This should be a unique alphanumeric name with no spaces. Query: This is where you type in your HQL query. Click on an existing query for an example. There is a good HQL syntax reference here: http://www.hibernate.org/hib_docs/reference/en/html/queryhql.html
Return Single Result
You can optionally use the Returns Single Result checkbox to specify that the query can return only one object (rather than a list). If this box is checked, then only one object is returned from the server, even if multiple objects match the query.
Bind Parameters
You can create bind parameters for user input. To create a new bind parameter, type in a name and a select the type from the drop-down menu. Then click the plus (+) button. The new parameter will appear in the Bind Parameters list.
When you build your query, you can refer to the bind parameter using the parameter name preceded by a colon (:paramName). For example, if you have a bind parameter called myParam, you could create the following query:
from Customers _a where _a.id=:myParam
To delete a parameter, select it in the list and click the delete (X) button.
75
To test a query in the Query editor, type in a value for each bind parameter in the Query Input field. If you have multiple bind parameters, type in the inputs as a comma delimited list. Click the Live Layout button, if you havent already done so. Then click the the execute button (the orange arrow). The results appear below the Query Input field.
76
Click to expand or collapse each operation. When you expand an operation you can see its inputs and outputs. This will be useful when you call the operation. For information about each of these automatically generated applications, see Database Service Operations on page 76. For more on service calls in general, see Working with Services and Operations on page 83.
The getCount operation performs a search on your database and returns an integer representing the number of records that match the search
77
conditions. The getCount operation has two inputs: the searchInstance input and the options input: The searchInstance input allows you to bind to each column in the table. Typically, you bind a column in the table to an input (Editor widget). You can bind to as many columns as you want. The search returns the number of records that match all the search conditions. The options input is the same as for the getList operation (getList on page 78), although the paging options are not applicable to the getCount operation:
Option Description Default: true matchMode ignoreCase maxResults firstResults orderBy
excludeNone Exclude attributes with null values from search. Default: true
GetByID
When you import your database, WaveMaker Studio automatically creates a getByID operation for each table in the database. The getByID operation takes an input of the same type as the primary key for that table. It returns the database record with an ID that matches the input. In general, to set up getByID, you follow these basic steps:
1. 2. 3. 4. 5. 6.
Import the database. Open the Page Designer. In the Model Tree on the right side of the Page Designer, click on the Components tab. Click on the cylinder icon to create a new service call. The Configure Service Call dialog appears. Create a database service and configure it to use the getById operation for the table. Bind the input to the widget that allows the user to specify a particular record. Typically, you bind to the primary key field in the selected List widget item.
78
The getList operation performs a search on your database and returns a list of records that matches the search conditions. The getList operation has two inputs: the searchInstance input and the options input: The searchInstance input allows you to bind to each column in the table. Typically, you bind a column in the table to an input (Editor widget). You can bind to as many columns as you want. The search returns records that match all the search conditions. The options input lets you configure the search options and also provides some paging configuration. The input options are as follows:
Option Description Default: true matchMode
values: anywhere - Search for value any where in the search field of the database. exact - Search for the exact values in the search field of the database (if user leaves the search value blank then data is not shown.) start - Search for value starts with the search criteria value in the search field of the database. end - Search for value ends with the search criteria value in the search field of the database. The default is start. ignoreCase maxResults firstResults orderBy Case insensitive string matching. Default: true For paging. Maximum number of rows to return. For paging. Starting with result #. For paging. The column to order the results by. orderBy syntax: asc|desc:<propertyname> [, asc|desc:<propertyname>]* For example, given a city instance, order by city name and related country name: "asc: city, asc: country.country" excludeNone Exclude attributes with null values from search. Default: true
The getList operation returns a list of objects. To display this list in your application, use a widget that displays lists, such as the DataGrid widget or the List widget.
Insert
When you import your database, WaveMaker Studio automatically creates an insert operation for each table in the database. The insert operation inserts a new record into the corresponding table in the database. It takes as input an object of the same type as the table. Typically, you create a variable to store the object, rather than binding directly between input widgets and the service operation. This way you
79
can reuse the same variable for all your insert, update or delete operations on this table. In general, to set up an insert operation, you follow these basic steps:
1. 2. 3.
Import the database. In the Page Designer, create an Editor widget for each column in the table. This is where the user will input the data for the new record. Create a variable of the same type as the table. (You set the type of the variable using the type property. The drop-down list of types includes a type for each table in each database you have imported into this project.) Bind the data from the input Editors to the variable. Create a database service and configure it to use the insert operation for the table. Bind the inputs to the variable you created. Bind the insert service to the variable Configure a Button widget to execute the insert operation on click.
4. 5. 6. 7.
Update
When you import your database, WaveMaker Studio automatically creates an update operation for each table in the database. The update operation updates a specified record in the corresponding table in the database. It takes as input an object of the same type as the table. Typically, you create a variable to store the object, rather than binding directly between input widgets and the service operation. This way you can reuse the same variable for all your insert, update or delete operations on this table. In general, to set up an update operation, you follow these basic steps:
1. 2.
Import the database. In the Page Designer, create an Editor widget for each column in the table. Populate each Editor with the existing database value for the selected record. You can get the data by binding to either a service call or to data selected in a Grid. Create a variable of the same type as the table. (You set the type of the variable using the type property. The drop-down list of types includes a type for each table in each database you have imported into this project.) Bind the data from the Editors to the variable.
3.
4.
80
5. 6.
Create a database service and configure it to use the update operation for the table. Bind the inputs to the variable you created. Configure a Button widget to execute the update operation on click.
Delete
When you import your database, WaveMaker Studio automatically creates a delete operation for each table in the database. The delete operation deletes the specified record in the corresponding table in the database. It takes as input an object of the same type as the table. Typically, you create a variable to store the object, rather than binding directly between input widgets and the service operation. This way you can reuse the same variable for all your insert, update or delete operations on this table. In general, to set up a delete operation, you follow these basic steps:
1. 2.
Import the database. In the Page Designer, create an Editor widget for each column in the table. Populate each Editor with the database value for the selected record. You can get the data by binding to either a service call or to data selected in a Grid. Create a variable of the same type as the table. (You set the type of the variable using the type property. The drop-down list of types includes a type for each table in each database you have imported into this project.) Bind the data from the Editors to the variable. Create a database service and configure it to use the delete operation for the table. Bind the inputs to the variable you created. Configure a Button widget to execute the delete service on click.
3.
4. 5. 6.
81
You can access the service call events just as you would access widget events. Select the service call (in the Model Tree), then click the Events tab in the Property Editor.
For each event, you can select an existing service call or you can create a new service call. Select the New option to configure a new call from an existing service. Select the JavaScript option to create and call a new JavaScript function.
Create the data model. Select your root data model node in the tree.
82
3.
4. 5.
In the Username and Password fields, type in the user name and password for the database youre exporting to. In the Connection URL field, type in the JDBC URL. An easy way to find this, if you are not sure what it is, is to go to the import dialog. Fill in all the information as though you want to import the database. Click on advanced options, remove the "ifexists=true" bit of the URL, and copy the JDBC URL. The JDBC URL might look something like this:
jdbc:hsqldb:file:c:/test/hsql/p1;shutdown=true
6. 7.
CHAPTER 6
Calling Services
To call a service operation, you create a Service Call. You can create the component at the page level or the application level and you can string
84
Service Calls together as well. This section explains how to create Service Calls:
Stringing (Queueing) Service Calls on page 86 Service Call Properties and Events on page 87
Click the Design tab to open the Page Designer. In the Model Tree on the right side of the Page Designer, click on the Components tab. The Components tab shows you the components (variables, service Calls and Navigations) that you have created for the current page, and also any components that you have defined on the Project level.
3.
Select the location where you want to put the Service Call (either the current Page or the Project itself). When you define a component on the Project level, it is available on all the Pages in your project. Components defined on the Page level are accessible only on that page. In general, it is best to place your Service Call on the page where you need it (Scoping on page 22). By default, components are added to the current page. Click on the cylinder icon. The Configure Service Call dialog appears.
4.
CALLING SERVICES
85
5.
At the very top of the screen there is a text field that contains the name of the Service Call. All Service Calls are automatically named, but its a good idea to change the name to something descriptive so that you will be able to identify the call later. Type in a name for the call. From the Service pull-down menu, select the service you want to use. This list contains a service for each database, web service, and custom service you have imported. It also includes the Page and Layer services for page and layer navigation (Navigation Between Pages and Layers on page 23). Once you select a service, the operations for that service populate the Operation drop down. Select the operation you want to call. Next you can set up bindings for the operations inputs. If the operation you are calling does not have any required inputs then you do not need to do this. Otherwise, select a required input in the Bind Targets list. After you select the input, go to the Bind Sources list on the right of the dialog, and select the source for the input data. The list includes all the widgets, Variables and Service Calls that you can choose for the input. you make your selection, a link icon appears over in the Bind Targets section of the screen. This shows that the binding is complete.
6.
7. 8.
9.
10.When
11.Repeat
this process for each required input in the operation, and for any other inputs that you want to bind. the project.
86
The Service Call component is complete. It appears in the Bind Source list and you can bind to it.
. Service Calls have an event called onResult that allows you to specify a second Service Call to execute after the current Service Call completes. See Setting Up an onResult Event on page 87 for instructions. queue. Service Calls have a property called queue that allows you to specify a list of calls to execute after that Service Call executes. See Setting Up a Service Call Queue on page 86 for instructions.
onResult
The onResult option is simpler when you want to call Service Calls in a row. Queue is more powerful and clear if you're stringing together a number of requests.
Setting Up a Service Call Queue
A Service Call queue is a list of Service Calls that execute in order, one after the other. The queue is set up as a property on the first Service Call. To set up a Service Call queue, follow these steps:
1. 2. 3.
Create all the service Service Calls that you need. In the Model Tree, click the Component tab and select the Service Call that will execute first. In the Property Editor, click the button next to the queue property (under the Operations heading). The Queue Services dialog box appears. From the Select Service drop-down menu, select the next Service Call that you want to execute and then click the Add to Queue button. In the same way, add the other Service Calls that you want to place in the Queue. You can move Service Calls around in the list by clicking on the Move Selected Up and Move Selected Down buttons. Service Calls will execute in the order they appear in this list. Click OK.
4. 5.
6.
Note that the queue will not proceed if there is an error condition along the way.
87
The onResult event is a property of a Service Call that allows you to specify a second Service Call to execute when the first is finished. To set this up, follow these steps:
1. 2. 3. 4.
Create all the service Service Calls that you need. In the Model Tree, click the Component tab and select the Service Call that will execute first. In the Property Editor, click the Events tab. From the drop-down menu for the onResult event, select the second Service Call.
You can alternatively set up Navigation components, or custom JavaScript, instead of specifying a Service Call to execute.
updateNow queue
onError
Allows you to trigger an action when the service call returns an error.
88
onResult
Allows you to specify a Service Call that executes when the current Service Call returns any result. For example, you can have serviceCallB go after serviceCallA by setting the onResult event of serviceCallA to be serviceCallB.
onSuccess
onSuccess event: allows you to trigger an action when the service call
succeeds.
Web Services
You can access Web services in your WaveMaker Studio application by importing the service into the application and then creating Service Calls. REST, SOAP and RSS Web services are supported. This section contains the following topics: About Web Service Types on page 88 Importing and Calling a SOAP or REST Service on page 88 Importing and Calling RSS Feeds on page 90
WEB SERVICES
89
1.
If you do not yet have a local copy of the .wsdl file, download it to a temporary location on your local file system. Be sure when you save the file from a URL you save it to a filename with the .wsdl extension. Click on the Services tab in the Editor tab bar across the top of WaveMaker Studio.
2.
3. 4. 5.
The Services editor appears. On the left side of the Services editor, click the Add tab. From the Service Type drop-down menu, select Web Service. When you select the Web Service service type, the service configuration fields appear. Select the appropriate type (either SOAP or REST) from the Type drop-down menu.
6. 7. 8.
For the WSDL Path field, click the Browse button and browse to the location where you saved the .wsdl file. Click the Import button. WaveMaker Studio imports the .wsdl file. The Services editor shows the Configurations screen. The Configurations screen is where you put authentication information required to access the Web service via HTTP. Most services do not require authentication and you can leave these fields blank. If the server does require authentication, fill in the appropriate fields with a valid username and password. You can optionally specify a connection timeout in milliseconds. Click the Save icon.
The Web service is now available in your WaveMaker application. It is listed in the Services List on the left side of the Service Editor. Expand the service to see all the service operations along with their inputs and outputs. You can bind these inputs and output to widgets in the Page Designer.
90
WaveMaker Studio has placed a copy of the .wsdl file in a service subdirectory under the project directory for this project. Click the WSDL tab to see the .wsdl file for the service. You cannot edit the .wsdl file here and we recommend that you do not edit it at all. If you do need to edit the .wsdl file (to change the service URL for example) find it under the directory for your project and edit it there. Delete the service from your application and re-import it using the same service name.
Click on the Services tab in the Editor tab bar across the top of WaveMaker Studio.
2. 3.
The Services editor appears. On the left side of the Services editor, click the Add tab. From the Service Type drop-down menu, select Web Service.
WEB SERVICES
91
4.
When you select the Web Service service type, the service configuration fields appear. Select Feed from the Type drop-down menu. The WSDL Path field is disabled. Leave this field blank and click the Import button. The new Feed service appears in the Services list on the left side of the Service editor. You specify the Feed URL as an input to the service so you do not need to define it in advance.
5. 6.
The fact that the feed URL is a service input allows you to bind the URL input to a widget such as a text editor or grid row. This gives you a lot more flexibility than you would have if the URL were a static part of the service configuration.
Calling the Feed and Displaying the Results
Once you create a feed service, you can call it in your application by creating a Service Call. Use a DataGrid widget to display the results. For example:
1. 2.
First create a new RSS Feed Service, called FeedService. (Creating the Feed Service on page 90 explains how to create the service.) From the Components tab of the Model Tree, create a new Service Call (Creating a Service Call on page 84): The Service Call should call the getFeed operation in your FeedService. Under Bind Targets, select url under the getFeed input. Under Bind Sources, click the Expression tab and type in the following URL in the Data Expression field:
http://rss.news.yahoo.com/rss/topstories
92
Note that for the purposes of this example we are just using a static URL. You could just as easily bind the input URL to a widget on the page. Click the Close button to complete the Service Call configuration.
3.
Back in the Page Designer, leave the new Service Call selected in the Model Tree and click to check the autoUpdate property check box.
JAVASCRIPT SERVICES
93
4.
To display the results of the feed, we use a DataGrid. In the Page Designer, drag a DataGrid widget from the Palette and drop it on the Page. In the Property Editor, click the button for the binding property. Under Bind Targets select the dataSet object for your DataGrid. Under Bind Sources expand the Service Call you created for the Feed and select the entries object. Click the Close button to complete the Service Call configuration. From the Property Editor, either add columns individually (addColumn) or add all the columns automatically (autoColumns).
5.
6.
View the feed results in the Page Designer with LiveLayout (Live Layout on page 15) or by running the project.
JavaScript Services
You can use your own client-side JavaScript to further customize your WaveMaker application. This section explains how to call custom JavaScript in WaveMaker Studio applications. This section discusses how and where you can call your custom JavaScript in a WaveMaker application: Executing JavaScript on Widget Events on page 94 Executing JavaScript on Page Loading on page 94 Executing JavaScript on Service Call Results on page 94 For help writing custom JavaScript for WaveMaker applications, see Customizing WaveMaker Applications with JavaScript on page 117.
94
In the Page Designer, select your button, formSubmitButton. In the Property Editor, click on the Events tab. From the resulting drop-down menu, select the JavaScript option. The WaveMaker Studio automatically opens the Script section of the Source tab and displays the following function stub:
formSubmitButtonClick: function(inSender) { },
4.
Type in the JavaScript function that you want to execute on the button click.
Open the page you want to edit Designer. Click on the Source tab and implement the start function. The start function executes when the page loads. For example, you could type the following:
start: function() { console.log("Hello WaveMaker"); },
This example uses the Firebug add-on to write to the console log (Debugging with Firebug on page 123).
JAVA SERVICES
95
For example:
1.
Create a Service Call component called getCustomer. This Service Call uses the getCustomerById operation in a service called cmdb. (To get this service, you can import the cmdb HSQLDB database that is included in the WaveMaker Studio installation.) Create a variable component called myCustomer of type cmdb.data.Customers (this type appears in the list of data types after you import the cmdb database). Bind the variable to the output of the getCustomer Service Call. Select the getCustomer component in the Components tab in the Model Tree. In the Property Editor, select the Events tab. For the onResult event, select JavaScript from the drop-down menu. The Script source tab opens with a stub function that runs on a successful result from the getCustomer Service Call. Add your own JavaScript to implement this function. For example, the following code accesses the variable data and concatenates the contactfirstname and contactlastname name fields together into a variable called customerName:
2.
3. 4. 5.
6.
Java Services
There are two basic ways to add Java code to your WaveMaker project: Write your own custom Java code (Creating and Calling a Custom Java Code Service on page 95) Integrate pre-existing code that is already written and available in either .java or .jar files (Integrating Existing Java Code on page 101) The examples at the end of this section should help you get started (Custom Java Service Example on page 101).
96
1.
Click on the Services tab in the Editor tab bar across the top of WaveMaker Studio.
2. 3. 4.
The Services editor appears. On the left side of the Services editor, click the Add tab. From the Service Type drop-down menu, select Java. When you select the Java service type, the following Java service configuration fields appear: Service ID - a user friendly name to reference your Java Operations Class Name - the name of the Java class
5.
Click the Create button. WaveMaker Studio creates a Java file and a stub for you. When you click the Create button to create the Java service, the stub file automatically opens in the Code editor and you can see the service in the Services list to the left of the Code editor.
JAVA SERVICES
97
6.
Type in your Java code. The following simple example method takes a string parameter and returns a string comprised of Hello followed by the value of the parameter:
public class TestClass { public String myMethod(String myParameter) { return "Hello " + myParameter; }
Private classes are not supported as services in WaveMaker Studio. For example, if you have the following:
NOTE:
public class A{} class B{}
Class B is private, and you the Server will not be able to access it. To use class B, you would need to either make it a public static inner class:
public class A{ public static class B{} }
Be sure to save the code by clicking the Save icon at the top of the Code editor.
When you save your code, the new Java service appears in the Services list. Each method is listed, along with its inputs and outputs.
98
You can now call your Java service operations by creating Service Calls, just as you would call any other service operation. For example, assume you created the Java service shown in preceding steps: The name of the service is:
TestClass
myParameter
In this example, were going to create a panel that contains a text input field, a button and a label. When the user types something in the field and clicks the button, the application calls the myMethod operation with the users input as the input parameter. You would set this up as follows:
1. 2. 3.
In the Page Designer, drag a Panel onto the page. Next drag an Editor widget, a Button widget and a Label widget into the panel. Create the Service Call. From the Components tab of the Model Tree, create a new Service Call (Creating a Service Call on page 84): Type in a name for the Service Call. For the service, select your custom Java service (TestClass). For the operation, select the myMethod operation. Under Bind Targets, select arg1 under input. Under Bind Sources, select the dataValue object from your Editor widget.
JAVA SERVICES
99
In the Page Designer, select the Button widget. For the onClick event, select the Service Call component you created for your Java service operation.
5.
In the Page Designer, select the Label widget. In the Property Editor, click the button for the binding property. Under Bind Targets select the caption object for your Label. Under Bind Sources find your Java Service Call component and select the string that it returns.
JAVA SERVICES
101
The exact path name depends on your username and the location of your WaveMaker Projects directory. The above path would be right for a default WaveMaker installation on Windows.
NOTE:
After you place the files in your project directory, the classes are available to you at development time. You can import them in your custom Java code. When you deploy your application, these classes will be included in the WEB-INF\lib of the generated WAR file. To register the new class as a custom service, you need to follow the steps described in Creating and Calling a Custom Java Code Service on page 95 to create the Java service and stub file. Cut and paste your existing Java code into the Java stub file and save from the Code editor.
Create a new Java service (the steps for doing this are explained in Creating and Calling a Custom Java Code Service on page 95): For the Service Type field, select Java. In the ServiceID field, type:
myCustomJavaServiceID
Click Create. After you click the Create button, the Source editor opens, displaying the following (empty) class:
public class SaveOrUpdateEmployee { }
4.
5.
Click the Blue Disk Button above the Code Editor Pane to Save. (You should get a message stating Saving Java Service. If you dont, you hit the wrong button!) Click the Save Project Button Open the Page Designer. Drag a Panel widget onto the Page. Drag into the Panel: an Editor widget a Button widget
6. 7. 8. 9.
103
Service Call. From the Components tab of the Model Tree, create a new Service Call (Creating a Service Call on page 84): In the Configure Service Call field, type:
myCustomHibernateCall
From the Service menu, select your custom Java service (TestClass). From the Operation menu, select the myMethod operation. Under Bind Targets, select arg1 under input. Under Bind Sources, select the dataValue object from your Editor widget. Click the Close button to complete the Service Call configuration.
11.In
the Page Designer, select the Button widget. For the onClick event, select the Service Call component you created for your Java service operation (myCustomHibernateCall).
Run it! Now you can saveOrUpdate, based on the presence or nonexistence of a record!
CHAPTER 7
Set up your data source. Run WaveMaker Studio and open your project. Click the Security tab. The Security Editor appears.
4.
In the Data Source pull-down menu, select the type of data source you want to use. You can choose Database, LDAP or Demo. When you make your selection, the configuration editor for that data source appears at the bottom of the Security Editor (default is Demo). Make the appropriate selections for your data source in the configuration editor. This will depend on what type of data source you are using: Using a Database for Login Data on page 107 Using LDAP for Login Data on page 108 Using the Demo Data Source for Login Data on page 107 Click to check the Authentication On check box. As you develop your application, you can use this check box to toggle the authentication on and off. That way, when you preview your application, you dont have to log in every time. Click the Save Configuration button. When you save a security configuration, WaveMaker Studio adds the security service and a default login page to your project. Save the project. The default login page (The Default Login Page on page 108) is now listed under Pages in the Dashboard. (You might need to refresh in order to see this page.)
5.
6.
7.
8.
107
9.
Preview the application. The default Login page appears. Try logging in.
Type the name in the Username field. Type the Password in the Password field. Click the Add button (plus sign). Select the user in the list. Click the Delete button (X).
The Demo data source automatically includes one default user name (demo) and password (demo).
Data Model
The Data Model that contains the columns for the for username, password. Choose the Data Model from the pulldown menu. (You have to import the database first. If you have imported the database and it does not appear in this list, try saving the project and refreshing the page). Select the table that contains the columns for the user names and passwords. Select the column for the user (login) name. Select the column for the password.
Be sure to save the configuration (click the Save Configuration button) before testing the authentication.
Be sure to save the configuration (click the Save Configuration button) before testing the authentication.
109
You can customize the login page, but do not rename it. If you do, WaveMaker Studio will not recognize it as the login page.
Use this operation to get the username of the current user. The operation takes no inputs and returns a string containing the userid of the user that is logged in on the current session.
logout: Use this operation to log a user out. This operation takes no inputs.
When you call it, it logs out the current user and terminates the session.
CHAPTER 8
Open the project in WaveMaker Studio and click the Dashboard tab to open the Dashboard. In the Dashboard under the Administration heading, click the Export Project button. The exported file will be in your project directory under export/<project name>.zip.
The export zip file will include the project directory and everything underneath it that cannot be recreated by another installation of the studio.
The project will now appear in the list of projects (a refresh may be required).
Open the project in WaveMaker Studio and click the Dashboard tab to open the Dashboard. In the Dashboard under the Administration heading, click the Generate WAR File button. WaveMaker Studio creates a WAR file for you (this might take a few minutes) and places it in your projects dist directory for your project. WaveMaker displays an alert when the WAR file has been successfully generated.
Project File Structure on page 113 Service Directory Structure on page 113 Webapproot Directory Structure on page 114 Page Container Directory Structure on page 115
113
Database configuration: stored in the services/directory as standard POJO classes and Hibernate configuration files Server configuration: stored in the webapproot/web-inf/ directory as Spring configuration files
The servicedef.xml file provides information used at design-time on the services operations (and their parameters and returns), and the types associated with a service. The src directory contains any necessary source for the service. The service directory structure includes:
For Java services: the source directory contains files created using a tool like Eclipse. Java source can also be imported in a jar in the top-level lib directory. For Database services: source directory contain WaveMaker-generated source to define the java data objects, the Hibernate queries (foo.ql.xml)and the Hibernate mapping (foo.hbm.xml). For Web services: the source directory contains a Java representation of the WSDL and the JAXWS schema file (foo.xjb).
Webservice services' source directories contain generated source (again, non-user editable), and generally the WSDL file they were generated from. Generally, each service has a single service class (which contains methods that are exposed to the client), and one class per datatype associated with that service. A typical data service will look like this:
<projectName>/ services/ sakilalight/ src/ sakilalight.properties sakilalight.spring.xml com/ wavemaker/ data/ Sakilalight.java sakilalight/ City.ql.xml Actor.ql.xml Country.java FilmActor.hbm.xml City.java Actor.java Address.hbm.xml FilmActor.ql.xml Film.hbm.xml Address.ql.xml designtime/ servicedef.xml
The .properties and .xml files contain standard Hibernate metadata. The Sakilalight.java contains the main service class, and all other .java files contain types.
115
The index.html and <projectname>.js files provide an entry point to the system, and bootstrap the AJAX interface. The WEB-INF directory contains the web.xml file, as well as XML files that specify the Spring configuration. Also, all compiled service classes (from services/<svcsname>/src), and classes from the top-level src directory, are copied into WEB-INF/classes. Libraries from the top-level lib directory are copied into WEB-INF/lib. The services directory contains a series of SMD files (one per service) with the service definition information. These are basically a translation of the information from the servicedef.xml, which is located in services/<servicename>/runtime.
The panes directory provides information specific to each page container. The css file provides CSS for that page; the HTML contains snippets for use in the page container; the .widgets.js provides a definition of the page layout and components; and lastly, the .js file contains any custom JavaScript associated with the page container.
APPENDIX A
For example, to set the value of the showing property on a panel widget called panel1, you would use:
this.panel1.setValue("showing", true);
This sets the value of the showing property to true making the panel and its contents visible. To hide the panel, you could set the value of the showing property to false:
this.panel1.setValue("showing", false);
To set the value of the caption property on a label widget called label1, you could use:
this.label1.setValue("caption", "Hi");
To get the existing value of a property on a specific widget, use the generic getValue syntax. You can use getValue for any widget property that appears in the Property Editor. For example, to get the value of the size property on a panel widget called panel1, you would use:
this.panel1.getValue("size");
This returns the value of the size property on panel1. To get the value of the disabled property on a Button widget called button1, you could use:
this.button1.getValue("caption");
You can use getValue and setValue together, to toggle between two values of a boolean type widget property. For example, suppose you have an
119
AutoForm widget called autoform1. AutoForm widgets have a readonly property which can be either true or false. To toggle the value of the readonly property, you could use the following syntax:
this.autoform1.setValue(readonly, !this.autoForm1.getValue(readonly));
To set a label to the current date, set the display property of the label to Date and insert the following line in an entry point such as the start function for the page:
this.label3.setValue(caption, new Date().getTime());
Normally this would be done in the onResult event for a Service Call which is triggered upon successful completion of the Service Call. If youre using a turbo.AutoForm, you can use the _clearEditors method to clear each editor. If your editors themselves get values from a grid selectedItem, then they can be cleared by clearing the grid selection using:
dataGrid.clearSelection()
If your editors themselves get values from a variable, then you can clear the variable using:
this.variable.setData()
For example:
this.panel1.loadComponent("myLabel", "turbo.Label", {caption: "I made this!"});
After you create the new widget, you need to re-render the parent widget so that the new widget is included:
this.mylabel.reflowParent();
Now suppose you create a Service Call component at the application level (rather than at the page level) and you named it appLevelServiceCall1. You can execute this Service Call on any page by calling:
app.appLevelServiceCall1.update();
You cant pass any parameters to the update function. The function relies on the existing input and output bindings of the Service Call. Service Calls have an event called onBeforeUpdate that allows you to put data into the Service Call right before the service is updated. This allows you to programmatically put data into the service's input data. The syntax for onBeforeUpdate is:
onBeforeUpdate(inSender, inInputData)
You can also put data into a serviceCall input manually before you call update().
For example, if you have a turbo.Variable that stores an object corresponding to a row in a customers table, you could call setValue to set the customer name as follows:
this.customerVariable.setValue(customerName, bob);
121
The input data for a turbo.ServiceCall is also a turbo.Variable. You can set its values manually in the same way (Executing Service Calls in Your JavaScript Code on page 120).
At runtime, a global object called app always owns the loaded page. When you run a project, the root runtime object is turbo.Application; turbo.Application loads the main page.
CSS Utilities
Dojo provides some CSS related utilities. The following are especially useful in WaveMaker applications:
dojo.addClass(domNode, classname)
where classname is a string representing the new CSS class name. For example:
dojo.addClass(this.domNode, customPanel) dojo.removeClass(domNode, classname)
123
where classname is a string representing the CSS class name that you want to remove. For example:
dojo.removeClass(this.domNode, customPanel) dojo.hasClass (domNode, classname)
where classname is a string representing the CSS class name that you are checking for. If the specified node has the specified classname, then dojo.hasClass returns true. If not, it returns false.
For example:
connect(this.domNode, onmouseover, this, mouseout)
This connect utility is actually a wrapper for the dojo.connect utility. The connect utility does the cleanup disconnect for you, so that you do not have to call dojo.disconnect.
Running WaveMaker Studio in Debug Mode on page 123 Firebug Status Bar on page 124 Printing to the Firebug Console on page 124 Firebug Command Line on page 124
The debug mode does not use this Dojo build. In debug mode, the WaveMaker Studio files are uncompressed so that they are more readable editable. The debug version is very useful for debugging your application with Firebug.
For example, to null the data value of an editor1 on the main page from the Firebug console use:
studio.part.editor1.setValue("dataValue", null);
NOTE: Note that within the Firebug console, you cannot use this to refer to the current page. Instead, you need to use studio.part.
You can get a lot of information at design time, through LiveLayout and through the Firebug console. However, note that page code is not run at design. To inspect a component at runtime, use the pagename.component syntax for components scoped at the page level:
main.label1
125
APPENDIX B
Create a module file that defines the widget (The Widget Module File on page 128). Add design-time support for the widget (Adding Studio Support for the Widget on page 132). Add runtime support for the widget (Adding Runtime Support for the Widget on page 133).
When you export the project or generate a WAR from the project, the new custom widget will be included. WaveMaker Studio provides an example custom widget in the Custom section of the Palette.
The example above contains the three function calls that you use in your widget module file:
1. dojo.provide("moduleName");
The dojo.provide statement declares the module this file will provide. The moduleName is the path of the widget module file (without the common folder) relative to the studio/static directory (Widget Module File Location on page 132). The moduleName uses dots (.) rather than slashes (/) in the path. For example, if our module file is named CustomWidgets, our module name would be wm.packages.example.CustomWidgets and our dojo.provide statement would look like this:
dojo.provide("wm.packages.example.CustomWidgets");
2. dojo.require("moduleName");
The dojo.require statement states what modules need to be imported for this module. If you are extending an existing widget, then you need to import the module that defines the widget you are extending. For example, if we want to extend the WaveMaker Label widget, we would need the module for the Label widget:
dojo.require("turbo09.widget.Label");
All the predefined WaveMaker widget module files are located in the WaveMaker installation directory in the following directory:
studio\static\turbo09\widget 3. dojo.declare("widgetClassName", baseClassWidget, {/*widget body*/});
where: widgetClassName is the class name of the widget you are creating. baseClassWidget is the name of the widget that you are extending, if any.
129
contains the body of your widget declaration. This includes any properties (Widget Properties on page 130) and events (Widget Events on page 130) that you want to expose to users in the WaveMaker Studio. For example, the following widgets class name is turbo.WMLink and it has predefined values for the caption and link properties.
{/*widget body*/}
dojo.declare("wm.example.WMLink", turbo.Label, { caption: "WaveMaker", link: "http://dev.wavemaker.com" }
Before you can use the new widget, you need to: Put your widget module file in the WaveMaker custom widget directory (Widget Module File Location on page 132) Add it to the WaveMaker Studio (Adding Studio Support for the Widget on page 132) Add it to the Runtime (Adding Runtime Support for the Widget on page 133)
Defining Widgets
WaveMaker widgets are closely related to Dojo's Dijit widgets. More information about the Dojo toolkit and the Dijit project is available at http://dojotoolkit.org. Here are a couple of tips on widget creation: The easiest way to create a new widget is to use an existing widget as your base widget. All the functionality, events and properties that the base widget provides are already there and you can customize them to meet your needs. You specify the base widget in the dojo.declare statement. You will also need to import the widgets module in the dojo.require statement. If you want to create a widget that can contain other widgets, use the Panel widget as your base widget. The init function is the primary access hook to the underlying HTML of a widget. Here well implement the init function to create a div node, called myPetNode and append it to the DOM as a child node.
init: function() { this.inherited(arguments); this.myPetNode = document.createElement('div'); this.domNode.appendChild(this.myPetNode);
The life cycle for WaveMaker widgets is something like this: Creation:
1. 2.
construct: all constructors are invoked starting with base classes and working up to the sub class. create: create method is invoked which calls: prepare(inProps): copies the properties inProps that came from the constructor, i.e. when you do new Foo({ ... }), the { ... } are inProps b. build: setup any needed DOM, responsible for setting domNode property (note: does not call setDomNode) c. init: do whatever else you want to do to initialize your widget (the init function in Widget calls setDomNode, which triggers the initDijit as noted above). d. postInit: hook to do other stuff (rarely needed)
a.
Destruction:
1.
destroy: call destroy to kill a widget. Various classes override destroy to do custom cleanup turbo.Dijit calls this.dijit.destroy(), then calls inherited (turbo.Widget) destroy b. turbo.Widget destroys all child widgets, and does various other cleanup tasks.
a.
Typically one overrides init to do setup, and destroy to do cleanup. The rest are not usually needed. For Dijits, you may also want to override initDijit and do setup on the Dijit after calling the superclass function.
Widget Properties
Any properties that you define in dojo.declare are automatically shown as properties for that widget in the Property Editor. You can also provide default values for new and existing properties.
dojo.declare("wm.example.WMLink", turbo.Label, { caption: "WaveMaker", link: "http://dev.wavemaker.com"
For each new property you define, you can create get and set functions (for example for the caption property, you could create getCaption and setCaption functions). Define these in the widget declaration section of the dojo.declare function.
Widget Events
To add an event to a widget, you need to do two things: Declare the event in dojo.declare (Expose the Event in the Property Editor on page 131) Make the event fire (Make the Event Fire on page 131)
THE WIDGET MODULE FILE Expose the Event in the Property Editor
131
In your widget definition (in dojo.declare), any function that has a name starting with on is automatically treated as an event. For example, functions named onclick, onmouseover, onguard, ontop, would all be treated as events. Typically you just declare the function and leave it as an empty stub:
onWMclick: function() { },
Now the widget has an event called onWMclick. In the Property Editor, the event is listed in the Events tab. Here, application developers can set up whatever behavior they want this event to trigger, using a Service Call, Navigation Component, custom JavaScript, etc. When a user creates custom JavaScript for your event, the function for that event has one extra argument (not present in the widget definition) the inSender argument. For example, in the dojo.declare in your custom widget module, you define the following event on your custom widget:
onWMmouseout: function(inEvent) { },
Working in the WaveMaker Studio with the code for the very same event, the function looks like this:
function(inSender, inEvent) { },
The inSender references the widget that fired the event. In a WaveMaker Studio application, events are called in the context of the page. The keyword this refers to the page and this.customerEditor would refer to a widget of that name on the page, while inSender.caption would refer to the caption property of the widget that fired the event. This setup provides convenient access to all widgets and components defined on the page while still providing anonymous access to the widget that fired the event. Its your job to make sure that this event actually fires (Make the Event Fire on page 131).
Make the Event Fire
As the widget author, you are responsible for ensuring that the event fires. How you do this is ultimately up to you. A typical method would be to hook into standard browser DOM-level events. To do this, you can chain events together using the connect function within the init function.
init: function() { this.inherited(arguments);
In this example, when an onclick event occurs in an instance of the widget type were defining, the onWMclick event in the current object is called. Heres an example of how this might look in a complete dojo.declare statement:
dojo.declare("turbo.LinkLabel", turbo.Label, { init: function() { this.inherited(arguments); this.connect(this.domNode, "onclick", this, "onWMclick") }, onWMclick: function() { } });
In the example above, the this.inherited line calls the init function for the base widget, turbo.Label.
NOTE:
The connect function is a wrapper for the dojo.connect function. It includes some automatic disconnect functionality when the widget is destroyed.
where:
is the heading under which you want the widget to be grouped in the Palette. name is the name shown for the widget in WaveMaker Studio.
palette section
ADDING RUNTIME SUPPORT FOR THE WIDGET widgetClassName is the widgetClassName that you defined dojo.declare statement in the widget module file. moduleName
133
in the
is the name of the .js widget module file. This name should be the same as the moduleName in the dojo.provide in your widget file. image is the image shown in the Palette for the widget. description is the description shown under the widget name in the Palette.
For example:
// custom widgets ["Custom", "WaveMaker Link", "wm.example.WMLink", "wm.packages.example.CustomWidgets", "images/turbo/label.png", "A link to dev.wavemaker.com"]
NOTE:
Remember that you need a trailing comma unless your widget is the last one in the file and your widget must also be separated from the preceding entry with a comma.
The module name must match the moduleName you specified in the packages.js file (Adding Studio Support for the Widget on page 132).
Dojo Core:
browser normalization, language enhancements, and so on Dijit: Dojo widgets DojoX: big collection of stuff, with varying levels of maintenance and support
While our widgets do rely on Dojo, our base widget (turbo.Widget) is not a Dijit. WaveMaker use a separate widget system. We do have a turbo.Dijit wrapper class that wraps Dijits for use in WaveMaker Studio. For more information on the Dojo toolkit, refer to the Dojo web site: http://dojotoolkit.org/