- Easy Web Development with WaveMaker
- Edward Callahan
- 1940字
- 2021-08-13 16:20:34
Getting comfortable with the JavaScript client
The client is a JavaScript client that runs in a modern browser. This means that most of the client, the HTML and DOM nodes that the browser interfaces with specifically, are created by JavaScript at runtime. The application is styled using CSS, and we can use HTML in our applications. However, we don't use HTML to define buttons and forms. Instead, we define components, such as widgets, and set their properties. These component class names and properties are used as arguments to functions that create DOM nodes for us.
Dojo Toolkit
To do this, WaveMaker uses the Dojo Toolkit, http://dojotoolkit.org/. Dojo, as it is generally referred to, is a modular, cross-browser, JavaScript framework with three sections. Dojo Core provides the base toolkit. On top of which are Dojo's visual widgets called Dijits
. Finally, DojoX contains additional extensions such as charts and a color picker. DojoCampus' Dojo Explorer, http://dojocampus.com/explorer/, has a good selection of single unit demos across the toolkit, many with source code. Dojo allows developers to define widgets using HTML or JavaScript. WaveMaker users will better recognize the JavaScript approach.
Specifically, WaveMaker 6.5.X uses version 1.6.1 of Dojo. Of the browsers supported by Dojo 1.6.1, http://dojotoolkit.org/reference-guide/1.8/releasenotes/1.6.html, Opera's "Dojo Core only" support prevents it from being supported by WaveMaker. This could change with Opera's move to WebKit.
Building on top of the Dojo Toolkit, WaveMaker provides its own collections of widgets and underlying components. Although both can be called components, the name
component is generally used for the non-visible parts, such as service calls to the server and the event notification system. Widgets, such as the Dijits
, are visible components such as buttons and editors. Many, but not all, of the WaveMaker widgets extend functionality from Dojo widgets. When they do extend Dijits
, WaveMaker widgets often add numerous functions and behaviors that are not part of Dojo. Examples include controlling the read-only state, formatting display values for currency, and merging components, such as buttons with icons in them. Combined with the WaveMaker runtime layers, these enhancements make it easy to assemble rich clients using only properties. WaveMaker's select editor (wm.SelectMenu
) for example extends the Dojo Toolkit ComboBox (dijit.form.ComboBox
) or the FilteringSelect (dijit.form.FilteringSelect
) as needed. By default, a select menu has Dojo FilteringSelect
as its editor, but it will use ComboBox
instead if the user is on a mobile device or the developer has cleared the RestrictValues
property tick box.

A required select menu editor
Let's consider the case of disabling a submit button when the user has not made a required list selection. In Dojo, this is done using JavaScript code, and for an experienced Dojo developer, this is not difficult. For those who may primarily consider Dojo a martial arts Studio however, it is likely another matter altogether. Using the WaveMaker framework provided widgets, no code is required to set up this inter-connection. This is simply a matter of visually linking or binding the button's disabled
property to the lists' emptySelection
property in the graphical binding dialog.

Now the button will be disabled if the user has not made a selection in the grid's list of items. Logically, we can think of this as setting the disabled property to the value of the grid's emptySelection
property, where emptySelection
is true unless and until a row has been selected.
Where WaveMaker most notably varies from the Dojo way of things is the layout engine. WaveMaker handles the layout of container widgets using its own engine. Containers are those widgets that contain other widgets, such as panels, tabs, and dialogs. This makes it easier for developers to arrange widgets in WaveMaker Studio. A result of this is that border, padding, and margin are set using properties on widgets, not by CSS.
Tip
Border, padding, and margin are widget properties in WaveMaker, and are not controlled by CSS.
Dojo made easy
Having the Dojo framework available to us makes web development easier both when using the WaveMaker framework and when doing custom work. Dojo's modular and object-oriented functions, such as dojo
.declare
and dojo
.inherited
, for example, simplify creating custom components, which we will discuss more in Chapter 11, Mastering Client Customization.
The key takeaway here is that Dojo itself is available to you as a developer if you wish to use it directly. Many developers never need to utilize this capability, but it is available to you if you ever do wish to take advantage of it. Running the CRM Simple sample again from either the console in the browser development tools or custom project page code, we could use Dojo's byId()
function to get a div
, for example, the main title label:
>dojo.byId("main_labelTitle")
.
In practice, the WaveMaker style of getting a DOM node via the component name, for example, main.labelTitle.domNode
, is more practical and returns the same result.
If a function or ability in Dojo is useful, the WaveMaker framework usually provides a wrapper of some sort for you. Just as often, the WaveMaker version is friendlier or otherwise easier to use in some way. For example, this
.connect()
, WaveMaker's version of dojo.connect()
, tracks connections for you. This avoids the need for you to remember to call disconnect()
to remove the reference added by every call to connect()
. For more information about using Dojo functions in WaveMaker, see the Dojo framework page in the WaveMaker documentation at:
Binding and events
Two solid examples of WaveMaker taking a powerful feature of Dojo and providing friendlier versions are topic notifications and event handling.
Dojo
.connect()
enables you to register a method to be called when something happens. In other words: "when X happens, please also do Y". Studio provides visual tooling for this in the events section of a component's properties. Buttons have an event drop-down menu for their click event. Asynchronous server call components, live variables, and service variables, have tooled events for reviewing data just before the call is made and for the successful, and not so successful, returns from the call. These menus are populated with listings of likely components and if appropriate, functions. Invoking other service calls, particularly when a server call depends on data from the results of some previous server call, and navigation calls to other layers and pages within the application are easy examples of how WaveMaker's visual tooling of dojo.connect
simplifies web development.
WaveMaker's binding dialog is a graphical interface on the topic subscription system. Here we are "binding" a live variable that returns rows from the lineitem
table to be filtered by the data value of the orderid
editor in the form on the new order page:

The result of this binding is that when the value of the orderid
editor changes, the value in the filter parameter of this live variable will be updated. An event indicating that the value of this orderid editor has changed is published when the data value changes. This live variable's filter is being subscribed to that topic and can now update its value accordingly.
Loading the client
Web applications start from index.html
, and a WaveMaker application is no different. If we examine index.html
of a WaveMaker application, we see the total content is less than 100 lines. We have some meta tags in the head, mostly for Internet Explorer (MSIE) and iOS support. In the body, there are more entries to help out with older versions of MSIE, including script tags to use Chrome Frame if we so choose. If we cut all that away, index.html
is rather simple. In the head, we load the CSS containing the projects theme and define a few lines of style classes for wavemakerNode
and _wm_loading
:
<script>var wmThemeUrl = "/wavemaker/lib/wm/base/widget/themes/wm_default/theme.css";</script> <style type="text/css"> #wavemakerNode { height: 100%; overflow: hidden; position: relative; } #_wm_loading { text-align: center; margin: 25% 0px 25% 0px; } </style>
Next we load the file config.js
, which as its name suggests, is about configuration. The following line of code is used to load the file:
<script type="text/javascript" src="config.js"></script>
Config.js
defines the various settings, variables, and helper functions needed to initialize the application, such as the locale setting.
Moving into the body tag of index.html
, we find a div
named wavemakerNode
:
<div id="wavemakerNode">
The next div
tag is the loader gif, which is given in the following code:
<div id="_wm_loading" style="z-index: 100;"> <table style='width:100%;height: 100%;'><tr><td align='center'><img alt="Loading" src="/wavemaker/lib/boot/images/loader.gif" /> Loading...</td></tr></table> </div>
This is the standard spinner shown while the application is loading. With the loader gif now spinning, we begin the real work with runtimeLoader.js
, as given in the following line of code:
<script type="text/javascript" src="/wavemaker/lib/runtimeLoader.js"></script>
Note
When running a project from Studio, the client runtime is loaded from Studio via WaveMaker. Config.js
and index.html
are modified for deployment while the client runtime is copied into the applications webapproot
.
runtimeLoader
, as its name suggests, loads the WaveMaker runtime. With the runtime loaded, we can now load the top level project.a.js
file, which defines our application using the dojo.declare()
method. The following line of code loads the file:
<script type="text/javascript" src="project.a.js"></script>
Finally, with our application class defined, we set up an instance of our application in wavemakerNode
and run it.
There are two modes for loading a WaveMaker application: debug and gzip mode. The debug mode is useful for debugging, as you would expect. The gzip mode is the default mode. The test mode of the Run, Test, or Compile button in Studio re-deploys the active project and opens it in debug mode.
Note
This is the only difference between using Test and Run in Studio. The Test button adds ?debug
to the URL of the browser window; the Run button does not.
Any WaveMaker application can be loaded in debug mode by adding debug
to the URL parameters. For example, to load the CRM Simple application from Chapter 1, Getting Started with WaveMaker in debug mode, use the URL http://crm_simple.localhost:8094.com/?debug; detecting debug in the URL sets the djConfig.debugBoot
flag, which alters the path used in runtimeLoader
.
djConfig.debugBoot = location.search.indexOf("debug") >=0;
Like a compiled program, debug mode preserves variable names and all the other details that optimization removes which we would want available to use when debugging. However, JavaScript is not compiled into byte code or machine specific instructions. On the other hand, in gzip mode, the browser loads a few optimized packages containing all the source code in merged files. This reduces the number of files needed to load our application, which significantly improves loading time. These optimized packages are also minified. Minification removes whitespace and replaces variable names with short names, further reducing the volume of code to be parsed by the browser, and therefore further improving performance. The result is a significant reduction in the number of requests needed and the number of bytes transferred to load an application. A stock application in gzip mode requires 22 to 24 requests to load some 300 KB to 400 KB of content, depending on the application. In debug mode, the same app transfers over 1.5 MB in more than 500 requests.
The index.html
file, and when security is enabled, login.html
, are yours to edit. If you are comfortable doing so, you can customize these files such as adding additional script tags. In practice, you shouldn't need to customize index.html
, as you have full control of the application loaded into the wavemakerNode
. Also, upgraded scripts in future versions of WaveMaker may need to programmatically update index.html
and login.html
. Changes to the X-US-Compatible
meta tag are often required when support for newer versions of Internet Explorer becomes available, for example. These scripts can't possibly know about every customization you may make.
Tip
Customization of index.html
may cause these scripts to fail, and may require you to manually update these files. If you do encounter such a situation, simply use the index.html
file from a project newly created in the new version as a template.
- Java多線程編程實戰指南:設計模式篇(第2版)
- 國際大學生程序設計競賽中山大學內部選拔真題解(二)
- TypeScript Blueprints
- Building Modern Web Applications Using Angular
- 軟件測試工程師面試秘籍
- Mastering C# Concurrency
- Python Network Programming Cookbook(Second Edition)
- Cassandra Data Modeling and Analysis
- HTML5+CSS3+JavaScript Web開發案例教程(在線實訓版)
- 好好學Java:從零基礎到項目實戰
- Fastdata Processing with Spark
- IPython Interactive Computing and Visualization Cookbook
- UML軟件建模
- Hack與HHVM權威指南
- Learning Cocos2d-JS Game Development