You are on page 1of 148

WaveMaker Application Developers Guide

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

Overview. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Installing WaveMaker Studio . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Building Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5


Getting Started With Page Design . . . . . . . . . . . . . . . . . . The WaveMaker Tutorial . . . . . . . . . . . . . . . . . . . . The WaveMaker Studio Page Designer . . . . . . . . . . Design Toolbar . . . . . . . . . . . . . . . . . . . . . . Palette . . . . . . . . . . . . . . . . . . . . . . . . . . . . Page Builder . . . . . . . . . . . . . . . . . . . . . . . . Model Tree . . . . . . . . . . . . . . . . . . . . . . . . . Property Editor . . . . . . . . . . . . . . . . . . . . . . Keyboard Shortcuts . . . . . . . . . . . . . . . . . . . Designing Pages In WaveMaker . . . . . . . . . . . . . . . The layoutBox . . . . . . . . . . . . . . . . . . . . . . . . . . . Tying Widgets to Data and Services . . . . . . . . . . . . Live Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Working with Widgets . . . . . . . . . . . . . . . . . . . . . . . . . . Selecting Widgets . . . . . . . . . . . . . . . . . . . . . . . . . Arranging Widgets within a Container (Box Property) Setting Widget Size . . . . . . . . . . . . . . . . . . . . . . . Flex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Styling Widgets . . . . . . . . . . . . . . . . . . . . . . . . . . Binding Widgets to Data . . . . . . . . . . . . . . . . . . . . Bind to displayValue or dataValue? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.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

Working with Databases . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65


What Databases are Supported? . . . . . . . . . . . . . . . . . . . . Importing a Database . . . . . . . . . . . . . . . . . . . . . . . . . . . Basic Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . HSQLDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Oracle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . DB2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SQL Server . . . . . . . . . . . . . . . . . . . . . . . . . . Advanced Options. . . . . . . . . . . . . . . . . . . . . . . . . . Database Objects (Tables and Queries) . . . . . . . . . . . . . . . Tables (Types) . . . . . . . . . . . . . . . . . . . . . . . . . . . . Key Generation . . . . . . . . . . . . . . . . . . . . . . . Database Queries . . . . . . . . . . . . . . . . . . . . . . . . . . Return Single Result . . . . . . . . . . . . . . . . . . . Bind Parameters . . . . . . . . . . . . . . . . . . . . . . Testing Queries . . . . . . . . . . . . . . . . . . . . . . . Database Service Operations . . . . . . . . . . . . . . . . . . . . . . Viewing the Database Service and Service Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

Working with Services and Operations . . . . . . . . . . . . . . . . . . 83


About Services and Operations . . . . . . . . . . . . . . . . . . Calling Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating a Service Call . . . . . . . . . . . . . . . . . . . Stringing (Queueing) Service Calls . . . . . . . . . . . Setting Up a Service Call Queue . . . . . . . . Setting Up an onResult Event . . . . . . . . . . Service Call Properties and Events . . . . . . . . . . . Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . About Web Service Types . . . . . . . . . . . . . . . . . Importing and Calling a SOAP or REST Service. . . Importing and Calling RSS Feeds . . . . . . . . . . . . Creating the Feed Service . . . . . . . . . . . . Calling the Feed and Displaying the Results JavaScript Services . . . . . . . . . . . . . . . . . . . . . . . . . . Executing JavaScript on Widget Events . . . . . . . . Executing JavaScript on Page Loading. . . . . . . . . Executing JavaScript on Service Call Results . . . . Java Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating and Calling a Custom Java Code Service. Integrating Existing Java Code . . . . . . . . . . . . . . Custom Java Service Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

Setting up a User Login Page . . . . . . . . . . . . . . . . . . . . . . . .

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

Projects and Project Files . . . . . . . . . . . . . . . . . . . . . . . . . .


Importing and Exporting Projects . . . . . . Exporting WaveMaker Projects . . . . Importing WaveMaker Projects. . . . Generating a WAR File . . . . . . . . . . . . . . Enable Project Loggers . . . . . . . . . . . . . . WaveMaker Project Directory Structure . . Project File Types . . . . . . . . . . . . . Project File Structure . . . . . . . . . . Service Directory Structure . . . . . . Webapproot Directory Structure . . . Page Container Directory Structure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

Customizing WaveMaker Applications with JavaScript . . . . . . .


Working with Widgets . . . . . . . . . . . . . . . . . . . . Accessing a Widget in JavaScript . . . . . . . . Setting Widget Properties . . . . . . . . . . . . . Referencing the Calling Widget in an Event . Clearing Data Input Fields in JavaScript . . . Creating Widgets at Runtime . . . . . . . . . . . Executing Service Calls in Your JavaScript Code . . Setting Data Properties . . . . . . . . . . . . . . . . . . . Referencing Components at Runtime . . . . . . . . . . Object Structure on the Client . . . . . . . . . . . . . . . Commonly Used Utilities . . . . . . . . . . . . . . . . . . . CSS Utilities. . . . . . . . . . . . . . . . . . . . . . . The Connect Utility. . . . . . . . . . . . . . . . . Debugging with Firebug . . . . . . . . . . . . . . . . . . . Running WaveMaker Studio in Debug Mode . Firebug Status Bar . . . . . . . . . . . . . . . . . . Printing to the Firebug Console . . . . . . . . . Firebug Command Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

117

Creating Custom Widgets . . . . . . . . . . . . . . . . . . . . . . . . . .

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

Installing WaveMaker Studio


You can run WaveMaker Studio on Windows, Mac or Linux operating systems. The WaveMaker Studio installer installs WaveMaker Studio, Java (Sun JDK 1.5.0_12), and Tomcat (Apache Tomcat 5.5.23). Tomcat and JDK are required by WaveMaker Studio. The installer does not overwrite existing Java or Tomcat installations but it does create new installations. WaveMaker Studio also includes Hypersonic SQL DB (HSQLDB) as an embedded database. To install and run WaveMaker, follow these instructions:  Windows: On Windows the Tomcat application server is installed for you as a Windows serivce (called WaveMaker Server) that starts automatically. However, if you stop this service (using the Service Control Manager or the net stop WaveMakerServer command), then you must restart it manually (or reboot).  Linux: On Linux you need to start Mavericks manually using the wavemaker.sh script. This script starts Tomcat and then launches Firefox. To stop Mavericks, run the shutdown.sh script.  Mac: WaveMaker Studio runs on Mac OS X Leopard only. Download and open the WaveMaker.dmg file. Drag the WaveMaker icon into your Applications directory. To run WaveMaker, doubleclick the WaveMaker icon. The WaveMaker Studio Control Panel appears. Click the Start WaveMaker button to start the WaveMaker services. Wait a few seconds and then click the Launch Browser button. To stop WaveMaker, click the Stop WaveMaker button.

INSTALLING WAVEMAKER STUDIO

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

Getting Started With Page Design


This section provides you with an introduction to the WaveMaker Studio Page Designer and an overview of the basics of WaveMaker Pages. It contains the following sections:
   

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

The WaveMaker Tutorial


The best place to learn the basics about building pages is the WaveMaker Studio Tutorial. You can access the tutorial from the Project Dashboard as soon as you open a project in WaveMaker Studio. The tutorial walks you through the steps of creating a simple application.

BUILDING PAGES

The WaveMaker Studio Page Designer


The WaveMaker Studio Page Designer is where you build your application pages. To see the Page Designer, click the Design tab at the top left of the WaveMaker Studio screen. Here you select and configure the widgets that define your page, as well as the services and data that these widgets are tied to.

This section explains the following components of the Page Designer:

GETTING STARTED WITH PAGE DESIGN

     

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.

Delete. Delete the selected widget or component.

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.

GETTING STARTED WITH PAGE DESIGN

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.


Controls: This group contains controls

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:

GETTING STARTED WITH PAGE DESIGN

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.

GETTING STARTED WITH PAGE DESIGN

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

Shortcut <Ctrl> V <Ctrl> C <Ctrl> S <Ctrl> F <Ctrl> B <Esc> <Shift>

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.

Designing Pages In WaveMaker


This section gives a brief overview of how to design a page in the Page Designer. To design a page in WaveMaker, you arrange widgets (from the Palette) in the Page Builder. Widgets are the building blocks of your pages. The Palette provides many different types of widgets, such as text editors, grids, containers, pictures and so on. Once you drop a widget into the Page Builder, you can drag it around as you like.

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.

GETTING STARTED WITH PAGE DESIGN

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.

Tying Widgets to Data and Services


As you build your page, you are going to want to tie specific widgets to data and services in your application. For example, you might want to tie a DataGrid widget to a table in a database. In WaveMaker Studio, to set up this connection between a widget and a source of data, you use the widgets binding property (Binding Widgets to Data on page 21). Note that before you can set up a binding, you must first import the database (Importing a Database on page 65) or service (About Services and Operations on page 83) that you are using.

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:

WORKING WITH WIDGETS

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.

Working with Widgets


This section covers some basic information for working with widgets:  Selecting Widgets on page 17  Setting Widget Size on page 19  Styling Widgets on page 20


Binding Widgets to Data on page 21

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.

Arranging Widgets within a Container (Box Property)


Most widgets that can act as containers (the Panel widget, for example) have a property called the box property. The box property determines how the contents of the panel are laid out. For example, if the box property is set to Left-to-Right, then the contents of the panel are arranged horizontally, expanding vertically to the full height of the panel. In the following illustration, the outer Panel has the box property set to Left-toRight.

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:

WORKING WITH WIDGETS

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.

Setting Widget Size


For widgets in Top-to-Bottom or Left-to-Right containers, only one dimension is editable (the other dimension is controlled by the container).You have two basic ways to size a widget:  Click and drag to resize a widget with the mouse. If you resize a widget this way, the sizeUnits are automatically changed to pixels (px).  Use the size and SizeUnits properties to set the widget size.
Size defines

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).

ABOUT PAGES AND LAYERS

21

Binding Widgets to Data


You can bind widgets to data or service calls, using the binding property. When you click the binding property button, the Binding dialog appears:  Under Bind Targets select the item you want to bind.  Under Bind Sources, select the object to which you want to bind it. This could be an item in a list, the results of a service call, an expression, and so on.
Bind to displayValue or dataValue?

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.

About Pages and Layers


When we talk about designing a page in WaveMaker Studio, were talking about arranging and configuring a group of widgets that we want to present to the user as a unit and that is addressable. Addressable means

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.

ABOUT PAGES AND LAYERS

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.

Navigation Between Pages and Layers


The most common way to set up navigation between pages and layers is to create a Navigation Component. A Navigation component is an application component that loads a particular layer or page. In the case of pages, the Navigation component also stores information about where to display the page. Once you create the Navigation component, you call it just like a service call or any other application component. You create a Navigation component in the Components section of the Model Tree, by clicking the New Navigation icon.

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:

ABOUT PAGES AND LAYERS

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

The Accordion Widget


The Accordion widget is a Layers widget (The Layers Widget on page 52) for adding accordion layers. If you decide you dont want to use accordion layers, you can easily switch to another style of layer by changing the layersType property.

28

COMMON WIDGETS

The AutoForm Widget


The AutoForm widget is a widget for displaying, inputting or updating a record. The AutoForm widget has an associated DataSet object that represents its data source. It also has a DataOutput object, which you can use to get the data out of the AutoForm. When you define the DataSet (Getting the DataSet on page 28), the AutoForm widget automatically generates Editor widgets for every item in the DataSet (except lists and substructures). The binding on these Editor widgets is already done for you, so this can save you a huge amount of time. The Editor widgets that AutoForm generates for you are ordinary Editor widgets. You can configure them as you would any other widget and you are free to delete them. The AutoForm widget is a type of Panel widget. This means that AutoForm can act as a container for other widgets. Just drop them in the AutoForm widget. If you drop an AutoForm widget into another AutoForm widget, you can use the child widget as a SubForm (Creating SubForms on page 29). To use the AutoForm widget to insert or update records, you bind its dataOutput to an appropriate service call (Using the DataOutput on page 28). For a complete list of AutoForm widget properties, see AutoForm Properties on page 29.

Getting the DataSet


Like the DataGrid and List widgets, the AutoForm widget has an associated DataSet that defines the source of the data. You can bind this DataSet in the usual way, through the binding property, but AutoForm also provides a shortcut with its special dataSetName property. The dataSetName property is a simple drop-down menu that contains all the objects that are available as the DataSet for this AutoForm. To define the DataSet, simply select an item from the dataSetName property menu. The dataSetName menu includes: service calls, variables, selected item in DataGrids and Lists.

Using the DataOutput


In addition to a DataSet object, each AutoForm widget has an associated DataOutput object. The DataOutput object contains all the values (dataValue, rather than displayValue) of all the Editor widgets in the AutoForm that are bound to the DataSet.

THE AUTOFORM WIDGET

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.

Using AutoForm as a Detail Widget


Previous versions of WaveMaker Studio provided a Detail widget that displayed information about a data object. AutoForm provides all the functionality of the Detail widget and more. To use the AutoForm widget as a Detail widget, check the readonly property in the Display section of the Property Editor. This changes all the Editors from inputs to outputs.

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

COMMON WIDGETS editorSize:

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

THE BEVEL WIDGET

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.

The Bevel Widget


The Bevel widget is a simple divider bar that provides visual separation of elements on a Page. Similar to a Splitter (The Splitter Widget on page 62), but does not allow resizing of adjacent areas.

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.

The Button Widget


The button widget creates a button. You can configure the button using its properties and you can change the appearance using styles (Styling Widgets on page 20).  Button Properties on page 32  Button Events on page 32

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.

THE CONTENT WIDGET

33

The Content Widget


Content widgets allow you to easily use your own static markup. The WaveMaker Tutorial includes an example of how to use a Content widget.

How to Use the Content Widget


To add markup to a content widget, follow these steps:
1. 2. 3. 4. 5. 6. 7. 8. 9.

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

Content Widget Properties


The Panel 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 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.

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.

The DataGrid Widget


The DataGrid widget is a highly-configurable widget for displaying lists. DataGrid columns are sortable and sizeable by users. Each column in the DataGrid has its own properties that you can use to configure that column:  Steps for Creating a DataGrid on page 34  DataGrid Properties on page 35  DataGrid Events on page 40  Properties for DataGrid Columns on page 36

Steps for Creating a DataGrid


To use the DataGrid, follow these steps:
1. 2. 3. 4.

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.

THE DATAGRID WIDGET

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:

removes all columns from the grid

36

COMMON WIDGETS updateNow: updates the grid with live data from the service call while

in design modeno need to test run to see the data

Properties for DataGrid Columns


Each column in the DataGrid has its own properties that you can use to configure that column:


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

Display Types and their Editor Properties


Each DataGrid column has a display property. Set the display property to define the type of data youre displaying in the column. Once you set the display property, click the format property to further configure the column. The configuration options depend on the display type. In the list of format properties, click back to get back to the main properties. Possible values for the display property are described in the following sections:

THE DATAGRID WIDGET

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

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

THE DATAGRID WIDGET Money

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

Use to format a column value.

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

The Editor Widget


The Editor widget is a sophisticated widget for creating a wide variety of inputs. Use the display property to specify the type of input. Choices are: Date, Time, Number, Currency, Select (Select on page 45), Check Box, Text Area, Radio Button (Radio Button Groups on page 46) and Slider.

Properties of the Editor Widget


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:

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.

THE EDITOR WIDGET disabled:

41

when checked (true) the widget can take no inputs.

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.

Display Types and their Editor Properties


Each Editor widget has a display property. Set the display property to define the type of data youre displaying in the Editor. Once you set the display property, click the editor property to further configure the Editor. The configuration options depend on the display type. In the list of editor properties, click back to get back to the main properties. Possible values for the display property are described in the following sections:  Text on page 42  Date on page 43  Time on page 43  Number on page 44  Currency on page 44  Select on page 45  CheckBox on page 45  TextArea on page 46  Radio Button Groups on page 46
Text

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.

THE EDITOR WIDGET Date

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

 

THE EDITOR WIDGET password:

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

COMMON WIDGETS 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) the default value of this checkbox is true (the exact value would depend on the dataType you selected for the checkbox).

Radio Button Groups

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.

THE LABEL WIDGET Slider

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.

See Changes as You Type


To see changes as you type in an input field, check the source input's changeOnKeypress property.

The Label Widget


The Label widget provides non-editable text. Type the text you want to display into the caption property. If you want the text to be a link, type the URL into the link property.

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.

Display Types and their Formatting Properties


Each Label widget has a display property. Set the display property to define the type of data youre displaying in the Label. Once you set the display property, click the format property to further configure the Label. The configuration options depend on the display type. In the list of format properties, click back to get back to the main properties.  Number on page 50  Date on page 50  Time on page 50  Date Time on page 51  Money on page 51
  

Link on page 51 RegularExpression on page 52 Evaluation on page 52

50

COMMON WIDGETS Number

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

THE LABEL WIDGET Date Time

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

COMMON WIDGETS RegularExpression

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($&)

The Layers Widget


The Layers widget is a container for individual layers. Layers are containers similar to pages but with a different scope and more flexible and efficient navigation possibilities (About Pages and Layers on page 21). Each Layers widget is configurable with properties, as is each layer it contains:  Types of Layers on page 53  Layers Widget Properties on page 53  Layers Widget Events on page 54  Properties of Each Layer on page 55

THE LAYERS WIDGET

53

Events for Each Layer on page 56

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).

Layers Widget Properties


The following properties are available on the Layers widget: 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 disabled property.  showing: when checked (true), the widget is visible to users; when unchecked (false), the widget is hidden.


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:

size: specifies the size of

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

Layers Widget Events


The Layers widget provides the following two events:  onchange: fires after the Layers widget changes the active layer  oncanchange: fires when the layers object is about to change the activelayer. Use it to disallow the change of layer. This section explains a little more about the oncanchange event, and provides an example using both events. The oncanchange event has an argument called inChangeInfo which is an object of the following format:
{newIndex: inIndex, canChange: true}

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,

THE LAYERS WIDGET


button1Click: function(inSender) { this.canChangeTabs = !this.canChangeTabs; this.label1.setCaption(this.canChangeTabs ? "yes" : "no"); }, tabLayers1Change: function(inSender, inIndex) { this.label6.setCaption("Showing: " + this.tabLayers1.getLayer().name); }, tabLayers1Canchange: function(inSender, inChangeInfo) { // inChangeInfo contains: // - canChange, which should be set to false if the change should not occur // - newIndex, the index of the layer that will be shown (this can be used to selectively allow layer changes) inChangeInfo.canChange = this.canChangeTabs; }, _end: 0 });

55

Properties of Each Layer


Within the Layers widget, each individual Layer also has its own 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: not used for the Layer widget 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 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)  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  caption: the label on the tab (for Tabbed Layers) or accordion menu (for Accordion Layers).

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

Events for Each Layer


Each Layer in the Layers widget has an onShow event that fires when that Layer becomes the active Layer in the Layers widget.

The List Widget


A List widget is a very simple way to display a list of objects. In most cases, it is better to use a DataGrid widget (The DataGrid Widget on page 34) than a List widget because a List widget is far less configurable. For example, column heads are always the name of the item they are listing and cannot be renamed. You cannot sort on a column.

List Widget Properties


To configure a List widget, the following properties are available: 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 widget. 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). From this dialog you can also 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), 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

List Widget Events


The following event properties are available for the DataGrid widget:  onClick: fires when a user clicks in the List  onDblClick: fires when a user double-clicks in the List  onSelect: fires when a row in the List is selected  ondeselect: fires when the List widget loses focus

The Pane Widget


A Pane widget is a subpage container. It defines an area on a page where you display a subpage (Displaying Subpages on page 25). To use the pane widget, drag it into the page builder and then create a Navigation Component that displays a page in the pane (Navigation Between Pages and Layers on page 23).

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:

Pane Widget Properties


The Pane 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: not used for the Pane widget.  showing: when checked (true), the widget is visible to users; when unchecked (false), the widget is hidden. 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) Other Properties  pageName: select a default page to load in this Pane widget

Pane Widget Events


The Pane widget has one event, called onPageChanged. This event fires whenever a new page is loaded in this Pane widget.

THE PANEL WIDGET

59

The Panel Widget


In WaveMaker Studio, you typically lay your pages out in Panels. The Panel widget acts as a container for other widgets. This widget is not itself visible to the user (unless you specifically give it a background color or border using the styles property). The contents of each Panel are arranged horizontally or vertically, depending on the value of the box property (Arranging Widgets within a Container (Box Property) on page 18). Some of the widgets inside the Panel might have a specific size, while other are set up to fill the remaining space. When you use this method, your pages display more reliably on different browsers and different screens.

Panel Widget Properties


The Panel 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: the binding property is not used with the Panel widget.  showing: when checked (true), the widget is visible to users; when unchecked (false), the widget is hidden. 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 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)

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.

The Picture Widget


Use the Picture widget to add an image. In order for this to work, you need to put your image files in the webbapproot directory for your project.

How to Add the Image


To add an image to your WaveMaker Studio application, follow these steps:
1. 2. 3. 4.

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.

Picture Widget Properties


The Panel 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.  source: location of the image; can be either a local path relative to the webapproot directory (uses forward slash /) or a URL
 

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.

THE SPACER WIDGET

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.

Picture Widget Events


The Picture widget provides a single event, the onclick event. This event fires when a user clicks on the image.

The Spacer Widget


The Spacer widget is useful when you want to add space between elements in a container. By using the flex (Flex on page 19) value for the sizeUnits property, you can make the Spacer widgets particularly powerful. For example, to center a widget on a page, just put a Spacer widget on either side and give both Spacer widgets a flex of one.

62

COMMON WIDGETS

Spacer Widget Properties


You can specify the following properties for a Spacer widget:  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: this property is not used with the Spacer widget.  showing: when checked (true), the widget is visible to users; when unchecked (false), the widget is hidden.  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)  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.

The Splitter Widget


The Splitter widget is a moveable divider bar that provides visual separation of elements on a Page. Similar to a Bevel, except that users can move the Splitter to allow resizing of adjacent areas.

Splitter Widget Properties


The Splitter widget has the following properties: Common Properties

THE TABS WIDGET name:

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.

The Tabs Widget


The Tabs widget is a Layers widget (The Layers Widget on page 52) for adding tabbed layers. If you decide you dont want to use tabbed layers, you can easily switch to another style of layer by changing the layersType property.

64

COMMON WIDGETS

CHAPTER 5

Working with Databases


This chapter contains the following information:  What Databases are Supported? on page 65  Importing a Database on page 65  Database Objects (Tables and Queries) on page 70  Database Service Operations on page 75  Exporting a Data Model on page 81

What Databases are Supported?


Currently WaveMaker Studio supports MySQL, Oracle, and SQL Server. The installation also includes Hypersonic SQL DB (HSQLDB), as an embedded database. This database is included for demo and testing purposes. For more information on HSQLDB, see: http://hsqldb.org/web/hsqlDocsFrame.html

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

WORKING WITH DATABASES

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

WORKING WITH DATABASES HSQLDB

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:

The name of the 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

WORKING WITH DATABASES

Database Objects (Tables and Queries)


All the database objects available to your application are listed in the Database Objects list on the left side of the Data Model editor. Each database that you import into your application appears in the list. Click the database to expand it and see the Tables (Types) on page 70 and Database Queries on page 72 for that database.

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.

DATABASE OBJECTS (TABLES AND QUERIES)

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.

Length Precision Generator

Params

Below the columns information, the Data Model editor shows the relationships for the selected table. You can add and delete relationships here.

72

WORKING WITH DATABASES

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.

DATABASE OBJECTS (TABLES AND QUERIES)

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

WORKING WITH DATABASES

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.

DATABASE SERVICE OPERATIONS Testing Queries

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.

Database Service Operations


When you import a database, WaveMaker Studio automatically generates a service for that database. This service includes all the basic operations you need to work with the database. This section discusses the database service and operations:  Viewing the Database Service and Service Operations on page 75  Database Service Operations on page 76  Error or Success? Handling Results from Database Service Operations on page 80

Viewing the Database Service and Service Operations


After you import the database, you can click the Services tab to see the service.

76

WORKING WITH DATABASES

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.

Database Service Operations


This section discusses the automatically-generated operations:  getCount on page 76  GetByID on page 77  getList on page 78  Insert on page 78  Update on page 79  Delete on page 80
getCount

The getCount operation performs a search on your database and returns an integer representing the number of records that match the search

DATABASE SERVICE OPERATIONS

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

excludeZeros Exclude attributes with zero values from search.

Determines how to match string values. can be one of the following


values: "anywhere", "start", "end", "exact". Default: start Case insensitive string matching. Default: true Not applicable.For paging. Not applicable. Not applicable. For paging. Not applicable. For paging.

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

WORKING WITH DATABASES getList

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

excludeZeros Exclude attributes with zero values from search.

Determines how to match string values. can be one of the following

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

DATABASE SERVICE OPERATIONS

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

WORKING WITH DATABASES

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.

Error or Success? Handling Results from Database Service Operations


To take action based on the results of the database service call, you can use the onError and onResult events:  onError event: allows you to trigger an action when the service call does not change a record in database  onSuccess event: allows you to trigger an action when the service call does change a record in database

EXPORTING A DATA MODEL

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.

Exporting a Data Model


You can export your Data Model to a database. In the current release, we recommend that you do this only with simple Data Model that you are creating from scratch. If you import an existing database, do not try to make changes in the Data Model and then export those changes back to the database. To export a data model:
1. 2.

Create the data model. Select your root data model node in the tree.

82

WORKING WITH DATABASES

3.

The Connection Settings form appears to the right.

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.

Click the Save button. Click the Export button.

CHAPTER 6

Working with Services and Operations


This chapter contains the following information:WaveMaker Studio  About Services and Operations on page 83  Calling Services on page 83
  

Web Services on page 88 JavaScript Services on page 93 Java Services on page 95

About Services and Operations


WaveMaker Studio applications treat everything as a service. Database interactions, web service interactions, custom Java code, all these are treated as services. Each service is a group of one or more operations. Operations are defined actions that your application can invoke in order to make something happen. For example, a database service provides a variety of operations that allow you to interact with the database (such as update, delete, or insert). Many operations involve a request to the server to take some action, such as updating a database, authenticating a user, and so on. Some operations can be executed entirely on the client, such as changing the active layer in a set of tabbed layers. In a WaveMaker Studio application, a service can be a Database Service, a Web Service, a custom Java Service or a custom JavaScript service. WaveMaker Studio provides some predefined services. For example, the Security Service provides an operation to log out the current user (The Security Service on page 109).

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

WORKING WITH SERVICES AND OPERATIONS

Service Calls together as well. This section explains how to create Service Calls:
  

Creating a Service Call on page 84

Stringing (Queueing) Service Calls on page 86 Service Call Properties and Events on page 87

Creating a Service Call


To call an operation in a WaveMaker application, you create a component called a Service Call. At a minimum, a Service Call specifies the service and operation you want to invoke, and a source for any required inputs to that operation. Service Calls also have associated properties and events that you can use to further configure the call (Service Call Properties and Events on page 87). To set up a Service Call, follow these steps:
1. 2.

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.

12.Click Close. 13.Save

86

WORKING WITH SERVICES AND OPERATIONS

The Service Call component is complete. It appears in the Bind Source list and you can bind to it.

Stringing (Queueing) Service Calls


There are two ways to string together Service Calls:


. 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.

CALLING SERVICES Setting Up an onResult Event

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.

Service Call Properties and Events


Service Calls have the following properties:
Property name Description Specifies 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. Launches a dialog for setting up bindings for Service Call inputs. The component runs automatically. Also enables LiveLayout to populate the data directly in the WaveMaker Studio. Clears all current input values. The name of the operation you are invoking. The operation property is a dropdown menu from which you can choose any operation in the specified service. The name of the service that contains the operation you are invoking. The service property is a drop-down menu from which you can choose any service that you have added to your project. Use to update the service call (with new input data) while in design mode Defines a list of Service Calls to execute, in order, after this Service Call executes.

configure autoUpdate clearInput operation service

updateNow queue

Service Calls have the following events:


Event onBeforeUpdate Description Called right before a service is updated. Allows you to programmatically put data into the service's input data:
onBeforeUpdate(inSender, inInputData)

onError

Allows you to trigger an action when the service call returns an error.

88

WORKING WITH SERVICES AND OPERATIONS

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

About Web Service Types


You can import the following types of Web services in your WaveMaker Studio application:  SOAP services. SOAP (Simple Object Access Protocol) is a standard XML protocol for exposing and calling Web services. A SOAP service is described by a Web Services Definition Language (WSDL) document, often available through a URL from the service itself.  REST Services. A REST (Representational State Transfer) Web Service is comprised of resources accessed through unique URLs (requests) and returned as XML responses. An XML Schema typically defines the structure of those XML responses. In order to add a REST service to a WaveMaker Studio application, you need a WSDL document describing the service. Typically you create this WSDL file yourself.  RSS Feeds. RSS (Really Simple Syndication) defines services that provide periodically-updated lists of items. Many Web sites now provide a syndication feed that news readers and blog summaries can subscribe to.

Importing and Calling a SOAP or REST Service


In order to import a SOAP or REST service into your WaveMaker Studio application, you need the WSDL (.wsdl) file that describes the service. For SOAP services, WSDL files are provided by the service creator. For REST services, you probably need to create your own WDL file. Once you have located a WSDL file, import a SOAP or REST service, by following these steps:

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

WORKING WITH SERVICES AND OPERATIONS

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.

Importing and Calling RSS Feeds


RSS (Really Simple Syndication) Feeds are services that provide periodically-updated lists of items. Many Web sites now provide a syndication feed that news readers and blog summaries can subscribe to. This section explains both how to create the feed service and how to call it:  Creating the Feed Service on page 90  Calling the Feed and Displaying the Results on page 91
Creating the Feed Service

To add a Feed Service to your application, follow these steps:


1.

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

WORKING WITH SERVICES AND OPERATIONS

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

WORKING WITH SERVICES AND OPERATIONS

Executing JavaScript on Widget Events


To call JavaScript for a widget event, you select the widget, click the Events tab and choose the JavaScript option in the drop-down menu for the event. This automatically declares the appropriate function and opens the Source tab at the appropriate place. For example, suppose you have a button named, formSubmitButton and you want to create custom JavaScript to execute when the user clicks this button. To set up the JavaScript you follow these steps:
1. 2. 3.

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.

Executing JavaScript on Page Loading


To set up JavaScript that executes upon the loading of the page, follow these steps:
1. 2. 3.

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).

Executing JavaScript on Service Call Results


In your JavaScript code, you can access the results of a Service Call by writing JavaScript code in the source for the onResult event of the Service Call. The onResult event is called upon the successful completion of the Service Call. In order to make this work, you first need to create a variable bound to the Service Call output. Then you can access that variable in your code.

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.

customerName = this.myCustomer.getValue("data").contactfirstname + " " + this.myCustomer.getValue("data").contactlastname;

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).

Creating and Calling a Custom Java Code Service


To create a custom Java service in WaveMaker Studio, follow these general steps:

96

WORKING WITH SERVICES AND OPERATIONS

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{} }

or define it in its own file.


7.

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

WORKING WITH SERVICES AND OPERATIONS

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


It contains a single method called:


myMethod myMethod

has one input parameter (a string) called:

myParameter


The method returns the following string:


"Hello " + 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

Click the Close button to complete the Service Call configuration.


4.

In the Page Designer, select the Button widget. For the onClick event, select the Service Call component you created for your Java service operation.

100 WORKING WITH SERVICES AND OPERATIONS

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.

Click the Close button to complete the Service Call configuration.


6.

Save and run your project.

JAVA SERVICES

101

Integrating Existing Java Code


To integrate existing Java code into your WaveMaker application, you first need to put the .jar file or the .java files in the lib directory for your WaveMaker project. For example, if your project is called MyFirstApp, the path for the lib directory would look something like this:
C:\Documents and Settings\username\My Documents\WaveMaker\Projects\MyFirstApp\lib

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.

Custom Java Service Example


This section provides a Java code service example. You can find this and other examples posted on the WaveMaker developer forum at: dev.wavemaker.com This example shows how to create a custom Java code service that accesses elements in the Data model using Hibernate methods. In this example, we create a Service Call that checks whether a record exists and does one of the following things:  if the record exists, the operation updates the database  if the record does not exist, the operation inserts the new record in the database Hibernate contains many methods to assist with common database chores such as this. For this example, there is a Hibernate method called saveOrUpdate(). You can access this method using a custom code Service Call. For this example, assume your database has a table in it called Employees. To set up the custom service, follow these steps:
1. 2.

Create a Project called:


myTestApp

Import a database called:

102 WORKING WITH SERVICES AND OPERATIONS myDB 3.

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

In the Class Name field, type:


MyAddOrUpdateEmployeeClass

Click Create. After you click the Create button, the Source editor opens, displaying the following (empty) class:
public class SaveOrUpdateEmployee { }

4.

Edit the class so that it looks like this:


import com.activegrid.runtime.AGRuntime; // WaveMaker Runtime Class import com.wavemaker.mydb.MyDB; // the MyDB Class, ie $PROJECT_HOME\Projects\myTestApp\services\myDB\src\com\wavemaker\mydb\MyDB.java import com.wavemaker.mydb.data.Employee; // The Employee Class import org.hibernate.Session; // Session Class public class MyAddOrUpdateEmployeeClass { private MyDB foo = (MyDB)AGRuntime.getInstance().getService("myDB"); // Instantiate a MyDB called foo based on the myDB name we created public String saveOrUpdateEmployee(Employee employee) { foo.begin(); // Begin the transaction try { Session session = foo.getDataServiceManager().getSession(); // Get the Hibernate session session.saveOrUpdate(employee); // Save or Update foo.commit(); // Then commit } catch (RuntimeException ex) { foo.rollback(); throw ex; } return "success"; } }

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.

JAVA SERVICES 10.Create the

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!

104 WORKING WITH SERVICES AND OPERATIONS

CHAPTER 7

Setting up a User Login Page


Your WaveMaker Studio application can include a login page that requires users to sign on in order to gain access to the application. In order to set up user authentication you need set up a data source that stores your user IDs and passwords. You have the following options for storing this data:  You can use any database supported by WaveMaker Studio.  You can use LDAP (Lightweight Directory Access Protocol). WaveMaker Studio also provides a simple demo data source. You can use this data source to set up and test your login page during development.  How to Set Up a Log In Page on page 105  Using the Demo Data Source for Login Data on page 107  Using a Database for Login Data on page 107  Using LDAP for Login Data on page 108  The Default Login Page on page 108  The Security Service on page 109

How to Set Up a Log In Page


To set up a login page for your application, follow these steps:
1. 2. 3.

Set up your data source. Run WaveMaker Studio and open your project. Click the Security tab. The Security Editor appears.

106 SETTING UP A USER LOGIN PAGE

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.

USING THE DEMO DATA SOURCE FOR LOGIN DATA

107

9.

Preview the application. The default Login page appears. Try logging in.

Using the Demo Data Source for Login Data


The Demo data source provides a great design-time tool for authentication. With this data source you can quickly define a few usernames and passwords to use while creating and testing the login functionality for your application. Before you deploy your application, you should set up a more robust data source for authentication. To set up To set up authentication against a the Demo data source, click the Security tab and choose Demo for the Data Source type. The Demo Data Source configuration editor appears. To add a new user to the Demo data source:
1. 2. 3.

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).

To delete an existing user from the Demo data source,


1. 2.

The Demo data source automatically includes one default user name (demo) and password (demo).

Using a Database for Login Data


If youre using a database to store your authentication data, then you first need to import the database you plan to use. The database must include a table that provides a column for your user names and one for the passwords. The user names and passwords must be stored in the same table in the database. To set up authentication against a database, click the Security tab and choose Database for the Data Source type. You need to provide the following configuration information:

108 SETTING UP A USER LOGIN PAGE

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.

Entity User Name Field Password Field

Be sure to save the configuration (click the Save Configuration button) before testing the authentication.

Using LDAP for Login Data


To set up authentication against a database, click the Security tab and choose LDAP for the Data Source type. You need to provide the following configuration information:
Property LDAP URL Description This field specifies the host name and port number of the LDAP server. ldap://localhost:389/dc=wavemaker,dc=com Manager DN Manager Password User DN Pattern The DN for the account that you use to access LDAP. The password for the account that you use to access LDAP. Sets the pattern that WaveMaker Studio uses to create a DN for the user. The pattern should be the name relative to the root DN. The pattern argument {0} will contain the username. For example: "cn={0},ou=people"

Be sure to save the configuration (click the Save Configuration button) before testing the authentication.

The Default Login Page


WaveMaker Studio provides a simple login page for you. Whenever you save an authentication configuration, WaveMaker Studio checks to see if you have a login page in your project. If you dont, WaveMaker Studio will add the default login page to the project.

THE SECURITY SERVICE

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.

The Security Service


When you create a security configuration for your project, WaveMaker Studio adds a Security Service to your project. The Security Service contains two operations:
getUserName:

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.

110 SETTING UP A USER LOGIN PAGE

CHAPTER 8

Projects and Project Files


This chapter contains the following sections:  WaveMaker Project Directory Structure on page 112  Importing and Exporting Projects on page 111  Enable Project Loggers on page 112  WaveMaker Project Directory Structure on page 112

Importing and Exporting Projects


The current support for exporting projects is mainly intended to facilitate mailing projects to our support staff:  Exporting WaveMaker Projects on page 111  Importing WaveMaker Projects on page 111

Exporting WaveMaker Projects


WaveMaker Studio can export projects in zip format to facilitate sharing of projects through email. To export a WaveMaker project, follow these steps:
1. 2. 3.

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.

Importing WaveMaker Projects


To import a WaveMaker project, simply unzip the file into the directory where your projects are located. If there is already a project with that name it should be deleted beforehand.

112 PROJECTS AND PROJECT FILES

The project will now appear in the list of projects (a refresh may be required).

Generating a WAR File


WaveMaker Studio can generate a WAR file for your project, which you can deploy on any application server. To create a WAR file, follow these steps:
1. 2. 3.

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.

Enable Project Loggers


The log4j.properties has many useful loggers you can enable. The file is located under the project directory in the webapproot/WEB-INF/classes directory. Reload the application for the changes to take effect. For example, to see the SQL and Bind Parameters sent to the database, enable the following Hibernate loggers:
log4j.logger.org.hibernate.SQL
log4j.logger.org.hibernate.type

WaveMaker Project Directory Structure


WaveMaker Studio generates a project directory and a set of files for each application built using WaveMaker. All of the project files created by the WaveMaker Studio are human-readable files. Many of the files can be edited outside of the Studio using tools like Eclipse. These project files are used to generate a Java WAR file that can be deployed into any Java server. This section covers the following topics:  Project File Types on page 113
   

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

WAVEMAKER PROJECT DIRECTORY STRUCTURE

113

Project File Types


WaveMaker Studio project files include:  HTML files: stored in the webapproot/ directory as index.html  Custom code: stored in the services/ directory or as JAR files in the lib/ directory  Web services: stored in the services/directory as POJO classes and JAX-WS configuration files


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

Project File Structure


The top level of a WaveMaker Studio project contains four directories. These are:  services directory: contains service definitions, classes, and everything else needed for a service (including database, security, web services and custom services); services directory does not appear in projects that do not have any services  webapproot directory: contains the root of the standard web application  src directory: contains project-wide source (including the log4j configuration)  lib directory: contains project-wide libraries (empty by default)

Service Directory Structure


WaveMaker treats almost everything as a service, including security, data access, custom code and SOAP, REST and WSDL services. The files generated for each service follows the same general pattern:
<project_name>/ services/ <service_name>/ src/ designtime/ servicedef.xml

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:

114 PROJECTS AND PROJECT FILES

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.

Webapproot Directory Structure


The webapproot directory follows the typical structure for web applications. For example, this is where the index.html page is located, as well as the project level JavaScript file. The panes directory contains individual page container definitions.
webapproot/ WEB-INF/ <projectname>.js index.html services/ <serviceName>.smd

WAVEMAKER PROJECT DIRECTORY STRUCTURE


panes/

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.

Page Container Directory Structure


Each page container has its own directory that stores configuration information about that page as well as the widgets and styling for that page:
panes/ <paneName>/ <paneName>.css <paneName>.html <paneName>.js <paneName>.widgets.js

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.

116 PROJECTS AND PROJECT FILES

APPENDIX A

Customizing WaveMaker Applications with JavaScript


You can use your own client-side JavaScript to customize your WaveMaker application. Any JavaScript that your target browsers support can be used in a WaveMaker application. This chapter explains how to incorporate your JavaScript into your WaveMaker application and provides some information about how your JavaScript can interact with your project components. It assumes you are already familiar with JavaScript.  Working with Widgets on page 117  Executing Service Calls in Your JavaScript Code on page 120  Setting Data Properties on page 120  Referencing Components at Runtime on page 121  Object Structure on the Client on page 121  Commonly Used Utilities on page 122  Debugging with Firebug on page 123 For information on how to call JavaScript from your application, see JavaScript Services on page 93.

Working with Widgets


This section has the following topics:  Accessing a Widget in JavaScript on page 118  Setting Widget Properties on page 118  Referencing the Calling Widget in an Event on page 119  Clearing Data Input Fields in JavaScript on page 119


Creating Widgets at Runtime on page 119

118 CUSTOMIZING WAVEMAKER APPLICATIONS WITH JAVASCRIPT

Accessing a Widget in JavaScript


In your page code, you can use the syntax this.foo to specify a widget or component on the page. this refers always to the current page and foo would be the name of the component or widget. You use the value of a widgets name property to specify the widget. So, suppose you want to refer to a panel widget that has a name property set to panel1. If the panel widget is on the current page, you can refer to it like this:
this.panel1

Setting Widget Properties


For widgets, anything that shows in the Property Editor is a property that you can set on the widget in your code. To access these properties, use getValue and setValue. These two methods are available to all components.
getValue("propertyName") setValue("propertyName", value)

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

WORKING WITH WIDGETS

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());

Referencing the Calling Widget in an Event


Use inSender to refer to the calling object in an event. Every widget event is passed the inSender reference. For example, in the onclick event for a button, the reference to the button that was clicked is available via inSender. Use the inSender reference as you would a reference to any widget with this or app.

Clearing Data Input Fields in JavaScript


It is often necessary to clear the data input fields upon completion of an operation. For an editor named editor1 the data value can be nulled by calling:
this.editor1.clear();

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()

Creating Widgets at Runtime


To create widgets at runtime, use the .loadComponent method. The syntax for .loadComponent is:
parentWidget.loadComponent(inName, inType, inProps);

For example:
this.panel1.loadComponent("myLabel", "turbo.Label", {caption: "I made this!"});

120 CUSTOMIZING WAVEMAKER APPLICATIONS WITH JAVASCRIPT

After you create the new widget, you need to re-render the parent widget so that the new widget is included:
this.mylabel.reflowParent();

You can destroy objects at runtime with object.destroy.

Executing Service Calls in Your JavaScript Code


Service Calls can be executed in JavaScript by calling the update function. For example, suppose you created a Service Call component at the page level and you named it pageLevelServiceCall1. From that page, you can execute the Service Call like this:
this.pageLevelServiceCall1.update();

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().

Setting Data Properties


is a container for structured data. Its typically used to store data that is retrieved from a web service or a database. turbo.ServiceCall is a turbo.Variable subclass. You can use the setValue and getValue functions to manipulate data on turbo.Variable.
turbo.Variable

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);

and you could retrieve this value using getValue:


this.customerVariable.getValue(customerName);

REFERENCING COMPONENTS AT RUNTIME

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).

Referencing Components at Runtime


In your page code, you can use the syntax this.foo to specify any component that is scoped to that page. this refers always to the current page and foo would be the name of the component. For project -level components, you need to use the global object app to reference the application itself. At runtime, called app always owns the loaded page. For example, if you create a Variable component named myVariable (scoped to the project, rather than the page) you can reference that Variable from any page as:
app.MyVariable

Object Structure on the Client


In order to work with your WaveMaker application in custom code, you may want to know something about the object structure on the client. Briefly, the root level client side object is called turbo.Object. Below that, the component object (turbo.Component) is the top-level object that is designable in the WaveMaker Studio. Widgets (turbo.Widget), pages (turbo.Part) and variables (turbo.Variable) are all components. Service Calls are a subclass of variable and Navigation is a subclass of Service Call.

122 CUSTOMIZING WAVEMAKER APPLICATIONS WITH JAVASCRIPT

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.

Commonly Used Utilities


This section discusses some utilities that you are especially useful in WaveMaker applications:  CSS Utilities on page 122  The Connect Utility on page 123

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)

DEBUGGING WITH FIREBUG

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.

The Connect Utility


WaveMaker provides a utility that fires a target method on a target object after a source method on a source object has been called. This utility is used in the context of a component, (such as a page or a widget). The syntax is:
connect (srcObject, srcMethod, destinationObject, destinationMethod)

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.

Debugging with Firebug


The Firefox add-on, Firebug, provides several useful debugging tools. it is strongly recommended that you have Firebug enabled while developing with WaveMaker. To download Firebug, go to: http://getfirebug.com/ This section contains the following topics:
   

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

Running WaveMaker Studio in Debug Mode


WaveMaker Studio provides two startup options, regular or debug:  The regular mode runs WaveMaker using a Dojo build for efficiency. This build combines and compresses the Dojo files into fewer, larger files that are easier for the browser to quickly load and parse. Consequently, those files are more difficult to get meaningful error messages out of in Firebug.

124 CUSTOMIZING WAVEMAKER APPLICATIONS WITH JAVASCRIPT

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.

Firebug Status Bar


Firebug lets you know of errors within your application with a status bar error indicator. Watching the status bar indicator will quickly let you know when there is a problem.

Printing to the Firebug Console


From within any JavaScript function, informational statements and variables can be printed out the Firebug console using console.log(). To log a static string to the console use:
console.log("Hello WaveMaker");

Firebug Command Line


Firebug provides a command line for testing your code without editing your source files. To use the Firebug command line, open Firebug, click the Console tab, and type your JavaScript at the command prompt. Here are a few suggestions:  To enable debug information on studio widgets, use:
turbo.logging=true;


To use Firebug to directly inspect components or widgets at design time, use:


studio.part.widgetname

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);


To use Firebug to directly inspect global variables at design time, use:


studio.part.app.variablename

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


or app.component for components scoped at the project level:

DEBUGGING WITH FIREBUG


app.myVariable

125

126 CUSTOMIZING WAVEMAKER APPLICATIONS WITH JAVASCRIPT

APPENDIX B

Creating Custom Widgets


You can make your own custom widgets accessible in your WaveMaker applications and you can customize existing WaveMaker widgets. Customizing widgets requires some knowledge of JavaScript. In order to create and use a custom widget in WaveMaker, you need to do three things:
1. 2. 3.

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.

128 CREATING CUSTOM WIDGETS

The Widget Module File


You define a custom widget in a module file. The widget module file is a JavaScript module with the .js extension. A single module file can contain many widgets. Each widget within the module must have a unique widget name. Most custom widgets extend an existing widget, but you can also create an entirely new widget. Heres an example:
dojo.provide("wm.packages.example.CustomWidgets"); dojo.require("turbo09.widget.Label"); dojo.declare("turbo.WMLink", turbo.Label, { caption: "WaveMaker", link: "http://dev.wavemaker.com" });

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.

THE WIDGET MODULE FILE

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:

130 CREATING CUSTOM WIDGETS

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);

132 CREATING CUSTOM WIDGETS


this.connect(this.domNode, "onclick", this, "onWMclick") },

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.

Widget Module File Location


Place your custom widget file in your home directory under WaveMaker\common\packages. For example, if your home directory is myacct\Documents, then the custom widget directory would be:
myacct\Documents\WaveMaker\common\packages

Adding Studio Support for the Widget


In order to use your custom widget in the WaveMaker Studio, you need to add your module to the packages.js file (Packages File Location on page 133). The packages.js file defines the name, image and description for each widget, as it appears in the Palette. This file also determines which Palette heading the widget is listed under. The widget entries are separated by commas, except for the last entry in the file, which is not comma terminated. The syntax for the widget entries is:
[palette section, name, widgetClassName, moduleName, image, description]

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.

Packages File Location


The packages.js file is located in your home directory under WaveMaker\common\packages. For example, if your home directory is myacct\Documents, then the packages.js file would be:
myacct\Documents\WaveMaker\common\packagespackages.js

Adding Runtime Support for the Widget


To add runtime support for your custom widget, you need to add your module to the lib.js file (lib.js File Location on page 134). This will make the widgets in the module available to all projects run from the studio. To add the module to the lib.js file, simply add the module name, in quotes. Place a comma at the end of your entry in the file, unless it is the last entry. Be certain to comma terminate the previous entry. For example, you could add the following line to lib.js:
// custom Widgets "wm.packages.example.CustomWidgets

The module name must match the moduleName you specified in the packages.js file (Adding Studio Support for the Widget on page 132).

134 CREATING CUSTOM WIDGETS

lib.js File Location


The lib.js file is located in your home directory under WaveMaker\common\packages. For example, if your home directory is myacct\Documents, then the lib.js file would be:
myacct\Documents\WaveMaker\common\packages\lib.js

Testing the Widget


Reload WaveMaker Studio. Open a new or existing project. You should now see your custom widget in the Palette. If you receive any errors upon loading studio, check your syntax. The most common error of custom widgets is the failure to load the module. Could not import module wm.packages.example.CustomWidgets This can be the result of:  The module file is not available in the defined location  The module name and provide do not match  The declare statement does not match the packages definition Firebug can provide further information as to the cause of the failure (Debugging with Firebug on page 123). Firebug will also show you the contents of the JavaScript files. This is useful for tracking down problems caused by caching. When youre testing your widget, note that events do not fire in design mode. To test events, you need to actually run the application.

Dojo and WaveMaker


The WaveMaker widget architecture relies heavily on the Dojo toolkit, which is an Open Source DHTML toolkit written in JavaScript. Dojo is divided into three main parts:
  

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/

You might also like