Sei sulla pagina 1di 873

Welcome

Introduction Morfik's Programming Languages


What's New The Morfik Framework
For Delphi Developers Web Methods
The Workspace Using External Code
Working with Forms Debugging
Working with Controls Deploying an XApp
Working with Themes Tips and tutorials
Database Programming Release Notes
External Databases

Page 1
Introduction

In this connected age, when people think about the World Wide Web and the
speed in which things happen, the ability to adapt quickly is everything. The
development of sophisticated Web-based applications has never been a quick or
easy task, and the technology and tools generally used show more and more
weaknesses as the size of applications grow.

By thinking outside the box, Morfik is redefining how Web applications are built
from the ground up, introducing into them technology from other areas of IT
specialization such as traditional application development, graphics design,
computer-aided design and productivity applications. Morfik is combining elements
of all of these areas into the development of Web applications in order to make it
more productive.

The Old Way


To better understand Morfik's approach to Web development we have to look at traditional
web development with a critical view and an outside perspective. When the Web was
created, its main purpose was simply to make information easily accessible by other people,
mainly with the goal of making collaboration between groups of scientists and students,
easier. At that time there were no Web applications. There were simply Web pages.
Web pages were nothing more than simple text documents with some special tags (groups of
characters) inserted to enhance formatting. The idea of using the Web to ask for information
from the people who were visiting different pages did not take long to appear and mature
and so server-side programming for Web pages began. The next step was to add some small
measure of interactivity to the page itself because going back and forth between the server
and the browser, sometimes on different sides of the globe, made for a poor experience. This
was especially true when filling out large forms or multiple forms. After many years of
evolution of the Web, Web application development is still, essentially, done in the same
fashion. This means that thousands of people around the world are creating huge systems
with tools which were originally conceived to format text and to create basic interactivity in
Web pages. While this is possible, it is far from being the most productive way of doing it.

One other aspect of Web development the traditional way is that most frequently portions of
the browser side code get mixed with the server side code. This is hardly ideal, either, as it
makes for either bloated pages, or applications that require many page loads. Both scenarios
lead to reduced performance and a less-than-ideal user experience.

The Morfik Way


In 2005, Morfik introduced to the world a whole new way of creating Web applications,
through the use of high-level, object-oriented languages and visual design tools. With this
new tool set, developers can code their applications using time-tested software development
practices and leverage their experience while still getting the benefit of a modern visual
designer, which makes creating stunning interactive Web interfaces a breeze. Morfik
AppsBuilder is powered by a set of compilers for the Morfik language. This language has no
syntax of its own, just semantic meaning. Morfik implements a set of compilers which map
Object Pascal and Basic syntaxes to the underlying Morfik language, thus providing a familiar
syntax to allow developers to become productive quickly. The high-level code that is created
by developers is then compiled by the Morfik compiler. Code intended for the interface
(browser) side of the application is compiled into a combination of HTML, XML, CSS and
Javascript, while code intended for the application control (server) portion of the application is
compiled into a native binary executable or dynamically linked library.

A Great Tool for Browser Applications


The HTML/XML/CSS/Javascript code combination that Morfik compilers generate for running in
the browser is entirely standards-based and compliant, communicating with the Morfik
generated server components through standard HTTP requests and Web Service standards.
Because of this, the browser portion of a Morfik application (XApp) can call out to any
standards-based server platform and the Morfik-built server components be called from any
standards-compliant client application. This intrinsic flexibility has led to the possibility of
creating a new type of project in Morfik 2.0: the Browser Application. Browser applications (or

Page 2
Browser XApps), are applications which do not directly depend on any server-side component,
though they might use several different services from different service providers on the
Internet. The browser XApp is essentially an application which is 100% browser-based and
does not care at all about which server it was served from. Browser XApps can even run
without an internet connection!

Morfik Browser XApps can be used to interface with different services which are currently
available on the Web or simply to break down more complex projects with different teams
working on the Interface (presentation layer) and the application logic in separate projects.

The power and ease of use of the Morfik high-level language syntaxes will make Morfik
AppsBuilder the best tool to build complex applications which are required to run within a
browser, allowing the creation of projects which might not be feasible to implement directly in
Javascript. Browser XApps should be able to do just about everything you can do with a full
Web Application (which combines browser and server components). In order to access a
database a Browser XApp will still require interaction with a server component, due to
browser security limitations, but this component could be implemented in any platform which
is capable of creating industry-standard compliant web services. You can also use the XML
data sources in Browser applications to separate data from layout, in your project.

A Great Tool for Server Applications


Morfik AppsBuilder is designed to cover all the basic needs of a developer or company working
on the creation of a Web application. Web applications can go from having a couple of users
(during testing) to hundreds of thousands, in a very short time. With this in mind, Morfik set
out to create a scalable solution for Web-based, online applications which could accommodate
such disparate requirements. The first decision made when considering the development of
Morfik's server-side strategy was to focus on performance and scalability. Morfik server
components are totally stateless by default. Being native binaries, they consume many fewer
resources than similar solutions which are based on virtual machines as Java and .Net.
Another advantage of implementing server components as native binaries is that they can do
anything a native application is able to do on the selected server platform. Since Morfik
AppsBuilder and its framework are entirely standards-based, it is very easy to create a
full-featured Web Services server application in minutes, or to add a Web Services interface to
an existing application.

A Great Tool for Design


Morfik AppsBuilder is now even better tools for designers than they were ever before. An
enhanced Form Designer allows you to get a better feel for how your applications will look at
runtime. New improvements to the Morfik Framework and to the IDE itself allow for
instantaneous switching of the project's look through the use of Themes.

While web designers all over the world are spending their time coming up with tricks to create
nice-looking effects and then having to reproduce these tricks in many different places,
Morfik's R&D team is busily adding new features to the Morfik Framework and controls which
allow the developer to add new formatting and design touches to their applications by
changing a couple of properties and recompiling their applications.

Using the new Form Designer, developers and designers can now have a much clearer picture
of how their forms' components will come together inside the browser, and so should need
fewer iterations of design changes to get the desired look for their pages.

Aggregating the Web


Morfik applications can easily call out to a multitude of services which are available on the
Web and access internal company databases, bringing together data from myriad of sources
into a single front-end application. The ability to bring together these disparate data sources
comes from the fact that while Morfik AppsBuilder provides all the tools to create incredible
browser applications, it also provides all the tools to do server-side forwarding of calls to
other domains and the ability to access multiple databases from multiple vendors. Morfik
applications can extend or act as front-ends to legacy applications, or just to put Ajax clothing
on your existing Web-based applications. All this comes together to allow businesses to
provide consolidated information to their executives, regardless of where the information is
coming from.

Unprecedented Productivity

Page 3
The combination of Morfik's Framework, visual workspace and compilers allows developers to
quickly reach unprecedented levels of productivity in creating sophisticated web applications.
In fact, this is so much so that there are companies that are using Morfik to win contract bids,
even when the final work is required to be done on a different platform. These companies are
taking advantage of how fast and easy it is to create great-looking Ajax applications with
Morfik to provide site mock-ups or even fully-functional prototypes for the work they are
bidding for. This gives these companies a decided advantage as their competitors are not
able to put together a matching prototypes in the same space of time.

As of version 2.0, Morfik AppsBuilder has placed even further emphasis on productivity. The
new design features, such as Themes and Control Effects, were all created to allow
developers to quickly perform tasks which substantially alter the appearance of an application
or website, but which will no longer require extensive coding changes.

Also in Morfik AppsBuilder 2.0, in order to make developers' lives easier, project management
and navigation has become a much more visual experience by the general use of thumbnails
instead of plain text lists. Internal tests showed that people located the document they
wanted to work on much quicker by scanning for its likeness than by reading through the list
of document names. Combined with the ability of filtering the project view, it becomes not
only a time saver but a pleasant experience, which is just the opposite of what a looking for a
name in a possibly long list is.

Page 4
Morfik's Programming
Languages

This guide covers in detail all the language syntaxes supported by Morfik. It is not
intended as the definitive reference in programming with Basic, C#, Java and
Object Pascal but as a guide as to how these languages have been implemented
by Morfik.

Who is this guide for?


This guide was written for the developer who is coming to Morfik and wants to know how his
language of choice is supported in the product. No Web application development techniques
are discussed in this guide; its focus is solely to describe programming languages and the
details of their support within Morfik.

How is this book organized?


This book is composed of an introduction and four parts, each of them covering one of the
supported programming languages, as follows:

Introduction to Morfik Languages


Part I - Morfik Basic
 Overview
 Data Types and Variables

 Subroutines and Scope


 Object Oriented Programming
Part II - Morfik Pascal
 Overview
 Data Types and Variables

 Subroutines and Scope


 Object Oriented Programming
Part III - MorfikJ
 Overview
 Data Types and Variables

 Subroutines and Scope


 Object Oriented Programming
Part IV - Morfik CSharp|Morfik C#
 Overview
 Data Types and Variables

 Subroutines and Scope


 Object Oriented Programming

What do you need to use this book?


This guide makes no effort to teach the reader how to program, so basic knowledge of
programming is a requirement. Some familiarity with your language of choice is desirable but
not required as all the basic language constructs are described for each language.

If you are reading a printed copy of this document you will want to be at or near a computer
with Morfik AppsBuilder installed most of the time, so that you can try out examples or
experiment with some of the features we will be looking at.

Download Languages Guide


Feel free to view or download the PDF version.

Page 5
Morfik Languages Guide.pdf

category:Programming

Page 6
Introduction to Morfik Languages

Why Support Multiple


Languages?
Language Independence
Basic Common Concepts
Wrapping it up

Morfik AppsBuilder supports four high-level programming language syntaxes:


Pascal, Basic, MorfikJ and C#. (Note: MorfikJ and C# are not available in the
current Morfik 2 release, but will be made available in a future beta.) This guide
will provide a quick guide to all the supported languages, with emphasis on
language features which have been introduced by Morfik in addition to the
standard language specification and where we have differed from the specification
for some reason.

Why Support Multiple Languages?


Many people have asked why Morfik chose to support multiple languages. Well the answer is simple: we want
they are required to learn not only new technologies, but new programming languages.

In creating the technology behind Morfik AppsBuilder, Morfik has taken steps to welcome to the world of Web-
language does not have syntax of its own; only a set of semantic rules. On top of these rules, Morfik implemen

Note
It is important that you be aware that supporting the syntax of a language is not the same as supp
AppsBuilder, you are not writing an application that will run inside the JVM or .net Framework. Your

Language Independence
Towards the goal of supporting developers who have extensive programming experience with languages that
the Morfik programming language. These features have been added with great care to so that they "blend in"
another?

By making sure that all language syntaxes support all the features available in the underlying Morfik semantic
allows you to take an example which was written in Pascal and, supposing you prefer to read it in Basic, conve

The scope of usage of this feature is huge. Developers can download examples done by other people, using ot
language, if the project was created with Morfik AppsBuilder, can more easily hire replacement personnel.

Note
Please note that Language Conversion was originally intended for internal use in order to make it e
continuously on improving the results generated and hope to achieve the capability of converting al

In order to guarantee that code translation always occurs in a manner that is totally faithful to the original cod

When converting an existing project from one language syntax to another, absolutely everything is moved over

Page 7
Basic Common Concepts
Independent of which language syntax you have chosen for your usage, as I mentioned, you will work with the
which represent the Tables, Queries, Forms, Reports and WebMethods which are part of your application. At so

Other basic concepts which are shared are the basics of Object Oriented Programming which are generally cov

Some concepts of the underlying Morfik language were not supported by some languages and were added to t
hybrid object-oriented-procedural language as such supports these constructs which were added to the Morfik

Wrapping it up
Morfik AppsBuilder offers support for four different language syntaxes that share a common language feature s

Re-using code from third parties is made easier since code can be translated to help with the process of learni

Page 8
Morfik Pascal

Part II - Morfik Pascal

Morfik WebOS AppsBuilder implements several different syntaxes for the Morfik
language in order to ease the learning curve of developing web application for
developers with previous experience. Morfik Pascal is an implementation of a
Pascal language syntax for the Morfik language.

In the following articles a complete overview of the Morfik Pascal language syntax
is provided.
 Pascal Overview
 Pascal Data Types and Variables

 Pascal Subroutines and Scope


 Pascal Object Oriented Programming

Page 9
Pascal Overview

This chapter will provide you will a general overview of Morfik Pascal. It is
presumed that the user already has some familiarity with some dialect of Pascal,
such as Delphi, Virtual Pascal, FreePascal, etc.

Our focus will be on providing a quick reference for most language features and a
more detailed explanation for those features which are unique to Morfik Pascal.

Through the evolution of its usage in the industry, Pascal has undergone a huge
amount of change. The most popularly known dialect of the Pascal Language is,
without doubt, CodeGear ’ s Delphi so most of the time when we refer to Pascal
(not Morfik Pascal) we will be referring to CodeGear ’ s dialect of the Pascal
language.

Morfik Pascal Modules


Module Duality – Browser and
Server
Referencing Modules
Module Initialization and
Finalization
Adding Comments
MorfikDoc Comments
Variables
Initialized Variables
Constants
Typed Constants
Operators
Assignment Operator
Equality Operator
Inequality Operator
Logical Operators. AND, OR, NOT
Other Comparison Operators
Arithmetic Operators
String
Application Flow Control
Branching
If .. Then .. Else
Case .. Else .. End
Loops
While .. do
Repeat .. Until
For .. do
Conditional Compilation
Wrapping it up

Page 10
Morfik Pascal Modules
Morfik Pascal has the concept of Modules, which is present in a weaker form in most versions
of Visual Pascal. A Module in Morfik can have three forms, a browser side module, a server
side module or a dual module. In all three cases the module is represented by a single .mmd
file.

While, traditionally, the file was the only defining factor of the existence of module, in Morfik
Pascal a formal code construct defines the module, for each side: browser and server. This
construct, is called a unit. The simplest module that is possible to create with Morfik Pascal
can be seen in Listing 1.

Listing 1 – Empty module in Morfik Pascal.

Unit Globals ;

Interface

// T his is an empty module


Implementation

End .

Module Duality – Browser and Server


In Morfik applications modules can be Browser side, Server side or dual. Dual modules are
both Browser and Server at the same time. The Morfik IDE will show you a tabbed view of the
module allowing you to edit the part of the module that you want: Browser or Server.

Referencing Modules
In order to access the functions, variables and types which are declared in other Morfik
Modules it is necessary to import them. This is done in Pascal through the Uses clause as
shown in Listing 2.

Listing 2 – Empty module in Morfik Pascal, importing SystemUtilities.

Unit Globals ;

Interface

Uses SystemUtilities ;
// T his line imports module SystemUtilities
// T his is an empty module
Implementation
//...
end .

One Uses clause is used to declare all the modules you wish to import in the interface section
of a module, and another in the implementation section.

It is important to have in mind that referencing a module in the Browser side of another
module will not make the server side of this second module imports the same module ’ s
server side counterpart. If this is required, it must be done manually.

Module Initialization and Finalization


Morfik modules have Initialization and Finalization sections. In Pascal these are implemented
through two named code blocks. These blocks are called Initialization and Finalization and have

Page 11
a special syntax as shown in Listing 3.

Listing 3 – Module with Initialization and Finalization.

Unit Globals ;

Uses LogMod ;

Interface

Implementation

// T his is a module with Initialization and Finalization Section


s
Initialization
InitLogFile ;

Finalization
FlushLogFile ;

End .

The code contained in the Initialization section is called when your XApp is first loaded, while
the code in the Finalization is called when your application is terminated. The Finalization
section is only effective on the server where you can be sure that your application will actually
get finalized. While syntactically correct, a Finalization section on the browser side will never
be called. On the server side of the application, however, the Finalization section will always
be called on application shutdown.

It is also important to note that modules that are not statically bound on the browser side will
have their Initialization sections called when they are first loaded and not at the initial page
load. For more information on statically binding a module, refer to the Compiler Directives
section of this chapter.

Note
We recommend that the user accept the default behavior implemented by Morfik
which makes all Forms dynamically loadable and all pure code Modules statically
loaded - typically these settings should not be altered manually.

Adding Comments
Morfik Pascal offers three different ways of creating comments:

// T his a comment

{ T his is another comment which c


an
span multiple lines }
(* T his is yet another comment
which can span multiple lines*)

There are basically two types of comments in Morfik Pascal: end of line and multiple line. End
of line comments render all following text on the same line into comments. Multi line comments
render everything between the start and stop comment strings into a comment.

Note

Page 12
It is best to create small comments within your code using the one line comments
(to end of line) so that if you decide to comment out a section of a routine, you can
do it with multi-line comments. A sample of this can be seen below:
(* I ’ m commenting this section out for debugging purposes
Label1.Caption := ’ A caption... ’ ; //Changes the caption
*)
In this case, the multi-line comment is not affected in any way by including a line
with a single line comment.

MorfikDoc Comments
Morfik, taking its cue from work done for the Java platform, created an extension to normal
comments that allows the developer ’ s comments to be integrated with the IDE ’ s code
completion system. These special comments are a partial implementation of the JavaDoc
syntax, but unlike JavaDoc, which uses its own separate compiler, MorfikDoc comments are
processed by the Morfik high-level language compilers as part of the AppsBuilder background
compilation process and are thus, immediately available within the IDE ’ s code completion
system.

Listing 4 – MorfikDoc comment sample

(**

T his is a morfikdoc comment for T est P roce


dure
*)
procedure T est ;
begin
// ...
end ;

The element that the compiler uses to identify a comment as a documentation comment is the
second asterisk( * ) used in the opening of the comment. Any asterisks used in the start of
any lines of MorfikDoc comments will be stripped out, so that the code in Listing 5 will have
the same effect as that in Listing 4.

Listing 5 – MorfikDoc comment sample with extra asterisk

(**

* T his is a morfikdoc comment for T est


Sub
*)
procedure T est ;
begin
// ...
end ;

Variables
Usually you declare variables at the start of a procedure through the use of the Var
statement. This statement is a short version of the word Variable that has been in use in
Pascal since its very beginning.

Listing 6 – var statement for variable declaration

procedure

Page 13
T est ;
var
X : Integer
;
Y : double
;
begin
X := 2 ;
X := X + 1
;
Y := X / 5
;
end ;

Initialized Variables
Variables can be pre-initialized at declaration. This is done by a simple attribution in the Var
statement as in the following samples:

Var index
: integer = 10 ;

You can declare initialized variables also within sub routines as shown in Listing 7.

Note
Note that initialized variables cannot be used at the local scope level if you have
chosen Delphi as your platform backend compiler. In this case you could use Typed
Constants, as described later in this chapter, assuming you have Assignable typed
constants turned on in your Delphi configuration.

Listing 7 – Procedure with initialized variables.

procedure T est ;
var
x : Integer = 2
0;
y : Integer = 3
0;
begin
//...
end ;

You can also have the equivalent to initialized variables through the use of a new language
feature called Typed Constants .

Note
It is important to note that Morfik Pascal is case insensitive and that you cannot
therefore declare two objects at the same scope level with the same name.
Because of this, it is common practice to write code using "Proper" cased
identifiers since in some cases they can make your code a lot easier to read. You
can see this in the following examples:
function thisfunctiongetsabithardtoread: integer;
function ThisFunctionIsMuchEasierToRead: integer;
Var

Page 14
thisisavariablewithalongname string;
ThisIsAVariableWithALongName string;

Constants
Constants are normally used to hold literal values that are used in several different places
within an application. Here is a small sample of a constant declaration:

const
myConst = 1
0;
Str = 'Hello' ;

This sample shows the declaration of numeric and string literal constants. Constants declared
in this form cannot have their values changed at runtime.

In Morfik Pascal you can declare multiple constants under a single const clause as shown in
the previous example.

Typed Constants
Typed constants are a bit different from what you might expect, considering that they are
constant only in name. Typed constants are declared in the following form:

const
MyInitVar : integer = 20 ;
MyDoubleVar : Double = 2.1
5;

Notice that typed constants are declared with a formal type and function as initialized
variables of that type.

Note
The Morfik Pascal compiler does not generate an error if you try to assign a value
to a non- typed constant ; however at compile time the backend platform compiler
will generate an error.

Operators
Operators are symbols within your Morfik Pascal code which allow you to compare or perform
logical or arithmetic operations on all data types. There are operators to add, subtract,
multiply, divide, etc.

In this section we will see the Morfik Pascal operators and how they are used.

Assignment Operator
This operator allows you to assign new values to variables or object properties. Morfik Pascal
utilizes the ’ := ’ sign as the symbol for this operator. The following example means that the
variable called Variable1 is assigned the value of 5.
Variable1 := 5;

Equality Operator
Morfik Pascal uses as the equality the ’ = ’ (equals) sign when comparing values as seen in
the following example:

Page 15
if (X = Y) then

Inequality Operator
Morfik Pascal uses the pair ’<>’ (Less than and Greater than) of signs to represent the
Inequality operator. You can see the usage of this operator in the following example:

if (A <> B) then

Logical Operators. AND, OR, NOT


These operators are used for logical combinations in comparisons. The following are examples
of their usage:

if (X = Y) and (A <> B) then

if (X = Y) or (A = B) then

if (X <> Y) and ( not (A <> B)) then

Note
Through the usage of parenthesis you can combine several different logical
operations in one more complex operation as seen in the last of the previous
examples.

Other Comparison Operators


The following is a list of definitions of other comparison operators used in Morfik Pascal.

Operator Definition
< Less than. Yields a true value when the element to the left
side holds a value which is "smaller" than the value held by
the element to the right side.
> Greater than. Yields a true value when the element to the
left side holds a value which is "larger" than the value held
by the element to the right side.
<= Less than or equal. Yields a true value when the element
to the left side holds a value which is "smaller" or equal to
the value held by the element on the right side.
>= Greater than or equal. Yields a true value when the
element to the left side holds a value which is "larger" or
equal to the value held by the element to the right side.

Arithmetic Operators
Morfik Pascal has a full set of arithmetic operators which should be reasonably familiar to
anyone with minimal programming experience. The following is a full list of the arithmetic
operators.

Operator Definition
+ Addition operator, used on all
numeric data types.
- Subtraction operator used on all
numeric data types.
* Multiplication operator used on all
numeric data types.
/ Division operator used on floating
point numeric data types.
div Integer Division operator used on
integer numeric data types.

Page 16
Mod Remainder of division operator.
This operator yields the value of
the remainder of the integer
division of the term to the left by
the term on the right side.

String
String is a data type which is used to represent groups of characters. The following are
examples of string variables and constants:

const Str = 'Hello' ;


var
MyStr : String ;
MyStr2 : String =
'Hello!' ;

More details on string can be found in the Data Types Chapter of this guide.

Application Flow Control


All programming languages share some constructs which are specific for application flow
control. These structures are mainly divided into two groups: Branching and Loops.

All flow control structures (both for branching and loops) in Morfik Pascal can be used with a
single statement or a statement block (code between a begin .. end pair).

Branching
The Morfik Pascal language offers two constructs specific for branching control. These
constructs have equivalents in most programming languages and are quite straightforward in
usage.

If .. Then .. Else
The " IF " construct in most languages allows for choosing among two execution paths based
on a Boolean expression. In Morfik Pascal, however, due to the possibility of nesting the " IF "
statement you can actually branch into any number of different paths. The code snippet in
Listing 8 shows an example of using the " IF " statement with several possible execution
paths.

Listing 8 – Multiple paths with the If..Then..Else construct.

if ((( x + y ) > 10 ) and ( not


(( x - y ) > 0 ))) then
z := x / y
else
if ( X > Y ) then
Y := Z * X
else
if ( Y = Z ) then
Z := 25
else
x := y / z ;

If you place a ";" before the Else clause, the compiler will generate an error.

Note

Page 17
It is important to remember that the Else clause is a part of the "IF" statement and
should therefore never be preceded by a semi-colon (";").

Case .. Else .. End


The Case statement is used for conditional execution of code based on a list of values. The
Case statement can have an optional Else clause whose dependent code will be executed if
the value of the condition did not match any of the Case values. The code snippet in listing 9
shows an example of the usage of this language construct.

Listing 9 – Code snippet showing the usage of Select Case.

case z of
1:
z = z + 2;
2:
y = x + 5;
else
if z > ( x + y ) then
x := y + 5 ;
end ;

Loops
Loop constructs handle repetitions in the execution of certain code blocks within an
application.

While .. do
The While statement in Morfik Pascal is very much straightforward in its utilization. While the
condition specified is true, the contained code block will be executed. The following code
snippet shows an example of its usage.

While
Length ( StringT oConsume ) > 0 do
Delete ( StringT oConsume , 1 , 1 );

Note
In executing a While statement, the condition is always verified before the first
execution of the code block contained by the statement. This means that it is
possible that the contained code will never execute if the condition starts out as
false.

Repeat .. Until
The Repeat..Until loop structure has its condition set at the bottom of the code section it
contains. Having the condition at the bottom of the contained section means that the
contained code will be executed at least once, since the condition will only be checked
afterwards. This means that even if the condition is false at the start of the block the code will
be executed once, regardless.

The main difference between using the While..do or Repeat..Until constructs is that when you
use While..do , the contained code will be execute as long as the condition is true and when
you use Repeat..Until the code will be executed until that condition becomes true. The code

Page 18
snippet in Listing 10 shows examples of the possible usages of the Repeat..Until construct.

Listing 10 – Do Loop usage Examples.

i := XApp . OpenForms . Count –


1;
repeat
frm := XApp . OpenForms . Items [
i ];
ShowMessage ( frm . InstanceName );
i := i – 1 ;
until i < 0 ;

For .. do
When we have previous knowledge about the exact number of times a certain code block
should be executed, we can use the For do statement in one of its variations (ascending or
descending). The execution of the contained code of a For do statement is done in the
following order:

1. The value of the control variable is checked against the end value.

2. The contained code is executed

3. The control variable is incremented or decremented (depending on whether it is an


ascending or descending loop).

4. Return to step 1.

In order to have a descending For do loop you should change the "to" keyword for the
"downTo" keyword, inverting the maximum and minimum value order. The code snippet in
Listing 11 shows examples of both ascending and descending For .. Next loops.

Listing 11 – Examples of the usage of For .. do loops.

if Descending then
for i := Max DownT o Min do
//descending loop
ShowMessage ( IntT oStr ( i ))
else
for i := Min to Max do //ascending loop
ShowMessage ( IntT oStr ( i ))

Conditional Compilation
Morfik Pascal supports conditional compilation of code sections based on constants defined
(through the $Define directive) at compile time. This is useful to include or exclude certain
code sections for debug purposes, for example.

The following is a code snippet which exemplifies the usage of the $IfDef..$Else $EndIf
conditional compilation directives.

{$Define Aardvark}
{$IfDef Aardvark}
ShowMessage('you will see this!');
{$Else}
ShowMessage('you won''t see this!'
);
{$EndIf}

Page 19
Wrapping it up
Morfik Pascal is a full featured, powerful implementation of the Object Pascal language. In the
next chapters you will see more details on certain aspects of the Morfik Pascal language such
as its data types, sub routine and class construction.

category:Programming

Page 20
Pascal Data Types and
Variables

In this article we will take a closer look at the available data types in Morfik Pascal,
how to create new ones and how to use them in declaring variables and
constants.

Data Types
Simple Types
Ordinal Types
Integer Types
Character Type
Enumerated Types
Boolean Type
Subrange Types
Floating Point Types
String Type
String Constants
Structured Types
Arrays
Records
Classes
Sets
File Types
Typed Files
Binary Files
Pointers
The Pointer Type
Nil
Procedural Types
Variables
Variable Declarations
Qualifiers
Typecasts
Helper Methods
Creating a Helper
Method
Wrapping it up

Data Types
In Morfik Pascal, every time you declare a variable you must tell the compiler what its type is.
The type of a variable defines what values it can assume and what operations can be
performed on it during program execution.

Page 21
A type declaration specifies an identifier for the type. It is through this identifier that the type
will be referenced throughout the application.

There are several different major kinds of data types. In this chapter we will review each of
these kinds in detail.

Simple Types
Simple types define ordered sets of values. Let us go through the simple types that are
available to Morfik Pascal and see how these can be an important factor in making your code
clearer and more elegant.

Note
It is important to note that some of the functions designed to work with ordinal
data types are not available to browser side code.

Ordinal Types
Ordinal types represent a sub set of the Simple types. All simple types which are not floating
point numeric types are ordinal types which have a one to one mapping to an element of a
sub set of the set of Integer values (Z).

Integer Types
Morfik Pascal offers a wide choice of Integer types. You will probably find one of them suitable
for each special need. The following table shows each of the integer types which are available
on the server side of your application with the range of values it can store and the format in
which the value is stored.

Type Value Range Format


Shortint - 128 .. 127 Signed 8 bits
Smallint - 32768 .. 32767 Signed 16 bits
Longint - 2147483648 .. 2147483647 Signed 32 bits
Byte 0 .. 255 Unsigned 8 bits
Word 0 .. 65535 Unsigned 16 bits
Integer - 2147483648 .. 2147483647 Signed 32 bits
Cardinal 0 .. 4294967295 Unsigned 32 bits
Int64 - 9.2*10 18 .. 9.2*10 18 Signed 64 bits
LongWord 0 .. 4294967295 Unsigned 32 bits

Due to the limitations of the data types which are supported by the JavaScript engine inside
the browsers a few of these types are not available in the browser side of your application.
The following table lists the Integer types available to the browser side of your application.

Type Value Range Format


Smallint - 32768 .. 32767 Signed 16 bits
Longint - 2147483648 .. 2147483647 Signed 32 bits
Byte 0 .. 255 Unsigned 8 bits
Word 0 .. 65535 Unsigned 16 bits
Integer - 2147483648 .. 2147483647 Signed 32 bits

Note that if you declare a variable of one of the unsupported types on the browser side of
your application, the AppsBuilder will generate a compiler error for it.

Note

Page 22
It is important to realize that the browser side of your application, written with
Morfik Pascal, will be compiled into JavaScript for runtime execution. Because of
this, JavaScript supported types define what can or cannot be supported on the
browser side.
For numeric data, JavaScript has only one data type which is the equivalent of a
floating point Double . All the supported data types on the browser side must be
contained within the range of values covered by a Double .

Character Type
The Char data type is used to store a single character. The character encoding which will be
used is selected when you create your project.

The Char type is an ordinal type since there is a numeric value associated with each character
that is represented in the type. You can obtain this value and the set of characters is ordered
by it.

Enumerated Types
Enumerated types define ordered sets by enumerating the identifiers that represent its
elements. The order of the elements in the set is the same in which they were declared. The
presence of an identifier in the list of elements of an enumerated type is, basically, equivalent
to the declaration of a constant of that type. In Listing 1 there is an example of an
enumerated type which declares an element for day of week and a test sub routine showing
how this type can be used.

Listing 1 – The DaysOfTheWeek 'enumerated type.

T ype
DaysOfT heWeek = ( Sunday , Monday , T uesday , Wednes
day ,
T hursday , Friday , Saturday );

P rocedure test
var
ADay : DaysOfT heWeek ;
// ...
ADay := Monday ;
// ...
case ADay of
Monday : ShowMessage ( 'Monday' );
T uesday : ShowMessage ( 'T uesday' );
Wednesday : ShowMessage ( 'Wednesday' );
T hursday : ShowMessage ( 'T hursday' );
Friday : ShowMessage ( 'Friday' );
end ;
// ...
end ;

All enumerated type elements have a corresponding numeric value, with the first element in
the enumerated type having the value of 0 and all remaining elements having a value equals
to its predecessor plus one.

Note
On the server side of your application you can use the Pred and Succ functions to
obtain the previous and next values in an enumerated type. You can also apply
the Ord function to obtain the numeric value of an enumerated type variable.
These functions are not available on the browser side of the application. Similar
behavior to that of these functions can be obtained however. For example, in
order to obtain the next day in the DaysOfTheWeek set, instead of the Succ
function you could use code such as this:

Page 23
day := DaysOfTheWeek(Integer(day) + 1);
More about the converting between types can be found under the topic of
Typecasting in this chapter.

Boolean Type
The Boolean type is a special, pre-defined, enumerated type which is defined in the System
module of the Morfik Framework. The declaration is the equivalent of the following Morfik
Pascal enumerated type declaration:

T ype
Boolean = ( False , T rue
);

Note
Since Boolean is an enumerated value it is also an ordinal type with False having
the value of zero and True the value of one. On the server side of your application
you can apply the Ord function to obtain the numeric value of a Boolean variable.

Subrange Types
Subrange types define ranges of values within other ordinal types. We can, for example,
define a subrange type called WeekDays as being a range from the DaysOfTheWeek
enumerated type that is shown in Listing 1, as an example of enumerated types. The
following is an example of what such a declaration would look like:

type
WeekDays = Monday .. Frida
y;

A variable whose type has been declared as being a Subrange type will have all the
properties and characteristics of the base type of the Subrange, but will only accept values
which fall within the specified range.

Floating Point Types


Floating point data types are sub ranges of the set of Real Numbers (R). Morfik Pascal
supports several different floating point types, each of them stored in a different
manner/format. The following is a table of the supported data types and their capacities.

Type Range Significant Size


Digits in
Bytes
Single 1.5*10 -45 .. 3.4*10 38 7-8 4
Double 5.0*10 -324 .. 1.7*10 308 15-16 8
Extended 1.9*10 -4951 .. 1.1*10 4932 19-20 10
Currency - 19-20 8
922337203685477.5808
..
922337203685477.5807

Please note that Morfik Pascal uses different division operators, as mentioned in chapter 2,
for integer ("div") and floating point types ("/").

Page 24
Note
It is important to realize that the browser side of your application, written with
Morfik Pascal, will be compiled into JavaScript for runtime execution. Because of
this, JavaScript supported types define that can or cannot be supported on the
browser side.
For numeric data, JavaScript has only one data type which is the equivalent of a
floating point Double . All the supported data types on the browser side must be
contained within the range of values covered by a Double .

String Type
The string type is used to store a list of characters as if to store a word or a sentence. We
can think of this type as an ordered list of characters since the composing characters are
stored in the precise order in which they were stored. The following are examples of declaring
variables of the string type.

var
Str : String ;
Str2 : String =
'Hello! T his is a string!' ;

You can assign values to a string variable by assigning it a list of characters surrounded by a
pair of the single quotes character. Since single quotes are used to delimit the characters that
are being assigned to the string variable, having a single quote character within the character
list becomes a problem as the compiler would interpret it as being the end of the character
list. To work around this small problem, Morfik Pascal uses the same method as most other
Pascal language compilers, to repeat the single quote char indicating that it is to be
interpreted literally and not as a delimiter. The following is an example of how to embed a
single quote in the value assigned to a string variable:

var
s1 : String =
'this is a '' single quote' ;

String Constants
You can declare simple string constants or typed string constants. Typed Constants are
functionally equivalent to initialized variables. The following are some samples of string
constant declarations.

const
Str1 = 'Hello' ;
Str2 : string =
'Hello' ;

Structured Types
Structured types are types which store more than one atomic value. This essentially means
that we are storing more than one value within a single variable. Morfik Pascal allows you to
create structured types which have other structured types within their definition.

Arrays
Arrays are a structured data type which holds a fixed number of elements of a same type,

Page 25
called the base type. Arrays are ordered lists and can be accessed by a numeric index which
will refer to one specific entry in the array. Morfik Pascal allows any range of numbers to be
specified as the indexer of the array. The following are some sample declarations for arrays
types in Morfik Pascal:

type
T ZeroBasedIntegerArray = array [ 0. . 10 ] of
integer ;
T OneBasedIntegerArray = array [ 1. . 10 ] of
integer ;

In the first declaration we are actually specifying an array with eleven elements numbered
from zero to ten.

The following are some sample declarations of Array variables in Morfik Pascal:

var
A1 : T ZeroBasedIntegerArra
y;
A2 : T oneBasedIntegerArray
;
A4 : array [ 2. . 6 ] of
integer ;

Notice that you can directly define a variable as being an array or define it as being of a
pre-defined array type such as the ones presented in this topic.

Once the array variables have been declared you can access the individual array elements by
indexing the variable with the appropriate value such as shown in the following example:

A1 [ 0 ] := 1
;
A2 [ 1 ] := 1
0;

Records
Record is the name we give to structured types which allow us to store multiple elements of
information, with different data types, within a single variable. The declaration of a record
includes an identifier for the type and identifiers and types for each of the elements that
compose the structure. Frequently the component elements of a record are referred to as
fields, much as instance variables of a class are. The following is an example of a record
declaration:

type
T P ersonalData =
record
Name : String ;
Phone : String ;
end ;

Records can also be declared with an added " packed " modifier which instructs the compiler to
optimize memory usage, instead of prioritizing performance. The previous declaration would
then be as follows, if we added the packed modifier.

Page 26
type
T P ersonalData = packed
record
Name : String ;
Phone : String ;
end ;

You can access a field of a record by using the same "." (dot) notation which is used for
objects as show in the following example:

procedure test ;
Var
Client1 : T P ersonalDa
ta ;
begin
//...
Client1 . Name :=
'John' ;
//...
end ;

Classes
Classes are structured types very similar to structures, in many ways. Classes however can
"inherit" fields from other classes and can have procedures and functions as elements.

type
T P ersonalData = class
Name : String ;
Phone : String ;

procedure ChangeName ( ANewName : String );


virtual ;
procedure ChangeP hone ( ANewPhone : String );
virtual ;

end ;

We will see classes in much greater detail in Chapter 5 – Object Oriented Programming with
Morfik Pascal.

Sets
This type, defined by the Set keyword is exactly what its name implies – a set of values which
consists of a subset of the values that can be assumed by the base type.

Morfik Pascal not only implements this type, but a full range of operations which can be
handled on this data type.
The following is a declaration of a Set data type which is based on integer type:

type
T IntegerSet = Set Of
integer ;

Page 27
Literal values can be assigned to Set variables in a very simple and straightforward manner,
as shown in the following example:

Listing 2 – Set declarations and operations

Unit Sets ;

Uses SystemUtilities ;

Interface

type
T ByteSet = Set Of Byte ;

Var
S1 : T ByteSet ;

Implementation

procedure Go ;
var
S2 : Set Of Byte ;
begin
//...
S1 := [ 1 , 2 ];
S2 := S1 + [ 1 , 3 ];
S2 := S1 - [ 1 , 3 ];
S2 := S1 * [ 1 , 3 ];
//...
if S1 >= S2 then ShowMessage (
'superset' );
if S1 = S2 then ShowMessage ( 'equal' );
if S1 <> S2 then ShowMessage (
'unequal' );
if 3 In S2 then ShowMessage ( 'member'
);
end ;

end .

Note
The Set type allows the usage of operators which treat Sets in a special way. In
this example you can see Sets being added together or subtracted from one
another.
These set operations will result in new sets which will hold all the elements of the
two sets, in case of addition or a set with the elements of S1 which are not in S2,
in case of subtraction, for example.

File Types
File types represents a linear sequence of values saved into a file. File types are available
only on the server side of a Morfik application.

Typed Files
File types are declared with a base type which can be just about any fixed size type that can

Page 28
be declared in Morfik, leaving out other File types and dynamically allocated types such as
classes and pointer types. This data type is frequently referred to as a "typed file" since it
references a particular data type (the base type).

Listing 3 – Usage of the a typed file data type.

Unit FileT ypes ;

Interface

type
T IntegerFile = File Of
integer ;

var F1 : T integerFile ;

Implementation

procedure Go ;
Var
F2 : File Of Integer ;
begin
AssignFile ( F1 , 'c:\test.int' );
Rewrite ( F1 );
Write ( F1 , 9 );
CloseFile ( F1 );
end ;

end .

Binary Files
You can also work with binary files, which could be considered a special case of the Type Files
where the base type is Byte . These files are normally used for lower level I/O operations and
everything that goes in and out of them is seen as nothing more than a stream of bytes. The
following would be a declaration of such a binary file.

var
MyFile : File of
byte ;

Pointers
Pointers store the memory address of other variables. Most of the time pointer variables will
hold the address of a dynamically allocated variable.

The following are examples of pointer type declarations, which reference different data types,
including a structure.

type
T P ersonalInfo = record
Name : String ;
Phone : String ;
end ;

T P ersonalInfoList = array [ 1. . 10 ] of

Page 29
T P ersonalInfo ;

PInteger = ^ Integer ;
PCliente = ^ T P ersonalInfo ;
PClientes = ^ T P ersonalInfoList ;

Notice that pointer data types use the caret " ^ " symbol to indicate that they are actually a
reference to a variable which actually holds a value of the base type used in declaring the
pointer.

Listing 4 – Example of pointer usage.

Unit P ointers ;

Interface
//T he next line declares a pointer to an Integer variable

type
PInteger = ^ Integer ;

var
Ptr1 : P Integer ;

Implementation

procedure T est ;
Var
I1 , I2 : Integer ;
Ptr2 : ^ Integer ;
begin
I1 := 1 ;
I2 := 2 ;
Ptr1 := @ I1 ;
//Assign to variable P tr1 the address of I1
Ptr2 := @ I2 ;
//Assign to variable P tr2 the address of I2
//T he next line Assigns to I1 the sum of I1 and I2
I1 := Ptr1 ^ + Ptr2 ^
end ;

end .

Note
Note that in the example in listing 4 variables Ptr1 is declared as being of type
PInteger and Ptr2 is defined as ^ Integer. These types are essentially the same
since PInteger is declared as being ^ Integer.

The Pointer Type


In Morfik Pascal you can declare a variable as being of a type called Pointer . The pointer type
is a generic type, not bound to any base type. It holds a memory address and makes no
assumptions about what is stored in that memory position. The following is an example of a
Pointer type variable.

Page 30
var
Ptr : P ointe
r;

Nil
When a Pointer type variable needs to be "empty" or null, Morfik Pascal provides a predefined
value called Nil . Nil is essentially a Null pointer, a pointer that does not point to any memory
location.

Procedural Types
A procedural type is essentially the same thing as pointer to a function or to a method.
Procedural types are very useful; in fact it is through them that the Morfik Framework handles
events generated by the controls in Forms.

The way in which you declare a procedural type is very similar to writing the header of a
function or sub routine, as you can see in the following example:

T ype
T NotifyEvent = procedure ( Sender : T Object ) of
object ;
FuncT ype = procedure ( Str : string );

In Listing 5 you can see an example of how to declare procedural types, how to assign values
to them and how to use them in calling a function.

Listing 5 – Example of delegate usage.

Unit FunctionT ypes ;

uses SystemUtilities ;

Interface

T ype
T estClass = class
public
procedure T estP roc ( Sender : T Object );
end ;

T NotifyEvent1 = procedure ( Sender : T Object ) of


object ;
FuncT ype = procedure ( Str : String );

Implementation

procedure T estClass . T estP roc ( Sender : T Object );


begin
//...
end ;

procedure MsgFunc ( Str : String );


begin
ShowMessage ( Str );
end ;

Var

Page 31
N1 : T NotifyEvent1 ;

procedure T est ;
Var
T : T estClass ;
N2 : procedure ( Sender : T Object ) of object ;
MsgP roc : FuncT ype ;
begin
N1 := T . T estP roc ;
N2 := T . T estP roc ;
MsgP roc := MsgFunc ;
MsgP roc ( 'Hello' );
end ;

end .

In two variables declared in the example in Listing 5, you can see that the first one as the
keywords "of object" added at the end of the line. The same is true of the procedural local
variable declared inside the Test function. Procedural types declared with "of object" are
references to methods, while those declared without it are references to common procedures
or functions.

Variables
A variable is an identifier (a name, if you will) that we assign to a specific memory location
whose content can be altered. Variables can be defined as being of a standard or
user-defined data type.

Variable Declarations
In Morfik Pascal variable declarations must come at the start of a procedure, function or
method. All variables must be declared before the first line of code which is part of the body of
the function or method.

Variables can be declared one at a time or several at a time. The following sample shows you
both styles of declarations.

var
Int1 : integer ;
Int2 : integer ;
Str1 , Str2 , Str3 :
string ;

Variables can also be declared with their initial values as shown in the following example.

var
Int3 : integer = 10 ;

Str4 : string =
'Hello' ;

Note
Initialized variable declarations will not work for local variables if you have selected
to use Delphi as your backend platform compiler. In this case you can only have
global initialized variables.

Page 32
Variable declarations can have inline structured type declarations in them as can be seen in
the following example.

Var
AP erson : record
Name :
string ;
Phone :
string ;
end ;

Qualifiers
A reference to a variable may contain one ore more qualifiers which alter the meaning of the
identifier. Qualifiers may assume several different forms and in your contact with Morfik Pascal
through out this guide you have already had contact with them. Some examples of using
qualifiers are:
 prefixing a structure or class name to a member name,
 using the "." (dot) notation,

 indexing arrays and


 dereferencing pointer variables. You can see some usages of qualifiers in the following sample:

var
T estObj : T estClass ;
//...
N1 := T estObj . Nam
e;
A2 [ 1 ] := 10 ;
I1 := P tr1 ^ + Ptr2
^;

In all the cases shown in the sample, the meaning of an identifier is changed by a prefix, and
index or an operator (caret ( ^ ) – dereferencing operator).

Typecasts
Typecasts are a way to tell the compiler that you want it to temporarily treat a variable as if it
were of a different type. Typecasts can be accomplished using the name of the type you want
the compiler to consider as the type of the variable as if it were a function. The following is a
small sample of using a typecast to convert an integer to a pointer and a pointer to an
integer.

procedure test ;
var
P : Pointer ;
I : Integer ;
begin
I := Integer ( P
);
P := Pointer ( I
);
//...
end ;

Page 33
Note
No verification is done by the compiler regarding the properness of a typecast. It is
presumed that the developer knows what he is doing when a typecast is
requested.

Helper Methods
Morfik Pascal allows all language types to receive the addition of Helper Methods. Helper
Methods are, essentially, functions which are associated with the type and are available for
calling through a variable or a reference to a type.

Creating a Helper Method


Adding a Helper Method to a type is actually quite simple and can be done from anywhere in
the code where the type is within scope. The following is an example of adding a Method
called ToXString to the Integer data type. This method will return the string representation of
the integer value, with an upper case "X" in front of it.

function Integer . T oXString :


string ;
begin
Result := 'X'
+ Self . T oString ;
end ;

Notice that this Method makes use of another Helper Method of the Integer data type, the
ToString method.

An extensive list of Helper Methods has been introduced into the Morfik Framework in Morfik
2.

Wrapping it up
Morfik Pascal has a complete and sophisticated system for handling data types. In most
respects, while programming in Morfik Pascal and experienced Pascal Developer, should feel
right at home in working with Morfik Pascal.

category:Programming

Page 34
Pascal Subroutines and
Scope

Morfik Pascal has the same subroutine constructs as all the major Pascal
implementations available and then some more. Some additions were made to the
Morfik Pascal language in order to fully support the underlying Morfik language
semantics.

Types of Subroutines
Procedures
Functions
Returning Values
Parameters
Creating a Parameter List
Parameters Passed By Value
Constant Parameters
Parameters Passed By Reference
Output-Only Parameters
Untyped Parameters
External Subroutines
JavaScript Subroutines
Overloading Subroutines
Nested Subroutines and Data Types
Scope Rules
Subroutine (Function/Procedure)
Scope
Class Scope
Module Scope
Public Scope
Wrapping it up

Types of Subroutines
In Morfik Pascal there are two fundamental types of subroutines: Procedures and Functions.
The difference between a Procedure and a Function is whether or not the routine returns a
value.

Procedures
Procedures are subroutines that, by definition, do not return values, (except via input
parameters passed by reference, which is explained later). Since they do not return a value,
procedures cannot be part of expressions.

The following is a short example of a Procedure:

procedure T est ;
Var
F2 : file of Integer ;

Page 35
begin
AssignFile ( F1 ,
'c:\test.int' );
Rewrite ( F1 );
Write ( F1 , 9 );
CloseFile ( F1 );
end ;

Functions
Functions are subroutines that do return values. Because of this, functions can be used within
expressions where you would normally use a literal value.

The following is a short example of a function:

function GetT estString :


String ;
begin
Result := 'T est!' ;
end ;

Returning Values
Returning values from a function can be done in two different ways: through the Result
variable or by assigning a value to the name of the function itself.

In the previous example you can see the use of the Result variable which takes the following
form:

Result := < value >;

You can assign the value you want to return from a function to the function ’ s name, as if it
was a variable. This takes the following form:

FunctionName := < value >


;

If you have chosen to use this method, you cannot read back the value assigned to the
function name. This would be interpreted by the compiler as actually being a recursive call to
the function. In order to get around this limitation, common practice is to create an
intermediate variable which will hold the value until such time as you are ready to exit the
function, keeping the value available for reading. In order to simplify and standardize the
usage of this pattern, Morfik Pascal uses the Result variable. Assigning a value to the result
variable is essentially the same as assigning it to the name of the function but at any time
you can use Result in the right side of an expression, without initiating a recursive call.

Parameters
Passing parameters to subroutines is done through a list which is constructed in a very
specific way.

Creating a Parameter List


A subroutine parameter list is very similar to a sequence of variable declarations. This can be

Page 36
observed in the following example.

procedure T est ( P aram1 : string


; P aram2 : integer );

This simple example shows a parameter list with two parameters of different types. Morfik
Pascal has a number of modifiers which can be applied to parameters to change how they are
handled by the compiler. The following is a sample of all possible forms of declaring
parameters.

procedure
T est ( pValueP arameter1 : Integer ,
Const
pConstP arameter : Integer ,
Var pVarP arameter : Integer ,
Out pOutParameter : Integer ,
Const pConstUntypedP aramter ,
Var pVarUntypedP arameter ,
Out pOutUntypedParameter
)
begin
end ;

There are basically five different kinds of parameters:

1. By Value

2. Constant

3. By Reference

4. Output only

5. Untyped parameter

Parameters can be categorized in the following way:


Any parameter which does not have a Var, Const or Out modifier can be considered a
 parameter passed by value.
Any parameter which has no type definition can
 be considered as an untyped parameter.

Parameters Passed By Value


A parameter passed by value acts as a variable local to the subroutine to which it belongs.
The parameter is initialized to the value passed to the subroutine and though it can be
altered inside the routine, the new value will not persist after the code exits the subroutine.

procedure
ABC ( P aram1 : integer );
begin
Param1 := Param1 * 2 ;
end ;

If no modifier is specified for a parameter it is presumed by the Morfik Pascal compiler to be a


parameter passed by value.

Var

Page 37
I : integer ;
begin
I := 2 ;
ABC ( I );
CallOtherProc ( I
);

The value of variable " I " when the call to CallOtherProc is reached will be 2. The value of the
original variable has not been altered since the ABC routine worked on a copy of the value
held by the original value By value parameters can receive the result of any expression that
yields a compatible value as can be seen in the following example.

ABC ( ( 3 + 6 ) * 3 - 1
);

Constant Parameters
Constant parameters are very similar in usage to value parameters but they cannot be
altered within the subroutine. The main purpose of constant parameters is to serve as
insurance to the developer that when a parameter is not meant to be altered, it is not.

Note
In Morfik 07 the Morfik Pascal compiler will not immediately complain if you try to
alter a constant parameter within a subroutine. When you do a full compile of the
project, however, the backend platform compiler will complain.

Parameters Passed By Reference


Parameters passed by reference, using the Var modifier, should be used whenever a
subroutine needs to return a modified value for one or more of its parameters. By reference
parameters can only be called with the use of variables since any literal expression is
evaluated to a value and would not be addressable in memory to have its content changed.

Usage of by reference parameter within a subroutine is exactly like that of a by value


parameter, except that the value of the variable which was passed as a parameter will be
altered once the execution of the routine concludes. The following is an example of passing a
parameter by reference:

procedure ABC ( var


P aram1 : integer );
begin
Param1 := Param1 * 2 ;
end ;

In this case if we applied the same code that we used to review the workings of by value
parameters we would have a different result.

Var
I : integer ;
begin
I := 2 ;
ABC ( I );
CallOtherProc ( I
);

Page 38
The value of variable " I" when the call to CallOtherProc is made will actually be 4, since inside
the subroutine the value of 2 was multiplied by two and that result was returned in the
parameter declared with the Var modifier.

Output-Only Parameters
Output-only parameters are specifically for returning more than one value from a subroutine.
For returning a single value the norm is to just use a function. When there is a need to return
more than one value from a subroutine, multiple output-only parameters should be used.
Output-only parameters are declared using the Out modifier. Any value the subroutine
receives in an Out parameter is discarded.

Untyped Parameters
When a parameter does not have a predefined data type it can receive any variable or
constant, it cannot receive a literal value, though, as untyped parameters can only be
declared as Var, Const or Out. Morfik Pascal does not allow for By Value un-typed
parameters.

Untyped parameters are passed as memory addresses and it is up to the developer to know
how to handle them within the subroutine.

Note
An untyped parameter can be used as a way of being able to pass parameters of
different types to a subroutine. In many situations the same results can be
achieved by using different overloaded versions of a Procedure or Function.
Though there are situations where you could not accommodate all the necessary
data types with overloaded functions, their usage offers the added benefit of
additional type checking.
For more information see Overloading Subroutines later in this chapter.

External Subroutines
External subroutines can be brought into your Morfik Pascal universe from the Browser or the
intermediate code level on the server side of your application. External subroutines are
declared with the assistance of compiler metadata attributes. The following is an example
how a server side external routine can be imported into your code:

function IntT oStr ( AnInteger : integer ) :


string ;
[ 'external=systemext.pas' ]

JavaScript Subroutines
Sometimes, if you are experienced in using JavaScript, you might want to do some
experimenting with JavaScript code in your Morfik application. It is possible to include inline
JavaScript code on the browser side of your application through the use of JavaScript
subroutines. The following is an example of how to create an inline JavaScript subroutine in
your application.

procedure Go (); javascript ;


(*!

alert('programming in javascript is fun!


');
*)

Page 39
Notice that the body of JavaScript code is actually contained within a multi-line comment,
within your Morfik Pascal code. The JavaScript modifier in the subroutine ’ s declaration
instructs the compiler to look for the comment containing the JavaScript language code, right
after the subroutine ’ s header.

You can also use parameters with your inline JavaScript subroutines. In the next example you
can see the same routine from the previous example, but using a parameter for the string
which is shown, instead of a string literal.

procedure Go ( mymessage : string


); javascript ;
(*!
alert(mymessage);
*)

Note
The inline JavaScript code is not checked by the Morfik Pascal compiler so it is
entirely up to the developer to make sure that the code is correct or runtime errors
might occur.

Overloading Subroutines
In Morfik Pascal it is possible to have several different subroutines with the same name, as
long as they have different parameter lists. This is called Overloading and can be really useful.
Overloaded subroutines must be marked with the overload modifier. The following is an
example of how to use subroutine overloading.

function toString ( AnInt : Integer ) : string ;


overload ;
begin
Result := IntT oStr ( AnInt );
end ;

function toString ( AFloat : Double ) : string ;


overload ;
begin
Result := FloatT oStr ( AFloat );
end ;

Note
The addition of Overloading capabilities to the underlying Morfik semantic
structure, which is the basis for Morfik Pascal, was done at the end of the product
development cycle, for Morfik 07. This means that this feature is not exploited to
its full potential by the Morfik Framework itself.
In future releases of Morfik WebOS AppsBuilder you will, probably, see this feature
being more widely used.

Nested Subroutines and Data Types


Morfik Pascal fully supports nesting subroutines within one another. You can also have nested
data types, i.e. data types which are declared within a subroutine. The following example
shows how the syntax for these two features is implemented in Morfik Pascal.

Page 40
procedure
T est1 ( Param1 : integer );
//Nested data type declaration
type
PInteger = ^ integer ;

//Nested subroutine
procedure T est2 ( Param2 :
String );
begin
ShowMessage ( P aram2 );
end ;

Var
P : Pinteger ;
begin
P := Param1 ^;
T est2 ( IntT oStr ( P ^));
end ;

Scope Rules
A reference to an identifier, within an application, must happen within that identifier ’ s
declaration scope. The following are the main scope definition rules for Morfik Pascal.

Subroutine (Function/Procedure) Scope


Subroutine scope is defined by the boundaries of the subroutine itself. Any variables, data
types, and nested subroutines it declares will be visible only from within that subroutine. A
nested subroutine will have access to any identifier declared prior to its declaration, within
the surrounding subroutine.

A nested subroutine can define an identifier with the same name of an identifier declared in
the subroutine in which it is nested. The innermost variable will then hide the outermost one.

Class Scope
An identifier declared within a class is visible to all members of the class and its descendants.
This scope included instance variables, methods and properties. The Subroutine Scope rules
apply to all method declarations.

Module Scope
Identifiers (variables, data types, subroutines, classes) declared in the implementation
section of a module are visible within the module in which they are declared. They will be
visible to any subroutines and classes declared within the same module.

Public Scope
Identifiers (variables, data types, subroutines, classes) declared in the interface section of a
module are visible within the module in which they are declared and in any module that
imports that module. They will be visible to any subroutines and classes declared within the
same module and within the modules that have imported the module in which they are
declared.

This is the broadest scope level in Morfik Pascal.

In Listing 1 you can see examples of all the possible scope levels in Morfik Pascal.

Listing 1 – Possible Scopes in Morfik Pascal

Unit MyModule ; // Module/Public Scope

Page 41
Interface
// Whatever is defined in the interface has public scope
(**
MyInt is available within this module and in any module

that imports this module, since it is declared in the interface

section. (P ublic Scope)


*)
var
MyInt : integer ;

T ype
AClass = class // Class Scope
(**

Class level MyInt is available only within this class since

it is declared private. Within the class it hides the module

scope MyInt
*)
private
MyInt : integer ;

(**
Method OuterFunc defines a new scope
*)
public
function AClass . OuterFunc : String ;
//Method Scope

end ; // class definition

(**

GlobalProc is available within this module and in any modul


e

that imports this module because it is declared in the interfa


ce
section..
*)
procedure GlobalP roc ; //Function/P rocedure Scope

implementation

(**
AnotherInt is available only within this module since it
is declared in the implementation section. (Module Scope)
*)
Var
AnotherInt : integer ;

(**
Method OuterFunc defines a new scope
*)
function OuterFunc : String ; //Method Scope
(**
Method level MyInt is available only within this method.
Within the method it hides the Module and Class

Page 42
scope variables of the same name.
*)
Var
MyInt : integer ;

function NestedFunc : String ;


//Nested Function Scope
(**

Nested function level MyInt is available only within this


function. Within the function it hides the Module, Class
and method scope variables of the same name.
*)
Var
MyInt : integer ;
begin //Body of the nested function
end ;

begin //Body of the outer function


end ;

(**

GlobalProc is available within this module and in any modul


e

that imports this module because it was previously declared i


n
the interface section.
*)
procedure GlobalP roc ; //Function/P rocedure Scope
(**

P rocedure level MyInt is available only within this P rocedur


e

Within the Procedure it hides the Module scope variable of


the same name. (P ublic Scope)
*)
Var
MyInt : integer ;
begin
end ;

(**
InternalP roc is available only within this module since it

is declared only in the implementation secion. (Module Sco


pe)
*)
procedure InternalP roc ; // Function/P rocedure Scope
begin
end ;

end .

Wrapping it up
Morfik Pascal offers a powerful array of features from which to build your application. These

Page 43
include extensive support for subroutines including overloading and nesting.

category:Programming

Page 44
Pascal Object Oriented
Programming

We continue our trip through the world of Object Oriented Programming (OOP)
with Morfik Pascal. After a quick review of what exactly is OOP, this chapter will
provide you will a general overview of Morfik Pascal

What is Object Technology?


Object Oriented Programming
What Are Objects?
Basic Concepts
Encapsulation
Inheritance
Polymorphism
Classes
Class Declarations
Instantiating Objects from a
Class
Message Passing and Methods
Constructors and Destructors
Method Overload
Forward Class Declaration
Properties
Read Only properties
Write Only Properties
The Self Parameter
Class References (Metaclasses)
Inheritance
Virtual Methods
Overrides Methods
Abstract Methods
Class Methods
Helper Methods
Wrapping it up

What is Object Technology?


In a very simple definition, Object Technology (OT) is a set of methodologies for analysis,
design and programming whose goal is to model the characteristics and behaviors of real
world objects. In this chapter we will focus on the programming aspects of Object Technology,
more commonly known as Object Oriented Programming.

Object Oriented Programming


Morfik Pascal is built on the most common dialects of Pascal found in the world today, with
some added features. Over the recent years Pascal has had great advances as a language
and Morfik Pascal reflects that. Through all of its development, one of the main goals in

Page 45
creating Morfik Pascal was to provide a powerful, yet easy to use language for the
development of Web applications. Towards that end, Morfik Pascal was developed into a
powerful object oriented language which can hold its own against languages that are much
more widely known for their OOP features.

Today, no large scale application development project is undertaken without the use of OOP.
All major tools and languages support the concepts and they have been widely accepted into
mainstream for several years.

In order to be considered Object Oriented, a language must have built-in support for three
concepts:

Encapsulation – Modularization and the ability to hide implementation details.

Inheritance – Defining characteristics and implementation objects based on pre-existing


classes so that code can be easily and successfully reused

Polymorphism – the same message, when sent to different objects provokes different
responses, depending on the nature of the object that receives the message.

What Are Objects?


Objects are models we create to represent real world entities in software design. In everyday
life you are surrounded by object all the time. Look around and you will see: cars,
refrigerators, chairs, cats and dogs. All of these are objects.

Software applications also have objects such as buttons in the interface, grids and their cells,
menus, string lists, etc. These objects, just as their real world counterparts, have states and
behaviors. You can represent these characteristics (and their change over time – ie. states)
and behaviors with software structures which are generally called objects.

In its daily comings and goings a car can be modeled as a car. An object has characteristics,
which change over time defining its states (speed, aim, fuel consumption, etc) and behaviors
(engine off, engine on, accelerate, turn left, break, etc.).

You drive to the office where you work with clients. The way you interact with clients can,
also, be modeled through an object. The client also has characteristics (Current Phone,
Current Address, etc) and behaviors (Move, Close Deal, etc).

Basic Concepts
In programming, an object ’ s characteristics and state are defined by its instance variables
(sometimes called member variables, or fields). Instance variables should always be private
so as to not be accessible from outside of the object. Public instance variables are accessible
by code which does not belong to the object ’ s class. This should be avoided as we will see
when looking into encapsulation.

The behaviors of an object are defined by its methods. Methods handle all interaction with the
object and operate on the instance variables, altering the object ’ s state and even creating
new objects.

In figure 1 you can see a simple graphical representation of an object. This picture represents
the conceptual structure of an object, which is very similar to that of a cell. As in a cell, an
external structure (the membrane) is the only part to have contact with the outside world and
protects the nucleus.

Figure 1 – Graphical representation of an Object. The object ’ s instance variables are


encapsulated within it, surrounded by the object ’ s methods. Except on very specific cases
the object ’ s methods should be the only the only venue available for other objects to access
or alter instance variables. In Morfik Pascal it is possible to have instance variables declared
as public or published, except where absolutely necessary (like for IDE interaction with a
Form ’ s controls) this should be avoided as these variables will be globally available to other
objects. Access levels and member visibility will be seen in greater detail in this chapter.

Encapsulation
The basic idea behind the concept of Encapsulation is that the less that a user of objects you

Page 46
create knows about how they are implemented, the less he/she will be affected by changes
to that implementation.

A person that knows nothing about cars does not conclude anything about certain noises that
the engine makes. A person with a bit more experience could be tempted to guess at the
cause of a problem based on such noise and be frustrated by a new type of engine.

Please, don ’ t image that this will help in hiding problems with your code. The goal is to avoid
problems by avoiding a situation where developers create code that depends on how your
objects are implemented. This allows you to change how the objects are implemented without
adversely affecting code created by third parties.

Inheritance
To put it simply, inheritance is the capability of creating new types of objects (called Classes)
from previously existing types. With inheritance we re-use a previously existing class ’
(ancestor) functionality, add new functionality and, if necessary, alter some of the class ’
behavior, thus creating a new Class (descendant) with a huge part of its functionality already
tried and tested.

Before the advent of object oriented programming and the widespread use of inheritance,
code reuse was mostly done by the creation of function libraries or by the old cut-and-paste
method. The cut-and-paste approach to code reuse normally requires that the copied code
suffer small modifications and is very prone to introducing bugs in an application.

Polymorphism
Polymorphism is the ability to treat objects of different types as if they were all of the same
type, provided that they have a common ancestor. An example of this capability is that I can
write a function which takes a Form object as a parameter and then pass any of the forms in
an XApp to that function. This is possible because all forms in an XApp are descendant classes
of the Form class.

Classes
Morfik Pascal has full support for object oriented programming as it implements the Object
Pascal concepts and constructs as adopted by Delphi and FreePascal which are the most
commonly used Pascal compilers..

Classes are essentially the templates from which we create new objects in our applications. A
class represents the definition of what instance variables and methods a certain type of
object will have. A class is not an object in itself, but the recipe to create new objects. Actual
objects are made by creating them from a class definition in a process called instantiation.
This is very similar to how you can create several cakes from the same recipe.

In the Morfik Framework, except for a few of the higher level classes such as the Form and
visual controls, all class names are prefixed with the letter "T". This is a convention from the
Pascal world which was adopted by Morfik its purpose is to make it simpler to differentiate
when you are dealing with a class and when you are dealing with an object (an instance of a
class).

Class Declarations
Class declarations in Morfik Pascal are very similar to their counterparts in Delphi and
FreePascal, in keeping with the spirit of making the learning of the syntax as easy as possible
for developers coming from a previous Pascal background. You can see a class declaration in
Listing 1.

Listing 1 – A class declaration in Morfik Pascal

Unit ClassDecl ;

Interface

T ype
BaseClass = class ( T Object )
private

Page 47
fSomething : String ;
public
constructor Create ( aSomething : String );
Destructor Destroy ; override ;
Function GetSomething : String ; virtual ;

end ;

Implementation

constructor BaseClass . Create ( aSomething :


String );
begin
Inherited create ;
fSomething := aSomething ;
ShowMessage ( 'creating BaseClass...' );
end ;

destructor BaseClass . Destroy ;


begin
ShowMessage ( 'destroying BaseClass...' );
Inherited Destroy ;
end ;

function BaseClass . GetSomething : String ;


begin
Result := fSomething ;
end ;

end .

The class presented in this sample is a very simple one.

The first line of code in Listing 1 reads as:

BaseClass = Class
( T Object )

This informs the compiler that the class called BaseClass is a descendant of the TObject class

Member elements of a class can be variables, functions and procedures as well as properties.
Variables declared inside a class are called instance variables (or fields, or member variables),
while functions and procedures are called methods. We will see more about properties further
ahead in this chapter.

All members of a class can be declared with one of several scope modifiers. These include:
Private, Protected, Public and Published. The following table describes the scope defined by
each of these modifiers.

Visibility Scope
Modifier
Private Restricted to the current class, but can be accessed by
other elements declared within the same module.
Protected Restricted to the current class, but can be accessed by
other elements declared within the same module and
from within descendants of this class.
Public Accessible from all modules in the project, which have
imported the current module.
Published The same as Public but used for the declaration of

Page 48
Controls and Event Handlers which are accessed by the
visual editors within the Morfik IDE.

Method and
instance variable declarations using these modifiers take the following form :

private function T est : String ;

protected function T est : String ;

public function T est : String ;

published procedure MyEventHandler ( Event : T DOMEvent ); message ;

public
function T est : string ;
function T est2 : string ;

public
Str1 : string ;
Int2 : integer ;
private
Int3 : integer ;

Note that methods which are created to handle events triggered by controls are not only
declared as Published but they also get an additional modifier: "message".

Note
In Morfik Pascal it is not necessary to inform an access modifier for each element in
a class. You can use the modifier by them selves to specify the start of a section of
the class declaration which will have that specific access level. The section will end
where another access modifier is found, starting a new section.

Instantiating Objects from a Class


The process of creating objects is called instantiation. We instantiate an object based on a
class definition. To better illustrate this, let ’ s take a simple example. In listing 2 you can see
the definition of a simple class, called TPoint. This class defines objects capable of describing a
point in a two dimensional space.

Listing 2 – TPoint Class definition.

Unit geometry ;
T P oint = class ( T Object )
private
X : integer ;
Y : integer ;
public
procedure Move ( XValue , YValue : integer );
end ;

procedure
T P oint . Move ( XValue , YValue : integer );
begin
X := XValue ;
Y := YValue ;

Page 49
end ;

function NewP oint : T P oint ;


var
Pt : T P oint ;
begin
Pt := T P oint . Create ;
Pt . Move ( 10 , 10 );
Result := P ;
end ;
end .

Notice that in Listing 2 there is a function called NewPoint . This function instantiates a new
TPoint object through the use of the New operator and assigns it to a local variable called Pt .
Once the object has been created its methods can be called as the call to the Move method
demonstrates. This call, based on the methods definition, should set the X and Y instance
variables of the object to the value of 10.

Message Passing and Methods


If object A wants object B to perform some action on its behalf, in OT jargon, it should send a
message to object B. The message is sent by calling one of object B ’ s methods. It should be
noted that calling a method in Morfik Pascal is very similar to calling a sub routine or a
function. In some programming languages methods are called member functions of a class.
This should give you a general idea of how close the concepts are.

Figure 2 – Message sending/Method invocation between objects.

Constructors and Destructors

Page 50
Class instance variables normally require some initialization code and, also frequently, some
clean up code. This initialization and clean up are done through two special kinds of methods:
Constructors and Destructors. Constructors are the methods which are called when a class
instance variable is created, while destructors are called whenever a class instance is
destroyed.

Listing 3 – A Morfik Pascal class implementing a Constructor and a Destructor.

type
T estClass = class
public
constructor Create ;
destructor Destroy ; Override ;
end ;

constructor T estClass . Create ;


begin
inherited Create ;
//call to the ancestor's Constructor
//... instance initialization
end ;

destructor T estClass . Destroy ;


begin
//... instance clean up code
inherited Destroy ;
// call to the ancestor's Destructor
end ;

From within a Morfik Pascal class method you can call a method that is inherited from the
ancestor (also called Base) class, through the use of the inherited keyword as shown in
Listing 3.

Method Overload
Morfik Pascal supports having more than one method, within the same class, with the same
name, as long as they have different parameter lists. The different methods are implicitly
identified by the compiler through the complete method signature which is composed of the
method name plus its parameter list.

Let us bring together the concepts of a constructor and of method overloading to


demonstrate how they can be used. In Listing 4 we extend a bit the definition of our TPoint
class to include two constructors, thus using method overload. We also introduce a second
function, called NewPoint2 , for the creation of TPoint objects. This second function uses the
constructor definition that takes two integers as parameters, instead of calling the one that
takes no parameters and then calling the Move method.

Listing 4 – TPoint Class definition, revised.

Unit geometry ;

Interface

type
T P oint = Class ( T Object )
private
X : integer ;
Y : integer ;
public
procedure Move ( XValue , YValue : integer );

Page 51
constructor Create ; overload ;
constructor Create ( XValue , YValue : integer );
overload ;
end ;

implementation

procedure T P oint . Move ( XValue , YValue : integer );


begin
X := XValue ;
Y := YValue ;
end ;

constructor T P oint . Create ; overload ;


begin
inherited Create ;
X := 1 ;
Y := 1 ;
end ;

constructor T P oint . Create ( XValue , YValue : integer );


begin
inherited Create ;
X := XValue ;
Y := YValue ;
end ;

function NewP oint : T P oint ;


var
Pt : T P oint ;
begin
Pt := T P oint . Create ;
Pt . Move ( 10 , 10 );
Result := P ;
end ;

function NewP oint2 : T P oint ;


var
Pt : T P oint ;
begin
Pt := T P oint . Create ( 10 , 10 );
Result := P ;
end ;

end .

Forward Class Declaration


There are situations when one class in your application needs to reference another class
which, in turn references the first one. When working with Morfik you always need to have
any data types declared prior to their use, which would make this scenario impossible. In
order to work around this problem you can use what is called a forward class declaration as
can be seen in Listing 5.

Listing 5 – Usage of Forward Class Declarations

Unit
ClassForwardDeclarations ;

Page 52
interface

T ype
Class1 = Class ;

Class2 = class
Field1 : Class1 ;
end ;

Class1 = class
Field1 : Class2 ;
end ;

implementation

end .

The insertion of the line with the forward declaration, as show below, satisfies the compiler ’ s
need to know all referenced type before their usage.

Class1 = class
;

At this point the compiler knows that Class1 is a class and that it will be detailed later. If the
actual declaration is not found when the application is compiled an error will result.

Properties
Properties look very much like instance variables and are used as those, however they are
actually implemented through two sub routines, one for reading and one for setting the value
that is associated with them. Normally a property will be directly related with an instance
variable which holds its value.

Why use properties and not just plain instance variables? Properties have their values set
and read through what we call access methods giving us encapsulation of the underlying
instance variable and allowing us to take whatever appropriate action whenever their value is
read or changes. In listing 6 you can see how to add properties to a class, with Morfik Pascal.

Listing 6 – TPoint class with added properties.

Unit Geometry ;

T ype
T P oint = class ( T Object )
private
FX : integer ;
FY : integer ;
protected
function GetX : integer ;
procedure SetX ( Value : integer );
function GetY : integer ;
procedure SetY ( Value : integer );
public
property X : integer read GetX write SetX ;
property Y : integer read GetY write SetY ;

procedure Move ( XValue , YValue : integer );


constructor Create ; overload ;

Page 53
constructor Create ( XValue , YValue : integer );
overload ;
end ;

implementation

procedure T P oint . Move ( XValue , YValue : integer );


begin
X := XValue ;
Y := YValue ;
end ;

constructor T P oint . Create ; overload ;


begin
inherited Create ;
X := 1 ;
Y := 1 ;
end ;

constructor T P oint . Create ( XValue , YValue : integer );


begin
inherited Create ;
X := XValue ;
Y := YValue ;
end ;

function NewP oint : T P oint ;


var
Pt : T P oint ;
begin
Pt := T P oint . Create ;
Pt . Move ( 10 , 10 );
Result := P ;
end ;

function NewP oint2 : T P oint ;


var
Pt : T P oint ;
begin
Pt := T P oint . Create ( 10 , 10 );
Result := P ;
end ;

function T P oint . GetX : integer ;


begin
Result := FX ;
end ;

procedure T P oint . SetX ( value : integer );


begin
FX := Value ;
end ;

function T P oint . GetY : integer ;


begin
Result := FY ;
end ;

procedure T P oint . SetY ( value : integer );


begin

Page 54
FY := Value ;
end ;

end .

Note
In Morfik Pascal you can have properties which are read only or write only. This is
done by simply not specifying the underlying function or procedure which would
handle that task for a specific property.

Read Only properties


You can create a read only property in a class by simply not specifying a write method for the
property as shown in the following code snippet.

public
property Name : String read
GetName ;

Write Only Properties


You can create a write only property in a class by simply not specifying a read method for the
property as shown in the following code snippet.

public
property Name : String write
SetName ;

The Self Parameter


Every method in a class receives an invisible parameter called Self . This parameter is a
reference to the exact object through which the method is being called and can be used to
disambiguate variable names. Suppose that in a class with an instance variable called FX, you
had a method with a local variable called FX; how do you differentiate between them? You
can see a sample of how to use the Self parameter in listing 7.

Listing 7 – Usage of Self in the TPoint class.

Unit Geometry ;

T ype
T P oint = class ( T Object )
private
FX : integer ;
public
function GetX : integer ;
procedure SetX ( value : integer );
property X : integer read GetX write
SetX ;
end ;

implementation

Page 55
function T P oint . GetX : integer ;
Var
FX : integer ;
begin
FX := 2 * 15 ;
// assigns value to the local variable
// unrelated code
Result := Self . FX ;
end ;

procedure T P oint . SetX ( value : integer );


begin
FX := Value ;
end ;
end .

Class References (Metaclasses)


Class references allow us to perform operations on Classes instead of on objects (class
instances). This is very useful when you need dynamically choose what kind of class you are
going to use to instantiate an object.

In Listing 8 you can see a function which based on a string parameter, the kind of food an
animal eats, chooses which class of animal to instantiate.

Listing 8 – Class Reference declaration.

Unit Animals ;

Interface

type

Animal = class
public
class function FoodT ype : String ; virtual ;
end ;

AnimalClass = class of Animal ;

mouse = class ( Animal )


public
class function FoodT ype : String ; override ;
end ;

cat = class ( Animal )


public
class function FoodT ype : String ; override ;
end ;

dog = class ( Animal )


public
class function FoodT ype : String ; override ;
end ;

function GetAnimalWithFoodT ype ( food : String


) : AnimalClass ;

Page 56
procedure T estAnimal ;

Implementation

class function Animal . FoodT ype : String ;


begin
Result := '' ;
end ;

class function Mouse . FoodT ype : String ;


begin
Result := 'cheese' ;
end ;

class function Cat . FoodT ype : String ;


begin
Result := 'fish' ;
end ;

class function Dog . FoodT ype : String ;


begin
Result := 'slippers' ;
end ;

function GetAnimalWithFoodT ype ( food : String


) : AnimalClass ;
begin
if food = mouse . FoodT ype then
Result := mouse
else
if food = cat . FoodT ype then
Result := cat
else
if food = dog . FoodT ype then
Result := dog
end ;

procedure T estAnimal ;
var
MyP etClass : AnimalClass ;
MyP et : Animal ;
begin
MyP etClass := GetAnimalWithFoodT ype ( 'cheese' );
MyP et := MyPetClass . Create ;
MyP et . Free ;
end ;

end .

Inheritance
Inheritance as we have seen in a method through which we can define new and more
sophisticated classes of objects, based on pre-existing classes. Let us consider another
simple animal example. Most species of felines are generally referred to as cats or big cats.
One could conceive that if we had an object representation of a cat it would be a good
starting place to create an object representation for, say, a lion. In Morfik Pascal, as we have
seen when we previously discussed class declarations you can specify class inheritance when
you declare a new class.

In listing 9 you can see a small section of code with the declaration of the Lion class as a

Page 57
descendant from the Cat class.

Listing 9 – Lion and Cat classes

Cat = class
// Cat member variables and methods
end ;

Lion = class ( Cat )

// Lion additions to the members of the Cat class


end ;

In keeping to a simplistic view we can suppose that the Cat class would have all the instance
variables and methods to correctly describe the characteristics and behaviors of a generic
feline. This being the case all our Lion class would have to redefine is how it describes its
visual representation to the outside world.

Note
Note that by specifying a class name in parenthesis when we declare a class you
define that your class is a descendant of the class referenced.

To more clearly exemplify this extension by inheritance method of attacking code reuse, we
will examine a TPoint3D class which will be a descendant of the TPoint class we have seen
previously in this chapter. The TPoint3D class will simply add an extra coordinate Z which is
necessary to plot a point in three dimensional space.

Listing 10 – The TPoint3D class definition.

T P oint3D = class ( T P oint )


private
FZ : integer ;
protected
function GetZ : integer ;
procedure SetZ ( value : integer );
public
property Z : Integer read GetZ write SetZ ;

constructor Create ( XValue , YValue , ZValue : integer );


overload ;

procedure Move ( XValue , YValue , ZValue : integer );


overload ;

end ;

//...

constructor
T P oint3D . Create ( XValue , YValue , ZValue : integer );
begin
inherited Create ( XValue , YValue );
FZ := ZValue ;
end ;

procedure T P oint3D . Move ( XValue , YValue , ZValue : integer );

Page 58
begin
inherited Move ( XValue , YValue );
FZ := ZValue ;
end ;

function T P oint3D . GetZ : integer ;


begin
Result := FZ ;
end ;

procedure T P oint3D . SetZ ( value : integer );


begin
FZ := Value ;
end ;

The TPoint3D class adds an instance variable to the original TPoint class and overloads some
the methods in the TPoint class adding new versions which take three parameters.

Since the instance variables of our original TPoint class were all declared as private, we can ’ t
access them even within a descendant class. To work around this limitation we can use the
preexisting ones, as you can see in listing 10 ’ s implementation of the Move method for the
TPoint3D class which calls the Move method of its ancestor class and thus sets the X and Y
coordinates before setting its own Z coordinate.

Note
If there is a possibility that complex descendants of a class you are writing will be
created, you should make the instance variables protected , instead of private .

Virtual Methods
A method can be declared as Virtual by adding the Virtual modifier to its declaration in the
class. When a Virtual method is called the real type of the object contained in the variable and
not the type of the variable itself is used to identify which method is called.

When you assign a Cat object to a variable of type Animal (ancestor of Cat) and you call a
method through that variable if the method was not marked as Virtual the version of the
method which will get called will be the one defined in the Animal class. If the method was
originally marked as Virtual and is redefined in the Cat class, however, it will be the version
introduced in the Cat class that will be called.

Overrides Methods
When creating a descendant class from a class which has methods marked as Virtual you can
redefine those methods and be sure that the correct version of the methods will always get
called by adding the overrides modifier to the new method declarations.

In Listing 11 you can see a new version of the Animals module with a Virtual Eat method
added to the Animals class and reintroduced with the override modifier in the Cat and Dog
classes.

Listing 11 – Animals module with virtual and override methods introduced into the
Animals, Cat and Dog classes.

Unit Animals ;

Interface

type

Page 59
Animal = class
protected
QtyEaten : integer ;
public
class function FoodT ype : String ; virtual ;
procedure Eat ; virtual ;
end ;

AnimalClass = class of Animal ;

mouse = class ( Animal )


public
class function FoodT ype : String ; override ;
procedure Eat ; override ;
end ;

cat = class ( Animal )


public
class function FoodT ype : String ; override ;
procedure Eat ; override ;
end ;

dog = class ( Animal )


public
class function FoodT ype : String ; override ;
procedure Eat ; override ;
end ;

function GetAnimalWithFoodT ype ( food : String


) : AnimalClass ;

procedure T estAnimal ;

Implementation

class function Animal . FoodT ype : String ;


begin
Result := '' ;
end ;

procedure Animal . Eat ;


begin
QtyEaten := QtyEaten + 1 ;
end ;

class function Mouse . FoodT ype : String ;


begin
Result := 'cheese' ;
end ;

procedure Mouse . Eat ;


begin
QtyEaten := QtyEaten + 1 ;
end ;

class function Cat . FoodT ype : String ;


begin
Result := 'fish' ;
end ;

Page 60
procedure Cat . Eat ;
begin
QtyEaten := QtyEaten + 1 ;
end ;

class function Dog . FoodT ype : String ;


begin
Result := 'slippers' ;
end ;

procedure Dog . Eat ;


begin
QtyEaten := QtyEaten + 1 ;
end ;

function GetAnimalWithFoodT ype ( food : String


) : AnimalClass ;
begin
if food = mouse . FoodT ype then
Result := mouse
else
if food = cat . FoodT ype then
Result := cat
else
if food = dog . FoodT ype then
Result := dog
end ;

procedure T estAnimal ;
var
MyP etClass : AnimalClass ;
MyP et : Animal ;
begin
MyP etClass := GetAnimalWithFoodT ype ( 'cheese' );
MyP et := MyPetClass . Create ;
MyP et . Free ;
end ;

end .

Abstract Methods
In Morfik Pascal you can create methods without any implementation; these are generally
called abstract methods . These methods are placeholders, usually designed to ensure that all
descending classes have such a method. A call to such a method will result in a runtime error.
All classes which wish to make use of this method must override the inherited method.

An abstract method should have the modifier Abstract applied to it. The Animals module which
is shown in Listings 8 and 11 has an example where such a method could be used in the
Animal class: the FoodType shared function. Notice that this method returns an empty string
and essentially functions as a placeholder to be overridden in descendant classes. If the
Abstract modifier where used the declaration would look like this:

class function FoodT ype : string ;


Abstract ;

Note

Page 61
Abstract methods are especially interesting when you a creating a class for the
sole purpose of being the common ancestor of two or more classes.
It is important to note, however, that in Morfik 07 abstract methods are not
supported in browser side code.

Class Methods
Class methods are methods which are declared with the Class modifier and which can be
invoked through a class reference, without the need to actually have an instance variable.
You can see an example of this in the Animals sample module used to explain class
references. See listings 8 or 11 for a full example. Next you can see the header of a class
function extracted from that listing.

class function FoodT ype :


String ;

One use of Class methods can be to group together a set of functions which are related to a
certain subject but which would not necessarily constitute an object in itself. In Listing 12 you
can see an example of what such a class would look like and a small test sub routine showing
how to use it.
Listing 12 – A class with all methods marked as class methods.

T String = class

Class function length ( Str : string


) : integer ;

class function UpperCase ( Str : string ) :


string ;

class function LowerCase ( Str : string ) :


string ;

end ;

//...

class function length ( Str : string ) : integer ;


begin
Result := Length ( Str );
end ;

class function UpperCase ( Str : string ) : string


;
begin
Result := UpperCase ( Str );
end ;

class function LowerCase ( Str : string ) : string


;
begin
Result := LowerCase ( Str );
end ;

procedure T estT SringClass ;


Var
Str : string = 'my test string' ;

Page 62
StringLength : integer ;
begin
StringLength := T String . Length ( Str );
Str := T String . UpperCase ( Str );
end ;

Note
Initialized variables as seen in procedure TestTStringClass of Listing 12 will not
work if you have chosen to use Delphi as your platform backend compiler.

Helper Methods
Helper Methods can be attached to any data type, however, as classes already have methods
of their own it is important to consider how they interact.

If a Helper Method is declared with the same name of a method which is declared within the
class, the class' internal method will have precedence and hide the Helper Method. Helper
Methods cannot then, be used to change established class behavior as that would violate
encapsulation of the class. In line with this respect to class encapsulation a Helper Method
cannot access properties of a object which are not declared as public in its class, even if it is
being attached to that class.

Two main purposes guided the creation of Helper Methods. The simplest of them was to allow
for better usage of code completion by developers when working with fundamental types
such as strings, integers, etc. The second was to allow seamless integration of new data
types and classes to the entire Morfik Framework. An example of the later would be, for
example, to create a complex number data type and then have a new method, called
"ToComplex" attached to the string type. In this case, all string variables would automatically
expose the functionality of converting their values to complex numbers.

Note
Helper Methods were introduced in the Morfik 2 release cycle and are only
available in Morfik AppsBuilder, version 2 or higher.

Wrapping it up
Morfik Pascal offers a wide range of Object Oriented technology features which allow
developers to be very productive. Most features found in today ’ s most used programming
languages are a part of Morfik Pascal and you should feel free to explore new possibilities.
category:Programming

Page 63
What's New

Morfik's new Release 2 of the Morfik Web Development platform (codename M2) is
available as two separate products: Morfik AppsBuilder BX (for Basic programmers)
and Morfik AppsBuilder FX (for Pascal programmers). They are in essence direct
descendants of Morfik’s WebOS AppsBuilder Web development environment and
toolset and have been created to address developers with different needs.

Morfik Web Applications can be used in two variations: a hosted cloud-computing


model, in which a Morfik agent handles server management, and a more
traditional you-do-it-all model.

In the Cloud Computing model of deployment, a Morfik application can start by


using the pre-defined services provided by the Morfik agent that encompasses
most needs of interactive websites allowing the user to focus on creating the
browser side of the website/application. By providing database access, web
service proxying, sending emails, and user authentication capabilities, the Morfik
agent frees the user from the hassles of server maintenance and the need to
know how to do server-side programming. This is the ideal solution for users that
are looking for the quickest, easiest way to create an interactive online presence.

In the more traditional Web Services model, the user can create his/her own Web
services and publishes APIs for other sites/applications to call their applications,
deployed to any server running Windows or a supported Linux distribution. This
makes this the ideal option for Intranet deployments and for ISVs that want to
develop Web-based applications.

The following is a list of the major new features announced with Release 2 with a
short description grouped by the product it applies to.

Themes and Theme-Aware Controls


AppsBuilder gives the developer access to themes, which are organized color palettes and
font styles, assigned to different default settings. Themes give the user unprecedented ease
in customizing the look of a Morfik-built application or website without interfering with
application logic. Themes you add or change are available to you in all your applications. If
your Marketing department wants to tweak all your applications to fit a new corporate logo,
you can do it in minutes.

Custom themes used in an application are stored within the project so that it can be properly
moved to another machine without impact on how the application looks.

For more information see: Working with Themes

New & Custom Controls


Calendar and ProgressBar controls have been added.
Morfik 2 introduces a new architecture for custom controls, allowing indepedent developers to
develop controls for Morfik. The GoogleMap and Wysiwyg controls are the first controls to
take advantage of this architecture.

Morfik Effects
Special graphics effects have been added to all controls where they made sense and to Form
Bands. By combining design and graphics tools right into the Form designer Morfik now allows
you to create great looking applications and websites easily and quickly.

For further information see: Control Effects

Split-able Containers
By right-clicking on any container in a Morfik AppsBuilder R2 Form you can select an option to
split it either vertically or horizontally. This applies to the Form's bands as well.

For more information see: Defining a Form Layout

Page 64
Image Bundling
In order to optimize performance in Morfik applications the compiler now bundles together the
images it generates for the Morfik Effects. This allows smoother rendering of the web pages
that use Morfik Effects.

Clean URLs
Allow users to access your web pages using elegant, easy-to-remember URLs.

For more information see: Clean URLs

Web Actions
AppsBuilder provides a series of predefined actions which can be visually tied to events
triggered by controls. This translates into great ease of use for the user who is not an
experienced developer, while empowering the experienced developer to create his/her own
actions, which are automatically picked up by the Morfik IDE.

Related video: How to use Web Actions

Support for OpenSocial and Facebook APIs


AppsBuilder comes with direct support for the OpenSocial and Facebook APIs to allow the
user to create applications that interact with these platforms.

Synchronized Browser Code


The new compiler in AppsBuilder automatically generates specialized code to simulate
synchronous behavior for browser side code that makes asynchronous function calls, without
ever blocking the browser. This makes it much simpler to program certain aspects of
application logic. Using this features it is easy, for example, to create simple animations.

Web Service Data Sources


Morfik has always used a Web Services-based architecture to allow its browser-side code to
access database information. In AppsBuilder, this architecture has been extended to allow
Morfik applications to access any Web Service which conforms to a certain set of rules as a
data source. This allows browser-only applications to access data published by other Morfik
Applications or by services implemented with other tools such as PHP, .Net or Java.

Auto-Deployment To Cloud Computing Environment


AppsBuilder provides support for hosted cloud computing services. Applications can be
automatically deployed from within the IDE. This feature, which runs through a few steps in a
Wizard, can be called with a single click, and allows Morfik users to enjoy the easiest and
fastest turnaround time to take a project "From Concept To Consumer".

Helper methods
AppsBuilder allows any data type in the supported language types to be extended through
the addition of user-defined helper methods. This feature has been used extensively by Morfik
to add formatting, conversion and utility methods to all basic data types. This compiler
feature, added to the new methods implemented as part of the M2 framework, make the M2
code completion much more powerful and useful as utility ‘functions’ become semantically tied
to the data type they are meant to be used with.

Enhanced Compiler
The Morfik AppsBuilder compiler has been enhanced in many ways, including, but not limited
to, improved optimization, parallel compiling, full background compiling (without ever blocking
the IDE) and the inclusion of new language features such as helper methods.

Enhanced Web Methods


Web Methods (a Morfik implemented Web Service) can be declared in any module, without the

Page 65
need to create Web Method documents for each method. This makes it easier and faster to
create more extensive Web Service APIs. It also performs an automatic browser-side import
of Web Methods which are declared on the server side of a Form module. Creation of Web
Methods applies to Web Application projects only, but both Browser Application projects and
Web Application projects can call a Web Method.

For more information see: Creating Web Methods - In code

Browser Only Applications


Morfik has identified a large demand for what are essentially purely browser applications, be
they Facebook applications, Google Widgets or highly interactive front-ends for corporate
back-end systems. To address this market, Morfik has introduced the concept of Browser
Applications, building on its revolutionary Javascript Synthesis Technology (JST), which focus
entirely on browser development technology. These applications are totally server agnostic
and can be deployed to any web server in the world. Browser applications can still make Web
Service calls. Browser Applications are ideal for companies and individuals who want to enter
the social network application space, or that have an established Web presence that they
want to enhance.

Automatic Data Forms


AppsBuilder introduces as a new concept the automatic Data Form. This feature allows the
developer to treat a data source as if it were a Form, and just instruct the Morfik Framework
to open the data source in a specific section of a page (inside a SubForm control). A tabular
view of the data source’s data will be presented to the user with an alternating line (also
referred to as a zebra, or greenbar) background that matches the current application theme.
This automatically generated Form will also offer the user the possibility to switching to a
single-record view for data editing. (Browser XApps do not allow data editing.)

XML data sources


Browser Applications are able to see XML files as if they were a database table. This allows a
user to create a website that can take advantage of several of Morfik’s database-oriented
features even though the end application might be browser-only and deployed to any web
server.

For further information see: Defining XML Data Sources

New Way of Calling Web Services


AppsBuilder allows users to see Web Services as objects with properties to be set before
execution and other properties to read after the service execution in order to verify call
results. Combined with the synchronized browser code, this feature makes calling Web
Services a breeze.

For more information see: Calling Web Methods

RSS Feed designer


Creating RSS feeds has been made exceedingly easy in AppsBuilder through the addition of
an RSS feed editor that allows the user to choose from among his data sources the one which
will provide the information for the feed and to visually map the data source’s fields with the
RSS information slot.

For more information see: Creating RSS Feeds

More information about the changes in each release can be found in the following articles:

Release Notes
Historical Timeline of Releases

Page 66
Calendar

Figure 1 – A Calendar control.

The Calendar control provides a new way of displaying and selecting


dates.

Usage
Properties

BorderColor
BorderStyle

BorderWidth
Color
Cursor
Font
Hint
Left
Name
Opacity
Top
Events
OnChange
See also

Usage
In Morfik AppsBuilder the Calendar control is used to display or select dates in situations
where the more compact DateTimeEdit control would be inappropriate.

Properties

Page 67
The following is a list of the properties of the Calendar control with a short description of their
function.

BorderColor
The BorderColor property specifies the color that should be used for drawing a rectangular
border around the Calendar. Note: the border will not be visible unless the BorderStyle and
BorderWidth properties are also set.

BorderStyle
The BorderStyle property specifies the line style that should be used for drawing a
rectangular border around the Calendar. Note: the border will not be visible unless the
BorderColor and BorderWidth properties are also set.

BorderWidth
The BorderWidth property specifies the width of a rectangular border to be drawn around the
Calendar. Note: the border will not be visible unless the BorderColor and BorderStyle
properties are also set.

Color
The Color property determines the background color of dates in the Calendar control
(however the selected date and dates outside current month are given different colors).

Cursor
The Cursor property, if set, causes the appearance of the mouse cursor to change as it moves
over the control.

Font
The Font property (and its sub-properties Color and Name) is used to indicate which font
should be used for drawing the text in the Calendar.

Hint
The Hint property, if set, specifies the text of a tooltip that is displayed when the end user
moves the mouse cursor over the Calendar.

Left
The Left property specifies the horizontal position of the Calendar in the form.

Name
The Name property specifies the identifier used to reference the Calendar from browser- or
server-side code.

Opacity
The Opacity property determines the extent to which the Calendar obscures any controls
placed in its background. A value of 0 means that background controls are fully visible,
whereas a value of 100 means that background controls are completely obscured.

Top
The Top property specifies the vertical position of the Calendar in the form.

Events

OnChange
The OnChange event occurs when the selected date in the Calendar control changes.

Page 68
See also
 Morfik Controls
 Most Frequently Used Controls

 Control Effects

Page 69
ProgressBar

Figure 1 – A ProgressBar control.

The ProgressBar control is typically used to display feedback to the user while
some time-consuming task is being performed.

Usage
Frequently used
Properties
Position
Other Properties
BorderColor
BorderStyle
BorderWidth
Color
Cursor
Height
Hint
Left
MaxPosition
MinPosition
Name
Opacity
Top
Width
Events
See also

Usage
The ProgressBar control is typically used to display feedback to the user while some
time-consuming task is being performed. As the task progresses, the proportion of the control
that is highlighted grows, and the percentage value that is displayed increases, as seen in
Figure 2.

Page 70
Figure 2 – Demonstration of how ProgressBar's appearance changes as a task progresses.

Frequently used Properties


The following is a list of the most commonly used properties of the ProgressBar control with a
short description of their function.

Position
The Position property is an integer value which governs the proportion of the control that is
highlighted, and the percentage value that is displayed. Its value must lie between
MinPosition (0%) and MaxPosition (100%).

Other Properties
The following is a list of less-commonly used properties of the ProgressBar control with a
short description of their function.

BorderColor
The BorderColor property specifies the color that should be used for drawing a rectangular
border around the ProgressBar. Note: the border will not be visible unless the BorderStyle
and BorderWidth properties are also set.

BorderStyle
The BorderStyle property specifies the line style that should be used for drawing a
rectangular border around the ProgressBar. Note: the border will not be visible unless the
BorderColor and BorderWidth properties are also set.

BorderWidth
The BorderWidth property specifies the width of a rectangular border to be drawn around the
ProgressBar. Note: the border will not be visible unless the BorderColor and BorderStyle
properties are also set.

Color
The Color property is used to set the color in which the non-highlighted portion of the
ProgressBar will be drawn.

Cursor
The Cursor property, if set, causes the appearance of the mouse cursor to change as it moves
over the control.

Height
The Height property specifies the vertical extent of the ProgressBar.

Hint
The Hint property, if set, specifies the text of a tooltip that is displayed when the end user
moves the mouse cursor over the ProgressBar.

Left
The Left property specifies the horizontal position of the ProgressBar within the form.

MaxPosition
The MaxPosition property indicates the minimum possible value of the Position property.

MinPosition
The MaxPosition property indicates the maximum possible value of the Position property.

Page 71
Name
The Name property specifies the identifier used to reference the ProgressBar from browser- or
server-side code.

Opacity
The Opacity property determines the extent to which the ProgressBar obscures any controls
placed in its background. A value of 0 means that background controls are fully visible,
whereas a value of 100 means that background controls are completely obscured.

Top
The Top property specifies the vertical position of the ProgressBar within the form.

Width
The Width property specifies the horizontal extent of the ProgressBar.

Events
The ProgressBar control does not have any events.

See also
 Morfik Controls
 Most Frequently Used Controls

 Control Effects

Page 72
GoogleMap

Figure 1 – A Google Map control.

In Morfik AppsBuilder the GoogleMap control is used to provide Google Maps


functionality in your XApps.

Usage
Frequently used
Properties
APIKey
MarkerPosX
MarkerPosY
ShowLargeMapControl

ShowMapControl
ShowMapType
ShowMarker
ShowTooltip
Other Properties
BorderColor
BorderStyle
BorderWidth
Color
Cursor
Font
Height
Hint
HorizontalPlacement
Left
Name
Opacity

Page 73
Top
VerticalPlacement
Visible
Welcome
Width
Events
See also

Usage
The GoogleMap custom control provides a simple and powerful way for you to integrate
Google Maps into your XApps. To see this control in action, simply open the Mapping Device
project that is bundled with your Morfik installation (AppsBuilder 2.0.4.73 or later).

Frequently used Properties


The following is a list of the most commonly used properties of the GoogleMap control with a
short description of their function.

APIKey
This property specifies the Maps API Key that will be used to communicate with Google's
servers. Before deploying your XApp, you should obtain a Maps API Key from Google and
paste it in here.

MarkerPosX
This property allows you to specify the X coordinate of the starting location on your map.

MarkerPosY
This property allows you to specify the Y coordinate of the starting location on your map.

ShowLargeMapControl
This property specifies whether to display the large or small version of the map zoom/pan
device in the top-left corner of the map.

ShowMapControl
This property specifies whether to show or hide the map zoom/pan device in the top-left
corner of the map.

ShowMapType
This property specifies whether to display the Map/Satellite/Hybrid buttons in the top-right
corner of the map.

ShowMarker

ShowTooltip

Other Properties
The following is a list of less-commonly used properties of the GoogleMap control with a short
description of their function.

BorderColor
The BorderColor property specifies the color that should be used for drawing a rectangular

Page 74
border around the control. Note: the border will not be visible unless the BorderStyle and
BorderWidth properties are also set.

BorderStyle
The BorderStyle property specifies the line style that should be used for drawing a
rectangular border around the control. Note: the border will not be visible unless the
BorderColor and BorderWidth properties are also set.

BorderWidth
The BorderWidth property specifies the width of a rectangular border to be drawn around the
control. Note: the border will not be visible unless the BorderColor and BorderStyle properties
are also set.

Color
The Color property has no effect for the GoogleMap control.

Cursor
The Cursor property has no effect for the GoogleMap control.

Font
The Font property has no effect for the GoogleMap control.

Height
The Height property specifies the vertical extent of the control. Note: if the CanGrow or
CanShrink properties are set, the actual height of the control at run time may be different.

Hint
The Hint property, if set, specifies the text of a tooltip that is displayed when the end user
moves the mouse cursor over the GoogleMap control.

HorizontalPlacement
The HorizontalPlacement property, if set, governs how the control adjusts its size and
position in response to changes in the horizontal dimensions of its parent.

Left
The Left property specifies the horizontal position of the GoogleMap control.

Name
The Name property specifies the identifier used to reference the GoogleMap control from
browser- or server-side code.

Opacity
The Opacity property determines the extent to which the GoogleMap control obscures any
controls placed in its background. A value of 0 means that background controls are fully
visible, whereas a value of 100 means that background controls are completely obscured.

Top
The Top property specifies the vertical position of the GoogleMap control.

VerticalPlacement
The VerticalPlacement property, if set, governs how the GoogleMap control adjusts its size
and position in response to changes in the vertical dimensions of its parent.

Page 75
Visible
The visible property is used to make controls visible or invisible.

Welcome

Width
The Width property specifies the horizontal extent of the GoogleMap control.

Events
The GoogleMap control has no events.

See also
 Morfik Controls
 Most Frequently Used Controls

 Control Effects

Page 76
Wysiwyg

Figure 1 – A Wysiwyg control.

The Wysiwyg control allows the user to enter formatted text.

Usage
Frequently used
Properties
Text
Other Properties
BorderColor
BorderStyle
BorderWidth
Color
Cursor
Font
Height
Hint
HorizontalPlacement
Left
MaxLength
Multiline
Name
Opacity
ReplaceLineBreaks

Page 77
ShowAlignmentButtons

ShowContextMenu
ShowFormatButtons
ShowWebButtons
Top
VerticalPlacement
Visible
Width
Events
See also

Usage
The Wysiwyg control allows the user to enter formatted text.

Frequently used Properties


The following is a list of the most commonly used properties of the Wysiwyg control with a
short description of their function.

Text
Text is the most frequently used property of a Wysiwyg control as it allows setting and
reading of the content (all the text) that is displayed by the control.

Other Properties
The following is a list of less-commonly used properties of the Wysiwyg control with a short
description of their function.

BorderColor
The BorderColor property specifies the color that should be used for drawing a rectangular
border around the Wysiwyg control. Note: the border will not be visible unless the
BorderStyle and BorderWidth properties are also set.

BorderStyle
The BorderStyle property specifies the line style that should be used for drawing a
rectangular border around the Wysiwyg control. Note: the border will not be visible unless the
BorderColor and BorderWidth properties are also set.

BorderWidth
The BorderWidth property specifies the width of a rectangular border to be drawn around the
Wysiwyg control. Note: the border will not be visible unless the BorderColor and BorderStyle
properties are also set.

Color
The Color property is used to set the color in which the background parts of the Wysiwyg
control will be drawn.

Cursor
The Cursor property, if set, causes the appearance of the mouse cursor to change as it moves
over the control.

Page 78
Font
The Font property has no effect for the Wysiwyg control.

Height
The Height property specifies the vertical extent of the Wysiwyg control. Note: if the CanGrow
or CanShrink properties are set, the actual height of the TextLabel at run time may be
different.

Hint
The Hint property, if set, specifies the text of a tooltip that is displayed when the end user
moves the mouse cursor over the Wysiwyg control.

HorizontalPlacement
The HorizontalPlacement property, if set, governs how the Wysiwyg control adjusts its size
and position in response to changes in the horizontal dimensions of its parent.

Left
The Left property specifies the horizontal position of the Wysiwyg control in the form.

MaxLength
This property is not implemented in the current release.

Multiline
This property is not implemented in the current release.

Name
The Name property specifies the identifier used to reference the Wysiwyg control from
browser- or server-side code.

Opacity
The Opacity property determines the extent to which the Wysiwyg control obscures any
controls placed in its background. A value of 0 means that background controls are fully
visible, whereas a value of 100 means that background controls are completely obscured.

ReplaceLineBreaks
This property is not implemented in the current release.

ShowAlignmentButtons
This property is not implemented in the current release.

ShowContextMenu
This property is not implemented in the current release.

ShowFormatButtons
This property is not implemented in the current release.

ShowWebButtons
This property is not implemented in the current release.

Top

Page 79
The Top property specifies the vertical position of the Wysiwyg control.

VerticalPlacement
The VerticalPlacement property, if set, governs how the Wysiwyg control adjusts its size and
position in response to changes in the vertical dimensions of its parent.

Visible
The visible property is used to make Wysiwyg controls visible or invisible.

Width
The Width property specifies the horizontal extent of the Wysiwyg control.

Events
The Wysiwyg control has no events.

See also
 Morfik Controls
 Most Frequently Used Controls

 Control Effects

Page 80
Control Effects

Morfik AppsBuilder offers a wide variety of special formatting effects that can be
applied not only to bands and containers, but also to controls.

Morfik effects can be used to create interesting design elements which will enrich
you application or website's interface. The following pictures show some controls
in their plain form and with one or more effects applied to them.

Figure 1 - This picture shows a plain container and the same container with the
rounded corners and outer shadow effects applied to it.

Figure 2 - This picture shows a plain button and the same button with the
rounded corners, inner shadow and reflection effects applied to it.

Several effects can be combined in the same control to create a totally new visual
experience in your website. The Figure 3 shows a set of buttons such as the one
seen in Figure 2, but with several effects applied to them in order to define a new
look.

Figure 3 - This picture shows a set of three buttons which have had some effects
applied to them in order to present the appearance of an interrelated set of
options.

Note that in Figure 3 the buttons have had different but symmetrical effects
applied to them in order to give the impression of being a single strip of controls
with rounded corners on both sides.

Figure 4 - This picture shows a a container with the Gradient, Corners and

Page 81
Shadow effects applied and several controls. The view on the left is from the Form
designer and the one on the right from a browser. Some of the TextLabel controls
inside the container have the Antialiasing effect applied to them.

Figure 5 - This picture shows a a container with the Gradient, Corners and
Shadow effects applied and several Buttons. The buttons have different variations
of the Corners effect applied as to give the impression of continuous set.

Types of Effects Available


The following effects are available to be applied to different types of controls. Each control
has a different set of effects that can be applied to it, according to how they are used in an
application.
 Glow
 Shadow

 Reflection
 Gradient

 Antialiasing
 Corners

Combining Effects
All of these effects can be effectively combined in the same control (according to which ones
are available for a specific control) in order to achieve a desired result. If fact, it is quite
frequently the case of some controls. Button controls for example frequently have the
Gradient and Corners effects applied to them. Figures 4 and 5 show good examples of
combining the Gradient, Corners and Shadow effects in Container controls.

Applying effects to dynamically created controls


Morfik effects are determined at compile time and the corresponding images are generated at
that point. This means that you cannot just have these effects applied to a control you create
dynamically at runtime. You can, however, copy the background image of a pre-existing
control to another control. The following code snippet shows how this can be achieved.

P rocedure Content . Button1Click ( Event : T DOMEvent );


Var
cnt : Container ;
Begin
cnt := Container . Create ( 'NewButton' , Self );
cnt . Attrs . Left := 100 ;
cnt . Attrs . T op := 100 ;
cnt . Attrs . Height := Container1 . Height ;
cnt . Attrs . Width := Container1 . Width ;
cnt . Attrs . Background . Assign ( Container1 . Attrs . Backgro
und );

Page 82
cnt . CreateDomObject ;
End ;

See Also
 Working with Controls

Related Video
 Discover Image Effects

Page 83
Antialiasing

This effect creates softens the transition between the foreground and background
color around the edges of the text of selected controls. Antialiasing greatly
reduces the raggedness of the edges in characters and is recommended for titles
in your website which will not change as it converts the text into an image.

Applies to: TextLabel, Button;

Antialiasing is the easiest of the effects to use as it is essentially an on/off toggle.


The control is either using or not the effect with no options to configure.

Figure 1 - Two TextLabel controls showing the same text. The control on the
bottom has Antialiasing on while the one on the top has the effect off.

Note
The Antialiasing effect allows you to achieve better looking results when
large text is presented over contrasting colors, however it should be used
sparingly as each TextLabel or Button control to which the effect is applied
generates a new image in the project. Usage of too many images in a page
may result in longer page loading times.

See Also
 Control Effects

Page 84
Corners

This effect allows you to select a set of corners in a control that will be "rounded".
This effect allows you to soften your layout by eliminating some of the right
angles.

Applies to: Container, Rectangle, Button, TextEdit, ComboBox, ListBox;

Figure 1 - The Corners effect gallery as shown in the Home Tab of the Ribbon
when a compatible control is selected.

Morfik AppsBuilder offers a large number of options for configuring the corners of
your controls, as you can see in the picture in Figure 1. The following are some
examples of what you can achieve by applying the Corners effect to Morfik
controls.

Figure 2 - Several buttons with different variations of the Corners effect applied.
These buttons are also using the Gradient effect.

Figure 3 - A pair of container controls with two symmetrical variations of the

Page 85
Corners effect applied. These containers are also using the Shadow effect.

Figure 4 - A container controls with rounded Corners on the left side with a series
of buttons which follow in the same style. This container is also using the Glow
effect with a blueish color.

These are just some of the ways in which the Corners effect can be used and
combined with other effects to help you achieve great looking results in your
website or application.

See Also
 Control Effects
 Control Effects - Gradient

 Control Effects - Shadow


 Control Effects - Glow

Page 86
Gradient

This effect creates a smooth gradient fill for the control, based on the control's color. There are
two sets of gradient options: Darker and Lighter. The Darker gradients form a transition from the
control's selected color to black, while the Lighter gradients form a transition from the control's
selected color to white.

Applies to: Container, Rectangle, Button, TextEdit, ComboBox, ListBox, Image, DateTime, Form
Bands;

Figure 1 - The Gradient gallery as displayed in the Home tab of the Ribbon when an compatible
control is selected.

Figure 2 - A Button with a Darker gradient applied on top of a blue color.

Image controls have a different range of options available for creating gradients. Image control
gradients are defined between two gradient specific colors, instead of between the control's
selected color and black or white. In figure 3 you can see the Image control's Gradient effect
gallery.

Page 87
Figure 3 - The Gradient gallery as displayed in the Home tab of the Ribbon when an Image control
is selected.

You select the two colors for the Image control gradient effect directly on the gallery menu, as
seen in Figure 3. It is also possible to set the opacity for each of the colors used as a base for
the Image control gradient, which will give you a different effect as the resulting image will
become partially transparent.

Figure 4 - A container with a Lighter gradient over a blue color..

Page 88
Figure 5 - An Image control with a radial gradient of gray to whiter over a picture. With the
appropriate opacity levels set, this effect darkens the edges of the picture.

See Also
 Control Effects
 Applying Formatting to Controls

Page 89
Shadow

This effect creates a tight fitting shaded area around the control based on a
selected color. This, when combined with dark colors, causes the impression that
the object is projecting a shadow.

Applies to: Container, Rectangle, Button, TextEdit, ComboBox, ListBox, Image,


DateTime, Form Bands;

Figure 1 - The Shadow effect gallery as shown in the Home tab of the Ribbon
when a compatible control is selected.

In figure 2 you can see three containers with different types of shadows applied
to them. The first one has an inner shadow applied while the other two containers
have variations of the outer shadow applied to them.

Figure 2 - Three containers with different types of Shadows.


In some situations you may wish to use the Glow effect instead of the shadow
effect.

See Also
 Control Effects

Page 90
 Control Effects - Glow

Page 91
Glow

This effect creates a tight fitting halo around the control based on a selected color.
This, when combined with bright colors, causes the impression that the object is
glowing.

Applies to: Container, Rectangle, Button, TextEdit, ComboBox, ListBox, Image,


DateTime;

Morfik AppsBuilder offers many different ways to configure the glow effect for the
controls to which it can be applied. In Figure 1 you can see all the options
available in the Glow effect gallery. There are different variation on the size of the
glow area combined with variations in the colors supported in the current theme.

Figure 1 - The glow effect gallery options as shown in the Home tab of the Ribbon
when a compatible control is selected.

In Figure 2 you can see a container with a glow effect applied to it.

Figure 2 - A container with the glow effect applied.


In some situations you might wish to use the Shadow Effect instead of the Glow
effect.

See Also

Page 92
 Control Effects
 Control Effects - Shadow

Page 93
Reflection

This effect creates a mirror image of the control to which it is applied, underneath
it. The distance and size of the reflected image is selectable from the Reflection
gallery which is shown in the Home tab of the Ribbon when a compatible control is
selected.

Applies to: Container, Rectangle, Button, TextEdit, ComboBox, ListBox, Image,


DateTime;

Figure 1 - The reflection effect gallery as seen on the Home tab of the Ribbon
when a compatible control is selected.

Figure 2 - A TextLabel control with the reflection effect applied to it.

Note
When using the Reflection effect on TextLabel controls, especially when
using large sized fonts, you might wish to combine them with the
Antialiasing effect for better results.

Though the Reflection effect can be applied to a wide variety of controls it is most
commonly used with the TextLabel and Image controls. In figure 3 you can see an
Image control being reflected.

Page 94
Figure 3 - An Image control with the reflection effect applied to it.

Figure 4 - A set of Button controls with the reflection effect applied to them. These
Buttons are also using the Gradient effect and in some cases the Corners
effect.

See Also
 Control Effects
 Control Effects - Antialiasing

 Control Effects - Gradient


 Control Effects - Corners

Page 95
Defining a Form
Layout

Introduction
Any page layout in Morfik, no matter how complex, is ultimately comprised of individual forms.

Morfik provides the following entities for managing Form layout:


 Bands
 Containers

 Subforms

Bands
Morfik divides Forms into horizontal sections called Bands.

When you design your Forms you should consider what would be their purpose and so determine if
they will need to display a Header or Footer band. Figure 1 shows a picture of a Form with three
bands: Header, Footer and Details.

Figure 1 – A Form with three visible bands.

You can define if any of the three main bands will not be visible by simply setting its height to be
equal to zero. When working with databases (Morfik AppsBuilder only) you can, also, have additional
bands added for data grouping. Figure 2 shows a Form with both the Header and Footer band
heights set to zero.

Page 96
Figure 2 – A Form with the height of both the Header and Footer bands set to zero.

Splitting Bands and Containers


A powerful new feature in the Morfik 2.x Form designer is the ability to automatically split Bands and
Containers into sub-regions.

This allows developers to create complex form layouts quickly, without having to worry about the
precise placement of Subform controls.

Figure 3 shows how to split the Details band vertically.

Page 97
Figure 3 – Splitting the Details band.

Splitting a Band implicitly creates a Container for each side of the split.

Often, the developer will want to place a Subform control on to the Container, as shown in Figure 4.

Figure 4 – Container with Subform.

The split may be resized by dragging the dashed line. The Subform control is automatically resized
along with its parent Container.

Figure 5 – Resizing the split.

Page 98
Containers may be split using the same technique. In Figure 6, the developer is horizontally splitting
one of the Containers created as a result of the split performed in Figure 3.

Figure 6 – Splitting the Container.

See Also
 Working with Forms

Page 99
Clean URLs

Clean URLs are an exciting new feature of Morfik 2.0.4 that allows users to access
your website using elegant, easy-to-remember URLs.

Publishing a Clean URL


To demonstrate the Clean URL concept, we will use the Blog xapp. (The Blog xapp shipped
with Morfik version 1, and is available for download from labs.morfik.com).

In addition to its main page that displays the blog posts, the Blog xapp has an admin section.
We can make a clean URL for the admin section by doing the following:
Open the Index
1 form.
2 Select the FullSite subform.

3 Set FullSite's Form property to AdminMain.


Run the Publish Page command. (Tip: the Publish Page command is only visible when the Form
4 object is selected. To select the Form object, click in the workspace behind the form.)

5 In the Publish Page dialog, enter the title by which this page will be known.

Figure 1 – The Publish Page command.

Figure 2 – The Publish Page dialog.

Now, when the Blog xapp is running, it is possible to go directly to the admin section by
typing: http://127.0.0.1:9119/admin

Page 100
Publishing a Clean URL with Parameters
Clean URLs can also be used with parametric forms.

We can make a clean URL that displays individual blog posts by doing the following:
Open the Index form, and set the Form property of the subform FullSite to
1 BlogMain.
Open the BlogMain form, and set the Form property of the subform MainArticleArea to
2 ViewOneArticle.
Open the Publish
3 Page dialog.
4 Enter the Page Name 'articles'

5 Move the parameter ParamId to the Page Parameters list.

Figure 3 – Adding a parameter to the published page.

Now, when the Blog xapp is running, it is possible to go directly to, say, the second blog post
by typing: http://127.0.0.1:9119/articles/2

Editing or Removing Published Pages


In order to manage published pages that you have added to your project, Morfik provides the
Published Pages dialog. This is accessed via the Project tab of the ribbon.

Figure 4 – The Published Pages command.

The Published Pages dialog allows you to edit or remove any published page in your project.

Page 101
Figure 5 – The Published Pages dialog.

Related Video
 Clean URLs using Morfik Publish page

Page 102
Creating Web Methods -
In code

It is now very easy to create extensive Web Service based APIs with Morfik
AppsBuilder through coding. Web Methods can now be declared in any module
and you can declare as many as you want in any one module. This makes it easier
for experienced developers to create extensive APIs much quicker than it would
be possible using the special Web Method modules.

Declaring Web Methods in code involves creating a class that descends from the
WebMethod class and using some special metadata tags to inform the compiler
what are the parameters for this Web Method.

In the following listing you see an example of a code declaration for a Web
Method. In this case a Method that returns a list of objects with the names and
phones of some people. This module could be added to any AppsBuilder Web
projects and provided the necessary table (Contacts) where present, the project
would publish this the ListContacts Web Method.

Unit PhoneBookAPI ;

Interface

Uses
SystemSerialiser ,
SystemWebMethod ;

type

MyContact = class ( TSerializable )


Id : integer ;
Name : string ;
Phone : string ;
Constructor Create ( aId : integer ; aName , aPhone :
string );
end ;

ListContacts = class ( WebMethod )


MyContacts : List of MyContact ; [ 'WSPublished=true' ,
'WSFieldKind=out' , 'WSHeader=false' ];
procedure Execute ; override ;
end ;[ 'WSPublished=true' ];

Implementation

uses SystemDatabase ;

Constructor
MyContact . Create ( aId : integer ; aName , aPhone : string );
begin
inherited Create ;
Id := aId ;
Name := aName ;
Phone := aPhone ;
end ;

procedure ListContacts . Execute ;

Page 103
var
ContactRS : TRecordSet ;
aContact : MyContact ;
Begin
ContactRS := DefaultDBConnection . CreateRecordSet (
'SELECT "id", "contactname", "phone" FROM "Contacts"' );
try
ContactRS . Prepare ;
ContactRS . Active := True ;
ContactRS . First ;
If Not ContactRS . Eof then
while not ContactRS . Eof do
Begin
aContact := MyContact . Create ( ContactRS . FieldbyName
( 'id' ). AsInteger , ContactRS . FieldbyName ( 'contactname'
). AsString ,
ContactRS . FieldbyName ( 'phone'
). AsString );
MyContacts . Add ( aContact );
ContactRS . Next ;
End ;
ContactRS . Close ;
finally
ContactRS . Free ;
end ;
End ;

End .

See Also
 Working with Web Methods

Page 104
Defining XML Data
Sources

In order to make it easy for people who had prior experience in Morfik AppsBuilder or who are
working with both Browser Application and Web Application projects, Morfik has made working
with XML Data Sources to be just like working with regular tables.

You can see in Figure 1 the Table designer in the Morfik Workspace, with an XML Data Source
being defined.

Figure 1 - A new XML based table being created in the Morfik Table designer.
Morfik AppsBuilder, when you are working in a Browser project, will always treat the XML based
data source as being a table. It is, however, a much simpler database handling engine than a full
blown relational database and will therefore have a more limited range of data types which you
can use to define your table, as shown in Figure 2.

Page 105
Figure 2 - List of data types which can chosen for a field in an XML-based table.

In Figure 3 you can see the Table designer in Morfik workspace being used to create a regular
database table with the same fields as those in the table being created in Figure 1. Notice that
apart from a difference in the data type naming the designer works in exactly the same way. This
similarity makes alternating on projects which use XML data sources or relational databases very
easy.

Figure 3 - A new table being created in the Morfik Table designer using a relational database in a
Web project (AppsBuilder).

Page 106
See Also
 Working With XML Data
 Entering XML Data

Page 107
Entering XML Data

Figure 1 - Data entering into a XML based table in the Morfik workspace.

See Also
 Working With XML Data
 Defining XML Data Sources

Page 108
Calling Web Methods

Calling Web Methods in your application is quite simple. The following listing
shows the code for a Form from which a Web Method call is made. In this case it is
a simple method that returns a list of names and phone numbers.

The actual results are returned through a call back routine which is assigned to an
event of the Web Method class, when it is instantiated. The logic for this example
is that when a button is clicked a Web Method is called which returns a the list of
data. When the data is received, in a browser side callback routine, it is added to
the contents of a simple TextEdit control.

You can see the server implementation of this Web Method in a listing in the
Creating Web Methods - In code topic.

Unit Content ;

Interface

uses PhoneBookServerService ;

Type
Content = Class ( Form )
Button1 : Button ;
TextEdit1 : TextEdit ;
Procedure Button1Click ( Event : TDOMEvent ); Message ;
Private
{ Private declarations }
Public
{ Public declarations }
procedure HandleContacts ( WM : TListContacts );
End ;

Implementation

procedure Content . HandleContacts ( WM : TListContacts );


Var
I : integer ;
begin
If WM . MyContacts . Count > 0 then
For I := 0 to WM . MyContacts . Count - 1 do
TextEdit1 . Text := TextEdit1 . Text + WM . MyContact
s [ I ]. Name + ':' + WM . MyContacts [ I ]. Phone ;
WM . Free ;
end ;

Procedure Content . Button1Click ( Event : TDOMEvent );


var
ListContacts : TListContacts ;
Begin
ListContacts := TListContacts . Create ;
ListContacts . OnWebMethodReturn := @ HandleContacts ;
ListContacts . Execute ;
End ;

End .

Page 109
Note
This code only works in the Browser side portion of a Morfik AppsBuilder
project, at this time. This code will not work in a Browser Application
project.

When you are calling Web Methods created within the same project you can use
the RunWebMethod command. In this case, you will need to write code in the
HandleResponse Method of the browser version of your Web Method class to
process the return values.

The following is a sample call to the RunWebMethod command:

RunWebMethod ( 'AuthenticateUser' , '"AUserName='


+ UserNameEdit . Text + '", "APassword='
+ PasswordEdit . Text + '"' );

See Also
 Working with Web Methods
 Creating Web Methods - In code

Page 110
Creating RSS Feeds

Morfik AppsBuilder 2.0 offers an easy way to create RSS Feeds from information returned from a
database Query. Since this feature is dependent on server side framework code it is not available
in Morfik Browser Application projects.

Figure 1 - Contents of Project tab of the Ribbon with the RSS Feed option highlighted.

Selecting the RSS option from the Project tab of the Ribbon, you are taken to the RSS dialog
dialog which can be seen in Figure 2.

Figure 2 - The RSS Feed dialog in Morfik AppsBuilder.

You can create a new RSS Feed by clicking on the "New" button which will bring up another dialog
for specifying the sources for the information which will be used to create the feed. Figure 3
shows the dialog for entering Feed information.

Page 111
Figure 3 - Editing the information of an RSS Feed in Morfik AppsBuilder.
The general page of the RSS Feed editing dialog allows you to specify information such as name
and title of the feed as well as a copyright message and to choose the format which will be used
for the feed. The supported formats are: RSS 2.0 and Atom 1.0.

Figure 4- Editing the data source specific information for an RSS Feed. From the Data Source page
of the RSS Feed editing dialog you can specify where the Feed will draw its information from. This
is done by selecting a specific query and then mapping the fields in the query to the required
information fields in the Feed.

As an exercise, you might want to consider adding an RSS Feed to the application detailed in the
topic " A Blog Application ".

Page 112
See Also
 Working with Forms

Page 113
Historical Timeline of
Releases

We started the WebOS AppsBuilder R1 beta cycle (calling it pre-beta) around


October 2005 with the first public beta release being 0.8.0.0 on 9 December 2005
– immediately after the successful show at the Web 2.0 Conference in
San-Francisco. The timeline chart below shows all the major and some of the
minor releases that have been made available since then to the more recent
release of the public beta of Morfik 2.0.

Morfik is fully committed to giving access to new releases of the Morfik software on
a regular basis. As can be seen when reviewing the history of releases, there are
months when there is a significant time period between available builds, whilst in
other months, there are many new builds. The former is due to the
implementation of major architectural changes to the product which require
significant time to settle down. While the latter is the outcome of surfacing many
of the new features implemented during this major architectural period.

We are now in a period of frequent releases and we expect this to continue for
the next 2-3 months. These new releases will be focusing on enhancing and
strengthening the current feature set in Morfik, including support for image effects,
image bundling, optimisation, flow control, controls, auto-deployment, cloud
computing environments and localisation. After this period we will enter a series of
production builds and then release 3 alpha/beta cycle which, as explained before,
will initially result in longer time periods between new releases.

If you are interested in participating in the testing and development of Morfik


products, please email us at pioneerscoordinator@morfik.com .

TimeLine
In the following table the four numbers indicated in the Version column specify the Generation
Version, Service Pack, Point Release, and Internal Build, respectively.

For example 2.2.0.13 would be Version 2, Service Pack 2, Point Release 0, Internal Build 13.

Date Version Major Features


2008
June
2.0.3.11 Image
 Bundling
Firebird
 2.1
May
2.0.2.3 Image
 Effects
April
2.0.0.63 Public Beta
release of
Morfik
Express and
Morfik
AppsBuilder
 Release 2
February
1.4.0.1 Implementat
ion of new
Help
 System.
January
1.3.1.18 Improv
ed
Debugg
ing
 Experie

Page 114
nce.
Using Mozilla
technology
for Browser
 debugging.
2007
November

1.2.1.5 Changes in
the licensing
 schema
July
1.2.0.13 Completi
on of
porting
of Morfik
Framewo
rk into
Basic
(beta
 release)
IIS
suppo
 rt
XApp as
a plug-in
to
Apache
2.x under
Windows

Significant
improvemen
ts to the
Plastic
layout
 feature
May
1.1.0.6 Upgrade
to Indy
 10
Forma
t
Painte
 r.
JumpStart
for new
 projects.
1.0.2.5 Major
improvemen
t in
incremental
compile
 times
MS
Windo
ws
Vista
support

April
1.0.1.5 Major
langua
ge
 fixes
Enhanced
FreePascal
 support
March
1.0.0.7  Source files

Page 115
now in XML
format.
Free
Pasc
al
debu
 gger
Project
langua
ge
convers
 ion
Salesforce
.com API
v8
 support
February
0.9.16.1 Web
services

Service
connector
 s
Sale
sforc
 e
Intellis
 ense
Scri
ptor

Morfik
 DOC
Control
adapters

Major
upgrade to
 text editor
Major
upgrade to
 data grid
2006
Septembe
r
0.8.8.15 Background
 compilation
June
0.8.7.6 Fireb
ird
 2.0
External
database
 support
Universa
l
 CharSet
Delphi
suppor
 t
Developer'
s
 Handbook
April
0.8.6.6 FreePa
scal /
 Linux
JavaScript
 optimization
March
0.8.5.6  Back/Forwar

Page 116
d buttons
Ajax
 caching
Pre-fe
tching

January
0.8.4.4 HTTP
compression

JavaScri
pt
 Maker
0.8.3.3 First version
to be used
for a
production
website
(www.morfik
 .com)
2005
December

0.8.1.0 First public


release to
 Pioneers
October
0.7.2.8 Version
used to
create
Desktop
Gmail
prototype
and demo at
Web 2.0
 Conference.

Page 117
The Morfik Framework

The most important thing for a developer to be able to do to unleash all the power
of Morfik AppsBuilder is to understand HOW things work in the Morfik Framework.
This understanding will open new possibilities and new paths that you, as a
developer, can explore and exploit in order to create richer, more sophisticated
applications.

Once you have created Forms, Reports, and code modules for your application,
how do they behave at runtime? It is this knowledge and that of how to use it to
your advantage that we seek in this topic.

Browser Applications Vs. Web Applications


Application Duality vs. Unity
The Morfik Framework Enters the Scene
What is Ajax?
Morfik and Other Ajax-Based Packages
Understanding the Boundaries in an XApp.
Morfik High-level Objects
Which High-level Objects exist in Morfik?
Forms
Forms and Data. a tight coupling
SubForms
The OpenForm Function
Intelligent Form Caching
Reports
The OpenReport Function
Web Methods
XApp – The Morfik Application High-level
Object
Server side XApp – Your binary application
Events
OnStartUp
OnShutdown
Browser side XApp – Your Ajax application
Events
OnBeginLoad
OnEndLoad
Properties
Wrapping it up
See Also

Browser Applications Vs. Web Applications


Morfik Browser Application projects and Morfik Web Application projects share the same
browser side framework. Just about everything that can be done with one, can be done with

Page 118
the other with very few exceptions. Whenever there is such an exception, special attention
will be called to it.

Browser Applications have very different goals to Web Applications and this should be kept in
mind when looking at how the Morfik Framework works. Browser Applications are intended for
individuals and companies that have an existing infrastructure and wish to create a new web
interface. It is also designed to be used by individuals and small businesses that do not have
and quite possibly do not want to have a dedicated server of their own. In this scenario,
Morfik Browser Application projects allow the user to create rich websites that can be
deployed to just about any server.

Morfik Web Application projects are intended for creating custom, Web-based, applications
and data-driven Websites. Our goal is that Morfik AppsBuilder be the only tool a developer
needs to create such an application.

Application Duality vs. Unity


Web based applications have always been divided into two parts: the browser side code and
the server side code. Traditionally, the browser side code has always been about displaying
information to the end user, while the server side code has been about application control
logic, data validation and business logic. Web developers have not only always lived with this
duality, but with a cacophony of different tools, standards and languages that must be used
to create these two very dissimilar parts of the same application.

When you want to create a totally new application, from scratch, Morfik AppsBuilder brings a
totally different vision to this scenario: a vision of unity. To better understand how this is
accomplished and how to benefit from this, it is important to realize that Morfik does not
change the nature of web-based applications, so your application is still composed of two
parts: browser and server side, but what they do and how you build them is radically different
from other tools.

Morfik differentiates projects into two kinds:


Browser Projects - These projects are pure
browser applications. There is no server side
code created for them, in the Morfik Workspace.
These applications can, of course, make calls to
preexisting server applications or Web Service
APIs. Browser projects are ideal for creating
static websites, new front-ends to existing
systems or small applications for embedding into
Facebook or MySpace. These projects can also be
 accessed and ran on the iPhone.
Web Projects - These projects contain both the browser and server components of a Web-base
application. These projects can be compiled to be an add-on to an IIS or Apache Web server, or
as a stand-alone Webserver. These projects are ideally suited for situations where new
applications are being created, from scratch, as they allow for the entire project's code to be
 created within the same project.
While creating a Morfik Application, or XApp as it is generally called, most of your application
control and data validation logic will be written for the client side of the application. In truth,
the server side of your application, while retaining the capability of handling complex logic, is
not called upon to do so, most of the time. The Morfik basic infrastructure, which we shall now
call The Morfik Framework, allows the control logic, data validation and even business logic to
be handled by browser side code. This makes for a much richer end-user experience with
much better interface response times than traditional web-based applications.

The Morfik Framework Enters the Scene


So, what exactly is the Morfik Framework? How do I use it? What can it do for me?

Most modern software development tools offer the developer several key things: a
programming language (or more than one), an integrated development environment (IDE), a
function/class library and some "compiler magic". Most of what I just said is quite plain to
understand, but what do I mean by "compiler magic"? Well, its stuff that the compiler does for
you, to unburden you from having to do it yourself. This is the kind of stuff that you generally
take for granted in how a programming language works, but which has a huge impact on how
your application works and how much work you have to do to get it to do what you want.

Well, Morfik provides us with tons of "compiler magic" and services that allow us to create
extremely powerful applications in simple and intuitive manner.

Page 119
To allow you to transfer most of your application ’ s logic to the browser side of your
application, Morfik uses heavily a technique that has recently received the name Ajax, which
stands for Asynchronous JavaScript and XML. This technique allows a web application to be
totally contained in a single web page, from the browser ’ s point of view. In response to user
interaction, JavaScript code within this document makes calls to the server and receives new
parts (JavaScript and HTML code) to be inserted, dynamically into the document.

What is Ajax?
Even though you really do not need to know what Ajax is, in order to use Morfik AppsBuilder,
it will help you better understand how Morfik manages to accomplish some of the things you
see being done by your application that look a bit like magic to Internet old-timers. Anyone
who has been using the Internet for a couple of years is, by now, quite accustomed to its
page-centric model, where whenever you click on a link or option the entire page you are
working on is substituted by another, sometimes even by the same one, but with information
that is a bit different.

Ajax is a recent name for a way of using a set of technologies which have been around much
longer than this new moniker. These technologies, used for the specific purpose of creating
dynamic web applications started to receive world-wide attention when two events occurred:
the name Ajax was introduced by Jesse James Garret in an article and Google came out with a
site/application called Google Maps. Google Maps used these technologies to great effect, for
creating a totally simple and at the same time intuitive and dynamic interface for the user to
interact with maps, greatly increasing the usability of the site by not downloading enormous
quantities of information without the need to do so.

So what really is Ajax? Some people have said that is a technology, others that it is an
architecture, but in reality it is neither of those. It is not a technology in itself, but a way of
combining preexistent technologies. It is not an architecture, but it can be used to create one,
as Morfik has used it. So, Ajax is a way of using a certain set of technologies, which would
then, in my dictionary qualify it as being a technique or methodology, rather than a set of
technologies and it can be used as part of an architecture, while not being one.

If you are thoroughly confused now, don ’ t worry. It will pass.

Morfik and Other Ajax-Based Packages


If you work with IT and haven ’ t been on a long trip to the moon for the past two years,
chances are very good that you ’ ve heard about Ajax (or at least know that we ’ re not
talking about a house cleaning product) and heard that there are a lot of people working
with it. How is Morfik different from everybody else?

Just about everybody who has worked with Ajax, has created a library of JavaScript code that
makes it easier for web site developers to employ Ajax techniques to make their web sites
more interactive, more dynamic. They have built JavaScript/DHTML controls which can look
quite good give an application look and feel to a web site. Some of them have taken the next
step and started to make utility functions to handle common problems in complex site
development.

Morfik takes all of this, a couple of steps further. First of all, Morfik recognized from the
beginning that to build large scale Web-based systems, you need more than controls, you
need a runtime library. You need a solid base on which to build. That is where the Morfik
Framework comes in: the first powerful, object oriented development framework to be written
in a high-level language specifically to run inside the Web browser. While other development
solutions were being put together coming from the point of view of strong frameworks for
server-side programming, like .NET and J2EE, and being patched together with totally
unrelated JavaScript function libraries, such as Dojo and gooxdoo, Morfik was breaking ground
in creating a compiler specifically designed for Web applications, a solid object oriented
framework and a visual development environment. The combination of these elements gives
the Morfik user, a Web application developer, unparalleled flexibility and power. These, in
turn, empower Morfik users to create powerful and innovative applications in record time.

Understanding the Boundaries in an XApp.


In order to gain a better perspective on what exactly the Morfik Framework is, it is important
that we understand how a Morfik XApp works. This will give us a unique view of what is
handled by the Morfik Framework behind the scenes, many times in a transparent manner,
such as handling all the Ajax related code.

Page 120
Even though it is not immediately evident, when you start working with Morfik tools, as
mentioned, your application is divided into two parts which function in very different ways, but
which are constructed with the same set of tools. The first part is the browser side code,
which will contain most of the control logic for your application and will be responsible for the
interaction with the end user.

The second part of you application is composed of the server side logic you have created and
will be responsible for handling requests from the browser side of the application and
instantiate objects that are sent over to the browser side. In this manner, the server
component of your XApp actually works as an Object Server, which instantiates objects which
will run on the browser component of the XApp. These portion of the application is only
available in Morfik Web projects, created with Morfik AppsBuilder. In the case of Browser
projects, all the code necessary to create the Forms in an application is created at compile
time and does not rely on specific server side components.

Your Web XApp is, thanks to the Morfik Framework, a combination of an application server, a
web server, a database server and a lot of extra functionality that is specific to your
application ’ s logic.

While on the server side of your XApp, the code is totally stateless, in the browser side the
application is quite state-full. It is, therefore, in the browser side that your application gets to
weave the links and run most of the logic which will define its behavior.

Figure 1 – Composition of a running XApp.

When looking at both the server and browser side of the XApp, as they appear in figure 1,
you will notice that you have Object Factories in the server side and Live Objects in the
Browser side of your application. While this diagram should give you a better understanding
of how an XApp works, it can be a bit misleading, because it gives you the idea that no code
executes on the server, but object creation code. That is not true.
What you see represented in figure 1 is a generalization or simplification of how things work.
As we will see, behind all their simplicity of use, the Morfik AppsBuilder and the Morfik
Framework hide a great deal of sophistication and complexity. It is all this backstage, behind
the scenes work, that empowers you to create simple code.

Stateless Vs. Statefull Server Architectures


A stateless server architecture is one in which the server application retains no
state control information through its running-cycle. This means that each call made
to the server must carry all the necessary information for the server to decide
what to do and how to do it, since it does not rely on any previous information.
A statefull server architecture, on the other hand, implies that the server does
keep track of what its clients are doing and what is the state of each client ’ s
connection. This means that on calling the server you can rely that the server will
remember what you were doing previously (and actually remember who you are)
and act accordingly.
On a direct comparison, the stateless architecture offers the advantages of
scalability and reliability. Having a totally stateless server application means you
can immediately deploy it to any number of servers and implement load balancing

Page 121
between them. Since there is no state retained on the server, it is indifferent to
the clients which server they had previously "talked" to. The fact that the server
retains no memory of a previous call also makes it more difficult to end up in a
state that will cause the server to crash.

Morfik High-level Objects


In developing Morfik Applications, or XApps, you will come to deal with two very different kinds
of objects. Let ’ s name these: Common Objects and High-level Objects. What is the
difference between them?

Morfik Common Objects are objects that are created just like any class is defined in common
OOP languages such as Java, C# and Object Pascal. In fact you can create them in the Morfik
AppsBuilder using anyone of those languages, as well as BASIC. Common Objects work no
differently in Morfik than they do in any other language.

Figure 2 - Components of a Morfik High-level Object at runtime

Morfik High-level Objects on the other hand, are much more complex entities which have more
than one set of code and data representations and which get special treatment in the Morfik
Workspace along with some "compiler magic" to make them easy for the developer to work
with. These objects have both a server and a browser side code image, which will allow these
objects to work on both sides of the XApp, whenever appropriate.

In figure 2, you can see a small diagram that will help you understand the complexity of the
Morfik Objects we are talking about here. These are not your everyday, OOP language
objects but much more complex entities that are, internally, composed of two different sets of
code (for the server and the browser), an HTML (or XHTML) representation and an XML
representation of its data.

Note
It is important to have in mind that all the runtime components of a Morfik
High-level Object are generated by the Morfik Compiler and that the developer
does not need to know any HTML or XML, or JavaScript for that matter, to work
with such an object.

Page 122
Figure 3 – Temporary Live Object on the Server Component of an XApp.

If High-level Objects have a Server Component to them, shouldn ’ t there be a live object at
the server side of the XApp? In theory yes, but the Morfik Framework handles dynamic
creation and destruction of such live objects as they are required. Since the server does not
maintain state information, an object ’ s server side representation exists only for very brief
moments as they perform an action which was required by the browser side of the XApp.

You can imagine that you are creating an application which will run totally inside the browser
and that the server is what we could call an "object server" which creates new objects as
they are needed for use in the browser side of the application and sends them across the
wire to the browser, but you should remember that if you are creating a Web Application
(instead of a Browser application), even if small, it has parts that run on the server.

Which High-level Objects exist in Morfik?


As I mentioned, High-level objects get special treatment in the Morfik Workspace, therefore
we can know their base types by, mainly looking at the Workspace itself. Morfik High-level
Objects are generally referred to as documents in the Workspace and treated as such,
through its interface. Let ’ s have a look at the most commonly used High-level Objects in the
Morfik Framework.

Forms
Morfik Forms are the main interface to your application and, if it is a data-driven application, to
the data that is held within its database. They are designed as High-level Objects that mostly
run natively in a web browser. This means that anyone who has a modern browser and
access to the web, or a local machine that is running your application, can view your Forms.
They do not need proprietary software; they do not need to download any further plug-ins.
They can simply view your Form, as it is.
Every time you create a Form in the Morfik Workspace you are actually creating two Common
Object classes in your code: one for the server and one for the browser side of the
application. Both of the classes will be descendant from a Form class, but they will be two
different Form classes that are specifically designed for use within a browser or on a server.
Through special treatment by the Workspace and the compiler these classes are combined
into what we have been calling a High-level Object, which has both a server and a browser
side representation. Both of the ancestor classes for your Common Object classes are part of
the Morfik Framework.

Page 123
Figure 4 – Parameters dialog box showing a large set of them defined for a form.

When you create a new High-level Form Object, you are creating your descendants of the
Common Object Form classes. You are creating two entities which will have very different
behaviors at runtime but which, at the same time, are very tightly integrated, thus
representing the High-level Object. When, for example, you add items to a Form ’ s
Parameters property, they are added to the respective properties of both Forms. At runtime,
Morfik ’ s Framework makes sure that whenever an event is triggered in one of the classes,
the correct, updated, values are transferred from one side (browser or server) to the other.
This ensures that no matter where your code is running those parameters hold the correct,
valid, values.

A Form ’ s parameters are, therefore, very important since they are shared between the
server and browser sides of the XApp and thus becoming the path to keep information in
synch between the two sides of an application. In this way you can write applications that
have complete knowledge of their current state stored on the browser side, making the
server completely stateless, but which you can program as if that information was on the
server.

Looking at the parameter list that is shown in figure 4, you will notice that some of the
parameters appear in a lighter color. These grayed items are either system parameters,
defined for all forms, or parameters of a query which has been defined as a data source for
the Form.

Page 124
Figure 5 - Form parameters cross the browser/server border.

Forms and Data. a tight coupling


In the Morfik Framework, Forms and data are very tightly coupled. Each Form has a
DataSource property which can be directly assigned a Table or a Query, as defined visually in
the respective editors. What does this mean? It means that Morfik has made the leap of faith
that almost all modern applications use some sort of database and has decided to make data
access a central tenet of the Framework and not an add-on. Though you still have the a
DataSource object as a property of your Form, its use and customization is very tightly
integrated with the other classes and the Workspace itself.

When you create a Query, in Morfik ’ s visual query editor, you can specify query parameters
which you can then take advantage of to generally reuse the query in different situations.
Whenever you assign such a Query as the data source of a Form, its parameters will get
added as parameters of the Form. What this means is that whenever you pass parameters to
the Form you can actually be passing parameters to the underlying Query, also.

Note
Although originally created with server side support in mind, data access support
is present in Morfik Browser Application projects too. Browser XApps have XML
Data Sources which allow them to use most of the data-aware features of the
Morfik Framework for displaying information. Data is stored in XML files and is
read-only.

SubForms
The Morfik tools work with a type of control, the SubForm, which is very frequently used in all
sorts of different manners. SubForms are particularly useful for the creation of complex
interfaces where parts of a page change without the need to reload the entire page.

SubForms are very important in that they allow the developer to place one Form Object inside
another, thus allowing for the construction of very rich interfaces. In essence, SubForms allow

Page 125
you to transform any Form into a control.

The OpenForm Function


Though the OpenForm function is not a method of the class Form, it is heavily used for opening
forms inside the SubForm components or in place of the current Form.

Following is an example of the usage of the OpenForm function which is shown in greater
detail in specific topics.

OpenForm ( 'eMailP roductForm' , 'Index:MainArea' ,


'' );

In this example the eMailProductForm is being ordered to display inside the SubForm MainArea
of the Index Form. The empty string in this call is a parameter which allows for the passing of
parameters to the Form which will be opened.

It is important to have in mind that a call to the OpenForm function is totally asynchronous. As
you can see in the Pre-fetching Forms topic of Working with Forms , you can call the function
several times in a row and you will start the download of several Forms at the same time.

For developers used to working with other class libraries, this way of calling up a Form, which
relies on a function call instead of on the Form ’ s methods, might, at first, seem strange.
Morfik ’ s OpenForm function, in reality, relies on the Form ’ s methods and uses syntax which
would look quite familiar to those who come from a Delphi or Visual Basic background. The
reason for the function ’ s existence is to actually hide away the complexities associated with
the asynchronous nature of a "web" application. In this way, OpenForm actually simplifies the
developer ’ s work by handling this asynchronous nature without letting any of this show
through.

Intelligent Form Caching


The Morfik Framework implements its own, intelligent, Form caching at the browser side of
your application. It is this mechanism that allows you to pre-fetch Forms is described in in
specific topic, thus allowing for a much faster end-user experience while accessing your
website or online application. It is important to understand that this caching mechanism is in
no way related to the browser ’ s own cache. It is entirely implemented by the Morfik
Framework and comes into play when your application ’ s first/index/home form is first
loaded.

OpenForm Syntax

OpenForm(form, context, parameters);


||
| |__ blank - new browser window with new instance of script process (AJAX en
gine)
||
| |__ same - same browser window with new instance of script process (AJAX e
ngine)
||
| |__ FormInstanceName:SubformName[(bandindex)]
| | | |__ if not specified it's set to zero
|||
|||
| | |__ special strings: '_' ('_' denotes the containing
| | subform)
||
| |__ special strings :'self','parent','top'
|
|__ URL (this will result in a new instance of the script process to be instantiat
ed)
|

Page 126
|__ instancename:classname
|
|__ classname (in this case the instance name is implicitly set to be the same as

the class name)

If you want to explicitly use the Morfik Framework ’ s intelligent cache mechanism in your
application, you can do so by specifying the special parameter "OpenMode=DONOTACTIVATE"
in the third parameter position of the OpenForm function as shown in the example below:

OpenForm ( 'Form2' , 'Self:MainSubForm' ,


'"OpenMode=DONOT ACT IVAT E"' );

For more information, please see Working with Forms .

Reports
A Report is another kind of Morfik High-level Object which receives special treatment in the
Morfik AppsBuilder workspace, allowing you to very easily create richly detailed reports. As
reports are entirely generated on the server side of an application, they are only available in
Web Application projects and not in Browser Application projects.

A Morfik AppsBuilder Report is the most effective way to present your web application ’ s data
in a printed format. This is because you have control over the size and appearance of
everything on a report. Your design canvas directly corresponds with a single A4 or Letter
standard sheet of paper. You can, via the Report ’ s properties change such details as margin
size, the number of columns, the page breaks, and so forth. As you design you report you are
creating a new class, descendant from the Report class that is a part of the Morfik
Framework.

Though Reports seem to be very similar to Forms at a first glance, they differ significantly.
While Forms live a double life, being represented by two Common Object classes, one on the
server and one on the Browser side of the application, Reports are totally server based. This
means that there is only one class that handles all the customization of the report.

In a Morfik XApp the only kind of document in which all the logic rests on the server is the
report. By design Morfik AppsBuilder reports are totally processed on the server and then
transferred to browser in the print-ready PDF (Adobe ’ s Portable Document Format) format.

Morfik AppsBuilder Reports are created natively as PDF documents. This means that they can
be read via the web browser through the Adobe Acrobat Reader. The WYSIWYG (What You
See Is What You Get) nature of PDF documents make them perfect for printing. Your reports
are printed in exactly the same manner in which they are shown. This method of printing is
universal over all platforms, computers, operating systems, and printers. That is, virtually
anyone can print a Morfik Report without having to download any extra pieces of software,
due to the ubiquity of Adobe ’ s free Acrobat Reader. If a user does not have Acrobat Reader,
it can be downloaded for free.

Morfik reporting is built around a sophisticated report generation engine that allows you to
create documents at run-time that are not only data-driven but fully utilize features such as
sorting and grouping, which developers have come to expect from packages such as Crystal
Reports and Microsoft Access.

The OpenReport Function


Just as you have the OpenForm function for bringing up Forms, there is an OpenReport function
for handling reports. This function works very much like the OpenForm function. Below you can
see a simple example of how to use it.

OpenReport ( 'RptContactsList' ,
'' );

Page 127
As it happens when working with Forms and the OpenForm function, the OpenReport function ’
s main purpose is to make the developers ’ life easier by hiding away some of the
complexities related to the building an applications interface inside the browser.

For some additional information, please see Documents Overview .

Web Methods
The Web Methods are also High-level Objects, having both a server and a browser side
Common Object implementation, very similar to what happens with Forms. This kind of Object
is a very interesting addition to the Morfik Framework. This Object allows for the quick
implementation of "functionalities" on the server side of a Morfik XApp which can be called, in
a very simple manner, from the browser side of the application.

As with Forms, Web Methods are divided into two separate personalities, the browser side
and the server side. There are basically two "WebMethod" classes in the Morfik Framework,
one for each side of the application. When you are creating your own WebMethods you are
creating two descendants of these classes, one of each, which together will comprise your
High-level WebMethod Object.

Differently from Forms, whose primary function is browser specific, Web Methods are very
much server focused. A reasonable analogy would be to compare them with stored
procedures in databases, as Web Method code is primarily intended to run on the server side
with the browser side code being intended to treat the returning call. Due to this
characteristic, Web Methods can only be created in the Web projects of Morfik AppsBuilder.

Web Methods are the methods published by your XApp, which is in itself a Web Service. The
WebMethod classes allow you to easily create server "functions" that can be easily called
whenever necessary. This is done without exposing the developer to any unnecessary
complexity.

Though normally associated with a server-side functionality, within the realm of your own
application, called from the browser-side application logic, the server implementation of the
web method can be directly called from another web method.

Listing 1 – Browser side code for the @ARITHMETIC webmethod@

namespace @ ARIT HMET IC webmethod @


{

public class @ ARIT HMET IC webmethod @ :


WebMethod
{
published bool Browser ;
published double Value1 ;
published double Value2 ;
published string Operator ;

public override void HandleResponse ()


//P erforms arithmetic operations
{
double d ;

// If "Browser" parameter is False the function ends.


if (! Browser ) return ;

// If operator is "Add" then performs addition operation


if ( StringsEqual ( Operator , "Add" ))
d = Value1 + Value2 ;
// If operator is "Subtract" then performs subtraction
// operation
else if ( StringsEqual ( Operator , "Subtract" ))
d = Value1 - Value2 ;

Page 128
// If operator is "Multiply" then performs Multiplication
// operation
else if ( StringsEqual ( Operator , "Multiply" ))
d = Value1 * Value2 ;
// If operator is "FloatDivide" then performs division
// operation (results a float type)
else if ( StringsEqual ( Operator , "FloatDivide" ))
d = Value1 / Value2 ;
// If operator is "IntegerDivide" then performs division
// operation (results an integer type)
else if ( StringsEqual ( Operator , "IntegerDivide" ))
d = Round ( Value1 ) / Round ( Value2 );
// If operator is "Remainder" then performs a mod
// operation resulting the division remainder, an integer
else if ( StringsEqual ( Operator , "Remainder" ))
d = Round ( Value1 ) % Round ( Value2 );

// Shows the arithmetic operation result


ShowMessage ( FloatT oStr ( d ));
}
}
}

Listing 2 – Server side code for the @ARITHMETIC webmethod@.

namespace @ ARIT HMET IC webmethod @


{
public class @ ARIT HMET IC webmethod @ :
WebMethod
{
published bool Browser ;
published double Value1 ;
published double Value2 ;
published string Operator ;

public override void Execute ()


//P erforms arithmetic operations
{
double d ;

// If "Browser" parameter is T rue the function ends.


if ( Browser ) return ;

// If operator is "Add" then performs addition operation


if ( StringsEqual ( Operator , "Add" ))
d = Value1 + Value2 ;
// If operator is "Subtract" then performs subtraction
// operation
else if ( StringsEqual ( Operator , "Subtract" ))
d = Value1 - Value2 ;

// If operator is "Multiply" then performs Multiplication


// operation
else if ( StringsEqual ( Operator , "Multiply" ))
d = Value1 * Value2 ;
// If operator is "FloatDivide" then performs division

Page 129
// operation (results a float type)
else if ( StringsEqual ( Operator , "FloatDivide" ))
d = Value1 / Value2 ;
// If operator is "IntegerDivide" then performs division
// operation (results an integer type)
else if ( StringsEqual ( Operator , "IntegerDivide" ))
d = Round ( Value1 ) / Round ( Value2 );
// If operator is "Remainder" then performs a mod
// operation resulting the division remainder, an integer
else if ( StringsEqual ( Operator , "Remainder" ))
d = Round ( Value1 ) % Round ( Value2 );

// Shows the arithmetic operation result


ShowMessage ( FloatT oStr ( d ));
}
}[ 'P ublished=False' ];
}

Listings 1 and 2 show the implementation of a WebMethod in the C# language. In order for
you to use such a WebMethod, you need to call it using the RunWebService function. Listing 3
shows the Browser side code of a Form which demos the use of this function.
Listing 3 – Browser side code for the @ARITHMETIC form@.

namespace @ ARIT HMET IC form @


{

public class @ ARIT HMET IC form @ : Form


{
published T extEdit Value1 ;
published ComboBox Operator ;
published T extEdit Value2 ;
published Button Go ;
published CheckBox Browser ;

published message void GoClick ( T DOMEvent Event )


{
/*

Run Web Service calls a Web Method named "ARIT HMET IC webmethod" to pe
rform
the arithmetic operation passed as string on parameter Operator with Value1
and Value2 parameters. Browser parameter indicates if the server or browser
part will be executed.
*/
RunWebService ( "ARIT HMET IC webmethod" ,
"""Value1=" + Value1 . T ext + """," +
"""Value2=" + Value2 . T ext + """," +
"""Operator=" + Operator . T ext + """," +
"""Browser=" +
BooleanT oString ( Browser . Checked ) + """" );
}

Page 130
For some additional information, please see Working with Web Methods .

XApp – The Morfik Application High-level Object


All that we have been seeing in this chapter occurs under the direction of an XApp and this
term has been frequently used throughout this text. An XApp is an object of the TXApp class
that represents the Morfik application, or better yet, two objects of the two TXApp classes
that exist in the Morfik Framework. These objects "organize" how things work in your
application. It is rather interesting that though a Morfik application is essentially a
browser-based application, meaning an application that runs mostly inside the web browser;
the TXApp class has as much a double personality as does the Form class.

Let us take a quick look at some of the major features and functionalities of the TXApp class
both on the server and on the browser side of your application.

Server side XApp – Your binary application


On the server side, the XApp is your application. It represents your executable and has
events related to its start and shutdown. It is also responsible for interfacing with the Apache
core library that handles the basic web server functionalities of the application and for
launching a web browser, if starting as a service.

Events
The TXApp class offers a pair of server side events which you can use to trigger special
actions when the binary application starts up and shuts down.

OnStartUp
This event is triggered when a XApp is launched or loaded as a service. It happens once in
the execution-lifetime of your application.

OnShutdown
This event is triggered when a XApp is terminating. It happens once in the execution-lifetime
of your application.

Browser side XApp – Your Ajax application


Since your application runs mostly inside a web browser, the browser side XApp will be the
one you have most contact with, while building your application. There are several very useful
properties and events in this class which you can use in your code.

Events
On the browser side of your application the TXApp class also offers a pair of events.

OnBeginLoad
This event is triggered every time the browser sends a request to the server, as the request
is sent.

OnEndLoad
This event is triggered every time the browser sends a request to the server, as the request
is completed.

The OnBeginLoad and OnEndLoad events would be ideal places for you to, for example,
implement the on and off "loading..." message which is generally used in Ajax applications
that go through large scale interface transformations. The www.morfik.com website is a good
example of this behavior.

Properties
Just as on the server, on the browser side of your application, the TXApp class offers several
properties which might come in handy in different situations.

Page 131
Forms Property

The Forms property allows you to have access to all the Forms that exist in your application.
The code snippet that follows exemplifies a way of accessing these forms. (In this Pascal
example we take the Index form from the collection of XApp forms and typecast it to the Index
form class).

with Index ( xApp . Forms [ 'Index'


]) do
begin
btnNew . Enabled := False ;
btnP rint . Enabled := False ;
end ;

Wrapping it up
The Morfik Framework offers not only a wide range of classes, functions and High-level
Objects for use by the application developer, but a sophisticated services infrastructure that
combines with the class and function library. As you familiarize yourself with these entities
and the behavior of the services you should notice your individual productivity climbing.

See Also
 Working with Forms
 Working with Web Methods

 Working with Controls


category:Programming

Page 132
Documents Overview

There are two kinds of visual documents in Morfik projects: Forms and Reports.
Forms are available in all types of projects, while Reports are only available in the
projects with server side logic and code and therefore can only be created in
Morfik AppsBuilder.

There are other types of objects which, while not visual in nature, also have visual
designers and are treated as documents in the Morfik workspace for project
management purposes. (Modules, Tables, Queries and WebMethods)

Forms
Forms are the building blocks used to create the user interface of your application. When you
create a new project using the default template, your project contains two forms: Index and
Content.

Forms can be displayed within other Forms through the use of a SubForm control or in the form
of a floating or pop up window within the browser.

Figure 3 - A freshly created blank form.

Forms when created also follow the pattern of having three sections which are called bands:
header, detail and footer. If the header and footer bands are not needed for your design they
can be kept to zero height or hidden from the design surface entirely.

Figure 4 - A blank form without header and footer bands.

For more details on Forms and their usage, please refer to the specific topics on Working with
Forms .

Page 133
Reports
Reports are designed in a very similar manner to Forms, though their nature is very different.
The design surface for a Report should look quite familiar, once you have created a few Forms
in Morfik tools. Morfik Reports also have three sections or bands by default: Page header,
Detail and Page Footer. While Forms are intended to interact with the user through the
browser, reports are meant to be printouts.

Figure 5 - A freshly created blank Report.

Due to the fact that printing an HTML based page from a browser will result in the browser
adding its own page header and footer which might contain unwanted information, Morfik
Reports are generated as PDF files. The PDF format is generally accepted as a portable format
for documents and supported on all major computing platforms.

Morfik Reports were conceived as a means of allowing a custom web-based application to print
documents such as invoices or receipts and are not intended as a substitute for existing
corporate reporting systems.

See also
The Workspace

Page 134
Working with Forms

One of the major differences between Morfik tools and all other development tools
for the creation of Web applications is that the WebOS AppsBuilder does not force
the developer to understand how a browser works or how remote calls to a
server happen. The developer does not need to know how to code HTML, XHTML,
CSS, ASP, PHP, SOAP or whatever other acronym that has ever been invented to
describe techniques and file formats for web development. Applications for the
Web are developed in the same way that common applications are developed
using tools such as Borland ’ s Delphi or Microsoft ’ s Visual Studio.

When I first tried out Morfik AppsBuilder I was immediately impressed by how easy
it was to create the basics of a web application, without actually doing any coding.
What is more impressive was that not only did it not ask me to write any HTML or
scripting code, but it did not spit these out at me. I have seen many tools that
allow you to design HTML form interfaces and generate the corresponding HTML
files for you. Up to that moment they had been the pinnacle of web development
tools for me. Tools that offered WYSIWYG HTML design and were able to organize
your scripting code were the best one could expect. After ten years of intense
development efforts by people all around the world that was as far as we had
come.

New languages had been created and were flourishing. A major example of this is
the PHP scripting language currently in use in thousands, if not millions, of web
servers all around the globe. Techniques had been developed and file and data
formatting standards created. New terms such as SOAP and XML had come into
the everyday life of the software developer, or at least of those trying to stay in
synch with what was being developed. Things had been progressing at a frenetic
pace, driving us forward into new and unexplored frontiers such as hosted
Customer Relationship Management and even Word Processors, available on the
web.

A Problem To Be Solved
Taking Visual RAD to the Web
A Page By Any Other Name
Every Page is a Form, But Not All Forms are
Pages
Where Does an Application Start?
Designing a Form
What is a SubForm?
Forms Have Bands
Using the OpenForm Function
Pre-fetching Forms
Form Events
Data Manipulation Events
Data Navigation Events
Data Refresh Events
Form Instantiation Events
User Interface Interaction Events
OnBlur
OnClick
OnFocus
OnKeyDown

Page 135
OnKeyUp
OnMouseDown
OnMouseMove
OnMouseOut
OnMouseOver
OnMouseUp
OnResize
OnScroll
Browser Management Events
OnReadHistory
OnWriteHistory
Form Band Events
Browser Side Events
OnAfterGrowOrShrink
OnBeforeGrowOrShrink
Server Side Events
OnAfterPrint
OnBeforePrint
OnPrintStyle
Data Bound Forms
What Makes a Form Data Bound?
Two Kinds of Data Bound Forms
Continuous Forms
Single Forms
Positioning the Controls on a Form
Configuring the Form Designer
Wrapping it up
See also

A Problem To Be Solved
The only thing that bothered me was that I always thought that development tools were going about
this in the wrong way. Why? Well let ’ s go back a couple of years... I used to work a lot with Borland
’ s Delphi and Microsoft ’ s Visual Basic, two very similar, yet very different development tools. They
were similar in the interface that they provided to the developer and in the way you could extend
them with user-created components. They were different in how things were implemented under the
hood. While Visual Basic was an interpreted language, depending on an extensive runtime library to
execute applications and thus limiting what you could build with it (its own add on components had,
for a long time, to be built with another language), Delphi was a native compiler which produced first
class binary executables for the Win32 platform.

Both of these tools, as well as several others, hid entirely from the developer all the necessary
plumbing for getting a Windows application up and running. Using the Windows Software
Development Kit (SDK) and a C compiler, you needed to write one hundred and seventeen lines of
code just to display an empty blank window, which did nothing. Later tools such as Turbo Pascal for
Windows and Visual C would cut that down to twenty to thirty lines, by using extensive and
elaborate class libraries (OWL and MFC).

It was into that scenario that Microsoft introduced Visual Basic as a tool for the speedy creation of
simple applications for Windows. It totally hid all the complexity of the Windows environment and

Page 136
allowed developers to get an empty window up and running with zero lines of code. It was a major
breakthrough and soon developers started flocking towards it. Borland took this new way of
developing Windows applications to a whole new level when it introduced Delphi. Delphi offered the
same ease of use of Visual Basic but instead of depending on a runtime and interpreted code, had an
IDE that generated code, on-the-fly, for using its sophisticated and high-level class library, called the
Visual Component Library (VCL). The VCL was entirely written in Delphi and, again, totally hid the
details of how the Windows environment worked. It allowed you to create the same zero lines of
code window, but it did so as a native binary application which although it still did nothing, did it with
a reduced size and better performance. This was the era of visual tools and Rapid Application
Development (RAD).

Taking Visual RAD to the Web


So, why are we talking about developing applications for Windows with tools from Microsoft and
Borland when this is a book about Morfik? Well, I want to make a point. Back in the days of the pure
C and SDK development for Windows it was important, maybe even cool, to know all the hundreds of
functions of the Windows API. (I read the manuals for it.) You had to know how Windows worked in
order to be able to develop anything for it. Even the simplest of applications required the
understanding of things such as creating a message processing loop, painting text onto the screen,
etc, until these visual development tools, I mentioned, came along. When the World Wide Web hit us
in the face, in 1995, it was all about text and content. As its convenience and ubiquity grew, it soon
became a platform for application development and delivery and so we were back to the time when it
was necessary to know how things worked in order to get anything done. This time, instead of
needing to know how Windows worked we needed to know how the Web worked. It was studying
HTML, JavaScript and server/browser communication instead of the Windows API. One interesting
aspect of it was that it all seemed very easy. You could just bring up notepad and type in a web
page.

Development tools for the Web soon took us beyond notepad. But as each new tool appeared and
evolved it was always about making it easier for you to use the "Web API", and not about hiding it. It
seems that people just decided that it was too important that everybody know how this stuff worked
- until Morfik came along. The people that started Morfik had the same belief that I had; that it was
unacceptable that someone had to learn all that stuff (HMTL, XHTML, JavaScript, Blah, Blah...) in order
to be able to write simple applications for the Web. They perceived that the Web had, in fact, become
an application platform, as had Windows before it and that people needed a more productive way to
develop applications for this platform. Luckily for all of us, they had the resources and the will to apply
these, as well as their time, to this problem and bring us to this point.

Now, working with Morfik WebOS AppsBuilder we can go back to talking about forms and controls and
business needs without having to worry about learning how the Web works. We have been using it
for over a decade and it is about time that we let go of the text files and start developing real
applications for this wondrous new platform. This is what this chapter is about: Working with Forms
and how it is different from working on legacy web applications. Although Morfik forms are very similar
to windows forms at design time they are quite different at run time.

This is quite deceptive and could potentially become an impediment if the distinct run time model for
Morfik forms is not understood early in the learning cycle

A Page By Any Other Name


In the WebOS AppsBuilder we do not write pages, but design Forms. How can that be, when the
Web itself works with Pages? Well, we do work with Pages; we just don ’ t need to think of them
quite that way, most of the time. The main interface metaphor used by the AppsBuilder is the Form,
as in all major Windows development tools. This is a significant difference because when software
development became Page-centric, to accommodate the way things worked on the Web, it missed
the point that Web Pages were for delivering text content and not interactive applications. Modern,
Ajax enabled, Web applications have few pages, but these pages go through several changes in
appearance in order to interact with the user. With Morfik AppsBuilder you design Forms for user
interaction and not just text presentation.

Another major difference between Morfik Forms and HTML Pages is that the Forms can be
self-containing (both at design time and at run time) and therefore extremely modular. HTML pages
are NOT! Though you can use server side to compose a Page from several HTML snippets, you cannot
say that you define an HTML Page in terms of other HTML Pages.

Due to this characteristic the layout and, more importantly, the behavior of an arbitrarily complex
page can be recursively reduced down to simpler and simpler Form constructs.

In several of the previous chapters of this book, I have used WebOS Forms as examples of how

Page 137
things are done in the AppsBuilder and how you can use your language of choice to develop
applications. In this chapter we will go a lot deeper into what Forms are and how they are used.

Every Page is a Form, But Not All Forms are Pages


One of the most important things to know about Forms is that in the WebOS AppsBuilder all Pages
are Forms, but not all Forms are Pages, just as all squares are rectangles, but not all rectangles are
squares. This might seem a bit confusing, at first, but it is really simple. Forms can represent not only
an entire Page, but portions of a Page. You can actually build Forms that are composed of several
other Forms. For every page in your application you will have a "top level" Form which may or may not
contain other Forms in SubForm controls. While this might not seem like much at first, you will soon
see that this simple feature opens up enormous possibilities in application interface design. This is
particularly true because in contrast to the Windows environment where building interfaces based on
user created visual components, such as Forms, might have added "weight" to the application, the
WebOS AppsBuilder knows how to translate your interface design into the appropriate dynamic HTML
code without adding unnecessary weight to your application. The diagram in Figure 1 should give you
a general idea of how a Page/Form can be composed of several Forms (in this case called SubForms).

Figure 1 – Page/Form composition by using SubForms.

Where Does an Application Start?


When you create a new project in the Morfik IDE, it already has its first Form. This Form is called Index
and it is the default starting Form for you application. This closely parallels the way web servers work,
since most expect a Page called Index.html to be present in the directory that is being published. You
can change the name of this Form or specify any other Form as the default startup Form for your
application by going to the Application tab of the Options dialog and changing the Main Form property
It is this project property that tells the Morfik compiler which of the Forms that make up the project
will be the entry point for your application.

Designing a Form
In the Morfik WebOS AppsBuilder it is very easy to build Forms. It is, actually, very much like building
Forms in any modern visual development environment for Windows. Once you enter the Form
Designer you will see a floating palette of controls that can be used to create the interface of your
application. There are several different controls that can be used in combination to achieve very
interesting results.

Page 138
Figure 2 – Form Designer ’ s Toolbox

In Figure 1 you can see a view of the toolbox with the available controls. As all who have developed
applications in a visual IDE will notice, the main controls are the same as you would have in such a
tool. Let ’ s review some of the basic controls:

Glyph Control
TextLabel – This control is mainly used for displaying information
(text) in the Form/Page being constructed. It can easily be used to
represent a hyperlink.

TextEdit – This is a control geared towards editing single-line text.


It can be used for entering multi-line text through the configuration
of the MultiLine and WordWrap properties.

Button – A clickable button. Normally used to start some sort of


action.

OptionButton – generally used to provide choices

CheckBox – This control is used to allow the user to change/display


the current state of a boolean type variable.

ListBox – Used to display a list of options for the user to choose


from.

ComboBox – Used to display alist of options for the user to choose


from, which drops down right bellow a TextEdit..

DATE/TIME – Single line edit field (such as the TextEdit control)


specialized for date information input.

Container – As the name suggests, it is used to "contain" other


controls. Different formatting attributes can be applied to group or
highlight different elements in a Form.

Image – This control displays an image on the Form.

TabControl – With the TabControl the developer can visually group


related controls in different tabs on the Form, providing better UI
space management.

Flash – The Flash control allows the developer to insert any Flash
element into a Morfik Form.

Page 139
SubForm – With the use of the SubForm control you can embed
Forms within Forms. This allows the creation of sophisticated
applications through Form composition.

File Uploader – This control allows the selection and uploading of


files.

Timer – The timer control continually generates an event on the


browser side of the Form, allowing the developer to update or
refresh some portion of the user interface.

Rectangle – This control paints a rectangle on a form and is


generally used as a layout/formatting aid.

RSS – This option allows editting or creating a new RSS feed in the
current project.

In order to place any of these controls on a Form, all you have to do is click on the control button and
then click on the Form itself. A control will be created on the Form, exactly on the spot you clicked.
After the control appears you can drag it on the Form to adjust its position. Once the control is in the
desired position you can set its properties in order to select the desired appearance and behavior.

Figure 3 - The properties Window

In Figure 3 you can see a view of the Properties Window . It is the configuration of these properties
that allow the appearance and behavior of the components you add to the Form.
Properties in the Properties Window are grouped together in Tabs, such as: Format, Data, Event, Other
and All . Through the Event tab you get access to a complete list of events for the currently selected
component, and can choose to write code to handle any particular one.

You can also use the Properties Window to set properties for the Form itself or any of its bands.

If you double click the empty field besides the name of an event in the Event tab of the Properties

Page 140
Window a code stub for that event will be created and the code editor will be displayed so that the
event code can be inserted.

What is a SubForm?
One important question you might be asking yourself is: what exactly is a SubForm? I have talked a
lot about SubForms, but I have not gone into great detail. It is time to remedy this.

SubForms are special controls which can host Forms inside them. When placed on a Form a SubForm
is shown as a hashed area, as can be seen in Figure 4. Forms can be linked statically to SubForms, at
design time by assigning a form name to the Form property, or at runtime through the use of the
OpenForm function.

When statically bound to a Form, the SubForm control displays the Form name in parenthesis,
besides its own name.

Why Build Forms with other Forms?

Ok, I have mentioned that you can build Forms from other Forms, as shown in Figure 1. But why
would you want to do that? Can ’ t you simply create your Forms by placing controls directly on them?
Of course you can. The idea of breaking things up into smaller parts is directly tied to the concept of
modularity. In the WebOS universe, modularity is a key concept for it allows the exchange and
reloading of parts of a Page/Form, without having to actually reload the whole Page. This makes for
much more flexible and faster interfaces for web based applications,

When you have different elements which will occupy the same space within a Page/Form, at different
moments, you will be looking at a case for modularization into SubForms. An example of this behavior
can be seen in the following sample application that I have built for this purpose. In this application
the Index Form has two SubForms which will work as navigation and information display areas during
the application ’ s runtime. In the screenshot in Figure 4 you can see this application ’ s Index Form
loaded in the Morfik IDE Form editor.

Figure 4 – Index Form (initial application starting point) loaded in the Form Editor

Page 141
In the screenshot in Figure 4 the thin vertical SubForm on the left of the Form is the NavigationArea
SubForm, while the larger one is the MainArea SubForm. These SubForms display the names of the
forms that will be automatically loaded into them.

Forms Have Bands


In the Morfik WebOS Forms have bands, three in all, that are used to divide up the Form for
implementing specific behavior. The three bands are: Header, Footer and Detail. In the example in
Figure 4 you can see all the three bands in use. Notice that they can totally different formats,
including background color.

Figure 5 – The HostingPlans Form shown.

Figures 5, 6 and 7 show the same page as Figure 4, with different forms displaying inside the
MainArea SubForm control. Both the NavigationArea and the MainArea SubForm controls are inside the
Detail band of the Index Form.

In Figure 5 you can see the HostingPlansForm being displayed inside the MainArea SubForm control in
the Index Form. This Form has a Tabs control which shows a different tab for each of the hosting
plans being advertised.

Page 142
Figure 6 – The eMailProduct Form shown.

In Figure 6 you see the Index Form after the eMail button on the Navigation bar has been clicked.
Now the eMailProductForm is being shown in the MainArea SubForm. Notice that the application (or
site) is still in the same page and only the content of the area belonging to the MainArea SubForm
control has changed.

In Figure 7 you will see the same Index Form showing the contents of the InfrastructureForm in the
MainArea SubForm.

In order to get these results with the WebOS AppsBuilder all we have to do is create separate Forms
and then piece them together either statically or dynamically. As this application starts up it will load
two distinct Forms into the SubForm controls. One of these is the NavigationForm and the other is the
HostingPlansForm . These Forms are loaded statically because I have associated their names to the
Form property of their respective SubForm components.

Almost all the functionality in this application/site is automatically provided by the Morfik runtime
library. The only code really written in this application at this time is in the code included in the OnClick
events for each of the Button controls that are present in the NavigationForm . In each case it is a
single line of code that specifies a new Form to be opened inside the MainArea SubForm control.

Page 143
Figure 7 – The InfrastructureForm Shown.

In Listing 1 you will find the code for the NavigationForm ’ s browser module. Most of the code is
automatically generated by the AppsBuilder, requiring the developer to write, only the appropriate
commands to switch the Form that is visible on the page in the browser.

Listing 1 – Browser side code (in Morfik Pascal) for the NavigationForm.

Unit NavigationForm ;

Interface

T ype
NavigationForm = Class ( Form )
T extLabel1 : T extLabel ;
HostingButton : Button ;
eMailButton : Button ;
InfrastructureButton : Button ;
P rocedure HostingButtonClick ( Event : T DOMEvent ); Message ;
P rocedure eMailButtonClick ( Event : T DOMEvent ); Message ;
P rocedure InfrastructureButtonClick ( Event : T DOMEvent );
Message ;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
End ;

Implementation

P rocedure
NavigationForm . HostingButtonClick ( Event : T DOMEvent );
Begin
OpenForm ( 'HostingP lansForm' , 'Index:MainArea' , '' );

Page 144
End ;

P rocedure NavigationForm . eMailButtonClick ( Event : T DOMEvent );


Begin
OpenForm ( 'eMailP roductForm' , 'Index:MainArea' , '' );
End ;

P rocedure
NavigationForm . InfrastructureButtonClick ( Event : T DOMEvent );
Begin
OpenForm ( 'InfrastructureForm' , 'Index:MainArea' , '' );
End ;

End .

The code in Listing 1 brings us into contact with function/procedure which will be widely used in
everyday development of WebOS applications: OpenForm.

Using the OpenForm Function


The OpenForm function is used for opening forms inside the SubForm components or in place of the
current Form. In the example we just saw in Figures 2 through 5 all Forms were displayed inside
SubForms.

Observe an example of the usage of the OpenForm function taken from the above example:

OpenForm( ’ eMailProductForm ’ , ’ Index:MainArea ’ , ’’ );

In this example the eMailProductForm is being ordered to display inside the SubForm MainArea of the
Index Form. The empty string in this call is a parameter which allows for the passing of parameters to
the Form which will be opened.

It is important to have in mind that a call to the OpenForm function is totally asynchronous. As you
will see in the Pre-fetching Forms topic, you can call the function several times in a row and you will
start the download of several Forms at the same time.

OpenForm Syntax

OpenForm(form, context, parameters);


||
| |__ blank - new browser window with new instance of script process (AJAX engine)
||
| |__ same - same browser window with new instance of script process (AJAX engine)
||
| |__ FormInstanceName:SubformName[(bandindex)]
| | | |__ if not specified it's set to zero
|||
|||
| | |__ special strings: '_' ('_' denotes the containing
| | subform)
||
| |__ special strings :'self','parent','top'
|
|__ URL (this will result in a new instance of the script process to be instantiated)
|
|__ instancename:classname
|
|__ classname (in this case the instance name is implicitly set to be the same as the clas
s name)

Page 145
In the Rio de Janeiro Hosting example we have just seen, all uses of the OpenForm function followed
a specific pattern: opening a form in the MainArea SubForm. In the line below, taken from the
example, the first parameter is the class name for the Form you wish to open, and the second one is
the name of the SubForm component where you wish it to appear.

OpenForm( ’ eMailProductForm ’ , ’ Index:MainArea ’ , ’’ );

In this example the second parameter is specifying that we wish to open the Form in the SubForm
MainArea which is in the Form Index .

In this example you do not see any Form being opened in the NavigationArea SubForm. That is
because we have statically bound the NavigationForm Form to this SubForm control in the Index Form.
This is done, through the Properties Window, by setting the Form property of the SubForm control.

Pre-fetching Forms
The Morfik Framework and runtime library implement a great caching infrastructure for your
application, which allows the developer to download pages before the user comes to need them. This
allows for very rapid response times when accessing the application.

This feature allows the developers to create applications that are much more responsive to user
interaction and input since they can predict which Forms the user might want to access and download
them in the background.

How does this work? Let ’ s consider, as an example, an application with an initial Form/Page that
presents the user with ten choices, of which you know that one of three options will be chosen by
97% of users to start with. In this case, as you finish downloading the main Form/Page you can start
the download of those three most commonly used Forms in the background.

While the user is going through the task looking at the options and deciding where to go from there,
the browser is fast at work preparing the way for a rapid response by downloading the most likely
choices. If the user selects an option before the download process is complete, the application will
just continue normally with the download process as it was doing before, only now it knows that it
should display the requested option as soon as the download is complete.

Listing 2 – Browser side code (in Morfik Pascal) for pre-fetching 2 Forms before they are
actually needed.

P rocedure Index . WebFormShow ( Var Show : Boolean );


Begin
OpenForm ( 'Form1' , 'Self:MainSubForm' , '' );
If Not DoneP refetch T hen
Begin
OpenForm ( 'Form2' , 'Self:MainSubForm' ,
'"OpenMode=DONOT ACT IVAT E"' );
OpenForm ( 'Form3' , 'Self:MainSubForm' ,
'"OpenMode=DONOT ACT IVAT E"' );
DoneP refetch := T rue ;
End ;
End ;

Form Events
Both in Listing 1 and 2 you see Pascal code for handling Form events. This kind of code should be
familiar to any developer who has worked with a modern development tool for the Windows Platform,
but Morfik ’ s Forms are not for Windows but for the WebOS and therefore will have different kinds of
events.

In order to handle events from the form, or any other control, you should double click the empty field
besides the name of an event in the Event tab of the Properties Window. As a result a code stub for
that event will be created and the code editor will be displayed so that the event code can be
inserted.

Because of the uniqueness of the WebOS environment, it is important that the developer familiarize
himself/herself with the Morfik Form Class ’ events, in order to know how to take full advantage of

Page 146
its extensive, built-in, capabilities.

Form events can be grouped into six main categories; most events occur on the browser side. Those
that relate to the server side are indicated. Here is a table list of all the form events:

Data Manipulation Events


 OnBeforeSubmit
 OnAfterSubmit

 OnBeforeDataChange
 OnAfterDataChange
Data Navigation Events
 OnBeforeDBNavigate
 OnAfterDBNavigate
Date Refresh Events
 OnBeforeRefresh
 OnAfterRefresh
Form Instantiation Events
 OnDestroy
 OnCreate

 OnBeforeExecute (Server Side)


 OnAfterExecute (Server Side)

 OnReady
 OnShow
User Interface Interaction Events
 OnBlur
 OnClick

 OnFocus
 OnKeyDown

 OnKeyUp
 OnMouseDown

 OnMouseMove
 OnMouseOut

 OnMouseOver
 OnResize

 OnScroll
Browser Management Events
 OnReadHistory
 OnWriteHistory

Data Manipulation Events


These events fire whenever there is a request made to change any data in the database connected
to the document. The order of events is as follows:

1. Request to change data (which may be invoked via the user in the browser or programmatically)

2. OnBeforeSubmit

3. The request to alter data is submitted to the database

4. OnAfterSubmit

5. If successful, OnBeforeDataChange

Page 147
6. Data is changed

7. If successful, OnAfterDataChange .

Data Navigation Events


These events fire whenever there is a request made to move from one record to another. The order
of events is as follows:

1. Request to navigate between records (which may be invoked via the menu navigator or
programmatically)

2. OnBeforeDBNavigate

3. DBNavigate procedure

4. If successful, OnAfterDBNavigate

Data Refresh Events


These events fire whenever there is a request made to refresh the document with the latest data
from the database. The order of events is:

1. Request to refresh the data

2. OnBeforeRefresh

3. If the refresh is successful, OnAfterRefresh .

These events are different, and not to be confused with the Refresh or F5 option associated with the
browser, for example Internet Explorer.

Form Instantiation Events


These events fire whenever there is a request made to create and display a new document. Note
some of these events are server side as indicated. The order of events is:

1. Request to create and display a new form (which may be invoked via the browser or or
programmatically)

2. OnDestroy (of the old form)

3. OnCreate and the document is created at the server end

4. OnBeforeExecute (performed at the server)

5. The document is sent from the server to the browser end

6. If successful, OnAfterExecute (performed at the


server)

7. OnReady when the document has been fully received by the browser

8. OnShow (fires when the form first becomes visible)

The OnReady event is associated with the instant that the browser has completed receiving and
processing the form and any associated data. Just like the OpenForm function, it serves to enable the
developer to easily and almost seamlessly, handle the asynchronous nature of the Web.

An example of when this might be useful is if the developer has created a master-detail relation using
a form and subform. It is possible that he or she wishes to activate an event in the subform only
when the master form is ready.

User Interface Interaction Events


These events fire independently in response to user actions.

OnBlur
The OnBlur event occurs when an visual control (control or document) loses focus either by the
pointing device or by tabbing navigation.

Page 148
OnClick
The OnClick event occurs when the mouse button, or any other pointing device button, is
single-clicked over the control or document.

On a PC-based mouse it specifically corresponds to a left-mouse click

OnFocus
The onFocus event occurs when a visual control (control or document) receives focus either by the
pointing device or by tabbing navigation.

OnKeyDown
The OnKeyDown event occurs when a key is pressed down over a visual control (a control or
document)

OnKeyUp
The OnKeyUp event occurs when a key is released over a visual control (a control or document)

OnMouseDown
The OnMouseDown event occurs when the mouse button, or any other pointing device button, is
pressed while it is over a visual control (a control or document). On a PC-based mouse, it specifically
relates to the left-hand mouse button being depressed.

OnMouseMove
The OnMouseMove event occurs when the mouse, or any other pointing device button, is moved while
it is over a visual control (a control or document).

OnMouseOut
The OnMouseOut event occurs when the mouse pointer, or any other pointing device button, is moved
out (off) of the region defined by a visual control (a control or document).

OnMouseOver
The OnMouseOver event occurs when the mouse pointer or any other pointing device is over (within
the region defined by it) a visual control (a control or document).

OnMouseUp
The OnMouseUp event occurs when the mouse button, or any other pointing device button, is
released over the control or document. On a PC-based mouse, it specifically relates to when the
left-hand mouse button being released.

OnResize
This event is associated with every time the browser window is resized.

OnScroll
This event is associated with every time the browser scroll bars are being used

Browser Management Events

OnReadHistory
The OnReadHistory event allows you to directly interfere with in processing a URI to restore the form ’
s state. If you have taken some information out of the form ’ s written history, in the OnWriteHistory
event, you can restore it in the OnReadHistory event.

OnWriteHistory

Page 149
This event gives the developer an opportunity to the URI for the Form. It can be used to filter out
sensitive information, for example.

Form Band Events


As we have seen, earlier in this chapter, Forms have Bands. Bands are container objects that are
present in every Form. As full blown objects, themselves, the Bands have their own events which can
be used along with the Form ’ s events in order to best handle user interaction with your application.

Browser Side Events

OnAfterGrowOrShrink
This event is triggered right after a Band object is resized. This event can be used to reposition
controls on a band, if necessary.

OnBeforeGrowOrShrink
This event is triggered immediately before a Band object is resized. This event can be used to
reposition controls on a band, if necessary.

Server Side Events

OnAfterPrint
The OnAfterPrint event is called right after a band gets "printed" out to the data stream for the client.
It can be used for setting control variables.

OnBeforePrint
This event is triggered immediately before a band is "printed" out to the data stream for the client.
You can use this event to change the appearance of objects in the Band for each detail item in a
continuous Form.

OnPrintStyle
The OnPrintStyle event gives the developer an opportunity to override or extend the automatic HTML
styles generated for the controls on the form.

Data Bound Forms


In this chapter we have looked at how to create Forms, using controls and other Forms in order to
setup the user interface of an application. Since we did this with a simple, website-like application we
had no need for databases, but in the real world most modern applications need to rely, heavily, on
databases. The Morfik has taken this need into account right from the start. Database support is not
only available, but has been built into the very fabric of the Morfik Framework instead of being added
on later as an afterthought.

Now we are going to go back to the Contacts example we started with back in Chapter 2. We are
going to elaborate on that example by adding a pair of Forms, one for browsing the contacts and one
for editing and inserting a contact. Both of these Forms will be used inside a SubForm control on the
project ’ s Index Form.

You can see what the Index Form will look like, in design mode, in the screenshot in Figure 8. Notice
that the Index Form has only three controls in its Detail Band: two Buttons and a SubForm. In both
the header and footer bands a single TextLabel control is used for displaying a title and a copyright
message.

At runtime this application will present the interface shown in Figure 9 at startup. Notice that what
you see in Figure 9 is exactly what is shown in Figure 8, now with the ContactsList Form being
exhibited in the SubForm control of Index Form.

On this Form you can see information that is being brought in from the tblContacts table we designed
in Chapter 3. Looking at Figure 9 you will see that there is a series of small buttons right under the
"gray" area where the data is shown. That is a NavigationBar control and it can help you to navigate
elegantly through a dataset.

Page 150
This brings us back to the topic at hand: Data Bound Forms. Unlike other tools that have data bound
controls, the WebOS AppsBuilder has data bound Forms. What this means is that the entire Form is
"data-aware" and offers a series of features to help you in building your database centric
applications. The NavigationBar control, for example, is not a standalone control, but a property of
either the Header or Footer bands of a Form.

What Makes a Form Data Bound?


What is the difference between a Data Bound Form and any other Form? Well, just the value of the
dataset property. Every Form has a dataset property and it is whether or not this property is set that
defines if a specific Form is data bound or not.

So, a Form with the dataset property set to the name of one of the project ’ s tables or queries
becomes a data bound Form. It is as simple as that.

Figure 8 – The contact project ’ s Index Form.

So in our contacts example, the Index Form we see in Figure 8 is not a data bound Form. It is the
ContactsList Form which appears inside the ContactsArea SubForm control that is a data bound Form.

Two Kinds of Data Bound Forms


There are two different kinds of data bound Forms: Continuous and Single .

Continuous Forms
The ContactsList Form, shown in Figure 9, is a continuous data bound Form. This means that it will
continuously display data rows until it reaches a limit defined by the developer, then it will paginate.
This limit is set by the developer through the PageSize property, which defaults to a value of 10.

Page 151
Figure 9 – The Contacts application at run time. The Index Form is showing with
the ContactsList Form in display in the ContactsArea SubForm.

When you design a continuous form, you only design how one record is going to be displayed, within
the details band, and that gets replicated for each record that is actually shown. The developer
controls how many records will actually get shown through the use of the PageSize property.

At runtime, you might wish to perform an action on one specific control or set of controls, like
changing their visibility or color. Since you only design one set of controls, but will have many
occurrences of them, in practice, you need to select which of the sets you are referring to. This can be
done through the use of the BandIndex property of the control you wish access, as shown in the
following example:

P rocedure form1 . T extLabel1Click ( Event : T DOMEvent );


Begin
T extLabel5 . BandIndex := GetEventSource ( Event ). BandIn
dex ;
OpenForm ( 'Form2' , 'Form1:SubForm1' ,
'"P aramId=' + T extLabel5 . Caption + '"' );
End ;

In this example, we presume that we want to take action based on the click of a control. The control
which was clicked is obtained by the call to GetEvenSource(Event) function call and its BandIndex
property is used to set the BandIndex property of the control which we want to manipulate. In this
case the TextLabel5 control whose caption is used a parameter for opening a new form.

In case you wish to manipulate more than one control of a specific band you can set the BandIndex of
all the controls in one call to the SwitchBandIndex function. This function takes a TDOMEvent object as
its parameter and can be easily used by just passing to it the Event object that any event handler
method receives as a parameter.

Single Forms
The second kind of Form is the Single Form and as its name might have given away, it handles data
from a single table row. The EditContact Form in the Contacts example, which is displayed at design
time in Figure 10, is a Single type, data bound Form.

You saw this Form being created through the "Create Form Wizard" in Chapter 3. It is essentially the
same Form, but since it handles only a single row of data at a time, I have substituted the

Page 152
NavigationBar in the Footer band with a set of button controls which are a bit more appropriate to our
needs in this case. The screenshot in Figure 10 shows part of the Detail band as well as the Footer
band of the EditContact Form with this set of buttons.

In Listing 3 you will find the Browser side code for the EditContact Form. This code shows how to
enable and disable controls the current Form and on another Form.

5 Working With Forms 26 m2.PNG Figure 10 – The EditContact Form at design time in the WebOS
AppsBuilder.

Listing 3 – Browser side code (in Morfik Basic) for EditContact Form.

Imports Index
Namespace EditContact

P ublic Class EditContact


Inherits Form
Published Label_FirstName As T extLabel
Published Control_FirstName As T extEdit
Published Label_LastName As T extLabel
Published Control_LastName As T extEdit
Published Label_WorkEmail As T extLabel
Published Control_WorkEmail As T extEdit
Published Label_MobileP hone As T extLabel
Published Control_MobileP hone As T extEdit
Published Label_HomePhone As T extLabel
Published Control_HomeP hone As T extEdit
Published Label_WorkPhone As T extLabel
Published Control_WorkP hone As T extEdit
Published Label_WorkStreetAddress As T extLabel
Published Control_WorkStreetAddress As T extEdit
Published Label_HomeStreetAddress As T extLabel
Published Control_HomeStreetAddress As T extEdit
Published Label_HomeEmail As T extLabel
Published Control_HomeEmail As T extEdit
Published Label_Company As T extLabel
Published Control_Company As T extEdit
Published Label_ContactID As T extLabel
Published Control_ContactID As T extLabel
Published Label_DateofBirth As T extLabel
Published Control_DateofBirth As DateT imeEdit
Published btnCancel As Button
Published btnOk As Button
Published btnDelete As Button
Published btnPrint As Button

Sub SetEnabled ( Enabled As Boolean )


btnOk . Enabled = Enabled
btnCancel . Enabled = Enabled
End Sub

Sub ReturnT oList


' Return to "ContactsList" Form
Index2 ( xApp . Forms ( "Index" )). btnNew . Enabled = T rue
Index2 ( xApp . Forms ( "Index" )). btnPrint . Enabled = T rue
OpenForm ( "ContactList" , "Index:ContactsArea" , "" )
End Sub

Published Message Sub btnCancelClick ( Event As T DOMEvent )


SetEnabled ( False )

Page 153
gRefreshContactList = False
If gNewContact T hen
DeleteRecord ( Nothing )
gNewContact = false
SetEnabled ( T rue )
Else
SetEnabled ( T rue )
End If
ReturnT oList 'Return to the List view
End Sub

Published Message Sub btnOkClick ( Event As T DOMEvent )


SetEnabled ( False )
If ( Control_FirstName . T ext = "" ) or ( Control_LastName . T ext =
"" ) T hen
ShowMessage ( "Empty record." )
SetEnabled ( T rue )
Else
gRefreshContactList = False
SubmitPage ( Event )
End If
End Sub

Published Message Sub btnDeleteClick ( Event As T DOMEvent )


gRefreshContactList = False
If ConfirmAction ( "Are you sure you want to delete this record?" ) T hen
SetEnabled ( False )
DeleteRecord ( Event )
SubmitPage ( Event )
End If
End Sub

Published Message Sub btnP rintClick ( Event As T DOMEvent )


OpenReport ( "RptSingleContact" , """ContactIDP aram="
& gContactID &_
"""" )
End Sub

Published Message Sub WebFormShow ( ByRef Show As Boolean )


Index ( xApp . Forms ( "Index" )). btnNew . Enabled = False
Index ( xApp . Forms ( "Index" )). btnPrint . Enabled = False
If Show T hen
If gNewContact T hen
gContactID = ""
btnDelete . Enabled = False
NewRecord ( Nothing )
Else
btnDelete . Enabled = T rue
End If
End If
End Sub

Published Message Sub WebFormCreate ( Sender As T Object )


' Selecting single contact
If gContactID <> "" T hen
SQLFilter = """ContactID"" = " & gContactID
End If
End Sub

Published Message Sub WebFormAfterSubmit ( Failed As Boolean )

Page 154
' Getting current ContactID
SetEnabled ( T rue )
If not Failed then
gNewContact = False
gRefreshContactList = T rue
ReturnT oList
End If
End Sub

End Class

End Namespace

We will look into the OpenReport function you see in this example, in more detail in the next Chapter,
Working with Reports.

Positioning the Controls on a Form


The WebOS AppsBuilder IDE ’ s Form Designer makes designing interfaces quite easy. The designer
includes automatic alignment features which make aligning controls to one another and equally
spacing them a trivial matter.
Whenever you drag a control around the Form designer, thin blue lines will appear indicating that you
are in position for alignment with another control in form. Many lines can actually be shown at the
same time as the Form Designer tries to ensure that your controls are all properly aligned.

Figure 11 – Automatic control alignment in the Form Designer.

This behavior can be deactivated as you will see in the next topic.

Configuring the Form Designer


The Morfik WebOS AppsBuilder offers you a large set of configuration options. These include several
options to customize the behavior of the Forms and Report Designer. You can see the General tab of
the Options dialog in Figure 12. The options in the column on the left are related to the Forms and
Reports designers.

Page 155
Figure 12 – The General tab on the Environment Options dialog of the WebOS AppsBuilder.

I have found that the automatic alignment of controls is a great enhancer of developer productivity as
it allows to you to get great looking forms easily. If, for some reason, this feature is interfering with
how you want to position your controls you can disable it by switching from Snap to Smart Grid to
Snap to Visible Grid .

When using Snap to Visible Grid you might want to fiddle around with values to find the setting you
prefer for the X and Y grid step options. These options control how controls move and align on the
Form.

Wrapping it up
The Morfik WebOS AppsBuilder IDE offers a lot of great features for the creation of Forms and through
them the interface for your application. As we have seen in this chapter, you can create Forms that
work automatically with datasets and Forms that care nothing for datasets.

It is important to keep in mind that we have just glanced at the possibilities for your applications, so
far. We will see more examples and how to do more interesting stuff in the chapters to come.

See also
Making the Most of Forms
Working with Reports

category:Programming

Page 156
For Delphi Developers

For quick tips go to: Tips For Delphi Developers

Welcome

If you are an experienced Delphi developer and you thought of writing an application or utility
which would work in a centralized model, for which a web application would be great, but
shied away from writing them due to lack of familiarity with Web development tools, Morfik
AppsBuilder is just the rigth tool for you.

This lack of familiarity is for many the result of rejection of these tools, in general, due to their
concepts and usage principles which do not help developers to be productive. Let s be
honest. After working with Delphi for years, text editors with HTML syntax highlighting and
some help with the HTML tags are quite disappointing.

Morfik 1.x looked a lot like MS Access it worked very much like Delphi. Not only that but it
allowed me use Object Pascal to program not only the server side of a Web application, but
its browser side as well. Morfik R2 tools have a much more sophisticated interface and add a
large number of design-related features to its visual editors.

Actually programming a Morfik application is, in many ways, very similar to programming a
Delphi application. The Morfik Framework uses many concepts which will be immediately
familiar to any Delphi developer, from high-level objects such as Forms to the smaller helper
classes such as string lists.

In order to better illustrate the familiarity a Delphi developer will feel when working with
Morfik AppsBuilder the source code of a simple form is included bellow. This is the basis of the
Morfik version of the famous Hello World project.

'''Unit''' Form1
;

'''Interface''
'

'''Type''
'

Page 157
Form1 = '''Class'''(Form)
Button1 : Button;
TextLabel1 : TextLabel;
Procedure Button1Click(Event: TDOMEvent); '''Messag
e''';
'''Private'''
''{ Private declarations }''
'''Public'''
''{ Public declarations }''
'''End''';

'''Implementation''
'

'''Procedure''' Form1.Button1Click(Event: TDOMEve


nt);
'''Begin'''
TextLabel1.Caption := 'Hello Delphi World';
'''End''';

'''End'''
.

This application presents a single button in an HTML page and when the button is clicked it
changes the caption of a TextLabel control, the equivalent of Delphi s TLabel, to Hello
Delphi World . That is all that it takes to create a Web based application which uses Ajax
techniques to change its interface at run time.
Though a careful examination of this source code will immediately reveal some differences to
the source code of a Delphi Form, it should be obvious that there are many more similarities.

Morfik AppsBuilder compiles a web application into JavaScript for the browser side and into a
binary executable (or plug-in module) on the server side. A Delphi developer who wants to
create a Web application with Morfik can choose to use his own licensed Delphi as the
backend compiler for Morfik. In this case, instead of using Morfik's default backend compiler
(FreePascal) we can use the Delphi compiler. Morfik is compatible with Delphi 5.0 up to Delphi
2007 for Win32. No changes to an application s source code is necessary in order to switch
back and forth between backend compilers so the user can freely choose which ever one
suits his/her needs at the time. This makes it easy to use - for example, Delphi 2007 to
compile an application for Windows and FreePascal to compile the same application for Linux.

AppsBuilder allows Delphi developers to become immediately productive in creating


sophisticated Web applications, Web Services and even browser-only applications.

In fact, Morfik AppsBuilder is the easiest, most powerful path a Delphi developer can choose
to create Ajax Web applications while retaining all his/her familiarity with language
constructs, Framework and environment.

Page 158
See also
 Tips For Delphi Developers
Copyright notice

Page 159
Tips For Delphi
Developers

To a Delphi developer, at first Morfik AppsBuilder looks very similar to Delphi. It


really is, but in order to be a Web development tool, AppsBuilder must support the
the characteristics that make the web special but which, at the same time, makes
it different from Win32.

Most differences in how to do something in Morfik from how you would do it in


Delphi comes from the different underlying platforms: Web vs. Win32.

This is a list of tips which are meant to call the attention of a Delphi developer to
where the two platforms, and therefore the two tools, differ in behavior.

For an introductory welcome see Morfik for Delphi Developers .

Asynchronous Environment
The asynchronous nature of a Web application is the main initial challenge a Delphi developer
faces when starting to work with Morfik.

It is essential that the developer recognizes that the nature of the Web is asynchronous and
that it precludes the creation of browser side code which is exactly the same as one would
have in a traditional Win32 application.

The Morfik Framework, which is available in Object Pascal, offers some features which help to
minimize the effort for getting into this new world. In order to avoid the need to continually
handle the mundane everyday aspects of asynchronously calling the server and receiving the
reply (which might come in in chunks) the Morfik Framework implements a set of methods
which do this for the developer, when opening forms, running reports or making calls to web
services.

Whenever you are writing browser side code, this is one important aspect o keep in mind as it
is common for people to forget it and write code as if it would execute synchronously.

Dual Modules
Dual modules are another feature of Morfik which will be new to the Delphi developer and
which is, also, associated with the difference in nature of Web applications to traditional
Win32 applications. Web applications, most of the time, have both a browser and a server
side component to them.

In Object Pascal terms a module is a unit and a dual module actually contains two units with
the same name, one for the browser and another for the server side of the application. Within
the Morfik IDE the developer can switch from one to the other by clicking on tabs which are
available right below the code editor.

Morfik AppsBuilder does allow the developer to create both browser-only and server-only
applications easily but many developers will probably enjoy the ease and flexibility of the
single WebOS project that contains both side of a Web application.

Web Services
Morfik WebOS AppsBuilder makes it easy to create Web Service APIs for usage in other Morfik
applications or for calling from other platforms. Being an environment specifically designed for

Page 160
the creation of Web applications Morfik AppsBuilder creates Web Service enabled applications
by default.

Web Service APIs are created in Morfik by creating descendants of the WebMethod class. The
Morfik compiler automatically generates the .wsdl file required for other applications to call
your services.

Data-bound Forms
In Morfik, unlike, in Delphi, Forms are tightly integrated with data sources. This means that
the Forms themselves offer special services which can be used to create data driven
interfaces, without requiring any special controls.

Forms in Morfik have bands and behave in a manner which can be considered to be a cross
between a plain Delphi Form and a report.

Continuous Forms are specially good for displaying lists of items in Morfik applications. These
Forms repeat their details bands for each record/row in a table or in the result set of a query.

Tables and Queries


Tables and queries are first class citizens in the Morfik AppsBuilder IDE. Instead of being
represented by control icons on Forms or Data Modules, queries and tables are created
separately and can be accessed from anywhere in your application.

DLLs and Function Libraries


Though you can call DLL functions from the server side of a Morfik application, if you wish to
make a group of functions available to several of your applications you would do so by
creating an application that publishes a Web Services interface.

Morfik Plug-in applications are in fact DLLs which are dynamically loaded by a Morfik Host
Application Server. The plug-ins can, optionally, also be used with IIS or Apache directly.

Data Modules
If you are looking for data module-like functionality, have a look at " Where are the Data
Modules? ".

Importing Delphi Code


Most Delphi code, which is non-visual in nature, can be reused in a Morfik AppsBuilder
application, particularly in server side code. Appendix A of the Morfik Developer's Handbook
covers this. If you are a FreePascal developer, you will be interested in knowing that most
pure-Object-Pascal code can be directly ported to browser side code in Morfik as well.

See also
 Morfik for Delphi Developers .

Page 161
Where are the Data
Modules?

Being a Delphi developer having a first contact with Morfik you might be wondering where are the
data modules...

Well, Morfik AppsBuilder does not use them. A Morfik project has its data sources neatly
represented as high level project objects which can be viewed by selecting either Tables or
Queries in the Project tab of the AppsBuilder IDE. Morfik Web Application projects can have
Tables and Queries, while Morfik Browser Application projects can only have Tables. In Morfik
Browser Application projects, tables are XML data sources .

The following picture shows the list of tables in a Morfik Web Application project.

This has several advantages. A table or query which is created in your project is immediately
visible from anywhere in the application, without the need to add non-visual controls to each
individual Form.

The following image shows the list of queries in a Morfik Web Application project.

This allows your visual designs to be much less cluttered, thus better representing how your
application will really look at runtime. Each Form has a DataSource property which can be pointed
directly to one of these Table and Query high-level objects.

Page 162
Page 163
Web Methods

Web Methods are individual Web Service APIs which you can implement in Morfik
Web Application projects, and call from both Web Application and Browser
Application projects.

The following topics will provide more detail into the various aspects of creating
and using Web Methods in your projects:
 Creating Web Methods - Visually
 Creating Web Methods - In code
Calling Web
 Methods
 WebService, importing and consuming

 Why Use Web Methods ?

See Also
 Patterns for Using Web Services in Morfik
 Morfik 07 - Creating and Using WebMethods

 Issuing XMLHTTP Requests

Page 164
Creating Web
Methods - Visually

Morfik AppsBuilder has a special designer for creating Web Methods which will help you in
declaring the input and output parameters for the Method.

You can see the Web Method designer in the Morfik workspace in Figure 1.

Figure 1 - The Web Method designer in the Morfik Workspace.

Once you have entered your parameters in the Web Method designer's grid you can switch to the
server code view. The Web Method designer will have already generated the code for both the
browser and server side classes that will represent this Web Method in your application.

The following is a simplified version the server side code for one of the Web Methods in the
MorfikCMS sample application. In most of the code you see is generated automatically by the
Morfik workspace. Only the body of the Execute method for the AuthenticateUser class was hand
coded.

Unit AuthenticateUser ;

Interface

T ype
AuthenticateUser = Class ( WebMethod )

Page 165
AUserName : String ;
AP assword : String ;
CheckedOk : Boolean ;
FullName : String ;
UserId : Integer ;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
P rocedure Execute ; override ;
End ; [ 'P ublished=False' ];

Implementation

P rocedure AuthenticateUser . Execute ;


var
UserCatRS : T RecordSet ;
Begin
UserCatRS := DefaultDBConnection . CreateRecordSet (
'SELECT "Id", "FullName", "email", "Password" FROM "UserCatalog" ' +

'WHERE LOWCASE("UserCatalog"."email")=LOWCASE(:EMAILP ARAM)' );


try
UserCatRS . P aramByName ( 'EMAILP ARAM' ). AsString := AUserName ;
UserCatRS . P repare ;
UserCatRS . Active := T rue ;
UserCatRS . First ;
CheckedOk := False ;
If Not UserCatRS . Eof then
begin
if ( UpperCase ( APassword ) = UpperCase ( UserCatRS . FieldByName ( 'P assword' ). AsString ))
then
begin
CheckedOk := true ;
FullName := UserCatRS . FieldByName ( 'FullName' ). AsString ;
UserId := UserCatRS . FieldByName ( 'Id' ). AsInteger ;
end ;
end ;
finally
UserCatRS . Free ;
end ;
End ;

End .

When you are using the Web Method designer to create a new Web Method it will create a
corresponding class in the browser side of your project. The following listing shows purely the
generated browser code corresponding the web method shown in the previous listing.

Unit AuthenticateUser ;

Interface

T ype
AuthenticateUser = Class ( WebMethod )
AUserName : String ;
AP assword : String ;
CheckedOk : Boolean ;

Page 166
FullName : String ;
UserId : Integer ;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
P rocedure HandleResponse ; override ;
End ;

Implementation

P rocedure
AuthenticateUser . HandleResponse ;
Begin

End ;

End .

If you are building an application which will not have a browser side, i.e. an application meant to
work purely as a server which is called by other applications, you should consider directly coding
the Web Methods as in this case there will be no browser side code generated. All visually
created Web Methods have a browser class. It is important to note that this class, though not
necessary in this scenario, will not have any negative impact on how the server behaves, if
present.

See Also
 Working with Web Methods
 Creating Web Methods - In code

Related Video
Create a Simple WebMethod

Page 167
Issuing XMLHTTP
Requests

When working with Morfik, most of the time you will be using Web Method calls
when you need to handle communications between the Browser and the Server.
There are situations, however, in which you might want to directly issue an
XMLHTTP request to the server. The following code snippet is from the MorfikDemo
application that comes with Morfik AppsBuilder R2 and shows how to use the
TXMLHTTPRequestWrapper class directly.

TMorfikSuggest = Class ( TObject )


Private
XMLHTTPRequest : TXMLHTTPRequestWrapper ;
Function GetStatus : Integer ;
Function GetResponse : String ;
Public
Constructor Create ( Query : String );
Property Response : String Read GetResponse ;
Property Status : Integer Read GetStatus ;
End ;

{..........................................................................
....}

Implementation

{..........................................................................
....}
Constructor TMorfikSuggest . Create ( Query : String );
Var
Params : TParameters ;
Begin
XMLHTTPRequest := TXMLHTTPRequestWrapper . Create ;
Params := TParameters . Create ;
Params . AddList ( '"cls=sgt","q=' + Query + '"' );

Try
XMLHTTPRequest . Open ( 'GET' , BuildURL ( 'suggest.htm'
, Params , '' ), false , '' , '' );
XMLHTTPRequest . Send ( Nil );
Finally
Params . Free ;
Params := Nil ;
End ;
End ;

The following code snippet shows how to retrieve the reply from the server, in the
browser portion of your application.

Function TMorfikSuggest . GetResponse :


String ;
Begin
Result := XMLHTTPRequest . ResponseText
;
End ;

Page 168
See Also
 Working with Web Methods

Page 169
Morfik 07 - Creating
and Using
WebMethods

What are WebMethods?


What is a Web Service?
How do WebMethods Work?
Creating a WebMethod
WebMethod Parameters
Server Side Code
Browser Side Code
Browser or Server Side?
Using a WebMethod
Invoking a WebMethod
Beware. Asynchronous Platform
Using WebMethods to Authenticate Users
Publishing WebMethods for External
Consumption
Importing and Consuming External Web
Services
Calling the Imported Web Service
Wrapping it up

What are WebMethods?


WebMethods are a web version of the relational database ’ s stored procedures. They are routines or
services which can be called when required by your application or be published so as to be called
from other applications. WebMethods are implemented fully on the server, but have a Browser side
component so as to allow easy usage from within the same XApp. It is through the creation of
WebMethods that you build the Web Services interface of your XApp.

What is a Web Service?


Well, the World Wide Web Consortium (W3C) defines a Web Service as a software system designed
to support interoperable machine-to-machine interaction over a network. Though this is a very broad
definition, actual usage normally refers to SOAP (Simple Object Access Protocol) formatted XML
envelopes for a transport and WSDL (Web Services Definition Language) files for the interface
definition. This, more restrictive description, is the one accepted and backed by the Web Services
Interoperability Organization (WS-I).

No other Web development tool allows you to create Web Services in so effortless a manner.
Basically, you only need to worry about your business logic and leave the rest to the Morfik
Framework.

How do WebMethods Work?


WebMethods are divided in two parts, a browser and a server part. In truth, a WebMethod ’ s logic
can be mostly implemented on the browser side or on the server side. It is usual, however, for them
to have a bit of code on both sides, with the bulk of the work being handled on the server. Also
usually, the code on the browser side is mostly related to processing the reply sent by the server, i.e.
doing something meaningful with return parameters from the WebMethod call.

Page 170
Creating a WebMethod
As with all high level objects in Morfik, there are two ways you can create a new WebMethod in your
application: by going through a wizard or directly to WebMethod design view. If you choose to go
through the Wizard, it will ask you to specify what parameters will be passed on calling this
WebMethod.

When you choose to create a WebMethod you will get a High Level object composed of two Common
Object Classes, one for the browser and one for the server side of your application, just as with
Forms. In order to implement your WebMethod all you have to do is write the code for two methods,
one for each side of the application.

On the server side you will have the Execute method and on the browser side you will have the
HandleResponse method. The way to have information channeled from one of these sides of the
application to the other is to use the WebMethod Parameters.

WebMethod Parameters
WebMethod parameters are very much like function parameters. You specify the values for the
parameters when you call the WebMethod and from that moment on, parameters values are known
and kept updated whenever you can access them, be it on the browser or on the server side of your
code. Note that changes to "in" parameters are not reflected back to the browser. When an "in"
parameter is accessed from browser side code, its value will be the original value specified when the
WebMethod was called.

It is also important to note that you do not need to specify any values for parameters that have
default values.

In Figure 1 you can see the Editor for the WebMethod Parameters in Morfik.

Figure 1 – Web Method parameter editor in Morfik

You can also create the parameters though a Wizard, if you choose to create the WebMethod itself
using the Create WebMethod Wizard. You can see in Figure 2, the Create WebMethod Wizard ’ s
window along with a small window which is used for the developer to input information on each of

Page 171
the desired parameters.

Figure 2 – Creating a WebMethod and its parameters through


the Create Web Method Wizard.

The process of creating the WebMethod ’ s parameters is quite straightforward and should be quite
simple to complete. In order to give you a quick look at how the WebMethods work I have created a
small sample with the set of Parameters listed in Figure 1. This simple demo application uses a
WebMethod to process simple mathematical operations on the server side of the application.

Server Side Code


As previously mentioned, usually the server side code of a WebMethod does most of its heavy work.
In this case it is doing the actual math operations and preparing the result to be sent back to the
browser side of the application.

In listing 1 you can see the code for the server side common object class that implements that half of
the WebMethod high level object.

Listing 1 – Server side code of the MathProcessor WebMethod.

Unit MathP rocessor ;

Interface

T ype
MathP rocessor = Class ( WebMethod )
Operand1 : Double ;
Operand2 : Double ;
theOperator : String ;
theResult : Double ;
Status : Integer ;

Page 172
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
P rocedure Execute ; override ;
End ; [ 'P ublished=False' ];

Implementation

P rocedure MathP rocessor . Execute ;


Begin
Status := 0 ;
if theOperator = 'ADD' then
theResult := Operand1 + Operand2
else
if theOperator = 'SUB' then
theResult := Operand1 - Operand
2
else
if theOperator = 'DIV' then
theResult := Operand1 / Operand
2
else
if theOperator = 'MUL' then
theResult := Operand1 * Opera
nd2
else
Status := 1 ;
End ;

End .

Browser Side Code


The Browser side of this WebMethod involves getting the result of the operation from the server and
then doing something with it. Now, an interesting question is: what does the browser side of the
WebMethod do with the results it just received from the server? Since the call to execute a
WebMethod is asynchronous, as we will discuss shortly, there is nothing to return the results to. In
this case the browser side HandleResponse method takes on the responsibility of displaying the
results in a TextLabel control. You can see this code in Listing 2.

Listing 2 – Browser side code of the MathProcessor WebMethod.

Unit MathP rocessor ;

Interface

T ype
MathP rocessor = Class ( WebMethod )
Operand1 : Double ;
Operand2 : Double ;
theOperator : String ;
theResult : Double ;
Status : Integer ;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
P rocedure HandleResponse ; override ;

Page 173
End ;

Implementation

uses Index , SystemControls ;

P rocedure MathP rocessor . HandleResponse ;


Begin
Index ( xApp . Forms [ 'Index'
]). ResultLabel . Caption := FloatT oStr ( theResult );
End ;

End .

In order to test this WebMethod I created a very small test application with a single form. You can
see in Figure 3, this application at runtime within Internet Explorer.

Figure 3 – MathProcessor WebMethod test application.

Browser or Server Side?


WebMethods are a construct for running specific sets of commands on the server side of your
application. The browser side of your code should just process the response it received from the
server side, even though you can write code within the HandleResponse method to do other things,
for example, you could achieve the same results we have with the WebMethod shown in listings 1
and 2 could be achieved, with all the logic on the Browser side, if we changed the browser side to be
as is shown in listing 3. This practice, however, is not encouraged since it offers no benefit over the
creation of an ordinary function, which will accomplish the same results. This kind of implementation
will, also, be useless when you want to publish Web Services.

Listing 3 – WebMethod ’ s logic implemented in the Browser side.

Unit MathP rocessor ;

Interface

T ype
MathP rocessor = Class ( WebMethod )
Operand1 : Double ;
Operand2 : Double ;

Page 174
theOperator : String ;
theResult : Double ;
Status : Integer ;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
P rocedure HandleResponse ; override ;
End ;

Implementation

uses Index , SystemControls ;

P rocedure MathP rocessor . HandleResponse ;


Begin
if theOperator = 'ADD' then
theResult := Operand1 + Operand2
else
if theOperator = 'SUB' then
theResult := Operand1 - Operand2
else
if theOperator = 'DIV' then
theResult := Operand1 / Operand2
else
if theOperator = 'MUL' then
theResult := Operand1 * Operand2
else
Status := 1 ;
Index ( xApp . Forms [ 'Index'
]). ResultLabel . Caption := FloatT oStr ( theResult );
End ;

End .

Notice that in this case, all the actual mathematical operations were transferred to the browser side,
within the HandleResponse method.

Using a WebMethod
Up to this point we have seen how to create a new WebMethod and how to write some code for both
its browser and server side parts, but how to we use this code? How do we invoke a WebMethod?

Invoking a WebMethod
In order to invoke a WebMethod you need to make a call to the RunWebMethod function, passing its
name and the parameters which are required by the WebMethod. The parameters for the invoked
WebMethod are passed as a single string, composed of a series of pairs in the following pattern:

parameter_name=parameter_val
ue

These pairs are enclosed in double quotes and separated by commas. Whether the string itself is
involved in single or double quotes depends on the string delimiters of the developer ’ s language
syntax of choice.

In listing 4 you can see the source code for the simple test Form, which invokes the MathProcessor
WebMethod on the click of a button.

Page 175
Listing 4 – Invoking a WebMethod from an Object Pascal language Form.

Unit Index ;

Interface

T ype
Index = Class ( Form )
OpT xt1 : T extEdit ;
OpT xt2 : T extEdit ;
OperatorCombo : ComboBox ;
EqualsButton : Button ;
PaintBox1 : P aintBox ;
ResultLabel : T extLabel ;
P rocedure EqualsButtonClick ( Event : T DOMEvent ); Message ;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
End ;

Implementation

P rocedure Index . EqualsButtonClick ( Event : T DOMEvent );


Begin
RunWebMethod ( 'MathProcessor' , '"Operand1='
+ OpT xt1 . T ext + '",' +
'"Operand2=' + OpT xt2 . T ext + '",' +
'"theOperator=' + OperatorCombo . T ext + '"' );
End ;

End .

For an example of how this WebMethod could be used in modules written in other language
syntaxes, look at the code in listing 5. You can see the code necessary to invoke the same
MathProcessor WebMethod from a Form in Morfik Basic syntax.

Listing 5 – Invoking a WebMethod from a Basic language Form.

Namespace Form1
P ublic Class Form1
Inherits Form
Published OpT xt1 As T extEdit
Published OpT xt2 As T extEdit
Published OperatorCombo As ComboBox
Published EqualsButton As Button
Published PaintBox1 As P aintBox
Published ResultLabel As T extLabel
Published Message Sub EqualsButtonClick ( Event As T DOMEvent )
RunWebMethod ( "MathP rocessor" , """Operand1=" & OpT xt1 . T ext &
"""," & _
"""Operand2=" & OpT xt2 . T ext & """," & _
"""theOperator=" & OperatorCombo . T ext _
& """" )
End Sub
End Class
End Namespace

Page 176
Due to Morfik ’ s ability to work with multiple language projects, the code you see in listing 5 will work
perfectly with the Web Methods we have seen in this chapter, even though they are written in
different languages.

In listing 6, you can see the equivalent code in Java and in listing 7, in C#.

Listing 6 - Invoking a WebMethod from a MorfikJ language Form.

package Form2 ;

public class Form2 extends Form


{
published T extEdit OpT xt1 ;
published T extEdit OpT xt2 ;
published ComboBox OperatorCombo ;
published Button EqualsButton ;
published P aintBox PaintBox1 ;
published T extLabel ResultLabel ;

published message void EqualsButtonClick ( T DOMEvent Event )


{
RunWebMethod ( "MathP rocessor" , "\"Operand1=" + OpT xt1 . T ext +
"\"," +
"\"Operand2=" + OpT xt2 . T ext + "\"," +
"\"theOperator=" + OperatorCombo . T ext +
"\"" );

Listing 7 - Invoking a WebMethod from a C# language Form.

namespace Form3
{

public class Form3 : Form


{
published T extEdit OpT xt1 ;
published T extEdit OpT xt2 ;
published ComboBox OperatorCombo ;
published Button EqualsButton ;
published PaintBox PaintBox1 ;
published T extLabel ResultLabel ;

published message void EqualsButtonClick ( T DOMEvent Event )


{
RunWebMethod ( "MathP rocessor" , "\"Operand1=" + OpT xt1 . T ext +
"\"," +
"\"Operand2=" + OpT xt2 . T ext + "\"," +
"\"theOperator=" + OperatorCombo . T ext +
"\"" );
}
}
}

Page 177
It is interesting to observe that due to the fact that C# and Java have very similar syntaxes, the line
that invokes the WebMethod is exactly the same in both languages.

Beware. Asynchronous Platform


As you might have noticed navigating on the Internet, when you open a page in the browser, several
things seem to happen at the same time. As the text is downloaded, so are the images which are
shown as their download completes.

All action within the browser happens in an asynchronous manner. No action blocks another from
taking place simultaneously. So while picture A is being downloaded, so are pictures B, C and D.
Whichever picture has its download concluded first, will then be shown immediately.

It is very important to keep in mind that though a call to the RunWebMethod function will return
immediately, the desired results might not have yet been achieved since what really happened is that
an asynchronous call was dispatched to the server part of your application. As soon as that
asynchronous call is returned by the server-side execute method, then the browser side
HandleResponse method will be invoked, closing the full cycle of WebMethod invocation.

Using WebMethods to Authenticate Users


So far, we have gone through several different ways of calling a very simple WebMethod. In order to
get a better idea of what a WebMethod can do it will be interesting to look at a more complex
example. In Listing 8, I have included the source code for the server side of a WebMethod that looks
up usernames and passwords in a table and matches them in order to authenticate user access to
an application. In listings 9 and 10 you will be able to see the browser side code for this WebMethod
and the form which invokes the WebMethod, respectively.

Listing 8 – Server side code of a Web Method that does user authentication.

Unit UserLogin ;

Interface

T ype
UserLogin = Class ( WebMethod )
UserName : String ;
Password : String ;
Authorized : Boolean ;
UserID : Integer ;
CompleteName : String ;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
P rocedure Execute ; override ;
End ; [ 'P ublished=False' ];

Implementation

P rocedure UserLogin . Execute ;


Var
UserRS : T RecordSet ;
SQLstr : string ;
Begin

{Setup the SQL command to lookup the UserName and P assword.}


SQLstr :=
'SELECT "UserID", "Name" FROM "tbUser" where ' +
'"UserName" = ''' + UserName + ''' and ' +
'"P assword" = ''' + P assword + '''' ;

Page 178
{Create the recordset with the SQL command.}
UserRS := DefaultDBConnection . CreateRecordSet ( SQLStr );

UserRS . P repare ;
UserRS . Active := T rue ;
UserRS . First ;
Authorized := False ;
UserID := - 1 ;
CompleteName := '' ;
if not ( UserRS . Bof and UserRS . Eof ) then
begin
{if a corresponding entry was found the user is authenticated.}
Authorized := T rue ;
UserID := UserRS . FieldByName ( '"UserID"' ). AsInteger ;
CompleteName := UserRS . FieldByName ( '"Name"'
). AsString ;
End ;
UserRS . Free ;
End ;

End .

Observe that while the server side of the WebMethod does the actual validation, it is browser side
which triggers the response in the application ’ s interface and stores the complete name of the user,
and his username, in a browser side global variable.

Listing 9 – Browser side code of a WebMethod that does user authentication.

Unit UserLogin ;

Interface

T ype
UserLogin = Class ( WebMethod )
UserName : String ;
Password : String ;
Authorized : Boolean ;
UserID : Integer ;
CompleteName : String ;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
P rocedure HandleResponse ; override ;
End ;

Implementation

P rocedure UserLogin . HandleResponse ;


Begin
gUserID := UserID ;
gCompleteName := CompleteName ;
if Authorized then
{test value of parameter returned from server side}
begin
{if the user is authorized display welcome message.}
OpenForm ( 'frmMessage' , 'Index:sbfCurrentForm' ,
'"prmT itle=Welcome",' +

Page 179
'"prmMessage=' + gCompleteName + '",' +
'"prmAuxMessage=Select a project to start working",' +
'"prmFormT oOpen=frmProjectList"' );
OpenForm ( 'frmMenuOptions' , 'Index:sbfMenu' , '' );
end
else
ShowMessage ( 'Login Failed.' );
{if the user is not authorized, display an error message.}
End ;

End .

Listing 10 – Browser side code of a Form which invokes the UserLogin WebMethod.

Unit frmLogon ;

Interface

T ype
frmLogon = Class ( Form )
T extLabel_DocumentHeader : T extLabel ;
lblUserName : T extLabel ;
txtUserName : T extEdit ;
txtP assword : T extEdit ;
lblPassword : T extLabel ;
btnOk : Button ;
Container1 : Container ;
P rocedure btnOkClick ( Event : T DOMEvent ); Message ;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
End ;

Implementation

P rocedure frmLogon . btnOkClick ( Event : T DOMEvent );


Begin
RunWebService ( 'UserLogin' , '"UserName=' + txtUserName . T ext +
'",' +
'"P assword=' + txtP assword . T ext + '"' );
End ;

End .

Publishing WebMethods for External Consumption


When you create a WebMethod in your application, by default, it will not be included in the WSDL
(Web Service Description Language) file that Morfik WebOS AppsBuilder generates at compile type.
This essentially means that only your application will know how to use that method, since its interface
definition will not be made available in the WSDL file. If you wish to make a WebMethod available for
external consumption all you need to do is change the value of the Published metadata attribute for
the WebMethod derived class you are creating. If you look closely at listings 1 and 8, you will see this
metadata attribute appearing right after the class declaration.

If you change from the default value:

Page 180
[ 'P ublished=False'
];

to

[ 'P ublished=T rue'


];

This WebMethod will be included in the WSDL file which Morfik tools generate at compile time. Always
look for your .wsdl file in the same folder where your executable is being generated.

Importing and Consuming External Web Services

Figure 4 - Import Web Services menu option.

Morfik makes using external Web Services, very easy. The only thing you need to start, is to have the
WSDL file of the service you wish to use. For the sake of simplicity, I have chosen to import the WSDL
file which was generated for the math sample we just created, in this chapter. In Figure 4 you can
see the Import Web Services option, under the Project menu.

This wizard makes it extremely easy for you to import any web service you want (provided you have
access to its WSDL definition file), into your project.

Once the wizard is started, it will ask for the WSDL file that describes the service to be imported, as
can be seen in Figure 5.

Page 181
Figure 5 – Selecting the WSDL file to import.

Once you have selected the WSDL file the wizard will display all the methods found in the service
description, with their respective parameters, as shown in Figure 6.

Chapter_8_Creating_and_Using_Web_Methods_06_m2.PNG Figure 6 – Methods (with parameters)


available from the selected service. After you have completed the Import Web Service wizard, the IDE
will have generated a module with the classes required to correctly call out to the imported methods
in as easy a manner as possible. You can see the code of the module for these methods in Listing
11.

Listing 11 – Code for the automatically generated interface to the imported services

Unit MathT estService ;

Interface

Uses
SystemSerialiser ,
SystemInternet ;

T ype
T MFK_DBStatus =
(
dbsModified ,
dbsDeleted ,
dbsNew ,
dbsUnChanged
);

T MathP rocessor = Class ;

Page 182
T MathP rocessorResponse = Class ;
T MathP rocessor2 = Class ;
T MathP rocessor2Response = Class ;
T MathP rocessorResponse = Class ( T Serializable )
theResult : double ;
Status_1 : longint ;
P rocedure Serialize ( Serializer : T Serializer ); Override ;
P rocedure DeSerialize ( Serializer : T Serializer ); Override ;
End ;

T MathP rocessor2 = Class ( T Serializable )


Operand1 : double ;
Operand2 : double ;
theOperator : string ;
P rocedure Serialize ( Serializer : T Serializer ); Override ;
P rocedure DeSerialize ( Serializer : T Serializer ); Override ;
End ;

T MathP rocessor2Response = Class ( T Serializable )


theResult : double ;
Status_1 : longint ;
P rocedure Serialize ( Serializer : T Serializer ); Override ;
P rocedure DeSerialize ( Serializer : T Serializer ); Override ;
End ;

T MathP rocessor = Class ( T Serializable )


Operand1 : double ;
Operand2 : double ;
theOperator : string ;
P rocedure Serialize ( Serializer : T Serializer ); Override ;
P rocedure DeSerialize ( Serializer : T Serializer ); Override ;
End ;

T MathT estServiceSoapIntf = Class ( T SoapHttpClient )


P rocedure MathP rocessor ( Operand1 : double ; Operand2 : double ;
theOperator : string ; Var theResult : double ;
Var Status_1 : longint ); Virtual ;
P rocedure MathP rocessor2 ( Operand1 : double ; Operand2 : double ;
theOperator : string ; Var theResult : double ;
Var Status_1 : longint ); b ;
End ;

Implementation

Const
T MFK_DBStatus_EnumValues =
'dbsModified|' +
'dbsDeleted|' +
'dbsNew|' +
'dbsUnChanged' ;

{.................... T MathP rocessor ....................}

P rocedure T MathP rocessor . Serialize ( Serializer : T Serializer );


Begin
Inherited Serialize ( Serializer );
Serializer . WriteDouble ( 'Operand1 xsi:type="xsd:double"' , Operand1 );
Serializer . WriteDouble ( 'Operand2 xsi:type="xsd:double"' , Operand2 );
Serializer . Writestring ( 'theOperator xsi:type="xsd:string"' , theOperator );

Page 183
End ;

P rocedure T MathP rocessor . DeSerialize ( Serializer : T Serializer );


Begin
Inherited DeSerialize ( Serializer );
Serializer . ReadDouble ( 'Operand1 xsi:type="xsd:double"' , Operand1 );
Serializer . ReadDouble ( 'Operand2 xsi:type="xsd:double"' , Operand2 );
Serializer . Readstring ( 'theOperator xsi:type="xsd:string"' , theOperator );
End ;

{.................... T MathP rocessorResponse ....................}

P rocedure T MathP rocessorResponse . Serialize ( Serializer : T Serializer );


Begin
Inherited Serialize ( Serializer );
Serializer . WriteDouble ( 'theResult xsi:type="xsd:double"' , theResult );
Serializer . Writeinteger ( 'Status xsi:type="xsd:int"' , Status_1 );
End ;

P rocedure T MathP rocessorResponse . DeSerialize ( Serializer : T Serializer );


Begin
Inherited DeSerialize ( Serializer );
Serializer . ReadDouble ( 'theResult xsi:type="xsd:double"' , theResult );
Serializer . Readinteger ( 'Status xsi:type="xsd:int"' , Status_1 );
End ;

{.................... T MathP rocessor2 ....................}

P rocedure T MathP rocessor2 . Serialize ( Serializer : T Serializer );


Begin
Inherited Serialize ( Serializer );
Serializer . WriteDouble ( 'Operand1 xsi:type="xsd:double"' , Operand1 );
Serializer . WriteDouble ( 'Operand2 xsi:type="xsd:double"' , Operand2 );
Serializer . Writestring ( 'theOperator xsi:type="xsd:string"' , theOperator );
End ;

P rocedure T MathP rocessor2 . DeSerialize ( Serializer : T Serializer );


Begin
Inherited DeSerialize ( Serializer );
Serializer . ReadDouble ( 'Operand1 xsi:type="xsd:double"' , Operand1 );
Serializer . ReadDouble ( 'Operand2 xsi:type="xsd:double"' , Operand2 );
Serializer . Readstring ( 'theOperator xsi:type="xsd:string"' , theOperator );
End ;

{.................... T MathP rocessor2Response ....................}

P rocedure T MathP rocessor2Response . Serialize ( Serializer : T Serializer );


Begin
Inherited Serialize ( Serializer );
Serializer . WriteDouble ( 'theResult xsi:type="xsd:double"' , theResult );
Serializer . Writeinteger ( 'Status xsi:type="xsd:int"' , Status_1 );
End ;

P rocedure T MathP rocessor2Response . DeSerialize ( Serializer : T Serializer );


Begin
Inherited DeSerialize ( Serializer );
Serializer . ReadDouble ( 'theResult xsi:type="xsd:double"' , theResult );
Serializer . Readinteger ( 'Status xsi:type="xsd:int"' , Status_1 );
End ;

Page 184
{.................... MathT estServiceSoapIntf ....................}

P rocedure
T MathT estServiceSoapIntf . MathP rocessor ( Operand1 : double ; Operand2 : double ; theOperator :
string ; Var theResult : double ; Var Status_1 : longint );
Begin
BeginInvoke ( 'http://localhost:9119/?cls=soap' ,
'MathP rocessor xmlns="http://tempuri.org/"' ,
'MathP rocessorResponse xmlns="http://tempuri.org/"' ,
'MathP rocessor' );
T ry
T ry
RequestBody . WriteDouble ( 'Operand1 xsi:type="xsd:double"' , Operand1 );
RequestBody . WriteDouble ( 'Operand2 xsi:type="xsd:double"' , Operand2 );
RequestBody . Writestring ( 'theOperator xsi:type="xsd:string"' ,
theOperator );

Invoke ();

ReplyBody . ReadDouble ( 'theResult xsi:type="xsd:double"' , theResult );


ReplyBody . Readinteger ( 'Status xsi:type="xsd:int"' , Status_1 );
Except
Raise ;
End
Finally
EndInvoke ();
End
End ;

P rocedure T MathT estServiceSoapIntf . MathP rocessor2 ( Operand1 : double ;


Operand2 : double ;
theOperator : string ;
Var theResult : double ;
Var Status_1 : longint );
Begin
BeginInvoke ( 'http://localhost:9119/?cls=soap' ,
'MathP rocessor2 xmlns="http://tempuri.org/"' ,
'MathP rocessor2Response xmlns="http://tempuri.org/"' ,
'MathP rocessor2' );
T ry
T ry
RequestBody . WriteDouble ( 'Operand1 xsi:type="xsd:double"' , Operand1 );
RequestBody . WriteDouble ( 'Operand2 xsi:type="xsd:double"' , Operand2 );
RequestBody . Writestring ( 'theOperator xsi:type="xsd:string"' ,
theOperator );

Invoke ();

ReplyBody . ReadDouble ( 'theResult xsi:type="xsd:double"' , theResult );


ReplyBody . Readinteger ( 'Status xsi:type="xsd:int"' , Status_1 );
Except
Raise ;
End
Finally
EndInvoke ();
End
End ;

Begin

Page 185
End .

This unit (Listing 11) has a good quantity of auxiliary and support code which is not of much interest
to the user of services. From that listing what should mainly interest the programmer, who is a user
(consumer) of the web service, is a class that offers two methods, each tied to a "function" (a web
method, by its own right) of the service. You can see this classes interface below:

T MathT estServiceSoapIntf = Class ( T SoapHttpClient )


P rocedure
MathP rocessor ( Operand1 : double ; Operand2 : double ;
theOperator : string ; Var theResult : double ;
Var Status_1 : longint ); Virtual ;
P rocedure
MathP rocessor2 ( Operand1 : double ; Operand2 : double ;
theOperator : string ; Var theResult : double ;
Var Status_1 : longint ); Virtual ;
End ;

Careful observation of this code will undoubtedly reveal that this class ’ methods are, in fact, an
exact representation of what WebMethods we, originally, added to our application

Calling the Imported Web Service


Once the Web Service has been imported into your project, calling it up is quite simple. For the sake
of simplicity I created a copy of our WebMethod test application with a renamed WebMethod:
MathRequester . The main difference between this application and the original one is that the
MathRequester WebMethod does not process the operations; it forwards the request to the original
application, now running as a service.

Only the name of the WebMethod was changed and its server side code. The code you see in Listing
12 is that of the Server side of the MathRequester Web Method.

Listing 12 – Server side code calling out to the imported Web Service.

Unit MathRequester ;

Interface

T ype
MathRequester = Class ( WebMethod )
Operand1 : Double ;
Operand2 : Double ;
theOperator : String ;
theResult : Double ;
Status : Integer ;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
P rocedure Execute ; override ;
End ; [ 'P ublished=False' ];

Implementation

Uses
MathT estService ;

P rocedure MathRequester . Execute ;

Page 186
Var
MathInt : T MathT estServiceSoapIntf ;
Begin
MathInt := T MathT estServiceSoapIntf . Create ;
T ry
MathInt . MathP rocessor ( Operand1 , Operand2 , theOperator , theResult ,
Status );
Finally
MathInt . Free ;
End ;
End ;

End .

You will notice that this service ( MathRequester ) has the same parameters as the remote target
service ( MathProcessor ). This is necessary since the information is just going through this service,
but it also makes it quite easy to handle the remote call and the return of the result (out) values to
the browser side of your applications.

Wrapping it up
As we have just seen, WebMethods can be used to provide simple functionality which takes
processing from the browser to the server or they can be used to lookup information from a
database, returning such information to Forms in the browser side of the application. These are,
however, just a few possibilities. WebMethods are a very interesting construct within Morfik tools and
can be used for very different purposes.

By creating WebMethods you can make available, to 3 rd parties, certain functionalities of your online
system or create services which will be centrally available for use by several different applications.

category:Programming

Page 187
Patterns for Using Web
Services in Morfik

Using Web Services in a Morfik 07 XApp.


Morfik WebOS AppsBuilder allows developers to both publish and consume Web Services. In Morfik 07,
the publishing of Web Services, though adhering to industry standards, imposes limitations on the type
of parameters (specifically, structured/complex types) that a web services call can accept. Despite this
limitation, Morfik offers an extremely easy entrance path to the world of Web Services and Services
Oriented Architecture (SOA).

Morfik offers an easy way for the uninitiated to brave new frontiers, through the concept of a Web
Method which is a function/method which is published through Web Services Standards.

All Morfik Applications (XApps) are inherently Web Services compliant servers, in their server side
components. The Morfik Framework actively uses Web Services calls to implement all of its high level
communication between the server and browser sides of Morfik XApps.

Since browsers will not allow JavaScript code downloaded from domain A to make a call to a server in
domain B, for security reasons, Morfik 07 only allows calls to external Web Services to originate from the
server side of the XApp. Calls between the browser and server portions of an XApp are considered to be
a special case and the developer can create WebMethods which will be callable from the browser side
through the RunWebMethod command.

There are two basic scenarios for usage of Web Services in a Morfik 07 application, with two possible
variations in one of them.

Scenario 1
Intra-application calls from the browser to services offered by the server side portion of an XApp. In this
scenario we are considering that the application/site which is running in the browser is part of the same
Morfik XApp as the server side code.

Scenario 2
Calls to Web Services external to the application, implemented in another Morfik XApp (scenario 2a) or
any other source (scenario 2b). These calls are started on the Server side of an XApp, sometimes in
response to a an intra-application call from the browser side, as described in Scenario 1.

Scenario 2a Sc
en
ari
o
2b

Page 188
no
ne
]]

Using Web Services in an Morfik R2 XApp


Morfik AppsBuilder R2 offers an extended range of scenarios for the usage of Web Services and for
building the blocks which will be part of a SOA environment.

Among the major differences between Morfik AppsBuilder R2 and Morfik 07 is the removal of limitations in
the building of industry standards compliant web services server applications and the possibility of
initiating a web services call directly from within the browser (scenario 3).

Scenario 3
A single browser XApp calls directly web services provided by two (or more) different servers within the
same domain it was served from (scenario 3a).

Scenario 3a

One of the servers which is being called directly can make a call to an external service, provided by a
server in another domain (scenario 3b).

Page 189
Scenario 3b

Scenario 4
The process of creating "proxies" to external web services (as described in scenario 3b) is automated.
This allows Web Services to be easily called from browser XApps through a server XApp proxy.

Page 190
In this scenario the logical communication is between the browser XApp and an external web service.
This is impossible to implement without a server component due to browser security restrictions. Morfik
AppsBuilder R2 automates the process of creating proxies for this type of situation and allows the
developer to code the application as if the call was actually originating on the browser.

Scenario 5
The all-you-can-code web services scenario. It includes all the possibilities that are covered in scenarios
1 to 4 and shows that they can be used in conjunction to create sophisticated web applications and
websites.

Page 191
Conclusion
The changes in the Morfik Framework introduced in Morfik R2 to fully support all aspects of creating
industry standards compliant web service servers have been tailored to make the creation of such
servers easier and faster. Using Morfik R2 it is now much faster and practical to publish web services,
allowing developers to, very quickly, create applications which publish their services. These changes will
attract the attention of developers and should result in a higher number of applications so exposing their
services.

See Also
 Working with Web Methods
category:Programming

Page 192
Why Use Web Methods

There are three main reasons why you might want to use Web Methods in your
application: you want to publish Web Service APIs for third party usage, you want
to share code between different applications and last there things you cannot do
otherwise.

While the last reason might seem the most compelling, the first two are also quite
important.

Publishing Web Services APIs


There is essentially no difference between creating a Web Services API for your own
consumption or by third parties. The process is exactly as described in the topics that describe
the creation of Web Methods visually and in code .

Sharing Code Between Applications


Web Methods are, also, a good way of sharing server side code between different
applications. You can create applications which function as libraries of functionalities,
implemented as Web Methods.

See Also
 Working with Web Methods
 Creating Web Methods - Visually

 Creating Web Methods - In code


 Calling Web Methods

Page 193
The Workspace

Morfik AppsBuilder provides a modern work environment for the professional who
wants to create a website or a custom, web-based, application. In the following
topics we cover specific aspects of the workspace within which all the work
happens.
 Workspace Layout
 Workspace Elements
Ribbon
 Overview
 Documents Overview
Project
 View
 Property Inspector Overview

 Events Inspector Overview


 Support Panels Overview

 Using the Ribbon, Menus and Panels


 Customizing the Morfik Environment

 Navigating through code


 Keyboard shortcuts

See Also
 Working with Forms
 Working with Themes

 Working with Controls

Page 194
Customizing the
Morfik Environment

The Morfik workspace can be configured to better suit your needs and the way you work. There
are a lot of configuration options covering from the appearance of the interface to how the
compilers behave. For a full description of everything that can be customized, please refer to the
AppsBuilder 2.0 Options topic.

One of the first things you might want to customize is the color scheme used by the Morfik
workspace as it might have some influence in the design of your project. You can change the
color scheme directly from the Welcome screen and configure it to a darker color set if you are
going to be doing more design work or just to match your personal preferences.

Figure 1 - Color scheme selector in the Home tab of the Ribbon when no project has been
opened.

In figure 2 you can see the Morfik workspace using a darker color scheme.

Page 195
Figure 2 - The Morfik workspace with a darker color scheme selected.

For further information on how you can customize the appearance and behavior of the Morfik
environment you should go to the topics that describe each of the available options .

See also
 The Workspace

Page 196
Events Inspector
Overview

The Events Inspector panel allows you to assign event handling routines or
WebActions to specific events of Pages, Forms, Reports and Controls easily. It
presents an alphabetically sorted list of the events available for the selected
object. Figure 1 presents a picture of the Events Inspector panel displaying the
events for a Form.

Figure 1 - Morfik Events Inspector Panel, docked and pined to the left side of the
workspace.

The Events Inspector panel is docked to the left side of the workspace by default,
but can be detached in case you want to work in a dual monitor scheme.

See also
The Workspace

Page 197
Navigating through
code

Within the Morfik Workspace it is very easy to drill down through your code and even the Morfik
Framework itself. While within the code editor, in the Morfik Workspace, if you hold down the
control key, as you move your mouse pointer around you will see that the words in the code are
underlined, as shown in Figure 1.

Figure 1 - A section of code in the code editor of the Morfik Workspace with the
TXMLHTTPRequestWrapper identifier underlined.

If you click on the underlined word, you are taken to the place in the code modules, where that
identifier was defined. When you use this feature, in the Home tab of the Ribbon, while in the
code editor, a Navigate section is displayed. In this section, a pair of buttons: Back and Forward is
displayed to allow you to to navigate between the identifiers you have clicked on.

Figure 2 - Navigation buttons on the Home tab of the Ribbon when in the code editor. The Back
and Forward navigation buttons are highlighted.

In the Navigate section of the Home tab of the Ribbon, when in the code editor, a pair of
dropdown boxes is displayed allowing you to navigate to a specific class declaration in the
current module or to the implementation of specific method of the currently selected class. Figure
3 shows the Home tab of the Ribbon with these dropdowns highlighted.

Page 198
Figure 3 - Dropdown boxes with the list of classes and methods of the selected class in the
current module.

See Also
 The Workspace

Page 199
Project View

Morfik AppsBuilder 2.0 introduced a totally new Project view which is much more visual in nature.
In this view you can see all the high level objects and documents which are part of your current
project. This view is automatically selected when you open an existing project or create a new
one.

The documents which are visual in nature are now, by default, represented by a thumbnail view
of their appearance. This makes it very easy and fast to locate specific Pages, Forms and Reports
in projects with a moderate number of objects. Figure 1 shows the project view for a small
project, with the thumbnails being displayed.

Figure 1 - Project view showing thumbnails for documents.

In the case of projects with a high number of documents or with many similar documents, it is
sometimes best to make use of the filtering option that is available from the Home tab of the
Ribbon when you are in the Project View. In Figure 2 you can see the project view of a project
with a higher number of objects and the filtering mechanism being used.

Page 200
Figure 2 - Project view with filtering in use.

When a project has a very large number of objects or when you wish to see as many objects on
screen at the same time, you can reduce the zoom factor for the project view. This option is
available from the Home tab of the Ribbon. Figure 3 shows the Zoom controls on the Ribbon.

Figure 3 - Zoom level control for the Project view.

Other than using the controls in the Ribbon, you can also hold down the control key and use the
Mouse Wheel to zoom in and out of the project view.

Reducing the zoom level will eventually lead to all thumbnails being replaced by small icons
allowing a much greater number of objects to be seen on screen at the same time. Figure 4
shows a project view at its minimum Zoom settings.

Page 201
Figure 4 - Project view at its minimum zoom setting. The project view is always available in the
workspace, through the Project tab.

See also
The Workspace

Page 202
Property Inspector
Overview

The Property Inspector panel allows you to change properties and characteristics
of Pages, Forms, Reports and Controls easily. It presents an alphabetically sorted
list of the properties available for the selected object. Figure 1 presents a picture
of the Property Inspection panel displaying the properties for a Form.

Figure 1 - Morfik Property Inspector Panel, docked and pined to the left side of the
workspace.

The Property Inspector panel is docked to the left side of the workspace by
default, but can be detached in case you want to work in a dual monitor scheme.

You can also select the value of most of the formatting related properties from the
Home tab of the Ribbon while in the Form or Report designer, as seen in Figure 2.

Figure 2 - Formatting related properties displayed on the Home tab of the Ribbon,
when the Form designer is active.

These options in the Ribbon allow you to rely on the Property Inspector panel only
when you need to change properties which are less frequently modified.

See also
The Workspace

Page 203
Ribbon Overview

The Ribbon is the main toolbar of the Morfik workspace. The requirement of more
space to display graphically rich information on themes and layouts, as well as
color selection prompted the decision by Morfik to adopt a taller toolbar.
Interestingly the changes in layout of the workspace, including those involving
menus, toolbars, document tabs and the statusbar resulted in a reduction of only
9 pixels in the work area that is available for editing documents, in Morfik 2 in
relation to Morfik 1, even though there is a lot more space available for the
toolbar.

The Power Menu


The Power Menu is accessible by clicking on the white "power on" symbol on a dark blue background,
round button at the leftmost position of the Ribbon. This menu offers immediate access to most
functions in Morfik which are related to project and document management, such as closing and
opening files.

Home Tab
The Home tab of the Ribbon is where the most operations commonly used during the design of an
application or a website are located. The content of this tab changes to reflect what you are working
on at the moment. However, the options in the Document, Compile and Clipboard sections are always
kept visible.

Figures 1 and 2 show views of the Ribbon when Forms or Reports are being edited in their respective
designers. The other modes which this tab can switch to, when working with other kinds of objects,
will be reviewed in the topics discussing the appropriate designer/editor.

Figure 1 - Contents of Home tab of the Ribbon when in the Form designer. When you are working in
the Form designer, the Home tab offers options for inserting and positioning controls on the Form.
The most commonly changed properties for controls, which are those pertaining to their appearance,
are also available from the Home tab, so that you do not need to invoke the Property Inspector panel
when doing most of the design work.

Figure 2 - Contents of Home tab of the Ribbon when in the Report designer. When working in the
Report designer, the Home tab of the Ribbon offers almost exactly the same options as are those you
see when working in the Form designer. The controls which can be inserted into a Report are a
different set from the ones that can go into Forms, but the equivalent ones have essentially the same
characteristics of their Form counterparts.

Design Tab
The Design tab of the Ribbon offers immediate access to all theme related operations. From this tab
you can change the theme of the current project or create, modify and delete themes.

Figure 4 - Contents of Design tab of the Ribbon.

The contents of the Design tab do not change when you switch designers. You always have access to
the Theme options from this tab, regardless of what you are doing.

Project Tab

Page 204
The Project tab of the Ribbon allows you access to a variety of options which affect the project as a
whole, such as: importing data sources or web services, creating RSS Feeds, managing resources,
deploying and managing database backup and restore operations.

Figure 5 - Contents of Project tab of the Ribbon.

In the Project tab you have options available to create new project documents and objects such as
new Forms, Reports, Tables and Queries. You can also create RSS Feeds for the current project.

From this tab you can also have access to the options dialog from which you can configure project
specific options.

Debug Tab
The Debug tab of the Ribbon allows access to large number of debugging features. From this tab you
can add variables to the watches list, add or remove breakpoints and gather the information you
need to fix any issues in your application.

Figure 6 - Contents of Debug tab of the Ribbon, while debugging an application.

Most of the options available from the Debug tab only become available during an actual debugging
session.

View Tab
The View tab offers access to different views of the object currently being edited or views which apply
to the project as a whole, as is the case with the Relationship view.

Figure 7 - Contents of View tab of the Ribbon.

Insert Tab
The Insert tab of the Ribbon is only visible when you are working in the Form or the Report designers.
This tab offers you a list of controls that can be inserted into the document you are editing.

Figure 8 - Contents of Insert tab of the Ribbon, when in the Form designer.

Figure 9 - Contents of Insert tab of the Ribbon, when in the Report designer.

The controls which are available when designing Forms and Reports are not the same, due to the
difference in nature between these two document types. The controls which do have counterparts
are as similar to each other as possible.

Quick Access Bar


The Quick Access Bar is a small toolbar situated on the upper left corner of the main window of the
Morfik workspace. This toolbar is always visible and initially offers the options to open, save and save
all modified documents in the project.

Page 205
Figure 10 - The Quick Access Bar.

See also
The Workspace

Related Video
 Ribbon Menu and Toolbar

Page 206
Support Panels Overview

When you create or open a project in the Morfik workspace you have access to a
set of panels which is docked to the bottom edge of the main window of the
environment. These panels serve various support functions, some related to
providing feedback on what the environment is doing at any one point in time.

Figure 1 - Morfik Support Panels, docked and pined to the bottom edge of the
workspace.

The support panels are docked to the bottom edge of the workspace, by default,
but can be detached in case you want to work in a dual monitor scheme.

Output Panel
The Output panel provides you with feedback on what is being done by the Morfik compilers
and the environment itself. This is the selected panel in the picture shown in Figure 1.

Errors Panel
The Errors panel provides a listing of all the errors found in the source code of your current
project. Through this panel you can have quick access to the modules and lines where the
errors have been identified.

Figure 2 - Errors Panel, docked and pined to the bottom edge of the workspace, showing two
errors.

Search Panel
The Search panel provides feedback on the results of a search operation. From this panel you
can have quick access to the modules and lines of code which were found to match a given
search criteria. The results which are displayed have the words that were part of the search
criteria highlighted in bold.

Figure 3 - Search Panel, docked and pined to the bottom edge of the workspace, showing the
results of a global search for "OpenForm".

Debug Panels
Among the support panels you will find several other panels which are for debugging related
activities such as inspecting the value of variables or monitoring communications between the
browser and server portions of the application. These panels and their usage are covered in

Page 207
more detail in debug specific topics.

See also
The Workspace

Page 208
Using the Ribbon,
Menus and Panels

In order to use the Morfik workspace to its fullest potential you will need to be aware that many
options are available through different parts of the interface. Great care has been taken to
ensure that the most frequently used operations and commands relative to what you are
working on is presented to you at all times. There is, however, a too large a number of
possibilities to make all of them visible all of the time. In Figure 1 you can see a picture of the
Home tab of the Ribbon in the Morfik environment as seen when designing a Form.

Figure 1 - Contents of Home tab of the Ribbon when in the Form designer.

There are options which are available through context menus, that come up when you right-click
on an object or through panels. Configuring controls, Pages, Forms and Reports is an example
where a panel is very useful. Though most of the formatting options are available through the
Home tab of the Ribbon, these objects have too many options to make it viable to try to fit them
on onto the toolbar. In this case the Property Inspection panel is used to have access to the full
set of configuration options as it presents an alphabetical listing of all the properties for the
object that is selected. Figure 2 is a picture of the Property Inspector Panel displaying the
properties of a Form.

Figure 2 - Property Inspector panel, floating.

In other situations you will find interesting options of commands available to you through the
context menu, such as when designing a Form. In this case, for example, you can start editing
the data source that is associated with the current form by choosing the Design Data Source
option from the context menu as seen in Figure 3.

Page 209
Figure 3 - Context menu for the Form designer.

See also
The Workspace

Page 210
Workspace Elements

The Morfik workspace is composed of the following


elements:

Welcome Screen
Allows you to open an existing project, create a new one or select from one of the featured
samples. From this screen you can access Morfik informational resources and the environment
options.

Ribbon
The Ribbon is the main toolbar of the Morfik workspace.

Home Tab
The Home tab of the Ribbon is the one where the most commonly used operations are
grouped. Most of the time you will have it visible and interact with it to create your
documents.

Design Tab
The Design tab of the Ribbon concentrates all options which are related to themes in the
Morfik workspace. From this tab you can select a new theme or manage your theme library.
You can create, modify and delete themes from this tab.

Project Tab
The Project tab offers access to a variety of options which affect the project as a whole, such
as: importing data sources or web services, creating RSS Feeds, managing resources,
deploying and managing database backup and restore operations.

Debug Tab
Most options in the Debug tab only become active when Morfik tools are in debugging mode.
From this tab you can select options to single step into, step out or step over lines of code.
You can add breakpoints and variables to the watches list as well as select to display or not
to display specialized debug panels.

View Tab
The View tab allows direct switching to specific views of the current document, selection of
project specific views and filtering of the contents of the project when in Project view. From
this tab you can also select to display or not to display specialized debug panels.

Insert Tab
The Insert tab is only visible when you are in the Form or Report designer. This tab replaces
the control palette which was available in previous releases of Morfik tools and offers access
to all Morfik controls. The controls can also be accessed through a section of the Home tab,
though their buttons are much smaller there.

Document Designer/Editor
The central area of the Morfik workspace is occupied, most of the time, by a document
designer or editor. The only exception is when showing the Welcome Screen.

Project View
The Project view allows you to choose which project objects or documents you want to work
on. The contents of this view can be filtered from both the Home and View tabs of the Ribbon.
Filters can be applied by object type and/or name. This view can be considered the Project

Page 211
Editor.

Form Designer
The Form designer allows you to position controls on your form, and to alter their appearance
and behaviour. SubForm controls may be used to bind individual forms together, to produce
the final web page shown to users.

Report Designer
The Report designer is very similar in appearance and function to the Form designer. Reports
are generated, at runtime, as PDF files which are then sent to the browser. Reports run
entirely on the server side of an application and will require the presence of Acrobat Reader
on the end-user's computer in order to be viewed. (Morfik Web Application projects only)

Table Designer
The Table designer allows you to create tables or visualize their structure from within the
Morfik environment. In Morfik Browser Application projects the table designer is used to
design "tables" that are stored in XML files, whereas in Morfik Web Application projects you
can actually create tables in the project's associated database. All Morfik Web Application
projects have a corresponding database created by the built-in database management
system.

Query Designer
The Query designer allows you to visually create queries for either the built-in or external
databases. Queries can also be created through the code view of the Query designer
allowing for total flexibility in creating the SQL commands which will be passed to the
database. (Morfik Web Application projects only)

WebMethod Designer
The WebMethod designer creates a new WebMethod (Web Services API) by specifying the
input and output parameters and then adding some code to handle its execution on the
server and response on the browser. WebMethods are essentially server code that gets
executed in response to a call from the browser or another server application. A small portion
of browser code is associated with WebMethods as it is frequently necessary to handle their
return information. (Morfik Web Application projects only)

Relationship View
The Relationship view allows you to view and specify relationships between tables in the
project's associated database.

Code Editor
The code editor allows you to edit code associated with different objects in a Morfik project. In
Morfik Browser Application projects only browser code can be created, but in Morfik Web
Application projects the user can create both browser and server side code. Toggling
between different code views can be achieved through the F12 and shift-F12 keys or through
the Ribbon. It is possible to identify the current code view by the color of their keywords: Red
for Browser side and Blue for Server side.

Property Inspector
The Property Inspector panel allows you to set properties and change characteristics of most
objects that compose a project, such as: forms, reports, bands and controls.

Events Inspector
The Events Inspector panel allows you to create event handling code in your project and tie it
to the appropriate events for controls and forms.

Support Panels

Page 212
Several support panels are grouped together at the bottom of the workspace area. These
provide insight into project management tasks, such as compilation and errors, as well as
views to information that can help in the debugging process. Some of the panels are only
available when working with Morfik Web Application projects, as the information they present
relates to server side code and features.

See also
The Workspace

Page 213
Workspace Layout

The workspace in Morfik AppsBuilder lets you view documents, properties and code. The
workspace places most of the commonly executed operations on its toolbar so that you can
easily make changes to your project and documents.

Figure 1 - Morfik Workspace areas.

The Morfik Workspace is divided up into areas as indicated by the numbers in figure 1 of this
topic. The following is a description of what each area is used for:

1. The Ribbon - This is the applications main toolbar providing access to most of the project and
document management features as well as the document formatting.

2. Left Panels - This area by default presents two panels to the user: the Property and Events
inspectors.

3. Designer/Editor - The area at the center of the workspace is reserved for the document
designer or editor. The content in this section changes according to document and view which is
selected. While editing a Form, for example, a visual design and two code views would be
available. The current view can be changed from the Ribbon.

4. Bottom Panels - This area displays a series of support panels which can be used when
performing management tasks for your project or while debugging.

5. Right Panels - Just as the Left Panels, this area displays by default two panels: Debug Scripts
and Debug Source. These panels are of use only when debugging an application at the platform
compiler level (JavaScript and Object Pascal for the Browser and Server portions of the
application, respectively).

See also
The Workspace

Page 214
Page 215
Using External Code

This text includes a general overview of how to use external code with Morfik
AppsBuilder. The sections of the text that refer to importing JavaScript code apply
equally to both Morfik Browser Application and Web Application projects, while the
server side portions apply only to Morfik Web Application projects.

Morfik AppsBuilder was designed from the ground up to be a web application


development tool which allows developers to write code in a high level language,
regardless of whether the code is for the browser or server side of the
application.

While writing a Morfik application, you might wish to use some code that has been
written by someone else, in order to reduce the development effort. This can be
JavaScript code for the browser side of your application or source/binary libraries
(DLLs, SOs) for your server side.

During the application compile process, Morfik generates JavaScript code for the
browser side of your application and intermediate source code for the server side.
This intermediate code (which is in Object Pascal) is then compiled into the
executable, through one of the supported platform compilers (pass 3 of the
compile process).

In order to illustrate how to do this, I will present some code snippets from the
System.mmd module of the Morfik Framework.

Step 1 – Bringing your code in…


The first thing that a user needs to know when bringing external code into the Morfik
high-level language universe is that it is a two step task. The first step is making the code you
wish to bring in available at the JavaScript (browser side) or Intermediate Object Pascal
(server side).

For the browser side, this is almost immediate. Just add the JavaScript code file to your
application ’ s Resource Repository and you are ready to go to the next step. For server side
code it is just as easy, but more options are available.

If you have a DLL (or shared object) that you wish to use from your Morfik application, you
should write an Object Pascal import unit, which imports the functions you wish to have
access to. If your code is already written in Object Pascal, you can bring it right in. All you
need to do is to include the path to your source in the advanced configuration of the Project
Options. It will work just as an import unit would, except that all code will be linked to the
application, instead of depending on a DLL.

You might have to make small adjustments to your code, for compatibility, if it was written for
Delphi. (This will not be necessary if you are using Delphi as your backend compiler.)

Step 2 – Making your code available to your application…


Once you have gone through the work in Step 1 and have made your JavaScript or your
server side code accessible, you have to take an additional step to make the code available
to the Morfik High-level language compiler.

In order to make the code available you have to create a module with the declaration of the
functions or classes that you plan to use and mark them with the external metadata tag,
informing where it is actually implemented.

For example, the FreeMem and GetMem functions in the System.mmd module are actually
implemented in the SystemExt.pas unit. The following code informs the High-level compiler of
that:

Function FreeMem ( var P : Pointer ; Size : Integer ); [


'External=SystemExt' ];

Function GetMem ( var P : Pointer ; Size : Integer ); [

Page 216
'External=SystemExt' ];

The same principle applied to these functions can be applied to classes, as well. The following
code is an example of how to do it:

Exception = Class ( T Exception )


P rivate
FHelpContext : Integer ;
P ublic
Constructor Create ( Const Msg : String );
Constructor CreateFmt ( Const Msg : String ; Const Args : Array Of
Const );
Constructor CreateRes ( Ident : Integer );
Constructor CreateResFmt ( Ident : Integer ; Const Args : Array Of
Const );
Constructor CreateHelp ( Const Msg : String ; AHelpContext : Integer );
Constructor CreateFmtHelp ( Const Msg : String ;
Const Args : Array Of Const ;
AHelpContext : Integer );
Constructor CreateResHelp ( Ident : Integer ; AHelpContext : Integer );
Constructor CreateResFmtHelp ( Ident : Integer ;
Const Args : Array Of Const ;
AHelpContext : Integer );
P roperty HelpContext : Integer Read FHelpContext Write
FHelpContext ;
P roperty Message : String Read Msg Write Msg ;
End ; [ 'External=SystemExt' ];

These examples are of functions and classes which are made visible to all Morfik code through
the System.mmd module, but which is actually implemented in the SystemExt.pas Object
Pascal unit.

Of course, all of these examples are server side, but the browser side is even easier. On the
Browser side you might be referencing some functionality which is made available by the
browser itself, or by a JavaScript file. The two lines of code that follow show how to handle
both situations, respectively.

Function IsModuleLoaded ( m : String ) : Boolean ; [ 'External='


];

Function getDomainSuffix ( d : String ) : String ; [


'External=brlJLib' ];

The next code snippet is the declaration of the TXMLHTTPRequest class which is implemented
within the browser itself.

T XMLHT T P Request = Class


responseT ext : String ;
responseXML : String ;
onreadystatechange : P ointer ;
readyState : Integer ;
status : Integer ;
wrapper : Pointer ;
Function open ( Method , Url : String ; Async : Boolean ;
User , P assword : String );

Page 217
Function send ( Body : String );
Function setRequestHeader ( HeaderName , HeaderValue :
String );
Function abort ;
End ; [ 'External=' ];

As you can notice, whenever a function or class is implemented in the browser itself the right
hand side of the equals sign for the External metadata tag is left empty.

Wrapping it up
Using code created with other tools in Morfik is not a hard task, if you are familiar with how to
use those tools. Once this process is complete the functions or classes will be accessible to
high-level code created in Morfik.

See Also
 Morfik Languages
category:Programming

Page 218
Working with Forms

One of the major differences between Morfik tools and all other development tools
for the creation of Web applications is that the WebOS AppsBuilder does not force
the developer to understand how a browser works or how remote calls to a
server happen. The developer does not need to know how to code HTML, XHTML,
CSS, ASP, PHP, SOAP or whatever other acronym that has ever been invented to
describe techniques and file formats for web development. Applications for the
Web are developed in the same way that common applications are developed
using tools such as Borland ’ s Delphi or Microsoft ’ s Visual Studio.

When I first tried out Morfik AppsBuilder I was immediately impressed by how easy
it was to create the basics of a web application, without actually doing any coding.
What is more impressive was that not only did it not ask me to write any HTML or
scripting code, but it did not spit these out at me. I have seen many tools that
allow you to design HTML form interfaces and generate the corresponding HTML
files for you. Up to that moment they had been the pinnacle of web development
tools for me. Tools that offered WYSIWYG HTML design and were able to organize
your scripting code were the best one could expect. After ten years of intense
development efforts by people all around the world that was as far as we had
come.

New languages had been created and were flourishing. A major example of this is
the PHP scripting language currently in use in thousands, if not millions, of web
servers all around the globe. Techniques had been developed and file and data
formatting standards created. New terms such as SOAP and XML had come into
the everyday life of the software developer, or at least of those trying to stay in
synch with what was being developed. Things had been progressing at a frenetic
pace, driving us forward into new and unexplored frontiers such as hosted
Customer Relationship Management and even Word Processors, available on the
web.

A Problem To Be Solved
Taking Visual RAD to the Web
A Page By Any Other Name
Every Page is a Form, But Not All Forms are
Pages
Where Does an Application Start?
Designing a Form
What is a SubForm?
Forms Have Bands
Using the OpenForm Function
Pre-fetching Forms
Form Events
Data Manipulation Events
Data Navigation Events
Data Refresh Events
Form Instantiation Events
User Interface Interaction Events
OnBlur
OnClick
OnFocus
OnKeyDown

Page 219
OnKeyUp
OnMouseDown
OnMouseMove
OnMouseOut
OnMouseOver
OnMouseUp
OnResize
OnScroll
Browser Management Events
OnReadHistory
OnWriteHistory
Form Band Events
Browser Side Events
OnAfterGrowOrShrink
OnBeforeGrowOrShrink
Server Side Events
OnAfterPrint
OnBeforePrint
OnPrintStyle
Data Bound Forms
What Makes a Form Data Bound?
Two Kinds of Data Bound Forms
Continuous Forms
Single Forms
Positioning the Controls on a Form
Configuring the Form Designer
Wrapping it up
See also

A Problem To Be Solved
The only thing that bothered me was that I always thought that development tools were going about
this in the wrong way. Why? Well let ’ s go back a couple of years... I used to work a lot with Borland
’ s Delphi and Microsoft ’ s Visual Basic, two very similar, yet very different development tools. They
were similar in the interface that they provided to the developer and in the way you could extend
them with user-created components. They were different in how things were implemented under the
hood. While Visual Basic was an interpreted language, depending on an extensive runtime library to
execute applications and thus limiting what you could build with it (its own add on components had,
for a long time, to be built with another language), Delphi was a native compiler which produced first
class binary executables for the Win32 platform.

Both of these tools, as well as several others, hid entirely from the developer all the necessary
plumbing for getting a Windows application up and running. Using the Windows Software
Development Kit (SDK) and a C compiler, you needed to write one hundred and seventeen lines of
code just to display an empty blank window, which did nothing. Later tools such as Turbo Pascal for
Windows and Visual C would cut that down to twenty to thirty lines, by using extensive and
elaborate class libraries (OWL and MFC).

It was into that scenario that Microsoft introduced Visual Basic as a tool for the speedy creation of
simple applications for Windows. It totally hid all the complexity of the Windows environment and

Page 220
allowed developers to get an empty window up and running with zero lines of code. It was a major
breakthrough and soon developers started flocking towards it. Borland took this new way of
developing Windows applications to a whole new level when it introduced Delphi. Delphi offered the
same ease of use of Visual Basic but instead of depending on a runtime and interpreted code, had an
IDE that generated code, on-the-fly, for using its sophisticated and high-level class library, called the
Visual Component Library (VCL). The VCL was entirely written in Delphi and, again, totally hid the
details of how the Windows environment worked. It allowed you to create the same zero lines of
code window, but it did so as a native binary application which although it still did nothing, did it with
a reduced size and better performance. This was the era of visual tools and Rapid Application
Development (RAD).

Taking Visual RAD to the Web


So, why are we talking about developing applications for Windows with tools from Microsoft and
Borland when this is a book about Morfik? Well, I want to make a point. Back in the days of the pure
C and SDK development for Windows it was important, maybe even cool, to know all the hundreds of
functions of the Windows API. (I read the manuals for it.) You had to know how Windows worked in
order to be able to develop anything for it. Even the simplest of applications required the
understanding of things such as creating a message processing loop, painting text onto the screen,
etc, until these visual development tools, I mentioned, came along. When the World Wide Web hit us
in the face, in 1995, it was all about text and content. As its convenience and ubiquity grew, it soon
became a platform for application development and delivery and so we were back to the time when it
was necessary to know how things worked in order to get anything done. This time, instead of
needing to know how Windows worked we needed to know how the Web worked. It was studying
HTML, JavaScript and server/browser communication instead of the Windows API. One interesting
aspect of it was that it all seemed very easy. You could just bring up notepad and type in a web
page.

Development tools for the Web soon took us beyond notepad. But as each new tool appeared and
evolved it was always about making it easier for you to use the "Web API", and not about hiding it. It
seems that people just decided that it was too important that everybody know how this stuff worked
- until Morfik came along. The people that started Morfik had the same belief that I had; that it was
unacceptable that someone had to learn all that stuff (HMTL, XHTML, JavaScript, Blah, Blah...) in order
to be able to write simple applications for the Web. They perceived that the Web had, in fact, become
an application platform, as had Windows before it and that people needed a more productive way to
develop applications for this platform. Luckily for all of us, they had the resources and the will to apply
these, as well as their time, to this problem and bring us to this point.

Now, working with Morfik WebOS AppsBuilder we can go back to talking about forms and controls and
business needs without having to worry about learning how the Web works. We have been using it
for over a decade and it is about time that we let go of the text files and start developing real
applications for this wondrous new platform. This is what this chapter is about: Working with Forms
and how it is different from working on legacy web applications. Although Morfik forms are very similar
to windows forms at design time they are quite different at run time.

This is quite deceptive and could potentially become an impediment if the distinct run time model for
Morfik forms is not understood early in the learning cycle

A Page By Any Other Name


In the WebOS AppsBuilder we do not write pages, but design Forms. How can that be, when the
Web itself works with Pages? Well, we do work with Pages; we just don ’ t need to think of them
quite that way, most of the time. The main interface metaphor used by the AppsBuilder is the Form,
as in all major Windows development tools. This is a significant difference because when software
development became Page-centric, to accommodate the way things worked on the Web, it missed
the point that Web Pages were for delivering text content and not interactive applications. Modern,
Ajax enabled, Web applications have few pages, but these pages go through several changes in
appearance in order to interact with the user. With Morfik AppsBuilder you design Forms for user
interaction and not just text presentation.

Another major difference between Morfik Forms and HTML Pages is that the Forms can be
self-containing (both at design time and at run time) and therefore extremely modular. HTML pages
are NOT! Though you can use server side to compose a Page from several HTML snippets, you cannot
say that you define an HTML Page in terms of other HTML Pages.

Due to this characteristic the layout and, more importantly, the behavior of an arbitrarily complex
page can be recursively reduced down to simpler and simpler Form constructs.

In several of the previous chapters of this book, I have used WebOS Forms as examples of how

Page 221
things are done in the AppsBuilder and how you can use your language of choice to develop
applications. In this chapter we will go a lot deeper into what Forms are and how they are used.

Every Page is a Form, But Not All Forms are Pages


One of the most important things to know about Forms is that in the WebOS AppsBuilder all Pages
are Forms, but not all Forms are Pages, just as all squares are rectangles, but not all rectangles are
squares. This might seem a bit confusing, at first, but it is really simple. Forms can represent not only
an entire Page, but portions of a Page. You can actually build Forms that are composed of several
other Forms. For every page in your application you will have a "top level" Form which may or may not
contain other Forms in SubForm controls. While this might not seem like much at first, you will soon
see that this simple feature opens up enormous possibilities in application interface design. This is
particularly true because in contrast to the Windows environment where building interfaces based on
user created visual components, such as Forms, might have added "weight" to the application, the
WebOS AppsBuilder knows how to translate your interface design into the appropriate dynamic HTML
code without adding unnecessary weight to your application. The diagram in Figure 1 should give you
a general idea of how a Page/Form can be composed of several Forms (in this case called SubForms).

Figure 1 – Page/Form composition by using SubForms.

Where Does an Application Start?


When you create a new project in the Morfik IDE, it already has its first Form. This Form is called Index
and it is the default starting Form for you application. This closely parallels the way web servers work,
since most expect a Page called Index.html to be present in the directory that is being published. You
can change the name of this Form or specify any other Form as the default startup Form for your
application by going to the Application tab of the Options dialog and changing the Main Form property
It is this project property that tells the Morfik compiler which of the Forms that make up the project
will be the entry point for your application.

Designing a Form
In the Morfik WebOS AppsBuilder it is very easy to build Forms. It is, actually, very much like building
Forms in any modern visual development environment for Windows. Once you enter the Form
Designer you will see a floating palette of controls that can be used to create the interface of your
application. There are several different controls that can be used in combination to achieve very
interesting results.

Page 222
Figure 2 – Form Designer ’ s Toolbox

In Figure 1 you can see a view of the toolbox with the available controls. As all who have developed
applications in a visual IDE will notice, the main controls are the same as you would have in such a
tool. Let ’ s review some of the basic controls:

Glyph Control
TextLabel – This control is mainly used for displaying information
(text) in the Form/Page being constructed. It can easily be used to
represent a hyperlink.

TextEdit – This is a control geared towards editing single-line text.


It can be used for entering multi-line text through the configuration
of the MultiLine and WordWrap properties.

Button – A clickable button. Normally used to start some sort of


action.

OptionButton – generally used to provide choices

CheckBox – This control is used to allow the user to change/display


the current state of a boolean type variable.

ListBox – Used to display a list of options for the user to choose


from.

ComboBox – Used to display alist of options for the user to choose


from, which drops down right bellow a TextEdit..

DATE/TIME – Single line edit field (such as the TextEdit control)


specialized for date information input.

Container – As the name suggests, it is used to "contain" other


controls. Different formatting attributes can be applied to group or
highlight different elements in a Form.

Image – This control displays an image on the Form.

TabControl – With the TabControl the developer can visually group


related controls in different tabs on the Form, providing better UI
space management.

Flash – The Flash control allows the developer to insert any Flash
element into a Morfik Form.

Page 223
SubForm – With the use of the SubForm control you can embed
Forms within Forms. This allows the creation of sophisticated
applications through Form composition.

File Uploader – This control allows the selection and uploading of


files.

Timer – The timer control continually generates an event on the


browser side of the Form, allowing the developer to update or
refresh some portion of the user interface.

Rectangle – This control paints a rectangle on a form and is


generally used as a layout/formatting aid.

RSS – This option allows editting or creating a new RSS feed in the
current project.

In order to place any of these controls on a Form, all you have to do is click on the control button and
then click on the Form itself. A control will be created on the Form, exactly on the spot you clicked.
After the control appears you can drag it on the Form to adjust its position. Once the control is in the
desired position you can set its properties in order to select the desired appearance and behavior.

Figure 3 - The properties Window

In Figure 3 you can see a view of the Properties Window . It is the configuration of these properties
that allow the appearance and behavior of the components you add to the Form.
Properties in the Properties Window are grouped together in Tabs, such as: Format, Data, Event, Other
and All . Through the Event tab you get access to a complete list of events for the currently selected
component, and can choose to write code to handle any particular one.

You can also use the Properties Window to set properties for the Form itself or any of its bands.

If you double click the empty field besides the name of an event in the Event tab of the Properties

Page 224
Window a code stub for that event will be created and the code editor will be displayed so that the
event code can be inserted.

What is a SubForm?
One important question you might be asking yourself is: what exactly is a SubForm? I have talked a
lot about SubForms, but I have not gone into great detail. It is time to remedy this.

SubForms are special controls which can host Forms inside them. When placed on a Form a SubForm
is shown as a hashed area, as can be seen in Figure 4. Forms can be linked statically to SubForms, at
design time by assigning a form name to the Form property, or at runtime through the use of the
OpenForm function.

When statically bound to a Form, the SubForm control displays the Form name in parenthesis,
besides its own name.

Why Build Forms with other Forms?

Ok, I have mentioned that you can build Forms from other Forms, as shown in Figure 1. But why
would you want to do that? Can ’ t you simply create your Forms by placing controls directly on them?
Of course you can. The idea of breaking things up into smaller parts is directly tied to the concept of
modularity. In the WebOS universe, modularity is a key concept for it allows the exchange and
reloading of parts of a Page/Form, without having to actually reload the whole Page. This makes for
much more flexible and faster interfaces for web based applications,

When you have different elements which will occupy the same space within a Page/Form, at different
moments, you will be looking at a case for modularization into SubForms. An example of this behavior
can be seen in the following sample application that I have built for this purpose. In this application
the Index Form has two SubForms which will work as navigation and information display areas during
the application ’ s runtime. In the screenshot in Figure 4 you can see this application ’ s Index Form
loaded in the Morfik IDE Form editor.

Figure 4 – Index Form (initial application starting point) loaded in the Form Editor

Page 225
In the screenshot in Figure 4 the thin vertical SubForm on the left of the Form is the NavigationArea
SubForm, while the larger one is the MainArea SubForm. These SubForms display the names of the
forms that will be automatically loaded into them.

Forms Have Bands


In the Morfik WebOS Forms have bands, three in all, that are used to divide up the Form for
implementing specific behavior. The three bands are: Header, Footer and Detail. In the example in
Figure 4 you can see all the three bands in use. Notice that they can totally different formats,
including background color.

Figure 5 – The HostingPlans Form shown.

Figures 5, 6 and 7 show the same page as Figure 4, with different forms displaying inside the
MainArea SubForm control. Both the NavigationArea and the MainArea SubForm controls are inside the
Detail band of the Index Form.

In Figure 5 you can see the HostingPlansForm being displayed inside the MainArea SubForm control in
the Index Form. This Form has a Tabs control which shows a different tab for each of the hosting
plans being advertised.

Page 226
Figure 6 – The eMailProduct Form shown.

In Figure 6 you see the Index Form after the eMail button on the Navigation bar has been clicked.
Now the eMailProductForm is being shown in the MainArea SubForm. Notice that the application (or
site) is still in the same page and only the content of the area belonging to the MainArea SubForm
control has changed.

In Figure 7 you will see the same Index Form showing the contents of the InfrastructureForm in the
MainArea SubForm.

In order to get these results with the WebOS AppsBuilder all we have to do is create separate Forms
and then piece them together either statically or dynamically. As this application starts up it will load
two distinct Forms into the SubForm controls. One of these is the NavigationForm and the other is the
HostingPlansForm . These Forms are loaded statically because I have associated their names to the
Form property of their respective SubForm components.

Almost all the functionality in this application/site is automatically provided by the Morfik runtime
library. The only code really written in this application at this time is in the code included in the OnClick
events for each of the Button controls that are present in the NavigationForm . In each case it is a
single line of code that specifies a new Form to be opened inside the MainArea SubForm control.

Page 227
Figure 7 – The InfrastructureForm Shown.

In Listing 1 you will find the code for the NavigationForm ’ s browser module. Most of the code is
automatically generated by the AppsBuilder, requiring the developer to write, only the appropriate
commands to switch the Form that is visible on the page in the browser.

Listing 1 – Browser side code (in Morfik Pascal) for the NavigationForm.

Unit NavigationForm ;

Interface

T ype
NavigationForm = Class ( Form )
T extLabel1 : T extLabel ;
HostingButton : Button ;
eMailButton : Button ;
InfrastructureButton : Button ;
P rocedure HostingButtonClick ( Event : T DOMEvent ); Message ;
P rocedure eMailButtonClick ( Event : T DOMEvent ); Message ;
P rocedure InfrastructureButtonClick ( Event : T DOMEvent );
Message ;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
End ;

Implementation

P rocedure
NavigationForm . HostingButtonClick ( Event : T DOMEvent );
Begin
OpenForm ( 'HostingP lansForm' , 'Index:MainArea' , '' );

Page 228
End ;

P rocedure NavigationForm . eMailButtonClick ( Event : T DOMEvent );


Begin
OpenForm ( 'eMailP roductForm' , 'Index:MainArea' , '' );
End ;

P rocedure
NavigationForm . InfrastructureButtonClick ( Event : T DOMEvent );
Begin
OpenForm ( 'InfrastructureForm' , 'Index:MainArea' , '' );
End ;

End .

The code in Listing 1 brings us into contact with function/procedure which will be widely used in
everyday development of WebOS applications: OpenForm.

Using the OpenForm Function


The OpenForm function is used for opening forms inside the SubForm components or in place of the
current Form. In the example we just saw in Figures 2 through 5 all Forms were displayed inside
SubForms.

Observe an example of the usage of the OpenForm function taken from the above example:

OpenForm( ’ eMailProductForm ’ , ’ Index:MainArea ’ , ’’ );

In this example the eMailProductForm is being ordered to display inside the SubForm MainArea of the
Index Form. The empty string in this call is a parameter which allows for the passing of parameters to
the Form which will be opened.

It is important to have in mind that a call to the OpenForm function is totally asynchronous. As you
will see in the Pre-fetching Forms topic, you can call the function several times in a row and you will
start the download of several Forms at the same time.

OpenForm Syntax

OpenForm(form, context, parameters);


||
| |__ blank - new browser window with new instance of script process (AJAX engine)
||
| |__ same - same browser window with new instance of script process (AJAX engine)
||
| |__ FormInstanceName:SubformName[(bandindex)]
| | | |__ if not specified it's set to zero
|||
|||
| | |__ special strings: '_' ('_' denotes the containing
| | subform)
||
| |__ special strings :'self','parent','top'
|
|__ URL (this will result in a new instance of the script process to be instantiated)
|
|__ instancename:classname
|
|__ classname (in this case the instance name is implicitly set to be the same as the clas
s name)

Page 229
In the Rio de Janeiro Hosting example we have just seen, all uses of the OpenForm function followed
a specific pattern: opening a form in the MainArea SubForm. In the line below, taken from the
example, the first parameter is the class name for the Form you wish to open, and the second one is
the name of the SubForm component where you wish it to appear.

OpenForm( ’ eMailProductForm ’ , ’ Index:MainArea ’ , ’’ );

In this example the second parameter is specifying that we wish to open the Form in the SubForm
MainArea which is in the Form Index .

In this example you do not see any Form being opened in the NavigationArea SubForm. That is
because we have statically bound the NavigationForm Form to this SubForm control in the Index Form.
This is done, through the Properties Window, by setting the Form property of the SubForm control.

Pre-fetching Forms
The Morfik Framework and runtime library implement a great caching infrastructure for your
application, which allows the developer to download pages before the user comes to need them. This
allows for very rapid response times when accessing the application.

This feature allows the developers to create applications that are much more responsive to user
interaction and input since they can predict which Forms the user might want to access and download
them in the background.

How does this work? Let ’ s consider, as an example, an application with an initial Form/Page that
presents the user with ten choices, of which you know that one of three options will be chosen by
97% of users to start with. In this case, as you finish downloading the main Form/Page you can start
the download of those three most commonly used Forms in the background.

While the user is going through the task looking at the options and deciding where to go from there,
the browser is fast at work preparing the way for a rapid response by downloading the most likely
choices. If the user selects an option before the download process is complete, the application will
just continue normally with the download process as it was doing before, only now it knows that it
should display the requested option as soon as the download is complete.

Listing 2 – Browser side code (in Morfik Pascal) for pre-fetching 2 Forms before they are
actually needed.

P rocedure Index . WebFormShow ( Var Show : Boolean );


Begin
OpenForm ( 'Form1' , 'Self:MainSubForm' , '' );
If Not DoneP refetch T hen
Begin
OpenForm ( 'Form2' , 'Self:MainSubForm' ,
'"OpenMode=DONOT ACT IVAT E"' );
OpenForm ( 'Form3' , 'Self:MainSubForm' ,
'"OpenMode=DONOT ACT IVAT E"' );
DoneP refetch := T rue ;
End ;
End ;

Form Events
Both in Listing 1 and 2 you see Pascal code for handling Form events. This kind of code should be
familiar to any developer who has worked with a modern development tool for the Windows Platform,
but Morfik ’ s Forms are not for Windows but for the WebOS and therefore will have different kinds of
events.

In order to handle events from the form, or any other control, you should double click the empty field
besides the name of an event in the Event tab of the Properties Window. As a result a code stub for
that event will be created and the code editor will be displayed so that the event code can be
inserted.

Because of the uniqueness of the WebOS environment, it is important that the developer familiarize
himself/herself with the Morfik Form Class ’ events, in order to know how to take full advantage of

Page 230
its extensive, built-in, capabilities.

Form events can be grouped into six main categories; most events occur on the browser side. Those
that relate to the server side are indicated. Here is a table list of all the form events:

Data Manipulation Events


 OnBeforeSubmit
 OnAfterSubmit

 OnBeforeDataChange
 OnAfterDataChange
Data Navigation Events
 OnBeforeDBNavigate
 OnAfterDBNavigate
Date Refresh Events
 OnBeforeRefresh
 OnAfterRefresh
Form Instantiation Events
 OnDestroy
 OnCreate

 OnBeforeExecute (Server Side)


 OnAfterExecute (Server Side)

 OnReady
 OnShow
User Interface Interaction Events
 OnBlur
 OnClick

 OnFocus
 OnKeyDown

 OnKeyUp
 OnMouseDown

 OnMouseMove
 OnMouseOut

 OnMouseOver
 OnResize

 OnScroll
Browser Management Events
 OnReadHistory
 OnWriteHistory

Data Manipulation Events


These events fire whenever there is a request made to change any data in the database connected
to the document. The order of events is as follows:

1. Request to change data (which may be invoked via the user in the browser or programmatically)

2. OnBeforeSubmit

3. The request to alter data is submitted to the database

4. OnAfterSubmit

5. If successful, OnBeforeDataChange

Page 231
6. Data is changed

7. If successful, OnAfterDataChange .

Data Navigation Events


These events fire whenever there is a request made to move from one record to another. The order
of events is as follows:

1. Request to navigate between records (which may be invoked via the menu navigator or
programmatically)

2. OnBeforeDBNavigate

3. DBNavigate procedure

4. If successful, OnAfterDBNavigate

Data Refresh Events


These events fire whenever there is a request made to refresh the document with the latest data
from the database. The order of events is:

1. Request to refresh the data

2. OnBeforeRefresh

3. If the refresh is successful, OnAfterRefresh .

These events are different, and not to be confused with the Refresh or F5 option associated with the
browser, for example Internet Explorer.

Form Instantiation Events


These events fire whenever there is a request made to create and display a new document. Note
some of these events are server side as indicated. The order of events is:

1. Request to create and display a new form (which may be invoked via the browser or or
programmatically)

2. OnDestroy (of the old form)

3. OnCreate and the document is created at the server end

4. OnBeforeExecute (performed at the server)

5. The document is sent from the server to the browser end

6. If successful, OnAfterExecute (performed at the


server)

7. OnReady when the document has been fully received by the browser

8. OnShow (fires when the form first becomes visible)

The OnReady event is associated with the instant that the browser has completed receiving and
processing the form and any associated data. Just like the OpenForm function, it serves to enable the
developer to easily and almost seamlessly, handle the asynchronous nature of the Web.

An example of when this might be useful is if the developer has created a master-detail relation using
a form and subform. It is possible that he or she wishes to activate an event in the subform only
when the master form is ready.

User Interface Interaction Events


These events fire independently in response to user actions.

OnBlur
The OnBlur event occurs when an visual control (control or document) loses focus either by the
pointing device or by tabbing navigation.

Page 232
OnClick
The OnClick event occurs when the mouse button, or any other pointing device button, is
single-clicked over the control or document.

On a PC-based mouse it specifically corresponds to a left-mouse click

OnFocus
The onFocus event occurs when a visual control (control or document) receives focus either by the
pointing device or by tabbing navigation.

OnKeyDown
The OnKeyDown event occurs when a key is pressed down over a visual control (a control or
document)

OnKeyUp
The OnKeyUp event occurs when a key is released over a visual control (a control or document)

OnMouseDown
The OnMouseDown event occurs when the mouse button, or any other pointing device button, is
pressed while it is over a visual control (a control or document). On a PC-based mouse, it specifically
relates to the left-hand mouse button being depressed.

OnMouseMove
The OnMouseMove event occurs when the mouse, or any other pointing device button, is moved while
it is over a visual control (a control or document).

OnMouseOut
The OnMouseOut event occurs when the mouse pointer, or any other pointing device button, is moved
out (off) of the region defined by a visual control (a control or document).

OnMouseOver
The OnMouseOver event occurs when the mouse pointer or any other pointing device is over (within
the region defined by it) a visual control (a control or document).

OnMouseUp
The OnMouseUp event occurs when the mouse button, or any other pointing device button, is
released over the control or document. On a PC-based mouse, it specifically relates to when the
left-hand mouse button being released.

OnResize
This event is associated with every time the browser window is resized.

OnScroll
This event is associated with every time the browser scroll bars are being used

Browser Management Events

OnReadHistory
The OnReadHistory event allows you to directly interfere with in processing a URI to restore the form ’
s state. If you have taken some information out of the form ’ s written history, in the OnWriteHistory
event, you can restore it in the OnReadHistory event.

OnWriteHistory

Page 233
This event gives the developer an opportunity to the URI for the Form. It can be used to filter out
sensitive information, for example.

Form Band Events


As we have seen, earlier in this chapter, Forms have Bands. Bands are container objects that are
present in every Form. As full blown objects, themselves, the Bands have their own events which can
be used along with the Form ’ s events in order to best handle user interaction with your application.

Browser Side Events

OnAfterGrowOrShrink
This event is triggered right after a Band object is resized. This event can be used to reposition
controls on a band, if necessary.

OnBeforeGrowOrShrink
This event is triggered immediately before a Band object is resized. This event can be used to
reposition controls on a band, if necessary.

Server Side Events

OnAfterPrint
The OnAfterPrint event is called right after a band gets "printed" out to the data stream for the client.
It can be used for setting control variables.

OnBeforePrint
This event is triggered immediately before a band is "printed" out to the data stream for the client.
You can use this event to change the appearance of objects in the Band for each detail item in a
continuous Form.

OnPrintStyle
The OnPrintStyle event gives the developer an opportunity to override or extend the automatic HTML
styles generated for the controls on the form.

Data Bound Forms


In this chapter we have looked at how to create Forms, using controls and other Forms in order to
setup the user interface of an application. Since we did this with a simple, website-like application we
had no need for databases, but in the real world most modern applications need to rely, heavily, on
databases. The Morfik has taken this need into account right from the start. Database support is not
only available, but has been built into the very fabric of the Morfik Framework instead of being added
on later as an afterthought.

Now we are going to go back to the Contacts example we started with back in Chapter 2. We are
going to elaborate on that example by adding a pair of Forms, one for browsing the contacts and one
for editing and inserting a contact. Both of these Forms will be used inside a SubForm control on the
project ’ s Index Form.

You can see what the Index Form will look like, in design mode, in the screenshot in Figure 8. Notice
that the Index Form has only three controls in its Detail Band: two Buttons and a SubForm. In both
the header and footer bands a single TextLabel control is used for displaying a title and a copyright
message.

At runtime this application will present the interface shown in Figure 9 at startup. Notice that what
you see in Figure 9 is exactly what is shown in Figure 8, now with the ContactsList Form being
exhibited in the SubForm control of Index Form.

On this Form you can see information that is being brought in from the tblContacts table we designed
in Chapter 3. Looking at Figure 9 you will see that there is a series of small buttons right under the
"gray" area where the data is shown. That is a NavigationBar control and it can help you to navigate
elegantly through a dataset.

Page 234
This brings us back to the topic at hand: Data Bound Forms. Unlike other tools that have data bound
controls, the WebOS AppsBuilder has data bound Forms. What this means is that the entire Form is
"data-aware" and offers a series of features to help you in building your database centric
applications. The NavigationBar control, for example, is not a standalone control, but a property of
either the Header or Footer bands of a Form.

What Makes a Form Data Bound?


What is the difference between a Data Bound Form and any other Form? Well, just the value of the
dataset property. Every Form has a dataset property and it is whether or not this property is set that
defines if a specific Form is data bound or not.

So, a Form with the dataset property set to the name of one of the project ’ s tables or queries
becomes a data bound Form. It is as simple as that.

Figure 8 – The contact project ’ s Index Form.

So in our contacts example, the Index Form we see in Figure 8 is not a data bound Form. It is the
ContactsList Form which appears inside the ContactsArea SubForm control that is a data bound Form.

Two Kinds of Data Bound Forms


There are two different kinds of data bound Forms: Continuous and Single .

Continuous Forms
The ContactsList Form, shown in Figure 9, is a continuous data bound Form. This means that it will
continuously display data rows until it reaches a limit defined by the developer, then it will paginate.
This limit is set by the developer through the PageSize property, which defaults to a value of 10.

Page 235
Figure 9 – The Contacts application at run time. The Index Form is showing with
the ContactsList Form in display in the ContactsArea SubForm.

When you design a continuous form, you only design how one record is going to be displayed, within
the details band, and that gets replicated for each record that is actually shown. The developer
controls how many records will actually get shown through the use of the PageSize property.

At runtime, you might wish to perform an action on one specific control or set of controls, like
changing their visibility or color. Since you only design one set of controls, but will have many
occurrences of them, in practice, you need to select which of the sets you are referring to. This can be
done through the use of the BandIndex property of the control you wish access, as shown in the
following example:

P rocedure form1 . T extLabel1Click ( Event : T DOMEvent );


Begin
T extLabel5 . BandIndex := GetEventSource ( Event ). BandIn
dex ;
OpenForm ( 'Form2' , 'Form1:SubForm1' ,
'"P aramId=' + T extLabel5 . Caption + '"' );
End ;

In this example, we presume that we want to take action based on the click of a control. The control
which was clicked is obtained by the call to GetEvenSource(Event) function call and its BandIndex
property is used to set the BandIndex property of the control which we want to manipulate. In this
case the TextLabel5 control whose caption is used a parameter for opening a new form.

In case you wish to manipulate more than one control of a specific band you can set the BandIndex of
all the controls in one call to the SwitchBandIndex function. This function takes a TDOMEvent object as
its parameter and can be easily used by just passing to it the Event object that any event handler
method receives as a parameter.

Single Forms
The second kind of Form is the Single Form and as its name might have given away, it handles data
from a single table row. The EditContact Form in the Contacts example, which is displayed at design
time in Figure 10, is a Single type, data bound Form.

You saw this Form being created through the "Create Form Wizard" in Chapter 3. It is essentially the
same Form, but since it handles only a single row of data at a time, I have substituted the

Page 236
NavigationBar in the Footer band with a set of button controls which are a bit more appropriate to our
needs in this case. The screenshot in Figure 10 shows part of the Detail band as well as the Footer
band of the EditContact Form with this set of buttons.

In Listing 3 you will find the Browser side code for the EditContact Form. This code shows how to
enable and disable controls the current Form and on another Form.

5 Working With Forms 26 m2.PNG Figure 10 – The EditContact Form at design time in the WebOS
AppsBuilder.

Listing 3 – Browser side code (in Morfik Basic) for EditContact Form.

Imports Index
Namespace EditContact

P ublic Class EditContact


Inherits Form
Published Label_FirstName As T extLabel
Published Control_FirstName As T extEdit
Published Label_LastName As T extLabel
Published Control_LastName As T extEdit
Published Label_WorkEmail As T extLabel
Published Control_WorkEmail As T extEdit
Published Label_MobileP hone As T extLabel
Published Control_MobileP hone As T extEdit
Published Label_HomePhone As T extLabel
Published Control_HomeP hone As T extEdit
Published Label_WorkPhone As T extLabel
Published Control_WorkP hone As T extEdit
Published Label_WorkStreetAddress As T extLabel
Published Control_WorkStreetAddress As T extEdit
Published Label_HomeStreetAddress As T extLabel
Published Control_HomeStreetAddress As T extEdit
Published Label_HomeEmail As T extLabel
Published Control_HomeEmail As T extEdit
Published Label_Company As T extLabel
Published Control_Company As T extEdit
Published Label_ContactID As T extLabel
Published Control_ContactID As T extLabel
Published Label_DateofBirth As T extLabel
Published Control_DateofBirth As DateT imeEdit
Published btnCancel As Button
Published btnOk As Button
Published btnDelete As Button
Published btnPrint As Button

Sub SetEnabled ( Enabled As Boolean )


btnOk . Enabled = Enabled
btnCancel . Enabled = Enabled
End Sub

Sub ReturnT oList


' Return to "ContactsList" Form
Index2 ( xApp . Forms ( "Index" )). btnNew . Enabled = T rue
Index2 ( xApp . Forms ( "Index" )). btnPrint . Enabled = T rue
OpenForm ( "ContactList" , "Index:ContactsArea" , "" )
End Sub

Published Message Sub btnCancelClick ( Event As T DOMEvent )


SetEnabled ( False )

Page 237
gRefreshContactList = False
If gNewContact T hen
DeleteRecord ( Nothing )
gNewContact = false
SetEnabled ( T rue )
Else
SetEnabled ( T rue )
End If
ReturnT oList 'Return to the List view
End Sub

Published Message Sub btnOkClick ( Event As T DOMEvent )


SetEnabled ( False )
If ( Control_FirstName . T ext = "" ) or ( Control_LastName . T ext =
"" ) T hen
ShowMessage ( "Empty record." )
SetEnabled ( T rue )
Else
gRefreshContactList = False
SubmitPage ( Event )
End If
End Sub

Published Message Sub btnDeleteClick ( Event As T DOMEvent )


gRefreshContactList = False
If ConfirmAction ( "Are you sure you want to delete this record?" ) T hen
SetEnabled ( False )
DeleteRecord ( Event )
SubmitPage ( Event )
End If
End Sub

Published Message Sub btnP rintClick ( Event As T DOMEvent )


OpenReport ( "RptSingleContact" , """ContactIDP aram="
& gContactID &_
"""" )
End Sub

Published Message Sub WebFormShow ( ByRef Show As Boolean )


Index ( xApp . Forms ( "Index" )). btnNew . Enabled = False
Index ( xApp . Forms ( "Index" )). btnPrint . Enabled = False
If Show T hen
If gNewContact T hen
gContactID = ""
btnDelete . Enabled = False
NewRecord ( Nothing )
Else
btnDelete . Enabled = T rue
End If
End If
End Sub

Published Message Sub WebFormCreate ( Sender As T Object )


' Selecting single contact
If gContactID <> "" T hen
SQLFilter = """ContactID"" = " & gContactID
End If
End Sub

Published Message Sub WebFormAfterSubmit ( Failed As Boolean )

Page 238
' Getting current ContactID
SetEnabled ( T rue )
If not Failed then
gNewContact = False
gRefreshContactList = T rue
ReturnT oList
End If
End Sub

End Class

End Namespace

We will look into the OpenReport function you see in this example, in more detail in the next Chapter,
Working with Reports.

Positioning the Controls on a Form


The WebOS AppsBuilder IDE ’ s Form Designer makes designing interfaces quite easy. The designer
includes automatic alignment features which make aligning controls to one another and equally
spacing them a trivial matter.
Whenever you drag a control around the Form designer, thin blue lines will appear indicating that you
are in position for alignment with another control in form. Many lines can actually be shown at the
same time as the Form Designer tries to ensure that your controls are all properly aligned.

Figure 11 – Automatic control alignment in the Form Designer.

This behavior can be deactivated as you will see in the next topic.

Configuring the Form Designer


The Morfik WebOS AppsBuilder offers you a large set of configuration options. These include several
options to customize the behavior of the Forms and Report Designer. You can see the General tab of
the Options dialog in Figure 12. The options in the column on the left are related to the Forms and
Reports designers.

Page 239
Figure 12 – The General tab on the Environment Options dialog of the WebOS AppsBuilder.

I have found that the automatic alignment of controls is a great enhancer of developer productivity as
it allows to you to get great looking forms easily. If, for some reason, this feature is interfering with
how you want to position your controls you can disable it by switching from Snap to Smart Grid to
Snap to Visible Grid .

When using Snap to Visible Grid you might want to fiddle around with values to find the setting you
prefer for the X and Y grid step options. These options control how controls move and align on the
Form.

Wrapping it up
The Morfik WebOS AppsBuilder IDE offers a lot of great features for the creation of Forms and through
them the interface for your application. As we have seen in this chapter, you can create Forms that
work automatically with datasets and Forms that care nothing for datasets.

It is important to keep in mind that we have just glanced at the possibilities for your applications, so
far. We will see more examples and how to do more interesting stuff in the chapters to come.

See also
Making the Most of Forms
Working with Reports

category:Programming

Page 240
Adding Controls to a
Form

It is at Form design level that you add controls to your website or application s interface. Once
you are in the Form designer, the Home tab of the Ribbon displays a section called Controls which
gives you quick access to all available controls. You can see this section of the Ribbon highlighted
in the picture shown in Figure 1.

Figure 1 Controls section of the Home tab of the Ribbon, when in the Form designer.

In addition, when you enter the Form designer, a new tab, called Insert, becomes visible in the
Ribbon. This tab offers access to the same controls though a totally dedicated toolbar. This tab is
shown in Figure 2.

Figure 2 - Contents of Insert tab of the Ribbon, when in the Form designer.

When you choose a control from the Ribbon, you should click and stretch with the mouse in the
location of the Form where you want the control to appear. Once the control is placed on the
Forms drawing surface you can move it around, resize it, or change any of its properties through
the Home tab of the Ribbon or the Property Inspector panel.

Figure 3 shows a Form with a pair of controls (a TextLabel and a Button) created in its Details
band.

Figure 3 A Form with two controls: a TextLabel and a Button, added to it.

For more information regarding the usage and configuration of the Morfik controls, please read
the topics that are specific about how to work with controls.

See Also
 Working with Forms
 Working with Controls

Page 241
Applying Formatting
to Form Bands

In the Form designer, you can choose to apply formatting effects to the different bands of the
Form. This is especially useful when combined with TextLabel controls, which can have a
transparent background.

You can choose an effect from the Effects section of the Home tab of the Ribbon, when in the
Form designer, as shown in Figure 1.

Figure 1 – The Home tab of the Ribbon when in the Form designer, having one of the Form’s
bands selected.

Figure 2 shows a Form with a gradient effect applied to its Header band.

Figure 2 – A Form with a gradient effect applied to its Header band.

Different effects can be applied to all bands in a Form. This feature can be used in combination
with the effects which are applied to the Container hosting the Form, when Forms are made not
to be transparent.
When applied to a Band the gradient effect is based on the color that you selected for the band
and can go to darker or lighter tones. In figure 3 you can see the same Form that appears in
Figure 2, but with the background color of the Header band changed.

Page 242
Figure 3 – Same Form as shown in Figure 2 with the color of the Header band changed.

It is recommended that whenever possible you apply the formatting to the Container hosting the
Form, except when a combination of effects at both levels is desired.

Morfik Effects
In addition to the Gradient effect, you can also apply to Forms the Shadow and Corners Effect.
These effects can be used to effectively change the user's perception of your web site or
application by giving it a distinctive look.

See Also
 Working with Forms
 Control Effects

Page 243
Creating a Form

You can create a new Form in the current project by either selecting the Form
option from the Add button in the Home tab of the Ribbon or New Form from the
New Item option of the Power Button menu.

Figure 1 shows the drop down menu of the Add button in the Home tab of the
Ribbon and Figure 2 shows the New Item submenu that is available from the
Power Button menu.

Figure 1 - The drop down menu of the Add Button in the Home tab of the Ribbon.

Figure 2 - The menu of the New Item option in the Power Button menu.

Page 244
Note
In Morfik Browser Application projects, as no server side documents or
objects can be created, a number of options such as Report, Query and
Web Method, will not be available in these menus.

See Also
Working with Forms

Page 245
Debugging

The entire debugging infrastructure of Morfik AppsBuilder has been revised for
version 2.0. As of release 1.3.1.18, many of these changes were back ported into
the 1.x version branch. In this revision the debugging of browser and server side
code has been further integrated and it became possible to debug both sides of
the application, at the same time. To accomplish better integration with the Morfik
workspace a technology change was in order. This means that instead of relying
on Microsoft Script Debugger, Morfik has opted to use Mozilla technology.

New Browser Side Debugger


Browser Side Debugging
Stepping Through High-Level Language Source
Code
Stepping Through JavaScript Code
Following Application State
Server Side Debugging
Intermediate Source Code
Backend Compilers
Stepping Through High-Level Language Source
Code
Monitoring Communications for XApp Debugging
Wrapping it up
Related Video

New Browser Side Debugger


Part of the revamped debugging infrastructure is a new browser side debugger which is based on
Mozilla technology and a built-in Debug Browser Window which also uses Mozilla technology to run
your applications faster. This window is basically a built-in Firefox browser which is always loaded into
the workspace thus making debugging snappier and providing more information about the running
application. Note that debugging the browser side of a Morfik Web Application is essentially the same
as debugging a Morfik Browser Application.

Figure 1 shows the new new Debug Browser Window with a loaded application.

Page 246
Figure 1 – The Debug Browser Window.

The Debug Browser Window is open by default when the command to run an XApp from within the
workspace is selected. From this window all the main browsers can be called up (if present in the
computer) so that the user can test the application in whatever browser he/she needs to. Figure 2
shows in detail the toolbar buttons for choosing a browser to execute.

Figure 2 – Browser icons on the top toolbar of the Debug Browser Window.

The supported browsers are Internet Explorer, Firefox, Safari and Opera and a Morfik XApp should
look and work the same in all of them. In Figure 3 the same application which appears in Figure 1,
within the Debug Browser Window, is shown running in Apple ’ s Safari browser.

Page 247
Figure 3 – Booktrader XApp running in Apple ’ s Safari browser.

From this point on, we will have a more detailed look at the capabilities available when debugging
each side of a Morfik XApp.

Browser Side Debugging


With the new browser side debugger it is no longer necessary to download and install the Microsoft
Script Debugger. The is much more stable, not being subject to the compatibility problems that to
which the Microsoft solution is all too vulnerable.

Stepping Through High-Level Language Source Code


While debugging your XApp you can step through your high level language code to better understand
how your application is working. Though Morfik tools attempts to make a direct correlation of the
JavaScript source code line to a line in your high level source code, this is not always possible. This is
mostly due to the fact that a single high level language line of code might generate several lines of
Javascript code. In Figure 4 you can see a screenshot of the AppsBuilder workspace with a pair of
breakpoints set in the browser side high level source code. In this case the language used was
Morfik Basic.

Page 248
Figure 4 – Breakpoints set in the browser side high-level source code.

Notice the Breakpoints list at the bottom of the main window of the AppsBuilder worskpace, in Figure
4. You can set breakpoints by clicking on the grey gutter on the left side of the editor window. When
a breakpoint is set, a small red indicator is displayed in the gutter and the corresponding line of code
is highlighted in red.

Once you start to trace through your source code you will see an additional blue line which indicates
where the current execution point is. This line can also be identified by a small green arrow which
appears in the gutter of the code editor. In Figure 5 you can see the workspace with breakpoints set
and the execution point highlighting another line of code.

When the current execution point is over a line where a breakpoint has been set, the breakpoint ’ s
red line will be visible instead of the blue line of the current execution point. You will still be able to
know where the execution point is through the small arrow in the gutter section.

Page 249
Figure 5 – AppsBuilder workspace tracing through browser side high level source code.

Stepping Through JavaScript Code


While debugging your XApp it is possible to step through the JavaScript source code which is
automatically generated by the Morfik compiler, as can be seen in Figure 6.

Page 250
Figure 6 - AppsBuilder workspace tracing through JavaScript source code.

In order to have access to the generated JavaScript source code you have to enable intermediate
code debugging in the Debugger Options dialog, as shown in Figure 7.

Page 251
Figure 7 – Debugger Section of the Morfik Options dialog in the Morfik workspace.

Following Application State


You can follow your application state while tracing through your code, either in a high level language
or JavaScript through the "Watches" view. This view is available through one of the tabs which can
be seen at the bottom of the IDE ’ s main window as shown in Figure 8.

Figure 8 – The tabs of the panels at the bottom of the main window, with focus on the Watches
tab.

When you click on the Watches tab a panel scrolls upward giving you access to the Watches view, as
well as all the other tabs which were visible at the bottom of the window. This panel will
automatically hide itself as soon as your mouse moves off of it, unless you "pin" it in place. You can
do this by clicking on the small "pin" icon on the right hand side of the panel.

Page 252
Figure 9 – The Watches view on the lower part of the IDE ’ s main window.

You can see both the Watches tab and the Pin icon indicated by arrows in Figure 9.

Page 253
Figure 10 – Console in the Debug Browser Window.

As an additional aid to debugging your application the new Debug Browser Windows in Morfik
AppsBuilder has a console where errors, warnings and messages are displayed as your application is
executed. These are the same messages which will be displayed if the application is executed in
Firefox.

Note
Some error messages are displayed in the console, as shown in Figure 10. Some of these
messages are generated by code which is automatically created by the Morfik Framework
or the Morfik compiler.
These messages are being addressed, very carefully, to ensure that no change breaks
cross-browser compatibility and have no negative impact on application functionality.

Server Side Debugging


The Morfik AppsBuilder has its own, built-in, machine level debugger so that you can follow your
server side code. Debugging the server side code is very different from debugging the browser side
code since on the server side the final product of a compiled Morfik application is a binary executable
file.

Nothing could be further from source form script code of the browser side than the binary machine
language executable of the server side, even so the similarities far outweigh the differences. Once
you are familiarized with both processes you will be able to appreciate this.

Note

Page 254
Server side debugging is a feature of Morfik Web Application projects which support both
server and browser side code. Morfik Browser Application projects focus exclusively on
browser side code and therefore offer only browser-side debugging.

Intermediate Source Code


The similarities between the debugging processes for the browser and server sides of the application
start at the Intermediate Source debugging. You see, Morfik AppsBuilder generates Object Pascal
code from all the server side modules in your project, regardless of which language the module was
written in. This source code is then compiled into binary form in another compiling process which
takes the Object Pascal as input and gives out the binary application.

If you have enabled Intermediate Source debugging by selecting the respective options at the
bottom of the Debugger tab of the Debugger Options dialog, as shown in Figure 7, you will be able to
access and step through your Object Pascal intermediate source code. This works in the same
manner as stepping through your JavaScript code on the browser side of the application.

Figure 11 – Intermediate Object Pascal code generated for the Debugging test project which was
written in Morfik Basic.

Though accessing the intermediate source code for the server side application is possible it is
generally not necessary to do so. Debugging in the language you originally wrote your modules,
should be more than adequate.

Backend Compilers

Page 255
Morfik AppsBuilder can use several different compilers as its server-side backend compiler. When you
are going to debug the server side of your application, you should choose the target platform as
being "Windows, Intel x86". If you choose "Windows, Intel x86 (Delphi)" which uses CodeGear ’ s
Delphi compiler as the backend compiler (for compiling the intermediate Object Pascal code into
machine code), you will not be able to debug your application.

The AppsBuilder ’ s built-in debugger is compatible with the default server side backend compiler,
FreePascal, which uses a different format of debug information than Delphi. Also important to have in
mind is that different from the FreePascal compiler, which comes bundled with Morfik AppsBuilder, you
need to acquire a license for Delphi from CodeGear in order to use it.

Stepping Through High-Level Language Source Code


While debugging the server side portion of your XApp you can step through your high level language
code to better understand how your application is working. The debugger built into AppsBuilder IDE
allows you to set breakpoints at any point of your server side code, just as done in browser side
debugging.

Figure 12 – Stepping through, server side, Morfik Basic code.

In Figure 12 you can see a breakpoint set in one line and the execution point, already past it, in the
following line. Observe not only that the lines are highlighted but that the same icons are visible in
the gutter area of the code editor. Visually, there is not much difference between debugging code for
the server and browser portions of an XApp, as you may notice.

Also in Figure 12 you can see the watches view in the lower part of the window. Notice that just as in
the browser side you can follow the state of your application by using the Watches view.

Page 256
Monitoring Communications for XApp Debugging
The AppsBuilder debugger gives you access to a wide variety of information about your application,
including the ability to inspect the data packets and commands that flow between the two parts of
the application and the server side of the XApp and its database.

In Figure 13 you can see the XML view, indicated by an arrow, which will allow you to inspect the XML
packages traded by Server and Browser sides of the XApp.

Figure 13 – XML view during debugging of the server side of an XApp.

In Figure 14 you can see the HTTP view which allows you to see all the requests received by the web
server.

Page 257
Figure 14 – The HTTP view in the Morfik workspace.

Another monitor which is not active by default, but can be activated, is the SQL monitor. In Figure 15
you can see this view in the Morfik workspace main window.

Page 258
Figure 15 – SQL Monitor in the AppsBuilder workspace.

In order to activate SQL monitoring, which will allow you access to information such as displayed in
Figure 15, you need to enable SQL Monitoring in the Monitoring tab of the Debugger Options dialog,
as you can see in Figure 16.

Page 259
Figure 16 – Monitor Section of the Morfik options dialog.

In order to get the SQL events that can be seen in Figure 15, AppsBuilder should be configured as
shown in Figure 16. This view, along with the XML view, will allow you to have a better understanding
of what goes on under the hood of your XApp. When debugging your applications you can use these
options to catch only the events of interest.

Wrapping it up
Morfik AppsBuilder offers a multitude of debugging options and features which can help you
understand what is going on when your application is not behaving as you had expected.

Both server and browser side debugging at the high-level language source code level are available
and you can dive into the intermediate code as well, if you are familiar with it and so wish.

Morfik AppsBuilder (1.3.1.18 and up) has introduced an enhanced browser debugger, a built in Debug
Browser Window and added support for debugging both sides of the application at the same time.

category:Programming

Related Video
 Use Debugging Monitors
 Intermediate Source Code

Page 260
Working with Controls

Controls are the most basic building blocks of the interface of your website or
application. Controls are placed directly onto the design surface of Forms or
Reports, inside one of the document's bands.

Morfik AppsBuilder offers a set of controls which are Theme-aware and that will
change their appearance when you change the project's Theme guaranteeing that
your project has a consistent look, always.
 Most Frequently Used Controls
 Applying Formatting to Controls

 Control Effects
For information on more controls, please refer to Morfik Controls .

Page 261
Applying Formatting
to Controls

You can apply special formatting to controls to create nice visual effects, just as you do with
Forms or Pages. Some effects are specially interesting when combined with specific controls as is
the case, for example, of combining the Gradient effect with the Button control.

The formatting options which are common to all Morfik controls are available through the Home
tab of the Ribbon as shown in figure 1.

Figure 1 - The Home tab of the Ribbon with the control formatting options highlighted.

Using the options available in the Ribbon you can, for example, change font size, color and
attributes of a Button as well as apply effects to it. The following is an example of how you can
transform the appearance of a control. Lets start with a Button created with the default theme
which can be seen in Figure 2.

Figure 2 - Button created with the default theme.

Once the button is created we change its color to a dark gray tone as seen in Figure 3.

Figure 3 - Choosing a new color for the button.

We can then set its border to be a different color and width as shown in Figure 4.

Page 262
Figure 4 - Choosing a different color and a thinner border for the button.

The next step is to choose a gradient effect to apply to the button, as shown in Figure 5. In this
case we will choose a gradient to a darker tone of the color we have select for the button so as
to give the impression that the button is reflecting a light source from above.

Figure 5 - Selecting a dark gradient for the button.

As a last step we can choose a new Font color which will better highlight the text against the
much darker background colors of the formatted button, as shown in Figure 6.

Page 263
Figure 6 - Changing the color of the Font that is used in the Button.

The final result of applying all these formatting options to the button can be seen in Figure 7. You
can see that it is totally different from the button that was created when the Button control was
selected for placement on the Form.

Figure 7 - Final appearance of the button control after applying several formatting options.

See Also
Working with Controls

Page 264
Deploying an XAp

Note: for information on deploying Browser XApps, see Deploying a Browser


XApp .

Available Options
Click on the option that applies to you:

Platform Stand-alone XApp Morfik Plug-in XApp Plug-in XApp (ISAPI)


Windows Morfik Apache 1.3 Morfik Apache 1.3  Apache 1.3 
 Apache 2.2 
Linux Morfik Apache 1.3 < Available, not tested> < None>

Page 265
Page 266
Page 267
Page 268
Page 269
Page 270
Page 271
Page 272
Page 273
Page 274
Page 275
Page 276
Centos:

Centos
 4.3 .
Centos
 4.4 .

Cento
s 4.5
 .
Centos
 4.6 .

Cento
s 5.0
 .
Centos
 5.1 .
Debia
n:

Debia
n
Wood
y 3.0
 .
Debian
Sarge
 3.1 .

Debia
 n

Page 277
Sarge
on a
Strat
o
Serve
r 3.1
.
Debian
Etch 4.0
 .

Fedora:
Fedora Core
 3.
Fedora
 Core 4 .
Fedora
 Core 5 .
Fedora
 Core 6 .

Fedor
 a 7.

Fedor
 a 8.

Fedor
 a 9.
Mandrake/M
andriva:
Mandrake
 10.2 .

Mandriva
2006
 Free .
Mandriva
 2007 Free .

Mandriva
2007
Spring
 Free .
Mandriva
 2008 Free .

Mandriva
2008
Spring
 Free .
Open/SuSE:
SuSE 9.2
 .

SuSE
 9.3 .
SuSE
 10.0 .
SuSE
 10.1 .

OpenSu
SE 10.2
 .
OpenSuSE
 10.3 .

Page 278
Ubuntu
:
Ubuntu
 5.04 .
Ubuntu
 5.10 .

Ubuntu
 6.06 .
Ubuntu
 6.10 .

Ubuntu
 7.04 .
Ubuntu
 7.10 .

Ubuntu
 8.04 .

Installing Firebird:
1 Download and install firebird 2.0 database for your Linux platform .
Make Sure that firebird 2.0 has been installed as some linux distro's like Ubuntu download
firebird 1.5 instead (when you do apt-get install firebird). This site shows you how to
2 download firebird 2.0 for Ubuntu. Install Firebird for Ubuntu .
On Ubuntu this directory is located in the "/usr/lib/firebird/2.*/UDF/". On Ubuntu 8.04, Firebird is
 installed in /opt/firebird.
If you wish to create a new user use the "sudo useradd -G {firebird} username" command
 (without quotation marks, and replace username with the user name you wish to specify).
If you wish to add a existing user to a group use the "sudo usermod -a -G firebird username"
command (without quotation marks, and replace username with the user name you wish to
 specify).
 libc.so

 libcrypt.so
 libdl.so

 libpthread.so
 librt.so

 libuuid.so
Installing/Running XApps
Copy to Linux target the following files (mind capitalization): Binary executable file of an XApp -
1 XXX
Project file for an XApp, which describes source files, tables, queries, etc that are part of a
 project - XXX.Mxp
Resources file for an XApp, which contains images, text files, etc that are added into a project -
 XXX.Mxr
 A Firebird database file; the primary database for an XApp - XXX.Mxd
Web Service Description Language file describing how other applications can access the services
 exposed by an XApp - XXX.wsdl
 For example, for the Northwind project


The required files would be: "Northwind", "Northwind.Mxp", "Northwind.Mxr" and
 "Northwind.Mxd".


Firebird should have read and write access to database file (chmod 666 “databasefile" to get
 right file permission rw-rw-rw-) and execution rights to binary file.
Notes and Reminders: If you experience problems and are unable to resolve it yourself,
please send us a detailed error-report and if possible include the results of a strace log

Page 279
(zipped, please).

To get the strace, run the application as follows: strace -f -o myfile.log -s 255 myapplication
(eg. strace -f -o northwind.log -s 255 ./Northwind)

This should provide you with a myfile.log file which should help us diagnose the problem (you
may want to peek inside; maybe you'll find the reason for the faulty behavior yourself?)

Files Needed
 mfkudf.dll

 libhttpd.so

See Also
 Deploying a Browser XApp
Category:Deployment

Page 280
Deploying a Browser
XApp

Deploying a Morfik Browser XApp is a very straight forward process. Morfik


Browser XApps are entirely compiled into browser side code, making no
assumptions on which platform they will be served from.

In fact the process of deploying the application can be reduced to the simple
uploading of the files in the _ProjectNamePub ("Pub") folder and its sub-folders to
a publicly accessible on the Web. This can be done with any simple FTP client
software and the appropriate login information for the hosting server.

For example:
On deploying to an Apache web server you
can upload the XApp's files and sub-folders
to the httpd folder on the server or one of
 its sub-folders.
On deploying to a Microsoft Internet Information server you can upload the the
XApp's files and sub-folders to the wwwroot folder on the server or one of its
 sub-folders.
Before deploying the files of your Morfik Browser XApp to the hosting server, be
sure to compile the project as the files you see in the "Pub" folder may be from an
earlier compilation and might not reflect your latest changes.

See Also
 Deploying a Web XApp
 Browser Application

 Web Application

Page 281
Browser Application

A Morfik Browser Application is created from a Browser Project. Browser


applications are compiled to run totally inside the Web browser and in their final
form are entirely composed of industry standard HTML, XML, CSS, JavaScript and
image files.

See Also
 Web Application

Page 282
Web Application

A Morfik Web Application is created from a Web Project and is composed of two
parts: Browser and Server. The Browser portion of a Web application is almost
identical to a Morfik Browser Application but does assume that there is a server
side which can provide it with some built-in server side functionality.

The Server side portion of a Web application is a binary module which is compiled
specifically for the selected target platform.

See Also
 Browser Application

Page 283
Working with
Themes

Morfik AppsBuilder has built-in support for Themes. A theme is a set of colors, fonts and visual
effects that are used by all controls in a project. By using theme compliant/relative colors, for
example, you can quickly change the appearance of your application or Website.

Changing the theme used by a project will automatically result in the Morfik compiler
generating new images in support of the Effects applied to Forms and controls. This happens
automatically without any user intervention.

Figures 1 and 2 show two pictures of the same form, using different themes. Themes can be
moved to different computers and new themes can be imported into your Morfik workspace.

Figure 1 - A sample Form.

Figure 2 - Same Form as shown in Figure 1, using a different theme.

More detailed information on how to use Themes is available in the following topics:
 Selecting a Theme
 Creating a New Theme

 Modifying an Existing Theme

Related Video
 Using Themes in Morfik 2.0

Page 284
Creating a New
Theme

You can create your own themes with Morfik AppsBuilder. A Theme editor is built-in to the Morfik
workspace. You can access the Theme editor, to create a new Theme, by clicking on the New
Theme button on the Design tab of the Ribbon, which is shown in Figure 1.

Figure 1 - Contents of Design tab of the Ribbon, with the New Theme button highlighted.

When you click on the New Theme button, a small dialog is shown, asking for the name of the
Theme which is to be created. Enter a name for your theme and you will be taken to the Theme
editor to fill in the required information. There are two ways to work with color selection for a
Theme: using the color wheel, shown in figure 2, or manually.

Figure 2 Theme Editor showing the color wheel.

The color wheel generates a set of colors automatically for you and you can customize how many
base colors it uses in the process by selecting an option from the Scheme drop down listbox.
From this list you can choose the following options: Monochromatic, Contrast, Triad, Tetrad,
Analogic or Manual. The first five options use mathematical calculations based on color theory to
provide you with a matching set of colors. Once you have used the color wheel to choose a base
set of colors you can switch to manual mode and make any adjustments you like.

Page 285
Figure 3 Manual color configuration in the Theme Editor.

You can also choose to duplicate one of the existing themes and then modify it to suit your
needs. For more information, see Modifying an Existing Theme . Themes have not only colors but
also fonts, which can be configured by switching to the Fonts tab of the Theme editor.

Figure 4 Font configuration in the Theme Editor.

See Also
Working with Themes

Page 286
Modifying an
Existing Theme

You can easily modify any of the Themes in your Morfik environment. We recommend that if you
plan to modify one of the base Themes shipped with Morfik AppsBuilder that you first use the
Duplicate Theme button to create a copy of that original theme.

Figure 1 - Contents of Design tab of the Ribbon, with the Duplicate button highlighted.

In order to modify the Theme of your choice, first select it from the gallery in the Design tab of the
Ribbon and then click on the Edit Theme button in the same tab. Figure 2 shows the Edit button
highlighted.

Figure 2 - Contents of Design tab of the Ribbon, with the Edit Theme button highlighted.

When you choose to modify an existing theme, the Theme editor will appear directly in Manual
mode so that it is easier for you to modify the specific item you want.

Figure 3 Manual color configuration in the Theme Editor.

See Also
Working with Themes

Page 287
Selecting a Theme

In order to change the Theme being used by your project you should change to the Design tab of
the Ribbon. The Design tab is totally devoted to working with Themes, allowing you to easily
choose from a variety of Themes that are visible in the Themes gallery.

Figure 1 shows the themes gallery in the Design tab of the Ribbon.

Figure 1 - Contents of Design tab of the Ribbon, with the Theme Gallery highlighted.

Changing the Theme will result in the Morfik workspace reflecting the new appearance
immediately, in all documents that are part of your project. In the pictures shown in Figures 2 and
3 you can see the effect of changing the theme in a sample form.

Figure 2 - A sample Form.

Figure 3 - Same Form shown in Figure 2 using a different theme.

When your project is compiled, after a Theme change, all the images which are required to
achieve the effects which were applied to different elements of the project will be recreated
automatically.

See Also
Working with Themes

Page 288
Page 289
Tips and tutorials

Welcome to the page for Morfik Tips and Tutorials.

Most Recent All Tips


Connecting to an external database on
 localhost Activ
Sorting and Filtering Records in Continuous ating
 Forms Morfi
Working with external Firebird  k
 databases
Deploying
Parsin  an XApp .
g Pretty up the 'Loading...'
strings  message
 Dynamically specifying database
 connection details
Creating
 cookies Sending emails with
Creating an  attachments
 image map Adding Google AdSense Ads to a
 Morfik Application .
Duplicating a line of a
 A Blog
Table
Displaying a confirm message on browser Applicati
  on .
close
Fetching data programmatically
Debugging SQL  from Tables
 Statements
Using dates Calling Morfik functions from
  JavaScript
in Queries
Calling JavaScript from
Modifying the transparent property of  Morfik
 images
Implementing Handling MouseOver and
  MouseOut efficiently
drag-and-drop
Editing
Calling a method from another a
 Form RecordSe
 t
Browse by Tag
AutoSu
 Database bmit a
 Deployment  Form
Changing the appearance of
 IDE  controls
 Presentation
Keyboa
 rd
Programming
shortcu
 ts
Exporting a Table to a
 CSV file
Updating MySQL Tables based
 on nested Queries
Using NOW
 in a Query
Validating an
 input field
Editing and
 Searching Data
Parsing
 browser-side XML
Returning the value of any class
 member field as a string
Implementing transaction
 support

Page 290
Detecting if a
 Form is dirty
Creating Virtual
 Parameters
Inserting images into Image
 fields
Iterating through Bands in a
 Continuous Form
Using Stored Procedures in
 Morfik
Implementing a login to an
 external Firebird database
Implementing
 drag-and-drop
Parsing XML from a WebMethod
 parameter
Resolving conflicts with existing
 software
Adding items to a ListBox via
 the DOM
Saving a Report to the hard disk
 (programmatically) .
Sorting and Filtering Data at
Runtime using SQLServer Stored
 Procedures
Embedding Flash files such as
 YouTube videos
Retrieving IP
 addresses
Using associative arrays and
 hashmaps
Conditional importing of
 units
Inserting hyperlinks into TextLabel
 captions

Crea
ting
cooki
 es
Calling a WebMethod from the
 server
Creating and Calling Firebird
 Stored Procedures
Specifying column names in the
 Query Builder
Making .png images transparent
 in Internet Explorer
Input
mask
routin
 e
Working with external Firebird
 databases
Using Scriptor - basic
 example
Creating an
 image map
Inserting a new line into a
 TextEdit
Optimizing initial loading times
 of XApps
Formatting dates and times in
 TextLabels
Retrieving the control that
 triggers an event
 Invoking an event OnClose of

Page 291
browser window

Pars
ing
strin
 gs
Displaying a confirm message on
 browser close
Using Zapatec
 Tree Control
Using
custom
 servers
Calling a method from another
 Form
Sorting and Filtering Records in
 Continuous Forms
Browser Not
 Refreshing
Debugging
 Client-side
Debugging SQL
 Statements
Defining composite primary
 keys
Modifying font attributes on the
 server-side
Using Google APIs in
 XApps
Firewall
Compatibilit
 y
Using dates
 in Queries

Formatting
 numbers
Creating timers
 programmatically
Duplicating a line of a
 Table

Searc
hing a
 Table
Retrieving the filename entered
 in the FileUploader
Modifying the transparent
 property of images
Retrieving WebMethod
 exception messages
Changing the hint property at
 run-time
Working With
 XML Data
Working with
 WebActions
Creating
RSS
 Feeds
Managing
 Resources

De
mo
 s

Page 292
Page 293
Connecting to an external database on localhost

Introduction
This quick tip outlines how to connect to my an external database on localhost.

Solution
First you will need to grab the ODBC driver applicable to your database type and version and
1 install it.
Then set up a System DSN (Create an ODBC
2 Datasource) in Windows.
Then you'll be able to
3 connect to it in Morfik.
The Developer's handbook shows how to connect Morfik to an external
4 ODBC DSN.

See also
 Tips
Category:Programming

Category:Database

Page 294
Developer's handbook

As of Morfik AppsBuilder Release 1 (build 1.0.0.7),


the Morfik Developers Handbook is now included as part of the Morfik install
ation.
It is located in the same directory as the .exe file

Who is this book for?

This 230-page book was written for people who are familiar with using Object
Pascal, C#, Basic or Java and who wish to learn how to be productive in creating
applications using the Morfik WebOS AppsBuilder. If you have absolutely no
experience with at least one of these languages it is recommended that you read
a book about the specific language you plan on using, before working your way
through this book.

The goal is to introduce you to the concepts of the WebOS, the AppsBuilder’s
integrated development environment and the differences between the Morfik
dialects of Object Pascal, Basic, C# and Java and their most common
implementations.

Some aspects of database design and programming are also covered in order to
welcome those developers coming over from non-database related work and
those who have learned by doing, without the benefit of formal instruction.

How this book is organized?


Chapter 1 explains the main concepts of
WebOS and of the WebOS AppsBuilder. We
will cover a broad range of topics that will
help you understand how the WebOS
AppsBuilder works and consequently how
 your application, created with it, will work.
Chapter 2 explores the WebOS Applications Builder's integrated development
environment. The IDE offers a vast quantity of resources and features for
application development and though we won't cover every possible detail we aim to
 show you all you will need in order to get started and find out the rest by yourself.
Chapter 3 covers most aspects related to
working with databases within the contest
of a Morfik project. We will cover features
of Morfik's underlying database engine and
of the IDE that are specifically related to
 the development of database applications.
Chapter 4 goes into how code is organized in order to make up your application.
 The concepts of Applications, Modules and Documents are reviewed.
Chapter 5 gives you a quick, but fairly
complete, view of how to create and work
using Forms. Morfik's use of Forms and
their design is at the heart of the
 presentation layout
Chapter 6 closely parallels Chapter 5, doing for Reports the same thing Chapter 5
did for Forms. In this chapter we will look into the ability to create PDF reports with
 the WebOS AppsBuilder.
Chapter 7 gives you a quick overview of
what is the Morfik Framework and how it
 forms the base all we have seem before.
Chapter 8 covers the creation of WebMethods which allow your application to be
 called from other, 3rd party applications, through an industry standard interface.
Chapter 9 offers a general overview on
how to use External Databases in your
applications. In this chapter you will find
the necessary information to take your first
consistent step into using a database
 other than Firebird.

Page 295
Chapter 10 explains the Morfik Satellite Architecture and how it can be put to use in
 new and creative ways.
Chapter 11 describes how to create a fully
functional Blog application, from scratch
 with minimum coding.
Chapter 12 explains how to use Forms to accomplish more advanced tasks,
 generally associated with Desktop applications.
Chapter 13 offers a general overview of
debugging a WebOS application, that is
 browser- and server-side debugging.
Chapter 14 provides a general description of how to create a basic, browser side,
 custom control in Morfik and how to use it in the Morfik IDE.
Appendix A gives a quick overview of how
to bring external code into the Morfik
 universe.
Appendix B offers some tips on how to get the Microsoft Script Debugger to work
 on your computer.
Feel free to view or download the PDF version, either in separate sections or as a
single download.

Download entire HandBook (external link)


Developer's Handbook.pdf (10MB)

Page 296
Sorting and Filtering Records in Continuous Forms

Introduction
Continuous forms are very powerful when working with a large number of records and also
to create rich Grid functionalities. This example shows how you could sort columns in a
continuous form and also the ability to filter records based on search characters that are
placed for a column.

Solution
Download example here : SortAndFilterFB.zip (2 Mb)

See also
 Tips
 Tutorials
Category:Programming

Category:Database

Page 297
Working with external
Firebird databases

Introduction
You can easily connect and work with external databases from within a Morfik project. Native
connectivity is supported when working with external Firebird databases and data can be
accessed and edited from the databound forms. Following example shows how to work with
the external tables using WebMethods in Morfik.

Solution
The webMethod containing the SQL statments is called from a Form where parameters such
as the SQL Action (Select, Update, Insert), and values such as Country name and Currency
are passed into the WebMethod:

P rocedure Form1.Button1Click(Event: T DOMEvent);


Var
SQLComm : String;
Begin
SQLComm := ComboBox1.T ext;
RunWebMethod('wmdUpdateCountry','"prmAction='+ SQLComm +'","prmCountryName='+T extEdit
1.T ext+
'","prmCountryCurr='+T extEdit2.T ext+'"');
End;

Following is the code from the server module of the WebMethod (wmdUpdateCountry) called
above.

Unit wmdUpdateCountry;

Interface
Uses
SystemCatalog,
SystemConnectors,
SystemConnectorsIBO;
T ype
{...............................................................................}
wmdUpdateCountry=Class(WebMethod)
prmAction : String;
prmCountryName : String;
prmCountryCurr : String;
prmFound : Boolean;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
Procedure SelectExtFB;
Procedure InsertExtFB;
Procedure UpdateExtFB;
Procedure Execute; override;
{...............................................................................}
End; ['Published=False'];
{...............................................................................}

Page 298
Implementation

{...............................................................................}
P rocedure wmdUpdateCountry.SelectExtFB;
Var
CountryRS : T RecordSet;
DBServiceConnection : T DatabaseServiceConnection;
Connector : T DatabaseServiceConnector;
SQL : String;
Begin
prmFound := False;
Connector := T DatabaseServiceConnector(Catalog.GetServiceConnectorByID('Firebird1'));
DBServiceConnection := Connector.CreateConnection;
SQL :='SELECT "COUNT RY","CURRENCY" FROM "COUNT RY"';
CountryRS := T IBOServiceConnection(DBServiceConnection).CreateRecordSet(SQL);
CountryRS.P repare;
CountryRS.Active := T rue;
CountryRS.First;
While Not CountryRS.EOF Do
Begin
If (StringsEqual(CountryRS.FieldByName('COUNT RY').AsString,prmCountryName) And
StringsEqual(CountryRS.FieldByName('CURRENCY' ).AsString,prmCountryCurr)) T hen
Begin
prmFound := T rue;
Exit;
End;
CountryRS.Next;
End;
T IBOServiceConnection(DBServiceConnection).DestroyRecordSet(CountryRS);
End;
{...............................................................................}

{...............................................................................}
P rocedure wmdUpdateCountry.InsertExtFB;
Var
DBServiceConnection: T DatabaseServiceConnection;
Connector : T DatabaseServiceConnector;
SQL : String;
SQLCommand : T SQLCommand;
Begin
Connector := T DatabaseServiceConnector(Catalog.GetServiceConnectorByID('Firebird1'));
DBServiceConnection := Connector.CreateConnection;
SQL := 'INSERT INT O "COUNT RY" '+'("COUNT RY","CURRENCY") VALUES '+'(:"prmCountry",:"prmCurr
")';
SQLCommand := T IBOServiceConnection(DBServiceConnection).CreateSQLCommand(SQL);
T ry
SQLCommand.P aramByName('prmCountry').AsString := prmCountryName;
SQLCommand.P aramByName('prmCurr').AsString := prmCountryCurr;
SQLCommand.Execute;
Finally
SQLCommand.Free;
End;
End;
{...............................................................................}

{...............................................................................}
P rocedure wmdUpdateCountry.UpdateExtFB;
Var
DBServiceConnection: T DatabaseServiceConnection;

Page 299
Connector : T DatabaseServiceConnector;
SQL : String;
SQLCommand : T SQLCommand;
Begin
Connector := T DatabaseServiceConnector(Catalog.GetServiceConnectorByID('Firebird1'));
DBServiceConnection := Connector.CreateConnection;
SQL := 'UP DAT E "COUNT RY" SET "CURRENCY"=:"prmCurr" WHERE "COUNT RY"=' +''''+prmCountryNa
me+'''';
SQLCommand := T IBOServiceConnection(DBServiceConnection).CreateSQLCommand(SQL);
T ry
SQLCommand.P aramByName('prmCurr').AsString:= prmCountryCurr;
SQLCommand.Execute;
Finally
SQLCommand.Free;
End;
End;
{...............................................................................}

{...............................................................................}
P rocedure wmdUpdateCountry.Execute;
Begin
If prmAction = 'Insert' T hen InsertExtFB Else
If prmAction = 'Update' T hen UpdateExtFB Else
If prmAction = 'Select' T hen SelectExtFB;
End;
{...............................................................................}

End.

See also
 Tips

 Tutorials

External Links
Category:Database

Category:Programming

Category:Presentation

Page 300
Parsing strings

Introduction
This describes how you can use TArray to parse a string into an array of smaller string
sequences.

Notes
In the PHP world, this is
equivalent to the Explode
1 function.
Two independent versions are given depending on whether you wish for this functionality on
2 the browser-side or the server-side of your application.
Although the algorithm for this parser is very basic, it outlines
some of the subtle differences between string manipulation in
3 the browser-side and the server-side.

Server-side Solution

{...............................................................................}
T ListReader = Class(T StringList)
Procedure Readlist(Lst : String; aDelimiter : Char);
End;
{...............................................................................}

Implementation

{...............................................................................}
P rocedure T ListReader.Readlist(Lst : String; aDelimiter : Char);
Begin
Delimiter := aDelimiter;
SetDelimitedT ext(Lst);
End;
{...............................................................................}

{...............................................................................}
P rocedure Caller(Sender: T WebDocument; Var P Continue: Boole
an);
Var
Lst : T ListReader;
S : String;
i : Integer;
Begin
S := 'hello Australia morfik France';

Lst := T ListReader.Create;
Lst.Readlist(S,' ');
DebugOut(IntT oStr(Lst.Count));

For i := 0 T o Lst.Count - 1 Do
DebugOut(Lst[i]);
Lst.Free;
End;
{...............................................................................}

Page 301
Browser-side solution

{...............................................................................}
T StrList = List of String;
{...............................................................................}

{...............................................................................}
Function ReadList(Lst : String; Delimiter : Char) : T Str
List;
{...............................................................................}

Implementation

{...............................................................................}
Function ReadList(Lst : String; Delimiter : Char) : T Str
List;
Var
S : T String;
Arr : T Array;
i : Integer;
Begin
Result := Nil;
S := T String(Lst);
Arr := S.Split(Delimiter);
If (Arr <> Nil) And (Arr.length > 0) T hen
Begin
Result.Init;
For i := 0 T o Arr.length - 1 Do
Result.Add(T String(Arr[i]));
End;
Arr := Nil;
End;
{...............................................................................}

{...............................................................................}
P rocedure Index.Button1Click(Event: T DOMEvent);
Var
StrList : T StrList;
i : Integer;
Begin
StrList := ReadList('hello Australia morfik France',' ')
;

If StrList <> Nil T hen


For i := 0 T o StrList.Count - 1 Do
ShowMessage(StrList[i]);
End;
{........................................................................}

See also
 Tips
 Tutorials

External links
 Morfik forum: Explode function?
Category:Programming

Page 302
Page 303
Creating cookies

Introduction
This tip shows how to use cookies.

Details
This sample project demonstrate how to make use of the Cookie related functions in Morfik to
allow users of your xApp to store their user name in a cookie.

Cookies.zip

See also
 Morfik Forum:set and get a cookie value
 Tips

 Tutorials

External Links
Category:Programming

Category:Programming

Category:Presentation

Page 304
Creating an image map

Introduction
This intro shows how you could make a classic image map.

Background
In the simple case, that you have a static image that you place on the canvas at design-time
and there are simple (rectangular-shaped) areas that you wish to go to particular URLs, then
solution 1 is most likely the best option.

If, however, your image is data-driven, and the defined areas are also database-driven, then
solution 2, would be most appropriate.

Solution 1
Place a set of secondary controls (TextLabel or Image) on the main picture and set the Onclick
event of the control to open the ZOOMED image.

Solution 2
Files available for download

The project files for this solution can be downloaded here .

Description

Suppose you have a external DB with 2 tables: IMAGES and ZOOM.

The table IMAGES contain a picture and ZOOM table contain parts of picture that represent a
ZOOM and coordinates relative to IMAGE.

A couple of notes, if using a TextLabel, you need to add a number of "&_nbsp;" (remove the
underscore) in the caption property of the TextLabel to define the clickable area. If an Image
control is used, you should set the Picture property of the image control to a blank
transparent gif image. Also the Transparency property has to be on for the two controls.

The table that contains the ZOOM images could have 4 fields that keep the coordinate details
(Left, Top, Width and Height). On the load of the databound IMAGE form, for every ZOOM
image that belongs to the main IMAGE, a control (in this case a transparent image) can be
created dynamically based on the coord information from the ZOOM table. On the Click event
of the dynamically created transparent image you could open the appropriate ZOOM image in
a separate Floating form.

As you navigate through the IMAGE records, you could call the same method that is called in
the OnReady event of the IMAGE form.

See also
 Morfik Forum:duplicate a line of a table simply
 Tips

 Tutorials

External Links
Category:Database

Category:Programming

Category:Presentation

Page 305
Duplicating a line of a Table

Introduction
This intro shows how you could duplicate a line of a table, which has alarge number of fields.

We assume that the primary key is auto increment, so it's not possible to use simply use
"insert select * from from table" because of the primary key duplicate value.

Implementation
The following code shows how you could duplicate a record in a webMethod. note: this code
will raise an exception if the RecordNo value is not unique within the table.

Uses
SystemCatalog;

P rocedure wbsAppendRecord.Execute;
Var
SQL : String;
SQLCommand : T SQLCommand;
T ableData : T T ableData;
i : Integer;
Begin
T ableData := Catalog.T ables['T able1'];
If T ableData = Nil T hen Exit;

SQL := 'INSERT INT O "T able1" SELECT ';

For i := 0 T o T ableData.Fields.Count - 1 Do
Begin
If T ableData.Fields[i].SystemField T hen
SQL := SQL + 'NULL AS "' + T ableData.Fields[i].SysName + '"'
Else
SQL := SQL + '"' + T ableData.Fields[i].SysName + '"';
If i < T ableData.Fields.Count - 1 T hen
SQL := SQL + ','
Else
SQL := SQL + ' ';
End;

SQL := SQL +
'FROM "T able1" WHERE MFK$GUID = ( ' +
'SELECT MFK$GUID FROM "T able1" WHERE "RecordNo"=''' + IntT oStr(RecordNo)
+ ''')';

SQLCommand := SoapServer.DefaultDBConnection.CreateSQLCommand(SQL);
T ry
SQLCommand.Execute;
Finally
SoapServer.DefaultDBConnection.DestroySQLCommand(SQLCommand);
End;
End;

Page 306
See also
 Morfik Forum:duplicate a line of a table simply
 Tips

 Tutorials

External Links
Category:Database

Page 307
Displaying a confirm message on browser
close

Introduction
This article aims at teaching how one can intercept the closing of a browser window by asking
the user if they really want to close the browser window. In doing so, the following points
must be taken into consideration:
the developer code will never override the
 closing of the browser window,
all that developers can do is to ask the user to not close the browser
 window,

 the developer code can not be notified if the user chose to keep the window open,
finally the look of your
dialog is of the same as a
 ConfirmAction dialog.

Implementation
To do this we must use the

onbeforeunloa
d

event handler of a the

window

object. The event handler code will return a string value which the browser can then show to
ask the user if they want to close or not.

Using a

P rocedure

as oppose to a

Functio
n

changes this behaviour. If the event handler does not return a value, then only assigning an
event handler to the

onbeforeunloa
d

Page 308
by itself is not be enough to achieve the goal of this article, and therefore a

Functio
n

must be used. A

P rocedure

however can be used for other purposes and more information can be found here .

Unit Index;

Interface

T ype
Index=Class(Form)
Procedure WebFormReady(Var Ready: Boolean); Message;
Function HandleClose(Event: T DOMEvent) : String;
End;

Implementation

P rocedure Index.WebFormReady(Var Ready: Boolean);


Begin
Window.OnBeforeUnload := GetMethodPointer(Self,@HandleCl
ose);
End;

Function Index.HandleClose(Event: T DOMEvent) : String;


Begin
Result := 'Do you really really want to close this window?';
End;

End.

See also
 Invoking an event OnClose of browser window
 Tips

 Tutorials

External Links
Category:Programming

Page 309
Debugging SQL Statements

Introduction
Sometimes you need to know what commands are being sent to the database.

Solution
To do this you can turn on SQL Monitoring in the Debugger Options. The key items to trap are
1 Prepare
2 Execute
Turn these on and turn off the others. In particular, Profile causes errors as of the time of
writing (v 1.2.0.3)

The Prepare Statement will give you the SQL, with parameters indicated by question marks.
The Execute Statment will set values for each of the parameters.

Putting them together gives you the value of what is being passed to the database engine.

In order for this to work, make sure you are debugging server side.
Also note that the option to Monitor Designer SQL will return SQL statements generated by
the IDE at design time, for example when you open a table or a query in the IDE.

You can turn on Monitor SQL in the Debugger Options dialog on the Debug menu. You willl find
the option on the Monitors tab.

See also
 Tips
 Tutorials

External links
Category:Programming

Category:IDE

Page 310
Using dates in Queries

Introduction
This describes how use dates in Morfik AppsBuilder when writing Queries that are created
programmatically.

Solution
The default date values need to be in the following format dd/mm/yyyy (using forward slash
rather than dots) for the filter to work.

In this example, we take date from a DateTimeEdit control and pass it to our SQL statement.
It might be best to use the DateTimeEdit control in a form to enter date values rather than
using TextEdit controls. When using the DateTimeEdit control you need to use the
DateTimeToString function as shown in the below code sample:

Notes
If you have to use TextEdit control for entering date in the format you suggested, you could
change the date format by replacing the "." with "/" before passing the parameters in the
OpenForm function.

You could use TextEdits and the Zapatec Calendar controls to get the same results. There are
examples of how to use the Zapatec controls in the ZapatecDemo sample project. Place a
button next to the textedit control to hide or show the Zapatec Calendar and copy the
selected date from the Zapatec control into the two TextEdits before passing the values to
the Openform function. You could make the TextEdit controls readonly to minimize possible
incorrect date entry.

P rocedure frmDateRange.Button1Click(Event: T DOMEvent);


Var
dateFrom,dateT o : String;
Begin
dateFrom:= DateT imeT oString(FromDateT imeEdit.DateT ime,dfShort,eDate,
False);
dateT o := DateT imeT oString(T oDateT imeEdit.DateT ime,dfShort,eDate,Fals
e);
Openform('frmItemList','frmDateRange:Subform1',
'"prmStartDate='+dateFrom+'","prmEndDate='+dateT o+'"');
End;

See also
 Tips
 Tutorials

External links
 Morfik Forum: Working with dates in queries
Category:Programming

Category:Database

Page 311
Modifying the transparent property of images

Introduction
This describes how to set the transparent property of image at runtime

Notes
At design time, the IDE sets this to false every time the Form containing the image is closed
and reopened.

Solution
The first thing to do is ensure that in the original images, their backgrounds are set to
transparent.

Also the following Tip may be relevant :


Making_.png_images_transparent_in_Internet_Explorer

Now the key line of code is simply

MyImageControl.DOMStyle.Background := 'transpare
nt';

See also
 Tips
 Tutorials

External links
 Morfik Forum: How do I access the transparent property of image in code
Category:Programming

Page 312
Implementing drag-and-drop

Introduction
This tutorial outlines the foundations of implementing drag-and-drop.

In this actual demo, it allows users to drag the 'apple images' onto the 'apple container' and
the 'banana images' onto the 'banana container'.

Project Download
The actual application code, which is all browser-side is presented below. Of course, if you
want to see it in action or if you would like a copy of the images than you can download the
actual project here .

Solution
The core to drag and drop is to realise that there is not really an intrinsic event associated
with dragging. Therefore, you need to detect dragging by seeing if the mousebutton is down
and the mouse is moving.

Notes
Some of the minor issues that you will need to
contend with is overriding the browsers' behavior
1 when you click on an image.
Also included, is the framework for error checking so that if the application logic detects that the
user is attempting to drag the object to an invalid place, it will drop it back where it was
2 originally found.

Code

Unit frmMain;

Interface

T ype
frmMain=Class(Form)
Apple : Container;
AppleLabel : T extLabel;
BananaLabel : T extLabel;
Banana : Container;
Apple1Image : Image;
Apple2Image : Image;
Banana1Image : Image;
Banana2Image : Image;
T extLabel1 : T extLabel;
T extLabel2 : T extLabel;
Procedure WebFormMouseDown(Event: T DOMEvent); Message;
Procedure WebFormMouseUp(Event: T DOMEvent); Message;
Procedure WebFormMouseMove(Event: T DOMEvent); Message;
Procedure WebFormReady(Var Ready: Boolean); Message;
P rivate
{ P rivate declarations }
ClickedObject : T WebControl;
MouseStateX : Integer;
MouseStateY : Integer;
SelectedBasket: String;

Page 313
P ublic
{ P ublic declarations }
Function HandleDrag(Event: T DOMEvent) : Boolean; Message;
End;

Implementation
{..............................................................................}
T ype
{..............................................................................}
T DisplayCoords = Record
x : Integer;
y : Integer;
End;
{..............................................................................}

{..............................................................................}
T myDOMEvent = Class(T DOMEvent)
preventDefault : T BrowserEventProc;
End; ['External='];
{..............................................................................}

{..............................................................................}
T myDOMImage = Class(T HT ML_ImageElement)
ondrag : T BrowserEventProc;
End; ['External='];
{..............................................................................}

{..............................................................................}
P rocedure frmMain.WebFormMouseDown(Event: T DOMEvent);
Begin
T myDOMImage(self.DOMHandle).ondrag := GetMethodPointer(self, HandleDrag); //For IE
If Defined(T MyDOMEvent(Event).preventDefault) T hen T MyDOMEvent(Event).preventDefault(); //
for firefox

DomStyle.cursor:='move';
ClickedObject := GetEventSource(Event);
MouseStateX := Event.clientX - Detail.absLeft;
MouseStateY := Event.clientY - Detail.absT op;
End;
{..............................................................................}

{..............................................................................}
P rocedure frmMain.WebFormMouseUp(Event: T DOMEvent);
Procedure ResetMove;
Begin
ClickedObject.Left := ClickedObject.Attrs.Left;
ClickedObject.T op := ClickedObject.Attrs.T op;
End;

Procedure IdentifyBasket;
Var
Xp,Yp : Integer;
Begin
SelectedBasket := 'None';
Xp := Event.ClientX - Detail.absLeft;
Yp := Event.ClientY - Detail.absT op;
If (Xp>545 )OR (Xp<300) T hen Exit;
If (Yp>=19 )AND(Yp<=135) T hen SelectedBasket := 'Apple' Else
If (Yp>=198)AND(Yp<=313) T hen SelectedBasket := 'Banana';
End;

Page 314
Begin
IdentifyBasket;
DomStyle.cursor := 'default';
If P os(SelectedBasket, ClickedObject.Name) = 0 T hen ResetMove;
ClickedObject := Nil;
End;
{..............................................................................}

{..............................................................................}
P rocedure frmMain.WebFormMouseMove(Event: T DOMEvent);
Var
dX, dY : Integer;
DisplayCoords : T DisplayCoords;

P rocedure UpdateMouseStatus( DisplayCoords: T DisplayCoords);


Begin
dX := DisplayCoords.x - MouseStateX;
dY := DisplayCoords.y - MouseStateY;
ClickedObject.Left := ClickedObject.Left + dX;
ClickedObject.T op := ClickedObject.T op + dY;
MouseStateX := DisplayCoords.x;
MouseStateY := DisplayCoords.y;
End;
Begin
If ClickedObject <> Nil T hen
Begin
ClickedObject.DOMStyle.zIndex := '1000';
DisplayCoords.x := Event.ClientX - Detail.absLeft;
DisplayCoords.y := Event.ClientY - Detail.absT op;
UpdateMouseStatus(DisplayCoords);
End;
End;
{..............................................................................}

{..............................................................................}
P rocedure frmMain.WebFormReady(Var Ready: Boolean);
Begin
T myDOMImage(self.DOMHandle).ondrag := GetMethodPointer(self, HandleDrag); //For IE only
End;
{..............................................................................}

{..............................................................................}
Function frmMain.HandleDrag(Event: T DOMEvent) : Boolean;
Begin
Result := False;
End;
{..............................................................................}
End.

See also
 Tips

 Tutorials

Links
Category:Programming

Page 315
Calling a method from another Form

Introduction
It is quite common, in an application with multiple Forms, to call methods from a different
Form. This short article shows how this can accomplished.

Solution
When you need to access a method or property of one if the controls in Form2, from a
procedure/function in Form1, then this is how you reference it:

Form2(XApp.Forms['Form2']).MyT extLabel.Caption := 'H


ello';

You will also need to import Form2 in the implementation part of your code, so I basic demo of
it all would look something like this:

Unit Form1;

Interface

T ype
Navigation=Class(Form)
Button1 : Button;
Procedure Button1Click(Event: T DOMEvent); Message;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
End;

Implementation

Uses
Form2;

P rocedure Form1.Button1Click(Event: T DOMEvent);


Begin
ShowMessage(Form2(XApp.Forms['Form2']).MyT extLabel.Cap
tion)
End;

See also
 Tips
 Tutorials

Links
Category:Programming

Page 316
Activating Morfik

The activation process is very easy and straight forward.

In order to activate Morfik AppsBuilder you will need to enter a valid license key
into the textbox that appears when you first run the application. You should have
received this license key from Morfik.

Page 317
Pretty up the 'Loading...' message

Introduction
Morfik AppsBuilder now offers the ability to customize of the “Loading…” message.

Solution
It is simple. Now you can create a server-side application event (i.e. an event of your
application object) called OnPrintLoadingMessage() that will be called exactly before the
default "Loading..." message is going to be printed, so you can print your own message, and
by setting the var parameter Print to False you can prevent the Framework from printing its
own message, thus you can completely control the appearance of the "splash screen" (e.g.
include a logo, Flash, a tip of the day, anything that can entertain the user while your app
loads -- just remember, that the user might not have time to read long texts).

Example
To enter the following example, do the following:
Go to the Project
 (top) tab.
 Select the Server (bottom) tab.

 Press F11 to bring up the Properties sheet.


 Double-click on OnPrintLoadingMessage.

 Paste in the following code between the Begin and the End :

Response.WritelnString(' <div id="__LoadingT ext" '+


'style="left:48%;top:45%;position:absolute;font-weight:bold;'+
'text-align:center;font-size:12px;font-family:verdana,serif;'+
'background-color:#f0f0f0;padding:10px 14px 10px 14px;border:1px dotted
gray;'+
'color:red;">');
Response.WritelnString(' Loading...');
Response.WritelnString(' </div>');
P rint := False;

You will also find other interesting events here that may control the genration of the initial
bootstrap "code": look at Procedure TFormServer.GenerateMainHTMLPage; in
FrameWork\SystemServerDocForm.mmd for more details.

Notes
This feature was added into Morfik WebOS AppsBuilder (build 0.9.17.1).

See also
 Tips
 Tutorials
Category:Presentation

Page 318
Dynamically specifying
database connection
details

Introduction
There are various possible approaches;

(A) if the username/password are known at design time, use the service connector wizard to
connect to the database. you can then use code such as that in "Code Listing A" to obtain
records from the database

(B) if the username/password at run time differs from the username/password at design time,
use the service connector wizard to connect to the database at design time, then use the
code in listing B to specify the username/password at run time. You can then use code such
as that in listing A to obtain records from the database

(C) if you want to make an ad-hoc connection to an odbc data source at run time, use the
code shown in listing C

Code Listing A

Imports SystemCatalog
Imports SystemConnectorsODBC
Imports SystemDatabaseSQLDB

Namespace WebMethod2

Public Class WebMethod2


Inherits WebMethod

Public Overrides Sub Execute


Dim Query As T SqlQuery
Dim Connection As T ODBCServiceConnection
Connection = CT ype(Catalog.GetServiceConnectorByID("Northwind").CreateConnection, T ODBCService
Connection)
T ry
Query = New T SqlQuery(Nothing)
T ry
Query.Database = Connection.Connection
Query.SQL.T ext = "SELECT CategoryName FROM Categories"
Query.Prepare
Query.Open
Query.First
If Not Query.EOF T hen
ShowMessage(Query.FieldByName("CategoryName").AsString)
End If
Finally
Query.Dispose
End T ry
Finally
Connection.Dispose
End T ry
End Sub

End Class

Page 319
End Namespace

Code Listing B
The following code must be hooked up to the xApp's OnStart event.

If using Firebird-IBO:

Imports SystemConnectors
Imports SystemConnectorsIBO
Imports SystemCatalog

Namespace Project1XApp

Public Class P roject1XApp


Inherits T XApp

Published Message Sub XAppStart(Sender As T Object)


Dim SC As T ServiceConnector
SC = Catalog.GetServiceConnectorByID("Firebird1")
If SC Is T IBOServiceConnector T hen
CT ype(SC, T IBOServiceConnector).DbName = "database1.fdb"
CT ype(SC, T IBOServiceConnector).DbLocation = "c:\folder1\data
bases"
CT ype(SC, T IBOServiceConnector).DbUserId = "sysdba"
CT ype(SC, T IBOServiceConnector).DbP assword = "masterkey"
End If
End Sub
End Class
End Namespace

If using ODBC:

Imports SystemConnectorsODBC

Namespace Project1XApp

Public Class P roject1XApp


Inherits T XApp

Published Message Sub XAppStart(Sender As T Object)


Dim SC As T ODBCServiceConnector
SC = CT ype(Catalog.GetServiceConnectorByID("Northwind"), T ODBCServiceConn
ector)
SC.DBConnectionString = "put your odbc connection string here"
End Sub

End Class

End Namespace

Code Listing C

Page 320
Imports SystemDatabaseSQLDB

Namespace WebMethod1

Public Class WebMethod1


Inherits WebMethod

Public Overrides Sub Execute


Dim Connection As T SQLConnection
Dim Query As T SqlQuery
Connection = CreateSQLDbConnection("driverID", "userID", "password", "connection
String")
T ry
Query = new T SqlQuery(Nothing)
T ry
Query.Database = Connection
Query.SQL.T ext = "SELECT P roductName FROM P roducts"
Query.Prepare
Query.Open
Query.First
If Not Query.EOF T hen
ShowMessage(Query.FieldByName("P roductName").AsString)
End If
Finally
Query.Dispose
End T ry
Finally
Connection.Dispose
End T ry
End Sub

End Class

End Namespace

See also
 Tips

 Tutorials

External links
 Morfik Forum: Dynamically specify db connection details?
Category:Database

Page 321
Sending emails with attachments

Introduction
This tip shows how to send an email that includes an attachment.

Notes
The code provided below was written at the time when the AppsBuilder used indy 9. The
current release of the IDE for the pioneers is now using Indy 10 component. So to get the
above example working with the Authentication enabled you must make the following
change:

From

IdSMT P .AuthenticationT ype := atLo


gin;

To

IdSMT P .AuthT ype := atDefau


lt;

Code
here is an example of how to send an html email with attachment, this works in the current
release (which uses indy 9). With minor modifications, it will also work in the next coming
release, which will use indy 10.

P rocedure WebMethod1.Execute;
Var
IdMessage : T IdMessage;
HtmlLines : T StringList;
T extLines : T StringList;
IdSMT P : T IdSMT P ;
Begin
IdMessage := T IdMessage.Create(Nil);
IdMessage.Subject := 'this is the subject of your message';
IdMessage.Recipients.EmailAddresses := 'recipient@something.com';
IdMessage.From.Address := 'sender@something.com';
IdMessage.Sender.Address := 'sender@something.com';

HtmlLines := T StringList.Create;
HtmlLines.T ext := 'this is the html version of your message';
T IdT ext.Create(IdMessage.MessageParts, HtmlLines).ContentT ype := 'text
/html';

T extLines := T StringList.Create;
T extLines.T ext := 'this is the plain text version of your message';
T IdT ext.Create(IdMessage.MessageParts, T extLines).ContentT ype := 'text
/plain';

Page 322
T IdAttachmentFile.create(IdMessage.MessageP arts,'c:\attachment.pdf');

IdSMT P := T IdSMT P .Create(Nil);


IdSMT P .Host := 'smtp.something.com';
{the following lines are only needed if your server requires authentication}
IdSMT P .AuthenticationT ype := atLogin;
IdSMT P .Username := 'username';
IdSMT P .P assword := 'password';
{}
IdSMT P .Connect;
T ry
IdSMT P .Send(IdMessage);
Finally
IdSMT P .Disconnect;
End;
IdSMT P .Free;

IdMessage.Free;
HtmlLines.Free;
T extLines.Free;
End;

See also
 Tips
 Tutorials

External links
 Morfik Forum: Sending email query Category:Programming

Page 323
Adding Google AdSense Ads to
a Morfik Application

Introduction
Google AdSense is a service which provides advertisement for insertion into any web page,
based on the content that the service perceives to be associated with the website. This
service had opened the doors for many websites, which have significant traffic but which
would otherwise be considered as being insignificant by large media and advertisement
companies, to generate revenue from its visitors.

Getting Started
If you do not yet have an account with Google AdSense, you can quickly get one directly from
the Google website where at the bottom of the page a link to “Advertising Programs” can be
found. For the purposes of this paper we will only concern ourselves with the AdSense
program which is the one which allows the embedding of ads within your website.

If you do not have an AdSense account, you will need to create one to properly implement
what is described in this paper.

Google AdSense HTML Code


Once you have created an AdSense account you will be able to, through the management
interface for the program you will be able to create the layouts you want for your ads. This
topic considers the use of the “468x60 Banner” format, but any format can be used. Once you
have created the ad, the HTML source code for it is made available for inclusion in your
website.

In order to properly come into the XApp, occupying precisely the space set aside for it, we
must add a couple of elements of our own to the HTML source. The following is the code
provided by Google:

<script type="text/javascript"><!--
google_ad_client = "pub-4374970016542174";
google_ad_width = 468;
google_ad_height = 60;
google_ad_format = "468x60_as";
google_ad_type = "text";
google_ad_channel = "";
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.j
s">
</script>

To this code we must add two enveloping elements: a div and a body, to add formatting
attributes which will make sure no additional space, beyond the ad text gets added to the
website. With these additions the code will look as shown in the following snippet.

<body style="margin:0pt;padding:0pt">
<div class='adsense' style='text-align:center; padding:0px; margin:0
px'>
<script type="text/javascript"><!--
google_ad_client="pub-4374970016542174";

Page 324
google_ad_width=468;
google_ad_height=60;
google_ad_format="468x60_as";
google_ad_type="text";
google_color_border="EEEECC";
google_color_bg="EEEECC";
google_color_link="333333";
google_color_url="333333";
google_color_text="558866";
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"
>
</script>
</div>
</body>

Without these small additions, when we insert the ad into the Morfik XApp it will have
additional space around it and will cause scrollbars to appear around itself. It is very
important to note that the code generated by Google is not being altered at all, which would
be against Google's AdSense terms of use. We are adding formatting commands around it
just to eliminate the possibility of unwanted blank space to be included by the browser.

Figure 1 - A small Morfik Application displaying Google AdSense ads.

Bringing the ad into a Morfik Web Application Project


Once the original code from Google has been extended to ensure no unwanted extra spacing
will exist, it should be added to a Morfik Web Application project as a resource in the resource
repository. In this case the file will be saved as “ad.html” and should thus be referenced in
source code. A new project with a single Form can be created for purposes of testing.

In the Form where the ad is to be displayed a SubForm control, with the same dimensions as
the desired ad size, should be created. In this case the SubForm will have a height of 60 and
a width of 468. This SubForm should be visually positioned where the ad is to be displayed.

In order complete the process and have the ads appear inside the application, a small code
snippet should be added to the OnReady event of the Form where the ad is to be displayed.

Page 325
The following code snippet will tell the browser to request the code for the ad, from the same
Server from which your application is being loaded.

P rocedure Index . WebFormReady ( Var


Ready : Boolean );
Var
url : string ;
Begin
url := 'http://' + window . location . host ;
OpenForm ( url + '/ad.html?cls=res' , 'Index:SubForm1'
, '' );
End ;

With this code snippet in place the application will display the Google AdSense ads in the
appropriate place. The following picture is a screenshot of a Morfik XApp, running within
Internet Explorer 7, from which the code in this topic was obtained.

Notice that he ad comes into the Form perfectly, fitting exactly to the size of the
pre-positioned SubForm.

Bringing the ad into a Morfik Browser Application Project


In Morfik Browser Application projects the adapted HTML code file from Google does not need
to be added to resource repository. In these applications you have to make sure that the file
is in an accessible folder/directory so that the XApp can request it. The following code snippet
shows the slight change to the code which is necessary to make the application work properly
from any web server the developer may wish to use.

P rocedure Index . WebFormReady ( Var


Ready : Boolean );
var
url : string ;

Begin
url := 'http://' + window . location . host ;
openform ( url + '/ad.html' , 'Index:SubForm1' , '' );
End ;

Notice that in the case of Morfik Browser Application projects the URL for the ad file is actually
a little bit simpler than in the previous example.

Conclusion
It is a simple task to bring Google AdSense ads to a Morfik website or application, once an
account has been setup with Google.

See Also
 Managing Resources
 Adding Resources to the Project

 HTML Resources

Page 326
Adding Resources to the
Project

Adding new resources to a project is very simple and straight forward. Morfik
AppsBuilder treats all resources as files which are kept in a special folder. This folder
is named after the project's name (_ProjectNamePub) is always inside the folder
which holds the project's files.

Figure 1 - The Resource Explorer with the Add Resource button highlighted by the
mouse pointer.

Inside the "Pub" folder for your project you will find several other folders.
The Images folder is where you will want
store the images that will be used in the
 Project.
The System folder will contain compiler generated and support files which are related
 to the Morfik Framework.
The Scripts folder will is where the scripts
which are generated by the Morfik compiler,
 specifically for your project, are stored.

See Also
 Managing Resources
 The Resource Explorer

Related Video
 Add Images and Flash

Page 327
The Resource
Explorer

The Resource Explorer window is intended to allow you to have access to the resources which
are part of your current Morfik project. You can access this window by clicking on the Published
Folder button of the Project tab on the Ribbon. Figure 2 shows the Published Folder button
highlighted.

Figure 1 - the Project tab of the Ribbon control.

Once you select this option you will see the Explorer window which is similar to a Windows
Explorer window. Figure 2 shows this window displaying 3 images that were already added to
the current project.

Figure 2 - the Resource Explorer window with several images already added to the project.

See Also
 Managing Resources
 Adding Resources to the Project

Page 328
HTML Resources

HTML resources are added to a project in the form of normal HTML document files.

You can add pre-existing HTML files to your project, so that they can dynamically
opened in specific areas of your website or application. Alternatively you can
assign a string with HTML markup to the Caption property of TextLabel controls
which will then get properly rendered by the browser.

If you want to add, for example, a Google AdSense ad to your project you need to
generate the code for it on the Google AdSense website and then save it as an
HTML file which should then be added to your Published Folder as a resource. For
more information on preparing the file to insert the Google generated code, refer
to Adding Google AdSense Ads to a Morfik Application .

Displaying an HTML resource in a Morfik Web Application


In order to display an HTML document stored as a resource in a Morfik Web Application
project, you should use the OpenForm command, specifying a URL that includes the name of
the resource file, as shown in the following example.

P rocedure Index . WebFormReady ( Var


Ready : Boolean );
Var
url : string ;
Begin
url := 'http://' + window . location . host ;
OpenForm ( url + '/ad.html?cls=res' , 'Index:SubForm1'
, '' );
End ;

The URL that you need to use is composed in the following manner:

http:// + your_website + / + your_resource_file_name + ?cls


=res

an example of such a URL is the following:

http://www.morfiksite.com/ad.html?cls=r
es

The target for this OpenForm command should be a SubForm control in one of your project's
Forms.

Displaying an HTML resource in a Morfik Browser Application


In order to display an HTML document stored as a resource in a Morfik Browser Application
project, you should use the OpenForm command, specifying a URL that includes the name of
the resource file, as shown in the following example.

P rocedure Index . WebFormReady ( Var


Ready : Boolean );
Var

Page 329
url : string ;
Begin
url := 'http://www.yourwebsite.com/ad.html' ;
OpenForm ( url , 'Index:SubForm1' , '' );
End ;

The URL that you need to use is composed in the following manner:

http:// + your_website + / + your_resource_file_path_and_n


ame

an example of such a URL is the following:

http://www.morfiksite.com/ad.ht
ml

The target for this OpenForm command should be a SubForm control in one of your project's
Forms.

See Also
 Managing Resources
 Types of Resources

 Adding Google AdSense Ads to a Morfik Application

Page 330
Types of Resources

You can add just about any type of file as a resource in your project. Generally the
types of files you will want to add are images, text, HTML and XML documents and
perhaps some flash content.

The Morfik Resource Explorer treats all this content as general files so your
handling of all of them is absolutely the same.

Any externally created JavaScript files that you will want to use within your project
should be added to the project's resources.

More information on how to work with specific image resource types are available
in the following topics:
 Image Resources
 HTML Resources

See Also
 Managing Resources
 Adding Resources to the Project

Page 331
Image Resources

Morfik AppsBuilder allows you to work with all the standard image types used in
Website creation: GIF, JPG and PNG. Each of these files have their own unique
characteristics and might be better suited for a specific task.

When you want to work with transparency JPG files are not recommended as they
have no support for transparency information. Images with transparency are
specially useful when you want to handle pictures with a non-rectangular shape,
so that the background color of the Form underneath the image will show
through.

See Also
 Managing Resources
 Types of Resources

Page 332
A Blog Application

Note
This topic is currently under development, being updated to reflect the
latest version of Morfik AppsBuilder. If you would like to see the description
for creating a blog with Morfik 07, please refer to Morfik 07 - Creating a
Blog Application .

This topic explains how to create a Blog application with Morfik AppsBuilder R2,
using mostly visual development and writing as little code as possible. This was an
exercise that was done for Morfik 07 and revisited for AppsBuilder R2, in order to
demonstrate how visual application development can be applied to Web
application development, drastically reducing the effort necessary to create a
reasonably good looking application.

In the Morfik R2 version, this application adds support for an RSS Feed and a very
basic kind of user authentication, to prevent unauthorized editing of the posts.

The result of this exercise can be seen in Figure 1, which shows the blog
application running in the Morfik Debug Browser (Firefox based).

Focus on Code
Multi-browser Compatibility
Structure of the Blog Application
Pages and Forms, Organizing Your Information
MainPage. The starting point…
General site layout...
ArticleSummaryList. Viewing the ten most recent posts…
ViewOneArticle. Reading a full article…
BlogProfile. Information about the Blog’s Author
SideBar. Easy access to shortcuts…
FavoriteLinks. Recommended links…
RecentArticlesList. Recommended links…
ArchiveList. Archive of old articles…
AdminMain. General site administration...
CreateEditPosts. Adding and maintaining articles of the
blog
EditProfile. Maintaining the author’s profile
CreateEditLinks. Adding and maintaining favorite links
Wrapping it up
See Also

Focus on Code
In describing in this chapter how the application was created, I have not gone into all the details of
how all the visual effects, such as the dotted lines, were implemented. They are all done visually,
through the use of the form designer and can easily be reproduced.

Since it would not be practical to try do describe, in writing, all the steps necessary to reproduce the

Page 333
visual styling of the application, I will leave it as an exercise to the reader to download the project
from the blog website, from labs.morfik.com, and study how the effects were implemented. Our focus
on this chapter will be on the code necessary to make this application work; what little of it there is.

Multi-browser Compatibility
Another exercise which might be of interest to the user is to actually access this XApp through all the
main web browsers. There should be no perceptible difference in the application when viewed in IE,
Firefox, Safari or Opera.

Figure 1 – Blog XApp running in the Morfik Debug Browser (Firefox based).

The next Figure shows the same page being displayed in Opera.

Page 334
Figure 2 – Blog XApp running in the Opera.

Figure 3 shows the Admin section of the Blog website, which is the area which will be used by the
blog ’ s author.

Page 335
Figure 3 – The Admin section of the Blog website being displayed in Apple's Safari browser.

Structure of the Blog Application


Since the goal of this project was to create this sample application in as simple a manner as possible,
but whose techniques would be usable to just about everyone, this application relies only on three
tables: Articles , BlogInfo and Links . It also relies on three queries. We will see all these data sources
in use, further along, as we see how the application is visually designed.

The blog website is divided into two Areas: Blog and Admin. The Blog area is where users will go to
read the posts in the blog and navigate through its archives. The Admin area is for use by the blog
owner and is designed for creating new posts and editing existing ones, updating the author ’ s
profile and blog parameters as well as the favorite links displayed on the website.

The entire website can be said to be divided into different information views. At all times, what you
see in the browser is a combination of several information views. Morfik is especially good at creating
such information centric applications, as we will see.

Pages and Forms, Organizing Your Information


In Morfik, Pages are the highest level organization entity for an application or Website. Pages let you
put together a group of Forms in a specific layout, in order to display the your information in a nice
and consistent manner.
Forms are the pieces from which you put together the interface for your application/website. In most
cases forms are views into specific information which you want to display to the users of your
site/application. Our whole application is a large work in form composition, in order to get exactly the
desired effects.

Page 336
MainPage. The starting point…
In order to be able to easily switch between the two areas of the website we will create a page for
each. We will start with the MainPage which will be your Website's home page.

Figure 4 – View of the MainPage page in Morfik workspace. This page is the starting point for the
Blog Xapp.

This page will display the forms which have been assigned to its composing sections, properly
arranged in relation to one another. When any user accesses this application with the browser,
he/she gets back the MainPage , which will then bring into the browser the download five forms:
MainHeader , MainFooter , ArticleSummaryList , BlogProfile and SideBar . The SideBar form, in turn, will
download three additional forms that makeup the information that appears under the blog's profile
data on the right side of the page.

General site layout...


The general layout of information in the website is defined by the layout applied to the MainPage
page, when regular users are using the website to read recent posts or browser through the
archives.

This page uses a layout with has a header and a footer and splits the area in between into three
areas.

Both the MainHeader and MainFooter forms are connected (data bound) to the BlogInfo table, which
holds basic information about the Author and the blog. These forms, as their names suggest, are
responsible for the contents that are displayed in the Header and Footer sections of the MainPage
page. In Figure 5 you can see the MainPage page with each section numbered. Sections 1 and 2 take
the role of Header and Footer , respectively, while section 3 holds the main content for the home
page, section 4 contains the BlogProfile form and section 5 contains the Sidebar form which will bring in
three additional forms with summary information about the blog posts.

Page 337
Figure 5 – MainPage page with its sections numbered.

Looking closely at the MainPage page you will notice that the area between the Header and the
Footer is divided into three sections, which are statically bound to three forms: ArticleSummaryList ,
BlogProfile and SideBar .

In both the header and footer, the MainPage page displays information about the blog itself, such as
name, description and copyright terms. It is in the MainHeader form that we add our first snippet of
code to the Blog XApp, as shown in listing 1.

Listing 1 – Event Handler for the OnClick event of the AdminLink control.

P rocedure
MainHeader . AdminLinkClick ( Event : T DOMEvent );
Begin
If AdminLink . Caption = 'Admin' T hen
Begin
OpenPage ( 'AdminP age' , '' );
AdminLink . Caption := 'Home' ;
End
Else
Begin
OpenPage ( 'MainP age' , '' );
AdminLink . Caption := 'Admin' ;
End ;
End ;

The AdminLink control is a label that can be seen in the top/right corner of the form with the text
"Admin". This label, when clicked, will load up the page AdminPage . Essentially, this will replace the
entire website by the blog administration site. when the user is already in the Admin section of the
website, this link will be showing the word "Home" and when clicked will take him back to the blog's
home page.

ArticleSummaryList. Viewing the ten most recent posts…


A large section of the MainPage is occupied by the ArticleSummaryList form. This form presents the title
and summary of the five most recent posts to the blog, grouped by date.

Figure 6 – ArticleSummaryList form. Article view inside the MainPage page.

The ArticleSummaryList form is ordered and grouped by the date in which a post was published. In
order to appropriately handle the grouping for this view a special calculated column had to be added
to the RecentArticles query. This column, defined as: "x : xsDay("DatePublished")" extracts just the
day, in which the article was published.

The resulting SQL command is as follows:

Page 338
SELECT ALL
"Articles" . "T itle" ,
"Articles" . "Summary" ,
"Articles" . "DatePublished" ,
xsDay ( "DateP ublished" ) AS
"x" ,
"Articles" . "Id"
FROM
"Articles"

This command was created visually, through the Query Builder.

Once the query is correctly prepared you create the desired group bands in the form by choosing the
"Sorting and Grouping" option under the "Edit" menu. This will bring up the dialog that appears in the
following Figure.

Figure 7 – Defining sorting and grouping for the ArticleSummaryList form.

It is in the ArticleSummaryList form that we will add the second code snippet to our application. The
code you can see in Listing 2 is used to handle the OnClick event of two different controls and
basically replaces the view with the most recent posts with a new one which contains the detailed
view of the specific article on which the user clicked.

Listing 2 – Event Handler for the OnClick event of the ArticleTitle and ReadMoreLink controls.

P rocedure ArticleSummaryList . ArticleT itleClick ( Event : T DOMEvent );


Begin
ArticleId . BandIndex := GetEventSource ( Event ). BandIndex ;
OpenForm ( 'ViewOneArticle' , 'MainP age:SubForm1' , '"P aramId='
+ ArticleId . Caption + '"' );
ScrollT oT op ;
End ;

When working with continuous forms it is important to ensure that the referenced controls contain
information from the desired band. This is achieved by setting the BandIndex property of the controls,

Page 339
as in the code in listing 2.

It is interesting to note that the ArticleId TextLabel control which is located in the form has its visible
property set to be invisible and is only on the form so as to make it easy for us to have access to Id
of each article.

When you click on either the title for the article ( ArticleTitle TextLabel) or the "Read more…" option (
ReadMoreLink TextLabel), the event handler shown in listing 2 will be called and will switch the
content of the SubForm1 subform in page MainPage from the ArticleSummaryList form to the
ViewOneArticle form. This will allow the user to read the full article, instead of its summary.

Also, of interest in this small code sample is the use of the ScrollToTop procedure which scrolls the
browser window back to the top. This ensures that the user will be able to start reading the desired
article, without having to scroll back to the top, manually. This small procedure is defined in the
project's Globals module.

ViewOneArticle. Reading a full article…


The ViewOneArticle form is very simple, displaying the Article ’ s title and full body. It is through this
form, when it is displayed inside the MainPage page ’ s SubForm1 section/SubForm, so that the user
will be able to read a complete article.

Figure 8 – The ViewOneArticle form.

In this form the only existing code is associated with the onClick event of the "Return Home" link
which is the ReturnLink control. This code returns you to the default view of the blog, by switching the
content of the MainArticleArea subform in form MainPage page the ViewOneArticle form to the
ArticleSummaryList form. You can see this code in Listing 3.

Listing 3 – Code for the "Return to Home" option in the ViewOneArticle form.

P rocedure
ViewOneArticle . ReturnLinkClick ( Event : T DOMEvent );
Begin
OpenForm ( 'ArticleSummaryList' , 'MainP age:SubForm1' , ''
);
End ;

This form uses a Query called GetOneArticle as its data source. This query has one parameter which
is passed to the form when it is opened as can be seen in Listing 2.

This query is visually designed and defined as:

SELECT ALL
"Articles" . "T itle" , "Articles" .
"DateP ublished" ,
"Articles" . "Id" , "Articles" . "Body"
FROM
"Articles"
WHERE
"Articles" . "Id" = P aramId

Page 340
BlogProfile. Information about the Blog’s Author
The BlogProfile form is very simple in nature. All this form does is display a couple of fields from the
BlogInfo table which contain the author ’ s name and a short "bio". This information is displayed in a
separate form just for formatting convenience.

Figure 9 – The BlogProfile form.

Note that this form has symmetrical Corners effects applied to both its Header and Footer bands
which gives it a "softer" appearance. This effect is used throughout this application to provide a more
subtle finish to the different data regions of the Website.

SideBar. Easy access to shortcuts…


The SideBar form is used for formatting convenience, allowing us to host three different forms in a
single section of the MainPage page. This form contains three SubForm controls which will display the
following forms: RecentArticlesList , ArchiveList and BlogRoll . Each one of these forms will be discussed
separately in further detail.

Figure 10 – The SideBar form.

FavoriteLinks. Recommended links…


The BlogRoll form is used for displaying a list of links which the Author is recommending. This form
follows an exact formatting standard along with forms RecentArticleList and ArchiveList .

Page 341
Figure 11 – The BlogRoll form.

In this form you can see a TextLabel control displaying the text "LinkURL". This control, ( URL
TextLabel) is data-bound to the LinkURL field of the Links table and has its visible property set to
false. This is useful when the LinkLabel TextLabel that shows the name of the link is clicked, so that
the appropriate URL is available. The code for handling the OnClick event of LinkLabel is as follows.

Listing 4 – Code for the OnClick event of the LinkLabel control.

P rocedure
BlogRoll . LinkLabelClick ( Event : T DOMEvent );
Begin
Url . BandIndex := GetEventSource ( Event ). BandInd
ex ;
Window . open ( Url . Caption , '_self' , '' );
End ;

RecentArticlesList. Recommended links…


The RecentArticlesList form is used for displaying a list of the 10 most recent posts in the blog. This
form follows an exact formatting standard along with forms FavoriteLinks and ArchiveList .

Figure 12 – The RecentArticleList form.

In this form you can see a TextLabel control displaying the text "Id". This control, ( IDLabel TextLabel)
is data-bound to the Id field of the Links table and has its visible property set to false. This is useful
when the IdLabel TextLabel that shows the name of the link is clicked, so that the appropriate URL is
available. The code for handling the OnClick event of IdLabel is as follows.

Listing 5 – Code for the OnClick event of the IdLabel control.

P rocedure
RecentArticlesList . LinkLabelClick ( Event : T DOMEvent );
Begin
IdLabel . BandIndex := GetEventSource ( Event ). BandIndex ;
OpenForm ( 'ViewOneArticle' , 'MainP age:SubForm1' ,
'"P aramId=' + IdLabel . Caption + '"' );
ScrollT oT op ;
End ;

ArchiveList. Archive of old articles…


The ArchiveList form is used for displaying a list of all the years and months in which posts were made
in the blog. This form follows an exact formatting standard along with forms FavoriteLinks and
RecentArticlesList .

Page 342
Figure 13 – ArchiveList form, showing a grouping header and footer.

As you can see in Figure 11 this form also employs sorting and grouping in order to present the
desired interface elements to the end user of the blog. The ArchiveList form will display a list of years
with an indented list of months, for all the dates in which a post was made to the blog.

This form uses as its data source the visually designed query ArchiveQuery , which is defined as:

SELECT ALL
"Articles" . "T itle" ,
"Articles" . "Summary" ,
"Articles" . "DatePublished" ,
xsDay ( "DateP ublished" ) AS
"x" ,
"Articles" . "Id" ,
xsYear ( "DateP ublished" ) AS
"y"
FROM
"Articles"

As in the other we have just seen, ArchiveList also has an invisible TextLabel control which is
data-bound to the Id field of the Articles table. This is useful when a user clicks on the title of an
article, to specify which article should be brought up in the ViewOneArticle form, inside the SubForm1
Section/SubForm of the MainPage .

In this form, the LinkLabel control has the following code associated to its onClick event.

Listing 6 – Code for the OnClick event of the LinkLabel control in form ArchiveList .

P rocedure
ArchiveList . LinkLabelClick ( Event : T DOMEvent );
Begin
IdLabel . BandIndex := GetEventSource ( Event ). BandIn
dex ;
OpenForm ( 'ViewOneArticle' , 'MainP age:SubForm1' ,
'"P aramId=' + IdLabel . Caption + '"' );
ScrollT oT op ;
End ;

AdminMain. General site administration...


The AdminMain form is responsible for the general layout of information in the administration portion
of the blog website. This form employs a TabControl in order to allow for easy access to all the
necessary options for maintaining the website.

Page 343
The AdminMain form uses a single SubForm control to host other forms. Each one of these Forms will
be responsible for allowing data manipulation of one of the three tables data store all the blog
application's data.

The three images that you can see in figures 15 to 17 show how each of the Forms which will be
shown inside the AdminPlace SubForm of the AdminMain Form.

Figure 14 – AdminMain form showing the AdminPlace SubForm control.

The AdminMain form has basically the purpose of creating a tabbed menu for the selection of part of
the blog's data will be viewed/edited. The code in the AdminMain form is associated to the OnClick
event of the the three buttons which have been formatted to resemble a colored set of tabs:
ArticlesTab, LinksTab and ProfileTab.

This code switches the content of the AdminPlace subform of the same form, to display the necessary
Form for viewing or editing the selected type of data.

Listing 7 – Code to switch back to the main blog area of the website.

P rocedure
AdminMain . ViewBlogClick ( Event : T DOMEvent );
Begin
OpenP age ( 'MainP age' , '' );
End ;

Each of the TabSheets in the TabControl in form AdminMain contains a subform which is statically
bound to one of the following forms: CreateEditPosts , CreateEditLinks and EditProfile .

CreateEditPosts. Adding and maintaining articles of the blog


This form is bound to the Articles table and allows you to add new articles or edit pre-existing ones.

Note that this form has a green color applied to a header section that has a height of only 2 pixels.
This effectively creates a line that seems to merge with the Green Tab that is associated with this
Form in the AdminMain Form.

Page 344
Figure 15 – The CreateEditPosts form.

The CreateEditPosts form displays the Navigator in its footer band, allowing for a full range of database
functions. In order to display the Navigator of a data bound form, configure the Navigator property of
the footer band of the form.

EditProfile. Maintaining the author’s profile


The EditProfile form allows for the editing of a single record in the BlogInfo table. This table holds some
basic information about the blog and its author and should never have more than one record.

Note that this form has the red color applied to a header section that has a height of only 2 pixels.
This effectively creates a line that seems to merge with the Red Tab that is associated with this Form
in the AdminMain Form, as the case with the previous Form.

Figure 16 – The EditProfile form.

As you can see in Figure 16, the EditProfile form displays a reduced version of the Navigator in its
footer band. In order to achieve this sort of effect you should configure the navigator property of the
footer band, as previously mentioned.

CreateEditLinks. Adding and maintaining favorite links

Page 345
This form is bound to the Links table and allows you to add new articles or edit pre-existing ones. As
with the previous two forms, this one also has a colored band at the top, to match the corresponding
tab in the AdminMain form.

Figure 17 – The CreateEditLinks form.

The CreateEditLinks form is very simple, only allowing the author to maintain a list of links described
by a name and a URL.

Wrapping it up
The main objective of creating the application shown in this topic was to demonstrate that it is
possible to create applications which are quite sophisticated and benefit from a full Ajax
implementation, in Morfik, while actually writing very little code.

Most of the code in this project is actually generated by the Morfik workspace, such as the class
declarations, while only a handful of lines were actually hand coded.

See Also
 Introduction to Morfik Database Programming
 Working with Forms

 Working with Controls


 Control Effects
category:Database

Page 346
Morfik 07 - Creating
a Blog Application

This chapter explains how to create a Blog application with Morfik, using mostly
visual development and writing as little code as possible. This was an exercise I
put myself up to, in order to demonstrate how visual application development can
be applied to Web application development, drastically reducing the effort
necessary to create a reasonably good looking application.

The result of this exercise can be seen in Figure 1, which shows the blog
application running in IE 7, as a normal user will see it.

Focus on Code
Multi-browser Compatibility
Structure of the Blog Application
Forms, Organizing Your Information
Index. The starting point…
BlogMain. General site layout...
ArticleSummaryList. Viewing the five most recent posts…
ViewOneArticle. Reading a full article…
AuthorProfile. Information about the Blog’s Author
SideBar. Easy access to shortcuts…
FavoriteLinks. Recommended links…
RecentArticlesList. Recommended links…
ArchiveList. Archive of old articles…
AdminMain. General site administration...
CreateEditPosts. Adding and maintaining articles of the
blog
EditProfile. Maintaining the author’s profile
CreateEditLinks. Adding and maintaining favorite links
Wrapping it up

Focus on Code
In describing in this chapter how the application was created, I have not gone into all the
details of how all the visual effects, such as the dotted lines, were implemented. They are all
done visually, through the use of the form designer and can easily be reproduced.

Since it would not be practical to try do describe, in writing, all the steps necessary to
reproduce the visual styling of the application, I will leave it as an exercise to the reader to
download the project from the blog website, from labs.morfik.com, and study how the effects
were implemented. Our focus on this chapter will be on the code necessary to make this
application work; what little of it there is.

Multi-browser Compatibility
Another exercise which might be of interest to the reader is to actually access this XApp
through all the main web browsers. I have done so with all the browsers I personally have
access to, and there is not even a minor difference in what is displayed with Internet Explorer
7, Firefox 2 and Opera 9.

In verifying this I used a 19" LCD monitor, in portrait mode, showing the entire length of the

Page 347
blog ’ s start page to look for inconsistencies. I also placed the browser windows side by side
(2 at a time) to check for discrepancies. I found nothing. Considering that this application,
though simple in the amount of code it requires, is quite complex as far as element positioning
and style is concerned, I was very impressed by this.

Figure 1 – Blog XApp running in IE 7.

The next Figure shows the Admin section of the Blog website, which is the area which will be
used by the blog ’ s author.

Page 348
Figure 2 – The Admin section of the Blog website.

Structure of the Blog Application


Since the goal of this project was to create this sample application in as simple a manner as
possible, but whose techniques would be usable to just about everyone, this application
relies only on three tables: Articles , BlogInfo and Links . It also relies on three queries. We will
see all these data sources in use, further along, as we see how the application is visually
designed.
The blog website is divided into two Areas: Blog and Admin. The Blog area is where users will
go to read the posts in the blog and navigate through its archives. The Admin area is for use
by the blog owner and is designed for creating new posts and editing existing ones, updating
the author ’ s profile and blog parameters as well as the favorite links displayed on the
website.

Page 349
The entire website can be said to be divided into different information views. At all times, what
you see in the browser is a combination of several information views. Morfik is especially good
at creating such information centric applications, as we will see.

Forms, Organizing Your Information


Forms are the pieces from which you put together the interface for your application/website.
In most cases forms are views into specific information which you want to display to the users
of your site/application. Our whole application is a big work in form composition, in order to
get exactly the desired effects.

Index. The starting point…


In order to be able to easily switch between one of these areas and the other, a root form
called Index was created in this project. This form has only one subform control, which will
contain the entire website in it, and it covers its entire detail band. When the user first
accesses this site, the subform control is statically bound to the BlogMain form. When any user
attempts to access this application with the browser, he/she gets back the Index form, which
will then bring into the browser the BlogMain form, which will in turn, download three other
forms.

The purpose of having this form is to allow you to change the entire content of the page in
one action. This way, we can easily move back and forth from the blog interface (implemented
in form BlogMain ) to its Admin interface (implemented in form AdminMain ).

Figure 3 – Index form. Starting point for the Blog Xapp.

BlogMain. General site layout...


The BlogMain form is responsible for the general layout of information in the website, when
regular users are using the website to read recent posts or browser through the archives.

This form uses all three of the standard bands: header , details and footer . The BlogMain form
is connected (data bound) to the BlogInfo table, which holds basic information about the
Author and the blog.

Figure 4 – BlogMain form. Main layout of the website.

Looking closely at the BlogMain form you will notice that it has three subform controls, in its
details band, which are statically bound to three forms: ArticleSummaryList , AuthorProfile and

Page 350
SideBar .

In both the header and footer, the BlogMain form displays information about the blog itself,
such as name, description and copyright terms. It is in the BlogMain form that we add our first
snippet of code to the Blog XApp, as shown in listing 1.

Listing 1 – Event Handler for the OnClick event of the TextLabel4 control.

P rocedure
BlogMain . T extLabel4Click ( Event : T DOMEvent );
Begin
OpenForm ( 'AdminMain' , 'Index:FullSite' , '' );
End ;

The TextLabel4 control is a label that can be seen in the top/right corner of the form with the
text "Admin". This label, when clicked, will load up the form AdminMain inside the FullSite
subform of the the BlogMain form. Essentially, this will replace the entire website by the blog
administration site.

ArticleSummaryList. Viewing the five most recent posts…


A large section of the area covered by the BlogMain form is occupied by the ArticleSummaryList
form. This form presents the title and summary of the five most recent posts to the blog,
grouped by date.

Figure 4 – ArticleSummaryList form. Article view inside the BlogMain form.

The ArticleSummaryList form is ordered and grouped by the date in which a post was
published. In order to appropriately handle the grouping for this view a special calculated
column had to be added to the RecentArticles query. This column, defined as: "x :
xsDay("DatePublished")" extracts just the day, in which the article was published.

The resulting SQL command is as follows:

SELECT ALL
"Articles" . "T itle" ,
"Articles" . "Summary" ,
"Articles" . "DatePublished" ,
xsDay ( "DateP ublished" ) AS
"x" ,
"Articles" . "Id"
FROM
"Articles"

Page 351
This command was created visually, through the Query Builder.

Once the query is correctly prepared you create the desired group bands in the form by
choosing the "Sorting and Grouping" option under the "Edit" menu. This will bring up the
dialog that appears in the following Figure.

Figure 5 – Defining sorting and grouping for the ArticleSummaryList form.

It is in the ArticleSummaryList form that we will add the second code snippet to our
application. The code you can see in Listing 2 is used to handle the OnClick event of two
different controls and basically replaces the view with the most recent posts with a new one
which contains the detailed view of the specific article on which the user clicked.

Listing 2 – Event Handler for the OnClick event of the TextLabel1 and TextLabel4 controls.

P rocedure
ArticleSummaryList . T extLabel1Click ( Event : T DOMEvent );
Begin
T extLabel5 . BandIndex := GetEventSource ( Event ). BandIndex ;

OpenForm ( 'ViewOneArticle' , 'BlogMain:MainArticleArea' ,


'"P aramId=' + T extLabel5 . Caption + '"' );
window . scrollT o ( 0 , 0 );
End ;

When working with continuous forms it is important to ensure that the referenced controls
contain information from the desired band. This is achieved by setting the BandIndex property
of the controls, as in the code in listing 2.
It is interesting to note that the TextLabel5 which is located in the form has its visible property
set to be invisible and is only on the form so as to make it easy for us to have access to Id of
each article.

When you click on either the title for the article ( TextLabel1 ) or the "Read more…" option (

Page 352
TextLabel4 ), the event handler shown in listing 2 will be called and will switch the content of
the MainArticleArea subform in form BlogMain from the ArticleSummaryList form to the
ViewOneArticle form. This will allow the user to read the full article, instead of its summary.

Also, of interest in this small code sample is the use of the window.scrollTo method which
scrolls the browser window back to the top. This ensures that the user will be able to start
reading the desired article, without having to scroll back to the top, manually.

ViewOneArticle. Reading a full article…


The ViewOneArticle form is very simple, displaying the Article ’ s title and full body. It is through
this form, when it is displayed inside the BlogMain form ’ s MainArticleArea subform, that the
user will be able to read a complete article.

Figure 6 – The ViewOneArticle form.

In this form the only existing code is associated with the onClick event of the "Return to
Home" link which is the TextLabel4 control. This code returns you to the default view of the
blog, by switching the content of the MainArticleArea subform in form BlogMain from the
ViewOneArticle form to the ArticleSummaryList form. You can see this code in Listing 3.

Listing 3 – Code for the "Return to Home" option in the ViewOneArticle form.

P rocedure
ViewOneArticle . T extLabel4Click ( Event : T DOMEvent );
Begin
OpenForm ( 'ArticleSummaryList' , 'BlogMain:MainArticleArea'
, '' );
End ;

This form uses a Query called GetOneArticle as its data source. This query has one parameter
which is passed to the form when it is opened as can be seen in Listing 2.

This query is visually designed and defined as:

SELECT ALL
"Articles" . "T itle" , "Articles" .
"DateP ublished" ,
"Articles" . "Id" , "Articles" . "Body"
FROM
"Articles"
WHERE
"Articles" . "Id" = P aramId

AuthorProfile. Information about the Blog’s Author


The AuthorProfile form is very simple in nature. All this form does is display a couple of fields
from the BlogInfo table which contain the author ’ s name and a short bio. This information is

Page 353
displayed in a separate form just for formatting convenience.

Figure 7 – AuthorProfile form.

SideBar. Easy access to shortcuts…


The SideBar form is used for formatting convenience, providing a thin border around the forms
it will host in its subforms. This form contains three subforms which will display the following
forms: FavoriteLinks , RecentArticlesList and ArchiveList . Each one of these forms will be
discussed separately in further detail.

Figure 8 – SideBar form.

FavoriteLinks. Recommended links…


The FavoriteLinks form is used for displaying a list of links which the Author is recommending.
This form follows an exact formatting standard along with forms RecentArticleList and
ArchiveList .

Figure 9 – FavoriteLinks form.

In this form you can see a TextLabel control displaying the text "LinkURL". This control, ( URL
TextLabel) is data-bound to the LinkURL field of the Links table and has its visible property set
to false. This is useful when the LinkLabel TextLabel that shows the name of the link is clicked,
so that the appropriate URL is available. The code for handling the OnClick event of LinkLabel is
as follows.

Listing 4 – Code for the OnClick 'event of the LinkLabel 'control.

Page 354
P rocedure
FavoriteLinks . LinkLabelClick ( Event : T DOMEvent );
Begin
Url . BandIndex := GetEventSource ( Event ). BandIndex ;
Window . open ( Url . Caption , '_self' , '' );
End ;

RecentArticlesList. Recommended links…


The RecentArticlesList form is used for displaying a list of the 10 most recent posts in the blog.
This form follows an exact formatting standard along with forms FavoriteLinks and ArchiveList .

Figure 10 – RecentArticleList form.

In this form you can see a TextLabel control displaying the text "Id". This control, ( IDLabel
TextLabel) is data-bound to the Id field of the Links table and has its visible property set to
false. This is useful when the IdLabel TextLabel that shows the name of the link is clicked, so
that the appropriate URL is available. The code for handling the OnClick event of IdLabel is as
follows.

Listing 5 – Code for the OnClick 'event of the IdLabel 'control.

P rocedure
RecentArticlesList . LinkLabelClick ( Event : T DOMEvent );
Begin
IdLabel . BandIndex := GetEventSource ( Event ). BandIndex ;
OpenForm ( 'ViewOneArticle' , 'BlogMain:MainArticleArea' ,
'"P aramId=' + IdLabel . Caption + '"' );
window . scrollT o ( 0 , 0 );
End ;

ArchiveList. Archive of old articles…


The ArchiveList form is used for displaying a list of all the years and months in which posts
were made in the blog. This form follows an exact formatting standard along with forms
FavoriteLinks and RecentArticlesList .

Page 355
Figure 11 – ArchiveList form, showing a grouping header and footer.

As you can see in Figure 11 this form also employs sorting and grouping in order to present
the desired interface elements to the end user of the blog. The ArchiveList form will display a
list of years with an indented list of months, for all the dates in which a post was made to the
blog.

This form uses as its data source the visually designed query ArchiveQuery , which is defined
as:

SELECT ALL
"Articles" . "T itle" ,
"Articles" . "Summary" ,
"Articles" . "DatePublished" ,
xsDay ( "DateP ublished" ) AS
"x" ,
"Articles" . "Id" ,
xsYear ( "DateP ublished" ) AS
"y"
FROM
"Articles"

As in the other we have just seen, ArchiveList also has an invisible TextLabel control which is
data-bound to the Id field of the Articles table. This is useful when a user clicks on the title of
an article, to specify which article should be brought up in the ViewOneArticle form, inside the
MainArticleArea subform of form BlogMain .

In this form, the LinkLabel control has the following code associated to its onClick event.

Listing 6 – Code for the OnClick 'event of the LinkLabel 'control in form ArchiveList .

P rocedure
ArchiveList . LinkLabelClick ( Event : T DOMEvent );
Begin
IdLabel . BandIndex := GetEventSource ( Event ). BandIn
dex ;
OpenForm ( 'ViewOneArticle' , 'BlogMain:MainArticleArea'
,
'"P aramId=' + IdLabel . Caption + '"' );
window . scrollto ( 0 , 0 );
End ;

AdminMain. General site administration...


The AdminMain form is responsible for the general layout of information in the administration
portion of the blog website. This form employs a TabControl in order to allow for easy access
to all the necessary options for maintaining the website.

Just as with the BlogMain form, the AdminMain form uses several subform controls to host
other forms. The three images that you can see in figures 12 to 14 show how each of the tabs
in the TabControl are laid out, each TabSheet with a subform control taking all its internal
space.

Page 356
Figure 12 – AdminMain form showing the Posts TabSheet.

Figure 13 – AdminMain form showing the Profile TabSheet.

Figure 14 – AdminMain form showing the Links TabSheet.

The AdminMain form has basically a layout definition purpose. The only code in the AdminMain
form is associated to the OnClick event of the ViewBlog TextLabel control which can be found
inside its header band, on the right hand side. This code switches the content of the FullSite
subform of the Index form, to BlogMain , thus leaving the Administration part of the website. In

Page 357
order to make sure that the blog ’ s interface correctly displays any data that was changed
while in the Administration section, a refresh of the blog ’ s main form, BlogMain , is requested
by usage of the "OpenMode=Refresh" parameter on the call to OpenForm .

Listing 7 – Code to switch back to the main blog area of the website.

P rocedure AdminMain . ViewBlogClick ( Event : T DOMEvent );


Begin
OpenForm ( 'BlogMain' , 'Index:FullSite' ,
'"OpenMode=Refresh"' );
End ;

Each of the TabSheets in the TabControl in form AdminMain contains a subform which is
statically bound to one of the following forms: CreateEditPosts , CreateEditLinks and EditProfile .

CreateEditPosts. Adding and maintaining articles of the blog


This form is bound to the Articles table and allows you to add new articles or edit pre-existing
ones.

Figure 15 – The CreateEditPosts form.

The CreateEditPosts form displays the Navigator in its footer band, allowing for a full range of
database functions. In order to display the Navigator of a data bound form, configure the
Navigator property of the footer band of the form.

EditProfile. Maintaining the author’s profile


The EditProfile form allows for the editing of a single record in the BlogInfo table. This table
holds some basic information about the blog and its author and should never have more than
one record.

Page 358
Figure 16 – The EditProfile form.

As you can see in Figure 16, the EditProfile form displays a reduced version of the Navigator in
its footer band. In order to achieve this sort of effect you should configure the navigator
property of the footer band, as previously mentioned.

CreateEditLinks. Adding and maintaining favorite links


This form is bound to the Links table and allows you to add new articles or edit pre-existing
ones.

Figure 17 – The CreateEditLinks form.


The CreateEditLinks form is very simple, only allowing the author to maintain a list of links
described by a name and a URL.

Wrapping it up
The main objective of creating the application shown in this chapter was to demonstrate that
it is possible to create applications which are quite sophisticated and benefit from a full Ajax
implementation, in Morfik, while writing very little code.

Most of the code in this project is actually IDE generated, such as the class declarations, while
only a handful of lines were actually hand coded.

category:Programming

Page 359
Fetching data
programmatically from
Tables

Introduction
I am interested in customizing requesting and persisting data from the client side. Is there a
good place I can see an example of a javascript call that requests data and a call that
persists data that has been changed? That is, how can I request data from a database
"Morfik" style from the client and what form does this data appear. I want to write Javascript
that will request data from Morfik managed database connections (on the server) and tie
those results to other JS libraries on the client.

Said another way, I have an external Javascript library that I would like to use. I would like to
populate those controls with data from the database on the Xapp server side ODBC
connection. I assume there is a standard way that the client (browser) requests data (maybe
a query), and the result of that requested data is serialized on the server, returned to the
client, and deserialized into javascript datastructures that the current data aware Morfik
widgets use (the ones that are data bound). I would rather use the "Morfik Way" of
requesting that data from the client side than use another method, such as JSON, to send the
data. I want to keep it consistent in case I create control to control exchange of data.

Where can I find examples of what it is I want to do? I imagine it is possible, since somehow
Morfik does it for it's data aware controls.

Part 1
he following will take you through an example of fetching data from a table, the way that
Single Forms do it.

Consider having a table (Table1) with 3 columns (say, xxx,yyy and zzz) and a few rows of
data. The TBrowserDataSet object in the SystemControls unit in the Framework is what we
need to grab data from the server.

Since this object is written for Single Forms it doesn't take into account situations in which it
could be used by other things than Single forms. Here I've written a small unit which makes
the TBrowserDataSet ready for our use, so from now we have the TBrowserDatasetExt.

Unit DataBaseBridge;

Interface

Uses
SystemControls;

T ype

{..............................................................................}
T DataRequesterExt = Class(T DatasetRequester)
Procedure HandleResponse; Override;
End;
{..............................................................................}

{..............................................................................}
T BrowserDatasetExt = Class(T BrowserDataset)
DataRequestSoapClient : T DataRequesterExt;
Constructor Create(aOwnerForm : Form; aPageFilter,aP ageP arameters : String; aDataSource : String);
End;
{..............................................................................}

Page 360
Implementation

{..............................................................................}
P rocedure T DataRequesterExt.HandleResponse;
Begin
If Assigned(OnWebMethodReturn) T hen
OnWebMethodReturn();
End;
{..............................................................................}

{..............................................................................}
Constructor T BrowserDatasetExt.Create(aOwnerForm : Form; aPageFilter,aP ageP arameters : String; aDataSource :
String);
Begin
Inherited Create(aOwnerForm,aPageFilter,aP ageP arameters,aDataSource);
DataRequestSoapClient.Destroy;
DataRequestSoapClient := T DataRequesterExt.Create(Self);
End;
{..............................................................................}

End.

Part 2
In your code when you want to fetch data you must first download the snippet of Javascript
which represents a Table into the browser. The name of the Javascript file is '_ + TABLENAME
+ RTTI'. You can see the way to download the JavaScript in the Button1Click function.

Looking at the Uses statements in unit below, you will notice a _Table1RTTI unit. This unit is
automatically generated by the compiler. You need to import this so you can get the type
information of a table columns in Browser.

Unit Index;

Interface

Uses
DatabaseBridge,
_T able1RT T I;

T ype

{..............................................................................}
Index=Class(Form)
Button1 : Button;
Procedure Button1Click(Event: T DOMEvent); Message;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
DataSet : T BrowserDatasetExt;
Procedure CallBack;
Procedure GotData;
End;
{..............................................................................}

Implementation

Page 361
{..............................................................................}
P rocedure Index.Button1Click(Event: T DOMEvent);
Begin
Xapp.LoadModule('_T able1RT T I',@Self.CallBack);
End;
{..............................................................................}

{..............................................................................}
P rocedure Index.CallBack;
Begin
DataSet := T BrowserDatasetExt.Create(Self,'','','T able1');
DataSet.DataRequestSoapClient.OnWebMethodReturn := @Self.Got
Data;
DataSet.Refresh;
End;
{..............................................................................}

{..............................................................................}
P rocedure Index.GotData;
Var
Rec : T able1Record;
i : Integer;
Begin
For i := 0 to DataSet.DBList.Count - 1 Do
Begin
Rec := T able1Record(DataSet.DBList[i]);
ShowMessage('Column XXX: ' + Rec.xxx);
End;
End;
{..............................................................................}

End.

View this in action


There is a project on the Labs call "data-bound custom control", which uses the above
technique. Furthermore, its code is a little more refined..

See also
 Tips

 Tutorials

External links
 Morfik Forum: data abstraction

 Morfik Labs: data-bound custom control


Category:Database

Category:Programming

Page 362
Calling Morfik functions from
JavaScript

Introduction
From time to time you will want to drop to JavaScript to perform various operations (like when
you use a third-party JavaScript library). In those cases you may want to call a Morfik function
or method. How can it be done?

Calling Functions
Let’s see first how Morfik functions (and procedures) can be called:

function AFunctionT oCall(x, y: Integer; s: String) : Integer; ['Obfuscate=false','Optimize=


false'];
Begin
Result := x+y;
End;

function GetFuncResult: Integer; JavaScript; (*!


return AFunctionT oCall(34, 26, "hello");
*)

Very simple.

Explanation
Arman Mirkazemi has a few instructions, though:

It is possible to call Morfik functions from Javascript.

Firstly, you need to make sure that the compiler does not obfuscate the function name by
placing a compiler tag:

['Obfuscate=false']
;

infront of your function declaration.

Secondly, the JavaScript optimizer is designed to remove code that does not get called
anywhere in the application. When turned on, the JavaScript optimizer produces a lighter
weight JavaScript code to send to the browser.

To stop the optimizer from taking your function out you must add one more compiler tag
infront of your function declaration.

['Obfuscate=false','Optimize=false'
];

Calling Methods
OK. Now let’s see Morfik methods. They are a bit different, since you have to make sure that
self/this is set up properly:

Page 363
T ype
T T estClass = Class(T Object)
s: String;
i: Integer;
f: Double;

constructor Create;
function GetIMultipliedBy(x, y, z: Integer): Integer;
end; ['Obfuscate=false'];

constructor T T estClass.Create;
begin
s := 'apple';
i := 42;
f := 3.1415926;
end;

function T T estClass.GetIMultipliedBy(x, y, z: Integer): Integer;


begin
Result := i * x * y * z;
end;

function GetMethodResult(p: P ointer): Integer; JavaScript; (*!


return p(2,10,100);
*)

function getSimpleMethodP ointer(o,m: P ointer): P ointer; JavaScri


pt; (*!
if(m)
return function(){
return m.apply(o, arguments);
}
else
return null;
*)

P rocedure Index.ButtonT estClick(Event: T DOMEvent);


Var
tc: T T estClass;
s: String;
Begin
salamon := 'hello world';
tc := T T estClass.Create;
s := tc.s + '';
s := s + T JObject(tc).toString + '';
s := s + tc.ClassName + '';
s := s + IntT oStr(GetMethodResult(
getSimpleMethodP ointer(tc, @tc.GetIMultipliedBy)
));
tlT C.Caption := s;
End;

The tricky part is getSimpleMethodPointer(). It will return a pointer to the method instance
(technically it creates an anonymous function that calls the function on the class with all the
parameters it was called with). Please note that there is a similar Morfik function called
getMethodPointer(), but that does not handle multiple parameters at the moment and is also
fiddling with the bandindex that takes CPU cycles, so I prefer to use this one, if I know I’m not

Page 364
on a continuous form. And it cannot work on normal functions or class methods either (see
later).

BTW with this solution you do not need to turn off Obfuscation, since you will pass the actual
(obfuscated) name of the object and method to the function at runtime, as opposed to the
previous function call, where the compiler will not replace inside the JavaScript routine the
name of the Morfik function with the obfuscated version (wow! Simple, is it!?;-). So you could
do a similar trick with non-method functions by doing this: getSimpleMethodPointer(Nil,
AFunctionToCall); This would also eliminate the need for the DefeatTheOptimizer function,
since you do refer to the function-to-be-called-from-JavaScript, so the optimizer will not
eliminate it. Of course, you have to alter the JavaScript function to take the
function-to-be-called-from-JavaScript as a parameter. You can call class methods (ones that
don’t need an instance) the same way, by passing Nil as the first parameter.

Update - getSimpleMethodPointer() explanation


It turned out that I skipped some details on the parameters of getSimpleMethodPointer(), so
let’s remedy that now:
o is an object instance (address) upon which you
 want to call the method and
m is the method (address) of the object you want to call (always use the address-of (@)
 operator to play on the safe side).
First this seems straightforward, but! Let’s see a confusing example:

procedure AJavaScriptFunction(s : string; cb: pointer); JavaScript; (*!


cb(s);
*)

procedure Index.CallT heJavaScriptFunction;


begin
AJavaScriptFunction('Morfik rulez', getSimpleMethodPointer(Self, @SendMessa
ge));
end;

procedure Index.SendMessage(sMsg: String);


begin
...
end;

The important part is the getSimpleMethodPointer() call’s first parameter: Self. One could first
simply put Index instead of Self here, but that would be wrong. Why? because Index
represents the class (technically it will become (the name of) a JavaScript constructor function)
and we need instead an object instance here, which in our case is stored in Self. That’s why
in my original example I used tc (which is an object instance) instead of TTestClass (which is
the class). Hope this helps…

BTW (for Delphi chaps) it would be more prudent to use the semi-Hungarian naming
convention for forms, because then Index would be called TIndex, and no one would mistake
it for an instance variable (Var Index: TIndex, anyone?). Aren’t all good things invented by
Hungarians? ;-) Quiz question: why is it called the Hungarian naming convention?

One word on the address-of operator (@): if the function does have parameters then you don
’t have to use it, because the compiler can tell that you want to get the address of the
function, but if your function has no parameters, then (in Pascal) the compiler will guess that
you want to call the function, and getSimpleMethodPointer() will get the return value of the
function, which is not what we wanted. So play on the safe side and use the address-of
operator.

Enjoy! Comments appreciated…

See also
 Tips

Page 365
 Tutorials

External links
To discuss or for updates see piBlog: Morfik Tip: Calling Morfik functions or methods from
 JavaScript
Category:Programming

Page 366
Calling JavaScript from Morfik

Introduction
It was almost a year ago that I wrote about calling JavaScript from Morfik (in Morfik Tips: How
to integrate JavaScript into the client code). That method is still valid and especially suitable
for larger bodies of JavaScript (like libraries), but there is now an easier way of doing this.

Example
Let’s see an example for the new way:

function setOpacity(element:T HT ML_ElementExt; opacity: Integer); ['Obfuscate=false']; JavaSc


ript; (*!
var object = element.style;
object.opacity = (opacity / 100);
object.MozOpacity = (opacity / 100);
object.KhtmlOpacity = (opacity / 100);
object.filter = "alpha(opacity=" + opacity + ")";
*)

function getOpacity(element:T HT ML_ElementExt): Integer; ['Obfuscate=false']; JavaScript; (*!


var object = element.style;
return (object.opacity);
*)

You can simply copy the above function into your Pascal source file (browser side;-) and then
you can call it passing the DOMHandle of any visual control together with an opacity value (in
the range of 0-100) to set the element’s opacity, regardless of browser.

Explanation
Let’s look at the syntax:
The function declaration part can be pretty much the same as with any
ordinary Morfik function (in the Pascal dialect you can use “function”
 instead of “procedure”, if you wish).
Then we have the ’Obfuscate=false’ ; annotation that will direct the code generator to not
 obfuscate the function.
Then we have the JavaScript; directive that tells the compiler that this is
 a JavaScript routine.
Then comes the actual
JavaScript, enclosed in
the special comment tag
 (*! … *).
You can return the result of the function with the
 standard JavaScript return statement.
It is very simple to call JavaScript this way from our code, but please keep in mind that the
compiler cannot check the JavaScript code, so keep as much as possible in
Pascal/Basic/C#/Java and use these techniques only when absolutely needed. Fortunately, as
the Morfik Framework matures there are fewer and fewer cases when you have to…

See also
 Tips
 Tutorials

External Links

Page 367
 To discuss or for updates see piBlog: Morfik Tip: Calling JavaScript form Morfik Take #2
Category:Programming

Page 368
Handling MouseOver and MouseOut
efficiently

Introduction
I owe you with an article on AnalogClock internals, but today we are in for a quick tip. What I
wanted to do is: create a hover effect (i.e. the entire row is highlighted when the mouse is
over) for continuous forms.

Explanation
First I put a Container on the continuous form and placed all the other text controls and
checkboxes and others on the Container (since the Detail does not have OnMouseOver/Out
events), then set up the Container for OnMouseOver and OnMouseOut. It fundamentally
worked, but the hovering effect was slooow and sometimes did not even register on some of
the lines (depending on how fast I moved the mouse pointer).

I though the issue was related to the way the controls contained by Container bubble these
events to Container. So I simply set the OnMouseOver/Out event handlers for all controls to
the same event handlers and bingo! now it works properly. The exact code sample is below:

P rocedure T estForm.InfoContainerMouseOut(Event: T DOMEv


ent);
Begin
SwitchBandIndex( Event );
InfoContainer.DOMStyle.backgroundColor := 'White';
End;

P rocedure T estForm.InfoContainerMouseOver(Event: T DOME


vent);
Begin
SwitchBandIndex( Event );
InfoContainer.DOMStyle.backgroundColor := 'LightBlue';
End;

Now there are two more items I have to explain:


SwitchBandIndex() will do some magic for
continuous forms, making sure that by using
controls like InfoContainer you will access the
right instance of that control (since there are as
many instances, as many bands/lines in your
 continuous forms are);
DOMStyle is another magic property of all controls through which you can access and
manipulate the style of the underlying HTML control: here I set the background color of the
 InfoContainer (for the technically more inclined: it is a DIV deep inside).
That’s it. Clean and simple. Now if we could manipulate the :hover pseudo-class easily...

See also
 Tips
 Tutorials

External links
To discuss or for updates see piBlog: piBlog>Morfik Tip: How to handle MouseOver and
 MouseOut efficiently
Category:Presentation

Page 369
Category:Programming

Page 370
Editing a RecordSet

Introduction
I'm wanting to know that correct syntax to edit a record of a recordset inside a while not
rs.eof loop

That is, something like

rs.edit
rs.fieldbyname("fieldname")=...
...
rs.update

Part 1
Following is an example of using the Select and Update SQL statements to update fields in a
table. This is implemented in the execute method of a Webmethod. In this example, the
"OrderStock" field in the Books table is set to 1 if the "UnitsInStock" field has value less than
10 and for BOOKID greater than 5.

P rocedure WebMethod1.Execute;
Var
BooksRS : T RecordSet;
SQLCommand: T SQLCommand;
Begin
BooksRS := DefaultDBConnection.CreateRecordSet('SELECT "BookID","Binding","OrderStock" FROM "Bo
oks"');
BooksRS.Prepare;
BooksRS.Active := T rue;
BooksRS.First;
While Not BooksRS.EOF Do
Begin
T ry
SQLCommand := DefaultDBConnection.CreateSQLCommand('UPDAT E "Books" SET "OrderStock" =
1'+
' WHERE "UnitsInStock" < 10 AND ' +
' "BookID" > ' + IntT oStr(BooksRS.FieldByName('"BookID"').AsInteger + 5) );
SQLCommand.Prepare;
SQLCommand.Execute;
Except
DefaultDBConnection.DestroySQLCommand(SQLCommand);
End;
BooksRS.Next;
End;
BooksRS .Free;
SQLCommand.Free;
End;

See also
 Tips
 Tutorials

Page 371
External links
 Morfik Forum: editing recordset
Category:Database

Page 372
AutoSubmit a Form

Introduction
Sometimes it is useful to automatically submit the Form contents to the database whenever
the user exits a page (ie opens another one), without requiring the user to manually press
the submit button. One reasonably easy way to achieve this is to define an customized
openForm function that first checks to see if there is anything to submit to the database and
after this, it opens up the new form.

P rocedure Form1.OpenFormExt(NewForm, location, parameters : St


ring);
Begin
If Form1.Dataset.DBSubmitList.Count >0 T hen
Form1.SubmitP age;
OpenForm(NewForm, location , parameters);
End;

No doubt you can make the necessary modifications to this code so that you could put it in a
module (say Globals), thereby allowing you to access it from any of your forms.

See also
 Tips
 Tutorials

External links
 Morfik Forum: Best Way to Autosubmit
Category:Database

Page 373
Changing the appearance
of controls

Introduction
Ever wanted to a control to appear differently than its default look?

For example, you will see that the buttons on www.morfik.com appear different from the
Morfik's default apperance and behavior? How is this done you ask?

Part 1
You can generally modify the style of any control. Here is a small code snippet for altering the
style of a button:

Sub SetMorfikFormatting(B as Butto


n)
Dim F as T Font
B.Attrs.BorderStyle = bsSingle
B.Attrs.BorderColor = $c0c0c0
B.Attrs.Color = $f6f4f4
F.Name = "Verdana"
F.Height = 9
F.Style = []
F.Color = $0000cc
B.Attrs.Font = F
End sub

Part 2
You could also make changes to the style of a button in the server side codes. For example
the following routine gives the button the XP theme look. You need to set the borderStyle
property to bbs3D for the two buttons.

P rocedure frmAccountEdit.DocumentFooterBeforeP rint(Sender: T WebControl; Canvas: T WebCanvas; Var P rint:


Boolean);
Begin
SaveButton.CtrlStyles := SaveButton.CtrlStyles - [csColor, csBorder];
CancelButton.CtrlStyles:= CancelButton.CtrlStyles - [csColor, csBorder];
End;

See also
 Tips
 Tutorials

External links
 Morfik Forum: Changing the appearance of controls
Category:Presentation

Page 374
Keyboard shortcuts

General Formatting and Editing

Function Keyboard shortcut


Copy Ctrl + Insert, Ctrl + C
Cut Shift + Delete, Ctrl + X
Paste Shift + Insert, Ctrl + V
Delete Ctrl + Delete
Select All Ctrl + A
Undo Ctrl + Z
Redo Shift + Ctrl + Z
Search again F3
Replace Ctrl + R

Project and IDE

Function Keyboard shortcut


Help F1
Save Ctrl + S
Close Ctrl + F4
Open Ctrl + O
Toggle Property Sheet visibility F11
Cycle through Design mode F12
Cycle through open Documents Ctrl + TAB
Reverse cycle through open Documents Ctrl + Shift + TAB
Run F9
Rename Project Item F2
Toggle Browser/Server/Designer F12
Find Ctrl + F
Exit Alt + F4

Form Designer

Function Keyboard shortcut


Select Multiple objects Shift + Left Mouse Button
Move selected control(s) by 1 px Ctrl + Arrow keys (Standard)
Arrow keys (Alternative)
Move selected control(s) by 20 px Ctrl + Shift + Arrow Key (Standard)
Shift + Arrow Key (Alternative)
Resize selected control(s) by 1 px Shift + Arrow Key (Standard)
Ctrl + Shift + Arrow Key (Alternative)
disable guidelines snapping when dragging Alt
controls
screenshot capture of current Form to a Scroll Lock
clipboard
Activate Inplace Caption Editor F2
Property Sheet F11
Equivalent to clicking the ellipsis (...) button Ctrl + Enter
Selects Parent Control in design mode Esc

Page 375
Datagrid

Function Keyboard shortcut


Next Field Tab
Next Field Right Arrow
Previous field Shift + Tab
Previous Field Left Arrow
Same field, next record Down Arrow
Same field, previous record Up Arrow
New Record Insert

Debugger

Function Keyboard shortcut


Trace Into F7
Step Over F8
Until Return Shift + F8
Run To Cursor F4
Continue F9
Insert Breakpoint F5
Stop Ctrl + F2

Code Editor, General

Function Keyboard shortcut


Move Cursor to next word Ctrl + Right
Move Cursor to previous word Ctrl + Left
Back to Last Location Alt + Right
Forward to Last location Alt + Left
Exit Alt + F4
Go to Line Number Ctrl + G
Insert Tab Tab
Move to previous Tab Shift + Tab
ToggleMacroRecording Ctrl + Shift + R
PlaybackMacro Ctrl + Shift + P
OpenFileAtCursor Ctrl + Enter
FileBegin Ctrl + Home
FileEnd Ctrl + End
ScreenTop Ctrl + PageUp
ScreenBottom Ctrl + PageDown
Cut Ctrl + X
Paste Ctrl + V
Paste Ctrl + C
FindNext F3
FindPrevious Shift + F3
FindDialog Ctrl + F
ReplaceDialog Ctrl + R
ScrollDown Ctrl + Down
ScrollUp Ctrl + Up
Undo Ctrl + Z
Redo Ctrl + Shift + Z
DeleteToLineEnd Ctrl + Shift + Y
DeleteLine Ctrl + Y
FindNext Ctrl + L
Insert Tab Ctrl + I
NewLine Ctrl + N

Page 376
DeleteWordRight Ctrl + T
Indent Block Ctrl + Shift + I
UnIndent Block Ctrl + Shift + U
Undo Alt + Backspace
Redo Alt + Shift + Backspace
Cut Shift + Del
DeleteBlock Ctrl + Del
Paste Shift + Insert
Copy Ctrl + Insert
Insert ToggleOverwrite
FileBegin Ctrl + Q + R
FileEnd Ctrl + Q + C
DeleteWordLeft Ctrl + Backspace
SelectAll Ctrl + A
StartIncrementalSearch Ctrl + E
CopyBlock Ctrl + K + C
LowerCaseWord Ctrl + K + E
UpperCaseWord Ctrl + K + F
IndentBlock Ctrl + K + I
SelectLine Ctrl + K + L
UpperCaseBlock Ctrl + K + N
LowerCaseBlock Ctrl + K + O
OutdentBlock Ctrl + K + U
SelectWord Ctrl + K + T
DeleteBlock Ctrl + K + Y
CapitalizeBlock Ctrl + K + M
MoveBlockBegin Ctrl + Q + B
MoveFileEnd Ctrl + Q + C
MoveLineEnd Ctrl + Q + D
MoveScreenTop Ctrl + Q + E
MoveBlockEnd Ctrl + Q + K
MoveFileBegin Ctrl + Q + R
MoveLineBegin Ctrl + Q + S
MoveScreenTop Ctrl + Q + T
MoveScreenBottom Ctrl + Q + U
MoveScreenBottom Ctrl + Q + X
Open file at cursor Ctrl + Enter

Note: for Compound key combinations, that is, those combinations that utilize tw
o letters
(eg Ctrl+K+I), you need to press the modifier-keys with the first letter,
quickly followed by the modifier-keys and the second letter.

For example, to indent a block of text, the shortcut is Ctrl_K+I,


which should be implemented as Ctrl+K quickly followed by Ctrl+I.

Code Editor, Computer assisted coding

Function Keyboard shortcut


Code Completion Ctrl + SpaceBar
Display Code parameters/MorfikDoc Ctrl + Shift + SpaceBar
Navigate to method declaration Ctrl + Shift + UpArrow
Navigate to method implementation Ctrl + Shift + DownArrow
ExpandAll Ctrl + Multiply
ExpandCurrent Ctrl + Plus
CollapseAll Ctrl + Divide

Page 377
CollapseCurrent Ctrl + Minus

See also
 Tips

 Tutorials
Category:IDE

Page 378
Exporting a Table to a CSV
file

Introduction
This outlines how to export a Morfik table to a .CSV file.

It takes a Table that is specified at runtime and creates a file on your .CSV file on your hard
disk.

Download project
 This project can be downloaded for easier reference from: MorfikProject_ExportingToCSV.zip
This projects was compiled using
Morfik AppsBuilder Release 1
 (build v1.0.2.5)
In this example, the .CSV file is stored in the same directory as
 your project's files.

Solution
The core unit of this project is contained in two modules, which are invoked via a
WebMethod.

For the WebMethod, the relevant server-side code is:

P rocedure wbsExport.Execute;
Var
aCSVExporter : T CSVExporter;
Begin
aCSVExporter := T CSVExporter.Create(SoapServer.Request, SoapServer.Respo
nse);
aCSVExporter.T ableName := prmT ableName;
aCSVExporter.IncludeSystemFields := T rue;
aCSVExporter.Prepare;
aCSVExporter.Run;
aCSVExporter.Destroy;
End;

For the TableExporter module the relevan server-side code is:

Unit T ableExporter;

Interface

Uses
SystemServer,
SystemUtilities,
SystemDatabase,
SystemClasses;

T ype
{..............................................................................}
T Exporter = Class(T HT T P Server)
T ableName : String;

Page 379
IncludeSystemFields : Boolean;
P rotected
FieldNames : T StringList;
FieldT ypes : T StringList;
Procedure GetT ableFields; Virtual;
Procedure GetFieldT ypes; Virtual;
Function Get_FieldT ype(Name : String) : String;
P ublic
Destructor Destroy; Override;
Procedure Prepare;
Property FieldT ype[Name : String] : String Read Get_FieldT ype;
End;
{..............................................................................}

Implementation

{..............................................................................}
Destructor T Exporter.Destroy;
Begin
FieldNames.Free;
FieldT ypes.Free;

Inherited Destroy;
End;
{..............................................................................}

{..............................................................................}
P rocedure T Exporter.P repare;
Begin
GetT ableFields;
GetFieldT ypes;
End;
{..............................................................................}

{..............................................................................}
P rocedure T Exporter.GetT ableFields;
Var
RecordSet : T recordSet;
SQL,S : String;
Begin
SQL := 'SELECT "RDB$FIELD_NAME","RDB$RELAT ION_NAME","RDB$FIELD_SOURCE" FROM "RDB$
RELAT ION_FIELDS" WHERE "RDB$FIELD_NAME" ' +
'NOT CONT AINING ''$'' AND "RDB$RELAT ION_NAME" NOT CONT AINING ''$'' AND "RDB$RELAT I
ON_NAME" = ''' + T ableName + '''';

RecordSet := DefaultDBConnection.CreateRecordSet(SQL);
FieldNames := T StringList.Create;

T ry
RecordSet.P repare;
RecordSet.First;
RecordSet.Active := T rue;

While Not RecordSet.EOF Do


Begin
S := '';
S := RecordSet.FieldByName('RDB$FIELD_NAME').AsString;
FieldNames.Add(S);
RecordSet.AP INext;
End;

Page 380
Finally
DefaultDBConnection.DestroyRecordSet(RecordSet);

End;
End;
{..............................................................................}

{..............................................................................}
P rocedure T Exporter.GetFieldT ypes;
Var
RecordSet : T recordSet;
SQL,S : String;
Name,FT ype : String;
Begin
RecordSet := DefaultDBConnection.CreateRecordSet('');
FieldT ypes := T StringList.Create;

RecordSet.SQL.Add('SELECT ');
RecordSet.SQL.Add(' "RDB$FIELDS" ."RDB$FIELD_SUB_T YP E" AS "SubT ype",' );
RecordSet.SQL.Add(' "RDB$RELAT ION_FIELDS"."RDB$FIELD_NAME" AS "FieldID",' );
RecordSet.SQL.Add(' "RDB$T YP ES" ."RDB$T YP E_NAME" AS "FieldT ype"');
RecordSet.SQL.Add('FROM');
RecordSet.SQL.Add(' "RDB$RELAT ION_FIELDS",');
RecordSet.SQL.Add(' "RDB$FIELDS",');
RecordSet.SQL.Add(' "RDB$T YP ES"');
RecordSet.SQL.Add('WHERE');
RecordSet.SQL.Add(' "RDB$FIELDS"."RDB$FIELD_NAME" = "RDB$RELAT ION_FIELDS"."RDB$FIELD_SO
URCE" AND');
RecordSet.SQL.Add(' "RDB$FIELDS"."RDB$FIELD_T YP E" = "RDB$T YP ES" ."RDB$T YP E" AND');
RecordSet.SQL.Add(' "RDB$T YP ES"."RDB$FIELD_NAME" = ''RDB$FIELD_T YP E'' AND');

If Not IncludeSystemFields T hen


RecordSet.SQL.Add('"RDB$RELAT ION_FIELDS"."RDB$FIELD_NAME" NOT CONT AINING ''$'' AND');

RecordSet.SQL.Add(' "RDB$RELAT ION_FIELDS"."RDB$RELAT ION_NAME" = ''' + T ableName + '''');


RecordSet.SQL.Add('ORDER BY');
RecordSet.SQL.Add(' "RDB$RELAT ION_FIELDS"."RDB$FIELD_NAME" ASC');

T ry
RecordSet.P repare;
RecordSet.First;
RecordSet.Active := T rue;

While Not RecordSet.EOF Do


Begin
Name := RecordSet.FieldByName('"FieldID"' ).AsString;
FT ype := RecordSet.FieldByName('"FieldT ype"').AsString;

If Ftype = 'BLOB' T hen


If RecordSet.FieldByName('"SubT ype"').AsString = '1' T hen
FT ype := 'T EXT ';

FieldT ypes.Add(Name + '=' + FT ype);


RecordSet.AP INext;
End;
Finally
DefaultDBConnection.DestroyRecordSet(RecordSet);
End;
DebugOut(FieldT ypes.T ext)
End;

Page 381
{..............................................................................}

{..............................................................................}
Function T Exporter.Get_FieldT ype(Name : String) : String;
Begin
Result := FieldT ypes.Values[Name];
End;
{..............................................................................}

End.

For the CSVExport module the relevant code is:

Unit CSVExport;

Interface

Uses
System,
SystemUtilities,
SystemDatabase,
SystemDatabaseIBO,
T ableExporter;

T ype
{..............................................................................}
T Field_T ype = (ftBLOB,ftT ext,ftINT EGER,ftDAT E, ftDOUBLE);
{..............................................................................}

{..............................................................................}
T CSVExporter = Class(T Exporter)
P rivate
PrintFile : T extFile;
RecordSet : T RecordSet;
Function PrintHeadings;
Function PrintData;
Function FormatString(aString : String) : String;
Function QueryT able;
Function GetFieldT ype(Name : String) : T Field_T ype;
P ublic
Procedure Run;
End;
{..............................................................................}

Implementation

{..............................................................................}
P rocedure T CSVExporter.Run;
Begin
AssignFile(PrintFile,T ableName + '.csv');
Rewrite(P rintFile);
PrintHeadings;
QueryT able;
PrintData;
CloseFile(P rintFile);
End;
{..............................................................................}

Page 382
{...............................................................................}
Function T CSVExporter.FormatString(aString : String) : String;
Var
Str,S : String;
k : Integer;
Begin
Str := aString;
S := '';
If Str <> '' T hen
Begin
Repeat
k := P os('"',Str);
If k <> 0 T hen
Begin
S := S + Copy(Str,1,k) + '"';
Delete(Str,1,k);
End
Else
Begin
S := S + Str;
Str := '';
End;
Until Str = '';
S := '"' + S + '"';
End;
Result := S;
End;
{...............................................................................}

{..............................................................................}
Function T CSVExporter.P rintHeadings;
Var
i : Integer;
S : String;
Begin
If FieldNames = Nil T hen DebugOut('FieldNames is nil');
S := '';
For i := 0 to FieldNames.Count - 1 Do
Begin
If S <> '' T hen S := S + ',';
S := S + FormatString(FieldNames[i]);
End;
WriteLn(PrintFile,S);

End;
{..............................................................................}

{..............................................................................}
Function T CSVExporter.QueryT able;
Begin
RecordSet := DefaultDBConnection.CreateRecordSet('SELECT * FROM "' + T ableName
+ '"');
T ry
RecordSet.P repare;
RecordSet.First;
RecordSet.Active := T rue;
Except
End;

End;

Page 383
{..............................................................................}

{..............................................................................}
Function T CSVExporter.GetFieldT ype(Name : String) : T Field_T ype;
Var
S : String;
Begin
S := FieldT ype[Name];
If S = 'VARYING' T HEN Result := ftT ext Else
If S = 'T EXT ' T HEN Result := ftT ext Else
If S = 'BLOB' T HEN Result := ftBLOB Else
If S = 'LONG' T HEN Result := ftINT EGER Else
If S = 'INT 64' T HEN Result := ftINT EGER Else
If S = 'SHORT ' T HEN Result := ftINT EGER Else
If S = 'DAT E' T HEN Result := ftDAT E Else
If S = 'T IME' T HEN Result := ftDAT E Else
If S = 'T IMEST AMP ' T HEN Result := ftDAT E ELSE
If S = 'FLOAT ' T HEN Result := ftDOUBLE Else
If S = 'DOUBLE' T HEN Result := ftDOUBLE ;
End;
{..............................................................................}

{..............................................................................}
Function T CSVExporter.P rintData;
Function NeedsQuotes(S : String) : Boolean;
Var
i : Integer;
Begin
For i := 0 to Length(S) - 1 Do
If S[i] > 'Z' T hen
Begin
Result := T rue;
Exit;
End
End;

Function GetAsT ext(Field : T DBField) : String;


Begin
Result := FormatString(Field.AsString);
End;

Function GetAsInteger(Field : T DBField) : String;


Begin
Result := Field.AsString;
End;

Function GetAsDate(Field : T DBField) : String;


Begin
Result := FormatDateT ime('dd/mm/yyyy hh:nn:ss',Field.AsServerDateT ime,0);
Result := FormatString(Result);
End;

Function GetAsBlob(Field : T DBField) : String;


Begin
Result := '';
End;

Function GetAsDouble(Field : T DBField) : String;


Begin
Result := FloatT oStr(Field.AsDouble);

Page 384
End;

Var
Field : T DBField;
Name : String;
i : Integer;
S : String;
Begin
While Not RecordSet.EOF Do
Begin
S := '';
For i := 0 to FieldNames.Count - 1 Do
Begin
If i > 0 T hen S := S + ',';

Name := FieldNames[i];

If NeedsQuotes(Name) T hen Field := RecordSet.FieldByName('"' + Name + '"')


Else Field := RecordSet.FieldByName(Name );

Case GetFieldT ype(Name) Of


ftBLOB : S := S + GetAsBlob (Field);
ftT ext : S := S + GetAsT ext (Field);
ftINT EGER : S := S + GetAsInteger(Field);
ftDOUBLE : S := S + GetAsDouble (Field);
ftDAT E : S := S + GetAsDate (Field);
End;
End;
WriteLn(P rintFile,S);
RecordSet.APINext;
End;
End;
{..............................................................................}

End.

See also
 Tips

 Tutorials
Category:Database

Category:Programming

Page 385
Updating MySQL Tables
based on nested Queries

Introduction
Following is the complete code for the server side module of a Morfik WebMethod that shows
how to update a mySQL Table based on the result of a Query (qryComplex) that is built on
multiple nested queries. Similar routines can be applied for any external database that is
using ODBC connectivity. Slight changes may need to be made to the SQL text depending on
the DB engine.

Part 1
This example is based on the World MySQL sample database (downloadable from mySQL
website). It show how to iterate through the records of a complex query and depending on a
certain value (in this case if CountryCode field in the query is GBR), the District field in the City
table is updated. It has been tested and works as expected.

Written in Morfik Pascal:

Unit wbmUpdateCity;

Interface

Uses
SystemDatabasedb;
T ype
{..............................................................................}
wbmUpdateCity=Class(WebMethod)
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }

Procedure UpdateCityDistrict(CountryCode : String; mydb : T Database);


Procedure Execute; override;
End; ['Published=False'];
{..............................................................................}

Implementation

{..............................................................................}
Uses
SystemCatalog,
SystemConnectors,
SystemConnectorsODBC,
SystemDatabaseSQLdb;
{..............................................................................}
P rocedure wbmUpdateCity.UpdateCityDistrict(CountryCode : String; mydb : T Database);
Var
sqCityT able: T SQLQuery;
Begin
sqCityT able:= Nil;
T ry
sqCityT able:= T SQLQuery.Create(Nil);
sqCityT able.Database := mydb;

Page 386
sqCityT able.SQL.T ext := 'UPDAT E `city` SET `District` = CONCAT (`District`,''UP DAT ED'') Where `Country
Code` ='+''''+CountryCode+''''+'';
sqCityT able.P repare;
sqCityT able.ExecSQL
Finally
sqCityT able.Free;
End;
End;
{..............................................................................}

{..............................................................................}
P rocedure wbmUpdateCity.Execute;
Var
Query : T SQLQuery;
SQL : String;
mydb : T Database;
Begin
Query := Nil;
T ry
mydb := T ODBCServiceConnection(T ODBCServiceConnector(Catalog.GetServiceConnectorByID('ODBC1')).
CreateConnection).Connection;
Query := T SQLQuery.Create(Nil);
T ry
Query.Database := mydb;
Query.SQL.T ext := GetQuerySQL('qryComplex');
Query.P repare;
Query.Open;
Query.First;
While Not Query.Eof Do
Begin
If StringsEqual(Query.FieldByName('Code').AsString,'GBR') T hen
UpdateCityDistrict(Query.FieldByName('Code').AsString,mydb);
Query.Next;
End;
Finally
Query.Free;
mydb.Free;
End;
Except
End;
End;
{..............................................................................}

End.

See also
 Tips
 Tutorials

External links
 Morfik Forum: UPDATE Mysql table with a recordset from a nested query
Category:Database

Page 387
Using NOW in a Query

Introduction
Do you need to make a query that shows only records with the field "mydate" greater than
NOW ?

Here's how to do it.

Just type in the criteria box for the field you wish to filter by the following: >xsNow()

Here is a sample of what your query's code will look like (on the SQL tab):

SELECT ALL
"Articles"."Id",
"Articles"."T itle",
"Articles"."DatePublished"
FROM
"Articles"
WHERE
"Articles"."DatePublished" > xsNo
w()

Also,if it is a Firebird database, you can use: " mydate < current_timestamp "

See also
 Tips
 Tutorials

External links
 Morfik Forum: Using NOW in a Query
Category:Database

Page 388
Validating an input field

Introduction
It is often that you have a numeric field that requires input validation before it is submitted in
a database.

There are two alternative ways of doing this in Morfik WebOS AppsBuilder:
1 At the Form (or control) design-level
2 In the Table design-level via the Validation Rule mechanism
You can use both any method but the implementation at the Form or Control levels gives you
a better control on the feedback to the users when incorrect value is entered.

The following methods outline how you can implement numeric validation to ensure that the
input value is between 10 and 100.

Field Validation at the Form or control level


In a Single form, where you edit table details, if you only wish to implement validation for a
single control then you could do define an OnChange event for the particular TextEdit, but if
you wish to do validation for a set of controls on the Form then it may be more effective to do
it all at once at the Form level, in on OnBeforeSubmit event.

This code framework is an example of how you could implement numeric validation at the
control level. It can be obviously modified for a Form-level event handler.

P rocedure MyForm.MyT extEditChange(Event: T DOMEvent);

Var
i : Integer;
Begin
T ry
i := StrT oInt(T extEditNumber1.T ext);
If (i<10) or (i>100) T hen
ShowMessage('P lease enter a number between 10 and 10
0.');
Except
// T his will be invoked if they don't enter numbers.
ShowMessage('Please enter a number between 10 and 100
.');
Exit;
End;
End;

It may initially be intuitive to use the keyup and keydown event handlers of controls to assess
the pressed key, however because people could type very fast, most browser
implementations (including both Internet Explorer and Firefox) can not always keep up with
firing up of the Keyup/down events, thus your validation may miss some unwanted
characters. The OnBlur event handler of controls is the event which is fired up when the user
switches focus by just clicking away.

This code framework is an example of how you could implement alphabetic validation at the
control level.

P rocedure Index.T extEdit1Blur(Event: T DOMEvent);


Var
T emp : String;

Page 389
i : Integer;
Begin
T emp := T extEdit1.T ext;
i := 1;

While i <= Length(T emp) Do


Begin
if (T emp[i] < 'A') OR (T emp[i] > 'z') T hen Delete(T e
mp,i,1)
Else Inc(i);
End;

T extEdit1.T ext := T emp;


End;

Field Validation at the Table level


Alternatively at Table design level, you could place following

"MyField" BET WEEN 10 AND 1


00

in the Validation rule for a field called MyField

Notes:
You must include the double quotes around the
 field name.
If an incorrect value is entered using this method, you will get a database engine error
 message which may not be clear to the user.

External links
 Morfik Forum: TextEdit and key press

See also
 Tips
 Tutorials
Category:Database

Category:Programming

Page 390
Editing and Searching
Data

This topic will provide you with a general overview of how to maintain data in your
application/website. Up to this point we have seen how to create the
end-user/visitor ’ s point of view. Now we are going to have a look at how to add
and edit the data that drives this application. This topic describes functionalities
which are not available in Morfik Browser Application projects. It is important to
note that the features described in this topic depend on portions of server-side
code from the Morfik Framework, and are thus not available in Morfik Browser
Application projects.

Managing Content
The Data Editing Forms
The EditSections Form
Choosing Control Type in the
Wizard
The EditSections Data Source
The EditArticles Form
The EditArticles Data Source
The EditUsers Form
The EditSiteInformation Form
The EditSiteInformation Data
Source
Adding Search Capabilities to a Form
Editing Data Without a NavigationBar
Filtering Data from a Table
The EditOneArticle Form
Wrapping it up
See Also

Managing Content
In our current example, MorfikCMS, we have made some effort to make sure that the end-user/visitor
’ s view of the content looked like a normal website, despite Morfik ’ s employment of Ajax
everywhere. In this part of this guide maintaining this "normal" website look will not be goal, instead
we are going to address this task directly, using as much of the Morfik Framework ’ s built in
functionality as possible.

Another topic in this documentation has already covered the user authentication process for the
MorfikCMS project. This process is fundamental in making sure that unauthorized users cannot alter
your website ’ s content, so all that we are going to see in this topic lies behind the authentication
barrier of our application. That means that only after the users sign-in will they be allowed to see the
link which will take them into the site management section of the application.

Figure 1 highlights the Site Management link which appears in the site ’ s footer once the user has
been authenticated. This link takes the user into what might seem to be an entirely different website
from the portions which are publicly accessible. The general layout remains the same since, in fact,
we are only changing which two Forms are displayed in the two SubForms of the Index Form.

Once the user chooses to enter Site Management the displayed content in the LeftArea SubForm
changes to the AdminSideBar Form and in the MainArea SubForm it changes to the EditSections Form.

Page 391
Figure 1 – The "Site Management" link in the application ’ s Footer.

The AdminSideBar Form which handles navigation within the Site Management portion of the
MorfikCMS project is actually a quite simplified version of the SideBar Form we are using in the public
section of the application. AdminSideBar is a fully static Form, with no database binding of its own.
Though it looks quite similar to the SideBar Form it employs common buttons instead of the TextLabel
+ Container scheme used in the SideBar Form, since this portion of the website is more focused on
being practical than in design.

Figure 2 shows the AdminSideBar Form. Notice that the color scheme is a bit different from the one
used in the SideBar Form due to the different nature of the controls used.

Page 392
Figure 2 – The AdminSideBar Form in design mode in Morfik Workspace.

On entering Site Management the EditSections Form is displayed in the MainArea SubForm is displayed
in the MainArea Form because "Sections" is the first option to appear in the list of the AdminSideBar
Form as seen in Figure 2. In this case it is obviously better to display that view than it would have
been to maintain the original content which would have been displayed in MainArea since this way it
is very clear that the user has entered the Management portion of the application. Figure 3 shows
the initial view of the "Site Management" portion of the application.

Figure 3 – Initial view of the Site Management portion of the MorfikCMS project.

Page 393
The Data Editing Forms
The MorfikCMS project will have 4 data editing Forms within its "Site Management" area: EditSections ,
EditArticles , EditUsers and EditSiteInformation . All these Forms are automatically generated through
the "Create New Form" Wizard and then lightly customized to achieve the effect we desire.

We will go through the customization done to the EditSection Form, in more detail, to explain what
was done and to what effect. The remaining Forms went through exactly the same customization
steps, except for the EditSiteInformation Form which requires a slightly different approach due to the
unique situation of handling a table which should always have a single record.

The EditSections Form


As previously mentioned the EditSections Form was automatically generated through the use of the
"Create New Form" Wizard and then slightly customized. The more obvious customization which is
the Title and images in the Header band is totally cosmetic and has no effect on the usage of the
Form, except to make clear to the user what the data which is currently being edited is.

The next customization much more important since it allows us to introduce a Morfik Framework
feature which is quite useful in creating data entering and editing forms: the data lookup capabilities
of ComboBox control.

Figure 4 shows the EditSections Form in design mode in the Morfik AppsBuilder Workspace. Notice
that the last control in the Form is a ComboBox, right besides a TextLabel control which reads "Parent
Section".

Figure 4 – the EditSections Form in design mode in the Morfik Workspace.

Choosing Control Type in the Wizard


When running the "Create New Form" Wizard you can select which types of controls will be created
for each of the table fields to which you have selected to bind your Form.

Page 394
Figure 5 – Option to automatically add controls the Form being created.

Once you choose to automatically add controls to the Form you can use the "Customize" button to
specify which controls will be used for each field. This option will bring up the dialog box which is
shown in Figure 6.

Figure 6 – Changing the type of a control through the popup menu.

In the picture shown in Figure 6 you can see the control selection for the Id field of the Section table.
Since Id is an AutoNumber field and thus automatically handled by the database it was decided that it
should be displayed in a TextLabel control so that the user cannot alter its value.

As can be seen in Figure 6 the default control suggestion for The ParentID field is a TextLabel which,
though usable, does not meet with our requirements for usability since it requires that the user have
previously looked up the value of the Id Field of another Section. This control type should then be
changed to being a ComboBox.

Once the Form is created by the Wizard, the ComboBox control is not yet ready to be effectively used.
The ComboBox ’ s lookup data binding properties must be set in order for it to work effectively.

Page 395
Figure 7 – Configuring the Lookup Data properties of the ComboBox bound to the ParentId field of
the Section table.

Immediately after the creation of the Form by the wizard only the DataField property is set, to bind
the control to the underlying field in the database. We need then to manually reconfigure the
LookupDataSource to choose where the data lookup data will come from, the LookupDataField which is
the information we want to copy onto our bound DataField and LookupTextField which is the field
whose values we want to display in the ComboBox for the user to choose from.

In this specific case we want to display the titles of the sections and once the user has chosen one,
store the value of its Id field in the current records ParentId field so we ’ ve configured these
properties as shown in table 1.

Table 1 – Data related properties for the ComboBox


Property Value
DataField ParentId
LookupDataField Id
LookupDataSource Section
LookupMaxRecords 50
LookupTextField Title

Note that in Table 1 we list the value of a property that was not previously mentioned:
LookupMaxRecords . This property controls the maximum number of records which will be fetched from
the database to populate the dropdown list of the ComboBox. In this case: 50 records.

Since these are topic groups, 50 might be a sufficiently large quantity. If you feel you might have
websites with a larger number of sections than this value should be appropriately adjusted to reflect
your needs.

In Figure 8 you can see the EditSection Form at runtime in the Morfik Debug Browser.

Page 396
Figure 8 – The EditSection Form at runtime in the Morfik Debug Browser.

The ComboBox control for editing the ParentId field can be seen with its dropdown list visible in the
screenshot that is shown in Figure 8. As can be seen from this example the ComboBox control can be
extremely useful in editing fields which relate one table to another. We make extensive use of this
feature in all the data editing Forms in the MorfikCMS project.

The EditSections Data Source


The EditSections Form is directly bound to the Section table allowing access to all the records in the
table. This is a simple and immediate approach which is easily implemented through the use of the
AppsBuilder "Create New Form" wizard.

The EditArticles Form


Since we have discussed all the specific detail on how to customize the automatically generated
Forms in our discussion of the EditSections Form, we will just quickly mention what customizations
were done to the EditArticles Form.

Figure 9 shows the EditArticles Form in design mode in the Morfik AppsBuilder Workspace. The
"Create New Form" Wizard automatically suggests the appropriate controls for the date fields and
once we have configured, as we did for the EditSections form, will generate ComboBoxes for the
SectionId (indicated by the "Section" TextLabel)and CreatedBy Fields.

Page 397
Figure 9 – EditArticles Form in design mode in the Morfik Workspace.

Once the Form is created it the Lookup data properties of the two ComboBox controls need to be set
as to bring up information from the Section table, exactly as done in the EditSections Form and to
bring up data from the UserCatalog table where the FullName field will be used in the LookupTextField
property so that the users ’ full names are displayed in the corresponding dropdown list.

The EditArticles Data Source


Analogous to the EditSections Form, the EditArticles Form is directly bound to the Article table allowing
access to all the records in the table. This is a simple and immediate approach which is easily
implemented through the use of the AppsBuilder "Create New Form" wizard.

The EditUsers Form


The EditUsers Form is very simple in nature since the table on which it is based is, also, a simple one.
Only one special customization, apart from adding the Title and accompanying images to the Header
band of the Form is required which is to configure one of the TextEdit controls for password display.
In this case, the control will only display small circles in place of actual characters when the user
types in a password.

This ensures that a person with access the site management area of the website can change a user ’
s password but cannot read the previously registered one.

Figure 10 shows the EditUsers Form in design mode in the Morfik AppsBuilder Workspace and Figure
11 shows the same Form at runtime in the Morfik Debug Browser.

Page 398
Figure 10 – The EditUsers Form in design mode in the Morfik Workspace.

In order to configure the TextEdit which is bound to the Password field to mask its content all that is
needed is to check the IsPassword property in the Property Window.

Page 399
Figure 11 – The EditUsers Form at runtime in the Morfik Debug Browser.

Note in Figure 11 that the Password field is displaying placeholders instead of the actual characters
from the field ’ s contents.

The EditSiteInformation Form


The EditSiteInformation Form is a special case within our content maintenance Forms because it is
bound to a table which always contains a single record.

In this Form, since there is always only one record, there is really no reason to have an Id Field
visible so after the Wizard created the Form that TextLabel was made invisible. You can see the
EditSiteInformation form in design mode in the Morfik AppsBuilder Workspace in Figure 12.

Figure 12 – The EditSiteInformation Form in design mode in the Morfik Workspace.

Note that since this Form should not be able to add new records to the underlying table the
NavigatorBar in the Footer Band has been configured to show only the Refresh, Submit and Edit
buttons.

Page 400
Figure 13 – The EditSiteInformation Form at runtime in Internet Explorer.

The EditSiteInformation Data Source


Analogous to the EditSections Form, the EditArticles Form and the EditUsers Form, the
EditSiteInformation Form is directly bound to the WebsiteInfo table allowing access to all the records in
the table. This is a simple and immediate approach which is easily implemented through the use of
the AppsBuilder "Create New Form" wizard. The fact that the WebsiteInfo table has a single record
does not require any specific action to make the EditSiteInformation Form work perfectly. The only
customization necessary is, as previously discussed, a configuration of the NavigationBar so that it
does not display any buttons which are not necessary.

Adding Search Capabilities to a Form


Morfik AppsBuilder and the Morfik Framework offer us several ways to work with database searches
in almost transparent ways. Every time we use a stored query as a data source for our Forms we are
using the databases intrinsic search features. These features allow us the end-user/visitor to
websites managed by our MorfikCMS project to drill down through the site ’ s content down to the
single article level.
Now we are going to see a very simple, and totally codeless, way of adding simple search and
filtering capabilities to our application. In order to do this we are going to go back to the EditArticles
Form and add a new button to its NavigationBar : the menu button.

This little button is all we need to add to the Form in order to add search and filtering capabilities to
it. When the menu button is clicked it displays a small popup menu with three options: Filter by Form,

Page 401
Apply Filter and Remove Filter.

Figure 14 – The Search/Filter menu in the NavigatorBar of the EditArticles Form.

In Figure 14 the Filtering menu is highlighted in red. Clicking on the "Filter by Form" option the
contents of all fields are cleared and the user can type whatever they want to search for, in the
corresponding TextEdit.

Figure 15 shows a user entering data for filtering in the TextBox bound to the Title field of the Article
table. Once the filtering criteria have been typed in all that is necessary is to click on the "Apply Filter"
option of the menu button.

Page 402
Figure 15 – The EditArticles Form in "Filter by Form" mode.

Note that once the "Apply Filter" option is selected the Form displays only the records which match
the criteria. Observe in the highlighted portion of Figure 16 that the NavigationBar indicates record 1
of 1.

Page 403
Figure 16 – The EditArticles Form with a filter set for articles with the word "PHP" in the title.

This is because with the filtering activated the Form sees only the one record in the table which does
have the word "PHP" in its Title field. This feature allows the developer to quickly add filtering and
basic searching into an application without actually writing a single line of code.

In the MorfikCMS sample project, considering the data load that each of the tables will probably have
in an average website, only the Article table seems to be a candidate for a search feature as it is the
only table which should have a large number of records.

Editing Data Without a NavigationBar


Up to this point, in this chapter, we have seen how to edit information without writing any code,
through the use of a NavigationBar. We will now take a quick look at how to edit some of the content
of the website, one record at a time.

Filtering Data from a Table


When we are just displaying data, we can work with all variations of Queries to get exactly the data
we want. When we are going to alter the data we must work with a table, however. In order to limit
the data which is going to be presented to the user to a specific record we must use a filter. In this
case this is done through the use of a single line of code, instead of through the visual interface of
the NavigationBar ’ s Menu button.

Using a filter is actually quite simple and follows closely what we have been doing with the queries.
In this case, however, we must manually create the parameter in the Form in which we will filter the

Page 404
data.

The EditOneArticle Form


In our current sample application we will be filtering the data presented by the EditOneArticle Form. As
just mentioned in this case we must manually declare the appropriate parameter and then write the
necessary code in the OnReady event, which is triggered when the form completes loading in the
Browser. Figure 17 shows the parameter list for the EditOneArticle Form with the added parameter at
the end.

Figure 17 – Parameter list of the EditOneArticle Form.

The following code snippet contains the entire event handler for the OnReady event of the
EditOneArticle Form, which is quite simple: one single line of code.

P rocedure EditOneArticle . WebFormReady ( Var


Ready : Boolean );
Begin
ChangeFilter ( '"Id"=' + P aramId );
End ;

This single line event handler forces the filtering of the records from the Form ’ s data source as
described in the filter expression. In this case the data source for the Form is the Article table.

Figure 18 shows the EditOneArticle Form open as popup for editing the record corresponding to a
specific article. Note how everything outside the EditOneArticle is now dimmed. Everything outside the
Form cannot be directly accessed thus simulating the behavior of a modal dialog in Windows.

Page 405
Figure 18 – The EditOneArticle Form as a popup.

In the EditOneArticle Form as we are always dealing with a single record, instead of using a
NavigationBar, which can display update controls, two normal buttons were used to confirm or cancel
the changes. The following code snippet contains the event handler for the SubmitBtn button which
confirms the edit of the data and sends the modified data back to the server.

P rocedure
EditOneArticle . SubmitBtnClick ( Event : T DOMEvent );
Begin
UpdateRecord ( Event );
SubmitP age ( Event );
OpenForm ( 'ViewOneArticle' , 'Index:MainArea' ,
'"P aramId='
+ Control_Id . Caption + '", "openmode=refresh"' );
Close ;
End ;

The following code snippet is the entirety of the event handler for the CancelBtn button which cancels
any changes made to the record currently being edited.

Page 406
P rocedure
EditOneArticle . CancelBtnClick ( Event : T DOMEvent );
Begin
CancelRecordChanges ( Event );
Close ;
End ;

Both of these even handlers close the Form. The event handler for the SubmitBtn button commands
the re-opening of the ViewOneArticle Form showing the article currently being edited, forcing its
refresh since the data will have been modified.

Wrapping it up
In this chapter we have seen that providing the end-user/visitor to your website with simple data
entry and editing functionality, as well as searching and filtering capabilities can be achieved with
minimal coding.

The Morfik AppsBuilder Workspace and the Morfik Framework provide a solid base on which to build
data management applications which are intrinsically simple.

See Also
 Morfik Database Programming
 Database Modeling

 Visual Database Programming


 Database Connections
SQL
 Statements
 Using Stored Procedures

 System Objects in a Database


 Working with Forms
category:Database

Page 407
Parsing browser-side
XML

The code shown below is now obsolete as the relevant methods have been
added to the Morfik Framework.

The relevant function is now: '''Function StrToXMLDocument(XMLString : S


tring) : TDOM_Document'''; in SystemUtilities.

''This page will be maintained for a short period of time for archival p
urposes only.

You can use this sample code to parse your xml content in the browser.

Unit Index;

Interface

Type
{.........................................................................
.....}
Index=Class(Form)
TextEdit1 : TextEdit;
Button1 : Button;
Procedure Button1Click(Event: TDOMEvent); Message;
Private
{ Private declarations }
Public
{ Public declarations }
End;
{.........................................................................
.....}

{.........................................................................
.....}
TActiveXExt = Class(TActiveX)
async : String;
Function loadXML(str : String) : Boolean;
End; ['External='];
{.........................................................................
.....}

{.........................................................................
.....}
TDOM_Parser = Class
Function parseFromString(Str, MimeType : String) : TDOM_Document;
End; ['External='];
{.........................................................................
.....}

Const

Page 408
{.........................................................................
.....}
SomeXML : String = '<root><element>First Element</element><element>Second
Element</element><element>Third Element</element></root>';
{.........................................................................
.....}

Implementation

{.........................................................................
.....}
Function ParseXML(XML : String) : TDOM_Document;
Function CreateParser : TDOM_Parser; Javascript;(*!
return new DOMParser();
*)
Var
XMLActiveX : TActiveXExt;
Parser : TDOM_Parser;
Begin
Result := Nil;

If Browser.EngineID = 'MS' Then


Begin
XMLActiveX := TActiveXExt(CreateActiveX('Microsoft.XMLDOM'));
XMLActiveX.async := 'false';

If Not XMLActiveX.loadXML(SomeXML) Then


Begin
Result := Nil;
Exit;
End;
Result := TDOM_Document(XMLActiveX);
End
Else
Begin
Parser := CreateParser;
Try
Result := Parser.parseFromString(SomeXML,'text/xml');
Except
Result := Nil;
Exit;
End;
End;
End;
{.........................................................................
.....}

{.........................................................................
.....}
Procedure Index.Button1Click(Event: TDOMEvent);
Var
Doc : TDOM_Document;
Element : TDOM_Element;
i : Integer;
S : String;
Begin
TextEdit1.Text := '';
Doc := ParseXML(SomeXML);
Element := Doc.documentElement;

Page 409
For i := 0 to Length(Element.childNodes) - 1 do
Begin
S := Element.childNodes[i].childNodes[0].nodeValue + '\n';
TextEdit1.Text := TextEdit1.Text + S;
End;
End;
{.........................................................................
.....}

End.

See also
 Tips
 Tutorials
Category:Programming

Category:Database

Page 410
Returning the value of any class member field as
a string

Introduction
We are building a generic framework to do data transfers/data binding efficiently (and some
other wonders;) in Morfik and we had this issue today that we wanted to get a field’s value
when we knew the field’s name.

Solution
So we cooked up the following little inline JavaScript function that will return the string
equivalent of the value of filed ‘v’ of class ‘c’. This is a first cut, some tests should be done
(and will be for our production lib) but it is a good start, if you happen to stumble upon the
same problem.

function GetValue(c:Pointer; v:String):String; JavaScript;


(*!
{
return c[v];
}*)

Among other things this demonstrates how you can call JavaScript code from within the Pascal
code without using external .js files. This is a relatively new syntax (from around the 0.9.1x.x
branch AFAIS) but is way cool.

If you happen to have to drop to JavaScript, some of my advices:


do NOT do that, unless you know what you are doing — if you
 are new to JavaScript, it will be an interesting experience;
in Project / Project Options / Compiler, switch off “Obfuscate JavaScript” (and “Optimize
 JavaScript”, for that matter) to make your life easier when you are debugging;
install the Microsoft Script
debugger as described in
 Appendix ‘G’ (if I recall correctly).
Happy sailing!

See also
 Tips
 Tutorials

External links
To discuss or for updates see piBlog: piBlog>Morfik Tip: How to return the value of any class
 member field as a string
Category:Programming

Page 411
Implementing transaction support

Introduction
Do you need explicit transaction control in some webmethods?

This tip gives you an example of how a transaction can be started and comitted in a
webmethod

Part 1
Here is some code which can be used (in the server-side) of a web method to test a
transaction with rollback.

Note that this field DBTransaction.Isolation has been set to tiConsistency. This field could be
set to: (tiConcurrency,tiConsistency,tiCommitted)

Related Code

Unit WebMethod1;

Interface

Uses
SystemDatabaseIBO;

T ype
WebMethod1=Class(WebMethod)
OrganizationID : String;
FundraiserID : String;
GuestID : String;
NewInvoiceID : Integer;
NewInvoiceIDStr : String;
P rivate
Function BeginT ransaction : T IB_T ransaction;
Procedure EndT ransaction(T ransaction : T IB_T ransaction; Rollback : Boolean = False);
Function AddInvoiceRecord: Boolean;
P ublic
Procedure Execute; override;
End; ['Published=False'];

Implementation

Function WebMethod1.BeginT ransaction : T IB_T ransaction;


Begin
Result := T IB_T ransaction.Create(SoapServer.DefaultDBConnection.DBSession);
Result.IB_Connection := SoapServer.DefaultDBConnection.DBConnection;
SoapServer.DefaultDBConnection.DBConnection.DefaultT ransaction := Result;
Result.StartT ransaction;
End;

P rocedure WebMethod1.EndT ransaction(T ransaction : T IB_T ransaction; Rollback : Boolean =


False);
Begin
If Rollback T hen T ransaction.Rollback
Else T ransaction.Commit;

Page 412
T ransaction.Free;
End;

Function WebMethod1.AddInvoiceRecord: Boolean;


Const
S = 'INSERT INT O "tblInvoices" ("OrganizationID","FundraiserID","GuestID","Amount","
P aid") '
+ 'VALUES (%s,%s,%s,%d,%d) RET URNING ID';
Var
SQLStr : String;
AcctRS : T RecordSet;
Begin
Result := False;
SQLStr := Format(S, [OrganizationID, FundraiserID, GuestID, 0, 0]);
AcctRS := DefaultDBConnection.CreateRecordSet(SQLStr);
T ry
AcctRS.P repare;
AcctRS.Execute;
NewInvoiceID := AcctRS.FieldByName('ID').AsInteger;
NewInvoiceIDStr := IntT oStr(NewInvoiceID);
Result := T rue;
Except
Result := False;
End;
AcctRS.Free;
End;

P rocedure WebMethod1.Execute;
Var
T ransaction : T IB_T ransaction;
Begin
T ransaction := BeginT ransaction;
T ry
AddInvoiceRecord;
Finally
EndT ransaction(T ransaction, T rue);
End;
End;

End.

See also
 Tips
 Tutorials

External links
 Morfik Forum: Changing the appearance of controls
Category:Database

Page 413
Detecting if a Form is dirty

Introduction
Sometimes you want to know if the user has made a Form dirty, in order to determine if
anything needs submitting to the database.

This code offers a technique to determine if a record that is bound to a Single Form has been
changed.

Required Code

Unit Form1;

Interface

T ype
{..............................................................................}
Form1=Class(Form)
Label_xxx : T extLabel;
Control_xxx : T extEdit;
Label_yyy : T extLabel;
Control_yyy : T extEdit;
Label_zzz : T extLabel;
Control_zzz : T extEdit;
Button1 : Button;
Procedure Button1Click(Event: T DOMEvent); Message;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
Function AnyRecordIsDeleted : Boolean;
Function CurrentRecordIsModified : Boolean;
End;
{..............................................................................}

Implementation

T ype
{..............................................................................}
P DBObject = ^T DBObject;
{..............................................................................}

{..............................................................................}
Function Form1.AnyRecordIsDeleted : Boolean;
Begin
GetState;
Result := DataSet.DBSubmitList.Count > 0;
End;
{..............................................................................}

{..............................................................................}
Function Form1.CurrentRecordIsModified : Boolean;
Var
CurRec : T DBObject;

Page 414
Begin
GetState;
CurRec := PDBObject(CurrentRecordVariant.Data)^;
Result := CurRec.Status in [dbsModified,dbsNew];
End;
{..............................................................................}

{..............................................................................}
P rocedure Form1.Button1Click(Event: T DOMEvent);
Begin
If CurrentRecordIsModified T hen ShowMessage('Must Submit changed Recor
d' );
If AnyRecordIsDeleted T hen ShowMessage('Must Submit Deleted Record(s)')
;
End;
{..............................................................................}

End.

See also
 Tips
 Tutorials
Category:Database

Category:Programming

Page 415
Creating Virtual
Parameters

Introduction
One of the key features of Morfik Forms, Reports and WebMethods are parameter s.

If you are using parameters extensively in your application then you may find yourself frequently
creating, modify ing and removing design-time parameters as you develop your Morfik project (XApp).
If this is the case, then you this technique of using 'virtual parameters' may be very helpful.

The Virtual Parameters technique is a way where for each Form, Report or WebMethod that utilizes
parameters, you simply define a single parameter, which in effect will act like a scalable and flexible
list of parameters, that you can modify programmatically at runtime.

Part 1 - Implementing the Virtual Parameters mechanisim


Create a new module and call it VirtualParameters. You will then need to define the browser- and
server-side logic for this module.

Browser-Side

Unit VirtualP arameters;

Interface

Uses
SystemClasses,
SystemUtilities;

T ype
{..............................................................................}
T VirtualParameters = Class
Items : List Of T P arameter;
Destructor Destroy; Override;
Procedure FromStr(Str : String);
Procedure Add(Prop, Value : String);
Function AsString : String;
Function ParamValue(Name : String) : String;
End;
{..............................................................................}

Implementation

{..............................................................................}
P rocedure T VirtualParameters.FromStr(Str : String);

Procedure AddT oList(p : String);


Var
sep : Integer;
Begin
sep := pos(':',p);
Add(Copy(p, 1, sep - 1), Copy(p, sep + 1, Length(p)));
End;

Var
T : String;

Page 416
m : String;
k : Integer;
Begin
m := Str;

Repeat
k := P os(';',m);

If k <> 0 T hen
Begin
t := Copy(m,1,k - 1);
Delete(m,1,k);
End
Else
Begin
t := m;
m := '';
End;
AddT oList(t);
Until m = '';
End;
{..............................................................................}

{..............................................................................}
P rocedure T VirtualParameters.Add(Prop, Value : String);
Begin
If Items = Nil T hen
Items.Init;

Items.Add(T P arameter.Create(prop,Value));
End;
{..............................................................................}

{..............................................................................}
Function T VirtualParameters.AsString : String;
Var
i : Integer;
p : T P arameter;
Begin
Result := '';

For i := 0 to Items.Count - 1 Do
Begin
P := Items[i];

If Result <> '' T hen


Result := Result + ';';

Result := Result + p.Name + ':' + p.Value;


End;
End;
{..............................................................................}

{..............................................................................}
Destructor T VirtualParameters.Destroy;
Var
i : Integer;
Begin
For i := 0 to Items.Count - 1 Do
Items[i].Free;

Page 417
Items.Clear;
Items.Free;

Inherited Destroy;
End;
{...............................................................................}

{...............................................................................}
Function T VirtualParameters.P aramValue(Name : String) : Str
ing;
Var
i : Integer;
Begin
For i := 0 to Items.Count - 1 Do
if StringsEqual(Items[i].Name,Name) T hen
Begin
Result := Items[i].value;
Exit;
End;
End;
{...............................................................................}

End.

Server-Side

Unit VirtualP arameters;

Interface

Uses
SystemClasses,
SystemUtilities;

T ype
{..............................................................................}
T VirtualParameters = Class
Items : T StringList;
Constructor Create;
Destructor Destroy; Override;
Procedure FromStr(Str : String);
Procedure Add(Prop, Value : String);
Function AsString : String;
Function ParamValue(Name : String) : String;
End;
{..............................................................................}

Implementation

{..............................................................................}
Constructor T VirtualP arameters.Create;
Begin
Items := T StringList.Create;
Items.NameValueSeparator := ':';
End;
{..............................................................................}

Page 418
{..............................................................................}
P rocedure T VirtualParameters.FromStr(Str : String);
Var
T : String;
m : String;
k : Integer;
Begin
m := Str;

Repeat
k := P os(';',m);

If k <> 0 T hen
Begin
t := Copy(m,1,k - 1);
Delete(m,1,k);
End
Else
Begin
t := m;
m := '';
End;
Items.Add(t);
Until m = '';
End;
{..............................................................................}

{..............................................................................}
P rocedure T VirtualParameters.Add(Prop, Value : String);
Begin
Items.Values[P rop] := Value;
End;
{..............................................................................}

{..............................................................................}
Function T VirtualParameters.AsString : String;
Var
i : Integer;
Begin
Result := '';

For i := 0 T o Items.Count - 1 Do
Begin
If Result <> '' T hen
Result := Result + ';';
Result := Result + Items[i];
End;
End;
{..............................................................................}

{..............................................................................}
Destructor T VirtualParameters.Destroy;
Begin
Items.Clear;
Items.Free;
Inherited Destroy;
End;
{..............................................................................}

{..............................................................................}

Page 419
Function T VirtualParameters.P aramValue(Name : String) : Str
ing;
Begin
Result := Items.values[name];
End;
{..............................................................................}

End.

Create a Form Parameter

In our Form, instead of creating multiple parameters we merely define a single parameter,
prmVirtualParameter.

Part 2 - Code example


This section gives an example of how you would use 'virtual parameters'.

We show how you can add to parameters, alongwith their values at runtime. The two parameters
that we are add called param1 and param2. We give them the values Value1 and Value2,
respectively.

Passing parameters to the server via an OpenForm action

{..............................................................................}
P rocedure Form1.Button1Click(Event: T DOMEvent);
Var
VirtualParam : T VirtualP arameters;

Page 420
Begin
VirtualParam := T VirtualP arameters.Create;

VirtualParam.Add('param1','VALUE1');
VirtualParam.Add('param2','VALUE2');

OpenForm('myForm','Index:MainSubForm','"prmVirtualParam=' + VirtualP aram.AsString


+ '"');

VirtualParam.Free;
End;
{..............................................................................}

Reading parameters values in server

On the server-side we receive the virtual parameter and, just to confirm, we show their values in the
Output panel of the IDE.

{..............................................................................}
P rocedure myForm.WebFormBeforeExecute(Sender: T WebDocument; Var P Continue: Bo
olean);
Var
VirtualParam : T VirtualP arameters;
Begin
VirtualParam := T VirtualP arameters.create;

VirtualParam.FromStr(prmVirtualP aram);

// print values of the parameters to the debug output

DebugOut(VirtualParam.P aramValue('param1'));
DebugOut(VirtualParam.P aramValue('param2'));

VirtualParam.Free;
End;
{..............................................................................}

That's it. :)

See also
 Tips
 Tutorials

External links
 Morfik Forum: Run time Parameter creation
Category:Programming

Page 421
parameter

Parameters in Morfik AppsBuilder very much like function


parameters.

There are three types of parameters:


 Form parameters
 Query parameters

 Web method parameters

Page 422
Form parameters

Defining Parameters
If a Form is directly bound to a Query that has parameters than all of these parameters will
also be available via the Form. For example, if one right-clicks on the Form and selects the
parameter option one may see:

The list of parameters include:


 any in-built Form parameters such as ViewMode, PageSize, StartingOffset and SQLFilter, etc;
any parameters that are associated with a
 data-bound query

 Form-specific parameters as defined by the developer for that particular Form parameters.

Setting Parameters
To read or set these parameters can be done as though they were locally declared variables.
That is, to set a parameter to the contents of a TextLabel can be done as follows:

// Morfik Pascal
T itleP aram :=T extLabel1.T e
xt;

Passing Parameters out of a Form


If the Form is not bound to a query that has parameters, then it is still possible to pass the
queries out of the Form. For example, to open another Form (that is bound to a parameter
query) with particular parameter values can be done as follows:

Page 423
// Morfik Pascal
OpenForm('Books by Genre','Form1:Subform1'
,
'"GenreP aram=' + GenreSelection.T ext + '
", '+
'"T itleP aram=' + T itleSelection.T ext + '",
'+
'"P riceP aram=' + P riceSelection.T ext + '",
'
);

Note that what is required to to concatenate all the parameters together to form a single
string parameters. This will get automatically parsed during the OpenForm procedure.

Note that in this case, the last three parameters have been directly brought in via the Query.

Using Parameters in a Form or Report


One of the most common situations to link a parameter to a Form (or report control) is as
soon as the Form has been invoked via the OpenForm command. In this case, the
OnFormReady event is most appropriate. In this case, prmGameID and prmPlayerColor are
Form parameters.

// Morfik Pascal
P rocedure frmGameOptions.WebFormReady(Var Ready: Boole
an);
Begin
LblGameID.Caption := prmGameID;
LblPlayerColor.Caption := prmPlayerColor;
End;

See also
 Parameters
 Query parameters

 Web method parameters

Page 424
Query parameters

The following screenshot shows how to define a parameter for a Query

Note that the key features that makes this Query different from a static Query is that the criteria
fields include parameters. In this Query there are three parameters: GenreParam, TitleParam and
PriceParam. We briefly outline the syntax used here:

Like GenreP aram || "


%"

The Like is a SQL User-defined function (UDF) that searches for all fields that begin with this
string.

The two '|' signs are the ANSI-92 standard symbol for string concatenation, and the '%' sign is
the ANSI-92 wild-card symbol.

Note Note

See also
 Parameters
 Form parameters

 Web method parameters

Pa ge 4 2 5
Related Video
 Queries with Parameters

Page 426
Inserting images into Image
fields

Introduction
Morfik tables allow defining fields with Picture as the type. Inserting images into these fields
through server side coding involves a little more than usual binary inserting, because the
content of a Picture field must carry information about itself.

Solution
The following Webmethod (server side) demonstrates inserting an image into a Picture field.

Unit WebMethod1;

Interface

Uses
SystemCatalog,
SystemClasses;

T ype
WebMethod1=Class(WebMethod)
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
Procedure Execute; override;
End; ['Published=False'];

Implementation

P rocedure WebMethod1.Execute;
Var
DBField : T DBFieldBlob;
DBFileBlob : T DBFileBlob;
DBFieldInfo : T DBFieldInfo;
DataStream : T MemoryStream;
Command : T SQLCommand;
Begin
DBFieldInfo := Catalog.GetT ableFieldByName('YOUR T ABLE NAME','YOUR FIELD NAME');

Command := DefaultDBConnection.CreateSQLCommand('INSERT INT O "YOUR T ABLE NA


ME" ' +
'("YOUR FIELD NAME") VALUES (:"img")');

T ry
DataStream := T MemoryStream.Create;
DBFileBlob := T DBFileBlob.Create(DataStream,DBFieldInfo,T rue,T rue);
DBFileBlob.Clear(T rue);
DBFileBlob.LoadFromFile('YOUR IMAGE FILE NAME',Nil);
DBFileBlob.SaveT oDBField(Nil);
DataStream.Seek(0,0);

Command.P repare;
DBField := T DBFieldBlob(Command.P aramByName('img'));

Page 427
DBField.LoadFromStream(DataStream);
Command.Execute;
Finally
DefaultDBConnection.DestroySQLCommand(Command);
DBFileBlob.Free;
DataStream.Free;
End;
End;

End.

See also
 Tips
 Tutorials

External links
Category:Programming

Page 428
Iterating through Bands in a Continuous
Form

Introduction
How can I iterate through all Bands in a continous Form, for example disable all Containers in
it?

Method 1
This code, which you can hook to any control in your continuous form will set Container1 in
every row to not visible.

P rocedure MyForm.SetContainerT oNotVisible(Event: T DOMEv


ent);
var
Ctrl1 : T WebControl;
i : Integer;
Begin
Ctrl1 := GetEventSource(Event);
For i := 0 to Ctrl1.DOMHandleArray.Handles.Length - 1 Do
Begin
Container1.BandIndex := i;
Container1.Visible := False;
End;
End;

Method 2
This code, is a variant in the situations where you wish to cycle through the bands of a
particular control prior to user interaction.In this case, we connect it to the OnReady event
handler.

P rocedure MyForm.WebFormReady(Var Ready: Boolean);


var
i : Integer;
Begin
For i := 0 to Container1.DOMHandleArray.Handles.Length -
1 Do
Begin
Container1.BandIndex := i;
Container1.Visible := False;
End;
End;

See also
 Tips
 Tutorials

 BandIndex

Page 429
External links
 Morfik Forum: iterrating through BandIndexex (sic)
Category:Presentation

Category:Programming

Page 430
BandIndex

The best way to understand how to directly access and manipulate controls within
a row that is part of a data-bound Continuous Form is to look at three examples.
It is critical to know whether you wish to access/manipulate the row at the
browser-side or the server-side. The first example was shown in the previous
section on "Event Handling -> Modifying controls at run-time". It is mentioned
again to aid context for the other examples.

Example 1
Consider a a Morfik application that has a Continuous Form, say a list of books that is
grouped first according to whether or not the book is a paperback, and then Continuous
according to author.

Further, imagine that if the user clicks any of the checkboxes, the checkbox will be checked
and the corresponding book's author and title will become bold. If the user clicks again, the
box will become unchecked and the book's author and title will revert to normal. This is done
via browser-side programming.

This method is only available on the browser-side. The equivalent in the server-side is LineNo
. (see example 3).

The code for the CheckBox1Click function may be implemented as:

// Morfik P ascal Syntax


Function Form1.T extLabel2Click(Event: T DOMEven
t);
Begin
SwitchBandIndex (Event);
// Notice that from here on there is no need for any
form
// of identifier for either the Label or the CheckBox
!
If CheckBox1.Checked = T rue T hen
Begin
CheckBox1.Checked := False;
T extLabelAuthor.FontStyle := [];
T extLabelT itle.FontStyle := [];

Page 431
End
Else
Begin
CheckBox1.Checked := T rue;
T extLabelAuthor.FontStyle := [fsBold];
T extLabelT itle.FontStyle := [fsBold];
End;
End;

Note that the BandIndexing can be done in a more explicit manner. The procedure:

// Morfik Pascal Syntax


SwitchBandIndex (Event
);

Could be replaced with the following two lines.

// Morfik Pascal Syntax


T extLabelAuthor.BandIndex := CheckBox1.BandIn
dex;
T extLabelT itle.BandIndex := CheckBox1.BandInde
x;

This is because SwitchBandIndex sets the band index of every control in the details band to
the same band index as the control that triggered the event. In most cases, this will be the
syntax that will be used for BandIndex-related code on the browser-side. This longer syntax
may be of use to better help understand the workings of example 2.

Example 2
Of course, if you are not actually requiring a user-interaction to know which row to alter, you
can do it even more easily.

// Morfik P ascal Syntax


Function Form1.T extLabel2Click(Event: T DOMEve
nt);
Begin
T extLabelAuthor.BandIndex := 3;
// Sets the font of the T extLabel in the 3rd row to
bold
T extLabelAuthor.FontStyle := [fsBold];
End;

See also
 LineNo

Page 432
LineNo

If at the time of creation, you wish for every second row to be a different color,
which is often useful to aid the user, one technique would be to place a container
that covers the entire details band, and then it is easy to set the color (or
transparency) of the container.

Note that this is done at the server, and the tracking of line numbers for a detail is
kept in memory. As soon as the Form has been created and sent to the browser
all details of line numbers are deleted from memory. To access particular rows,
after this point (since it is in the server) you should use Band Indexes and not line
numbers

// Morfik Pascal Syntax


Function "Thread List".DetailBeforePrint(Sender: TWebCont
rol;
Canvas: TWebCan
vas;
Var Print: Bool
ean);
Begin
If LineNo Mod 2 = 1 Then
Container2.Color := $0000FF;
Else
Container2.Color := $000000;
End;

See also
 BandIndex

Page 433
Using Stored
Procedures in Morfik

This topic will provide you will a general overview of how to use stored procedures
in order to simplify the implementation of some application features. In this
particular case we will see how to use executable stored procedures to clear log
tables and how to use selectable stored procedures to execute action queries at
the same time we retrieve data for the application.

It is not the goal of this work to be an all inclusive guide to writing stored
procedures. It is intended as a guide on how to use stored procedures from Morfik
AppsBuilder and thus will focus on the usage of the procedures instead of on their
creation.

Also treated in this chapter is how to provide visual feedback to the end user
while a long running server side process is being executed.

Two Kinds of Stored Procedures


Using Executable Procedures
The ManageLog Form
The ClearAccessLog WebMethod
The ClearLogUpTo WebMethod
Visual Feedback for Long
Processes
Using Selectable Procedures
Wrapping it up
See Also

Two Kinds of Stored Procedures


There are essentially two kinds of stored procedures: executable and selectable. This topic covers
the usage of both of these kinds of procedures from within a Morfik build web application.

The usage scenarios for these procedures were created as to complement and fit in nicely with the
MorfikCMS sample application. Morfik AppsBuilder, at a first glance does not offer any support for
using or calling stored procedures, be them executable or selectable. This impression is, however,
illusory.

Developers who are familiar with stored procedures can actually use both types of stored
procedures to enhance their applications as we will see shortly.

Using Executable Procedures


Executable stored procedures, as their name suggests are designed to execute some specific action.
In our MorfikCMS sample application executable stored procedures have been introduced to clear
the AccessLog table. Two Web Methods have been added to the MorfikCMS sample project to show
the usage of the stored procedures. Both Web Methods are invoked from a single Form which has
been added to the Site Management portion of the Website.

The ManageLog Form


The ManageLog Form is quite simple. It offers options to clear the AccessLog table in two manners: up
to a specific date, or completely. Figure 1 shows the ManageLog Form at design time in the Morfik
AppsBuilder Workspace.

Page 434
Figure 1 – ManageLog Form at design time in the Morfik Workspace.

Each of the buttons, shown in Figure 1, invokes a different Web Method one of which takes single
parameter which represents the date up to which the log should be cleared. In Listing 1 you can see
two event handlers which call the two supporting Web Methods. You will notice that both of the
event handlers call a procedure called StartWorking . This will be addressed further ahead in this
chapter, in greater detail.

Listing 1 – Browser side code for the ManageLog Form.

Unit ManageLog ;

Interface

T ype

ManageLog = Class ( Form )


Image1 : Image ;
HeaderGradient : Image ;
T extLabel1 : T extLabel ;
ClearAllBtn : Button ;
Container1 : Container ;
ClearUpT oBtn : Button ;
ClearUpT oDate : DateT imeEdit ;
P rocedure ClearUpT oBtnClick ( Event : T DOMEvent ); Message ;
P rocedure ClearAllBtnClick ( Event : T DOMEvent ); Message ;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
End ;

Implementation

Uses SystemUtilities ;

P rocedure ManageLog . ClearUpT oBtnClick ( Event : T DOMEvent );


Begin
StartWorking ;
RunWebMethod ( 'ClearLogUpT o' , '"AccessT ime='
+ ClearUpT oDate . DateT ime + '"' );

Page 435
End ;

P rocedure ManageLog . ClearAllBtnClick ( Event : T DOMEvent );


Begin
StartWorking ;
RunWebMethod ( 'ClearAccessLog' , '' );
End ;

End .

The ClearAccessLog WebMethod


The first of the two Web Methods which was created for the ManageLog Form was ClearAccessLog .
This is the simplest of the two WebMethods which were created to clear the log table simply
because it just erases all the content of the AccessLog table. This is achieved by executing a stored
procedure called "ClearAccessLog", just as the Web Method itself.

Listing 2 shows the full code for the server side portion of the ClearAccessLog Web Method.

Listing 2 – Server side code for the ClearAccessLog WebMethod.

Unit ClearAccessLog ;

Interface

T ype

ClearAccessLog = Class ( WebMethod )


P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
P rocedure Execute ; override ;
End ; [ 'P ublished=False' ];

Implementation

P rocedure ClearAccessLog . Execute ;


Var
SQLCommand : T SQLCommand ;
Begin
SQLCommand := DefaultDBConnection . CreateSQLComma
nd (
'EXECUT E P ROCEDURE "ClearAccessLog"' );
T ry
SQLCommand . P repare ;
SQLCommand . Execute ;
Finally
SQLCommand . Free ;
End ;
End ;

End .

Notice in the code for the Execute method of the ClearAccessLog Web Method that through the use of
the EXECUTE PROCEDURE statement we are essentially invoking the ClearAccessLog stored procedure
in the same way we would invoke another SQL language statement which does not return any data.

Page 436
This code is very close to what has been presented in Chapter 4, for the LogAccess method of the
AuthenticateUser WebMethod.

In the following code snippet you can see the full source code for the ClearAccessLog stored
procedure which is used by this Web Method.

SET T ERM ^ ;

CREAT E P ROCEDURE
"ClearAccessLog"
as
begin
delete from "AccessLog" ;
end ^

SET T ERM ; ^

Please, observe that this is an extremely simple stored procedure. In fact it would not be necessary
at all to use a stored procedure to execute this task as it is composed of a single statement which
basically deletes all rows from the AccessLog table. It is important to note that the complexity of the
stored procedure does not, in any way, affect the way it is called from within a Morfik application.

The ClearLogUpTo WebMethod


The ClearLogUpTo WebMethod does essentially the same as the ClearAccessLog , but restricted to the
time period predating a specific date. The major difference is that this WebMethod invokes a
different stored procedure, also homonymous to the Web Method, which requires as a parameter
the date up to which the log should be cleared.

Listing 3 shows the source code for the server side code for the ClearLogUpTo WebMethod.

Listing 3 – Server side code for the ClearLogUpTo 'WebMethod.

Unit ClearLogUpT o ;

Interface

T ype
ClearLogUpT o = Class ( WebMethod )
AccessT ime : String ;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
P rocedure Execute ; override ;
End ; [ 'P ublished=False' ];

Implementation

Uses SystemUtilities ;

P rocedure ClearLogUpT o . Execute ;


Var
SQLCommand : T SQLCommand ;
Begin
SQLCommand := DefaultDBConnection . CreateSQLCommand (
'EXECUT E P ROCEDURE "ClearLogUpT o"(:"AccessT ime")' );
T ry
SQLCommand . P repare ;

Page 437
SQLCommand . P aramByName ( 'AccessT ime'
). AsDateT ime := AccessT ime ;
SQLCommand . Execute ;
Finally
SQLCommand . Free ;
End ;
End ;

End .

Note in Listing 3 that the ClearLogUpTo stored procedure takes a parameter and that it is supplied
through the use of the ParamByName method.

Figure 2 – Code completion list of "Data type" properties for the parameter object.

The parameter passed on to the stored procedure has been sent to the server through a parameter
called AccessTime which was declared for the WebMethod and supplied in the call from the
ManageLog Form as shown in the ClearUpToBtnClick event handler in Listing 1.

Observe in the following code snippet that the code for the ClearLogUpTo stored procedure is quite
similar to that of the ClearAccessLog procedure, with the addition of the parameter which is used in
the WHERE clause of the Delete statement.

SET T ERM ^ ;

CREAT E P ROCEDURE "ClearLogUpT o" ( "AccessT ime"


timestamp )
as
begin
delete from "AccessLog"
where ( "AccessT ime" < : "AccessT ime" );
end ^

SET T ERM ; ^

As in the previous case, this is a very simple stored procedure which could be substituted by the
simple execution of the same Delete statement, which the procedure is executing, directly from the
application.

Visual Feedback for Long Processes

Page 438
In adding the two Web Methods which clear the AccessLog table, the MorfikCMS sample application
also introduces a way to visually give feedback to the application/website ’ s end users while a long
running process is being executed. In our sample case the clearing of the log never really takes long
as only a few rows exists at any one time in the AccessLog table. In a real world situation, however,
such a table might contain millions of rows and the operation to empty it might run for a little longer.
By just invoking the Web Method the process is started but the end user has no way of knowing
when the process ends. The first thing that immediately comes to mind when we think presenting
some visual feedback to the user is to imagine that we will display some visual message, but the
question of where soon becomes an issue. The user might have navigated away from the Form
which started the process so we have no way of knowing precisely where to display the message. It
can be done with a popup message when the process finishes, but the user might not tie in the
message with the action, depending on how long the process has been running for.

The path taken in the MorfikCMS sample project was to block the user ’ s session in the website
while the process is in execution. This is approach should be used sparingly as it might annoy certain
users and preferably in portions of the application which are used for administrative purposes as in
this case.

In the MenageLog Form ’ s browser side code, shown in Listing 1, in each of the event handlers which
invoke WebMethods, prior to invoking the Web Methods, there is a call to a global procedure called
StartWorking . The following code snippet shows the implementation of this procedure.

P rocedure StartWorking ;
Begin
IsWorkInP rogress := true ;
XApp . OpenForm ( 'WorkP rogress' , 'P OP UP ' ,
'"modal=true", "border=none"' );
End ;

The StartWorking procedure sets a global variable called IsWorkInProgress and then opens the
WorkProgress Form in popup modal mode.

Figure 3 – The WorkProgress Form at design time in the Morfik Workspace.

Page 439
Figure 4 – The WorkProgress Form at runtime in Internet Explorer.

The WorkProgress Form, shown in Figure 3, displays a message indicating that a "generic" operation
is being executed and uses an animated GIF image to provide the impression of the work being
done, as shown in Figure 4.

Both the ClearAccessLog and the ClearLogUpTo Web Methods in their browser side portions invoke
the StopWorking procedure which sets to false the global variable IsWorkInProgress to false. When
the next OnTimer event is processed by the timer control in the WorkProgress Form, it closes itself
automatically freeing the user to navigate again.

Using Selectable Procedures


The use of selectable stored procedures is even simpler than the use of the executable ones. A
selectable procedure behaves, essentially, as a table in a select Statement. This, which is actually a
feature of Morfik ’ s built-in Firebird database allows us to freely use stored procedures in creating
Morfik stored queries.

In the MorfikCMS sample application a stored query was added with the name GetOneArticleCount .
This query differs from the GetOneArticle query which was being used to get the data of a specific
article, when a user clicks on an article to see its full text, in that it retrieves the data from a stored
procedure.

The following code snippet shows the SQL language code of the GetOneArticleCount stored query.

SELECT * FROM "Article_SEL" ( :


P ARAMID )

Page 440
" Article _ SEL " in this case is the name of a stored procedure the definition of which can be seen in
the following code snippet.

SET T ERM ^ ;

CREAT E P ROCEDURE "Article_SEL" ( lookupid


integer )
returns (
"Id" integer ,
"T itle" varchar ( 64 ),
"Summary" varchar ( 250 ),
"Body" blob sub_type 1 segment size 80 ,
"DateCreated" timestamp ,
"DateP ublished" timestamp ,
"IsP ublished" smallint ,
"SectionId" integer ,
"CreatedBy" integer ,
"ViewCount" integer )
as
begin
for select "Id" ,
"T itle" ,
"Summary" ,
"Body" ,
"DateCreated" ,
"DateP ublished" ,
"IsP ublished" ,
"SectionId" ,
"CreatedBy" ,
"ViewCount"
from "Article"
where "Id" = : LOOKUP ID
into : "Id" ,
: "T itle" ,
: "Summary" ,
: "Body" ,
: "DateCreated" ,
: "DateP ublished" ,
: "IsP ublished" ,
: "SectionId" ,
: "CreatedBy" ,
: "ViewCount"
do
begin
update "Article" Set "ViewCount" = "ViewCount"
+1
where "Id" = : "Id" ;
suspend ;

end ^

SET T ERM ; ^

The code for this procedure was generated automatically through the use a Firebird administration
utility and the altered to include an update to the Article table where the value of the ViewCount
column is incremented by one. This allows the monitoring of how many times a specific article has
been selected for viewing by an end user/visitor.

Page 441
In effect the main difference of using this stored procedure and a simple query is that every time this
procedure is invoked the article it returns gets an update in the number of times it was viewed. This
kind of access statistics can be used to implement, for example, a list of the most popular articles.

Since we are dealing with a query which behaves exactly like a query which draws its data directly
from a table, and which has the same names for its output parameters as the columns of the original
table, all that is required it to replace the name of the data source for the ViewOneArticle Form in
order to start counting views.

Note
It is, also, necessary to add the ViewCount column to the Article table. This field should be
defined as a Number(Integer) column. This change has to be done prior to the creation of
the stored procedure or else it will not compile correctly as it references it.

Wrapping it up
Though creating complex stored procedures was beyond the scope of this chapter, Morfik makes
using them quite easy. Executable stored procedures can be used to delegate database intensive
operations directly to the database and selectable stored procedures can be used to execute some
action every time they recover some data.

See Also
 Morfik Database Programming
 Database Modeling

 Visual Database Programming


 Database Connections

 Editing and Searching


SQL
 Statements

 System Objects in a Database


 Working with Forms
category:Database

Page 442
Implementing a login to an external
Firebird database

Introduction
This outlines the key code required for implementing a login to an external Firebird database.

Part 1
Following is a working sample code from a webmethod called "Employee_LogonWS". The
name of the Connector in this example is 'Firebird1' and it is based on the Firebird
Employee.gdb sample database. It checks for the First and Last name and the value of
Authorised is checked in the HandleResponse event of the browser module.

unit Employee_LogonWS;

interface

Uses
SystemCatalog,
SystemConnectors,
SystemConnectorsIBO;

T ype
Employee_LogonWS=Class(WebMethod)
LastName : String;
Authorised : Boolean;
FirstName : String;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
Function Execute; override;
End;

Implementation

Function Employee_LogonWS.Execute;
Var
EmployeeRS : T RecordSet;
DBServiceConnection : T DatabaseServiceConnection;
Connector : T DatabaseServiceConnector;
SQL : String;
Begin
Connector := T DatabaseServiceConnector(Catalog.GetServiceConnectorByID('Firebi
rd1'));
DBServiceConnection := Connector.CreateConnection;

SQL :='SELECT "FIRST _NAME","LAST _NAME" FROM "EMP LOYEE"';


EmployeeRS := T IBOServiceConnection(DBServiceConnection).CreateRecordSet(SQ
L);

EmployeeRS.Prepare;
EmployeeRS.Active := T rue;
EmployeeRS.First;
Authorised := False;

Page 443
While Not EmployeeRS.EOF Do
Begin
If (StringsEqual(EmployeeRS.FieldByName('FIRST _NAME').AsString,FirstName)
And
StringsEqual(EmployeeRS.FieldByName('LAST _NAME' ).AsString,LastName))
T hen
Begin
Authorised := T rue;
Exit;
End;
EmployeeRS.Next;
End;
T IBOServiceConnection(DBServiceConnection).DestroyRecordSet(EmployeeRS);
End;

End.

See also
 Tips
 Tutorials

External links
 Morfik Forum: How can I do a Login form with a external Firebird DataBase ????
Category:Database

Page 444
Parsing XML from a WebMethod parameter

Introduction
Do you have a webmethod which has XML in one of its out parameters, and you need to
parse that parameter in the browser. Well, here's how you do it.

The magic function to use is:

Function StrT oXMLDocument(XMLString : String) : T DOM_Docu


ment;

which can be found in the SystemUtilities unit. This allows you then to use all the SystemDOM
methods (which are available via the SystemDOMHTNL unit) to manipulate the XML.

See also
 Tips
 Tutorials

External links
 Morfik Forum: Parsing XML from a parameter of a WebMethod
Category:Programming

Category:Database

Page 445
Resolving conflicts with existing software

Introduction
Occasionally when you install Morfik AppsBuilder, you may find that existing software conflicts
with AppsBuilder.

Here are some of the known conflicts and ways to fix them.

Common Conflicts

Morfik AppsBuilder takes a long time to load and close


SpyWare Doctor may cause this problem. Disable Spyware Doctor and then restart Morfik
 AppsBuilder

Morfik AppsBuilder hangs


SpyWare Doctor may cause this problem. Disable Spyware Doctor and then restart Morfik
 AppsBuilder

Can not Enable browser debugging


Spyware Doctor(from PCTools ) registered BHO appears to be the cause of being unable to
 disable the script debugging in Internet Explorer.
To enable script debuggin in Internet Explorer: (taken from www.pctools.com ):
1 Download the batch file to uninstall the bho from here
Exit from Spyware Doctor. Do this by right-clicking on the Spyware Doctor icon in the notification
2 area next to the clock on the Windows taskbar. Then select Exit from the menu that appears.
Close Internet
Explorer and any
3 other browsers
Run the batch file that was downloaded
4 in Step 1.

5 Enable the script debigging in Internet explorer settings

Errors when browser debugging


nView , which is a utility associated with the nVidiagraphics driver may cause problems when
 Enabled.
To disable nView utility,
1 go to the Windows control panel
2 double click on the nView/nvidia desktop manager.

3 In the new window, disable the nView desktop utility.

See also
 Tips
 Tutorials

Page 446
Adding items to a ListBox via the DOM

Introduction
If you wish to items to a ListBox that contains (HTML) formatting, then you will need to do this
programmatically at run-time. To do this, you should understand that a ListBox entry consists
of two entities: the logical value and the presentational value. The logical value gets sent to
the server when you submit the ListBox entities, whilst the presentational values describes
what is actually displayed to the user. By default, if you set a value of the ListBox at
design-time Morfik AppsBuilder sets both the logical and presentational vlaue to the same
value. To include general HTML formatting of a ListBox entry without sacrificing its integrity,
you can, at run-time, programmatically descend down to the DOM level and alter the
presentational value whilst keeping the logical value the same.

Part 1
Below is an example (in Morfik Pascal) of how to manually add items that may include HTML
formatting at runtime items to a List control at DOM level.

P rocedure Form1.Button1Click(Event: T DOMEvent);


Var
p : T HT ML_OptionElement;
i : Integer;
Begin
p := T HT ML_OptionElement(Document.createElement('option'));
p.style.backgroundColor := 'red';
p.style.fontWeight := 'bold';
p.text := 'Computers (most popular)';
p.value := 'item1';

T HT ML_SelectElement(Listbox1.DOMHandle).Options.Add(p,Listbox1.C
ount);

p := T HT ML_OptionElement(Document.createElement('option'));
p.text := 'Socks';
p.value := 'item2';

T HT ML_SelectElement(Listbox1.DOMHandle).Options.Add(p,Listbox1.C
ount);

p := T HT ML_OptionElement(Document.createElement('option'));
p.text := 'Shoes';
p.value := 'item3';

T HT ML_SelectElement(Listbox1.DOMHandle).Options.Add(p,Listbox1.C
ount);
End;
End;

Notes
Some points you may need to be aware of, is that Internet Explorer (IE6 and IE 7) and Firefox
all seem to behave slightly different. For example IE happily shows multiple spaces after each
other, however FF doesn't seem to like that. Neither seem to like the HTML equivalent of the
space character ( ). Also, some style properties show up fine in FF but not in IE. Overall, these
are indicating that the control over listboxes in the browser is very limited.

Page 447
We suggest for you to have a look at the Qooxdoo-like list control from the Labs section. This
control allows to better customize its look, insert images and even modify its implementation
to suit your needs.

See also
 Tips
 Tutorials

External links
 Morfik Forum: How can I show two or more followed space characters in a listbox?
Category:Programming

Page 448
Saving a Report to the
hard disk
(programmatically)

Objective: This project saves a Morfik generated PDF Report to the user's hard
disk when the user clicks on a button in the browser.

Source Files : MorfikForumProject_Saving_Report.zip

Comments : This projects was compiled using Morfik AppsBuilder Release 1


(build v1.0.2.5)

Date Uploaded : 11 May 2007

Original Forum Question: Saving Reports to hard disc or inserting into a


database

See also
 Tips
 Tutorials
Category:Programming

Page 449
Sorting and Filtering Data
at Runtime using
SQLServer Stored
Procedures

Introduction
Say you have a long list (many pages) of data and you want to allow the user to click
headings to sort the data by any column - not just on the one page, but across the entire
result set, or you want to allow the user to define filters at run time on the data returned, or
allow them to limit the number of records to the top n, where n is defined at runtime.

With data in SQLServer, this can be done by writing a Stored Procedure containing Dynamic
SQL and binding it to the form via a Morfik Query.

Background
Let's say we have a table of Countries Countries consisting of CountryID, CountryName
RegionID and Population

Then we have another table called Regions consisting of RegionID and RegionName.

We want to show on a form a list and allow the user to click on the headings and show
countries sorted by RegionName, CountryName or Population.

Solution
Create a StoredProcedure called GetCountryInfo in SQLServer as follows:

CREAT E P ROCEDURE GetCountryInfo @SortColumn VARCHAR(20) = 'xxx' @SortDirection VARCHAR(4) = 'AS


C'

AS

DECLARE @SQL NVARCHAR(4000)

SET @SQL = N'SELECT Regions.RegionName, Countries.CountryName, Countries.P opulation FROM Regions INN
ER JOIN Countries ON Regions.RegionID = Countries.RegionID '

IF @SortColumn <> 'xxx'


BEGIN
SET @SQL = @SQL + N' ORDER BY ' + @SortColumn + ' ' + @SortDirection
END

EXECUT E (@SQL)

Once you have that, you can now go into Morfik AppsBuilder and create a new query called
qryCountryInfo - make it an editable SQL query with the following text (note the SortColumn
and SortOrder string parameters):

EXEC GetCountryInfo SortColumn SortOr


der

Now create a continuous form and bind it to qryCountryInfo. In the form you can manually
bind text labels to the three columns in the detail band and place some text labels in the

Page 450
header, in which you can place the code that calls the query and passes the parameter
values.

See also
 Tips
 Tutorials

External links
Category:Programming

Category:Database

Page 451
Embedding Flash files such as
YouTube videos

Introduction
How do I display YouTube videos in my XApp?

Part 1
Most video-sharing sites offer the appropriate HTML code required to embed a video into your
page. We give details on how to embed the relevant HTML code for a YouTube video, but of
course this can be easily extende or modified for any of the other popular video sharing sites.

Part 2
The following example uses a Container which displays the actual video, and a button. When
the user can view the video by pressing the button.

Unit Index;

Interface

T ype
Index=Class(Form)
Container1 : Container;
Procedure Button4Click(Event: T DOMEvent); Message;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
BodySubform : Subform;
End;

Implementation

P rocedure Index.Button4Click(Event: T DOMEvent);


Begin
Container1.DOMHandle.innerHT ML := '<object width="425" height="350"><param name="m
ovie" ' +
'value="http://www.youtube.com/v/1zoVKU0uv1o">'+
'</param><param name="wmode" value="transparent">' +
'</param><embed src="http://www.youtube.com/v/iLvrOO95hDY" ' +
'type="application/x-shockwave-flash" wmode="transparent" ' +
'width="425" height="350"></embed></object>';
End;

End.

See also
 Tips
 Tutorials

External links
 Morfik Forum: How can I embed external flash files in a page

Page 452
Category:Programming

Category:Presentation

Page 453
Retrieving IP addresses

Introduction
It is common to want to know the IP address of the person that is accessing your XApp.

Solution
The following code in the Execute method of a Morfik WebServices (server side ) would return
the IP address of the person accessing you xApp:

P rocedure MyWebMethod.Execute;
Var
ClientIP : String;
Begin
ClientIP := SoapServer.Request.RemoteAddre
ss;
End;

See also
 Tips
 Tutorials

External links
 Morfik Forum: Retrieving and Converting IP Address
Category:Programming

Page 454
Using associative arrays and
hashmaps

Introduction
How can I use associative arrays and hashmaps on the browser side? In JavaScript, every
object can act as a map, but I don't know how I can leverage that feature from Morfik Pascal.
Any other way is appreciated.

Part 1
The following is an example of how to implement an associative array using Morfik Basic.

/*
%MA DYNAMIC
*/
Namespace Index

' the (0 T o 0) part is just to satisfy the compiler


Public T ype T AssociativeArray String(0 T o 0)

Public Class Index


Inherits Form

Published T extEdit_Index As T extEdit


Published T extEdit_Value As T extEdit
Published Button_Get As Button
Published Button_Set As Button

Private AssociativeArray As T AssociativeArray

Public Javascript Sub CreateAssociativeArray(AAssociativeArray As T Associative


Array)
/*!
AAssociativeArray = new Array();
*/

Published Message Sub WebFormCreate(Sender As T Object)


End Sub

Published Message Sub WebFormReady(ByRef Ready As Boolean)


CreateAssociativeArray(AssociativeArray)
End Sub

Published Message Sub Button_GetClick(Event As T DOMEvent)


T extEdit_Value.T ext = AssociativeArray(T extEdit_Index.T ext)
End Sub

Published Message Sub Button_SetClick(Event As T DOMEvent)


AssociativeArray(T extEdit_Index.T ext) = T extEdit_Value.T ext
End Sub

End Class
End Namespace

Page 455
Part 2
The following section was previously given as a forum response to the same question as a set of
guidelines on how to perform the same task in Morfik Pascal. Despite part 1 being complete in its
own right, this section is presented for the benfit of those who are more familiar with Pascal than
with Basic syntax...

Introduction
Assuming that you are using v9.16.x.x or above, you will notice that inside the "System" unit
in the Framework, we have added the complete set of objects which exist in JavaScript as
defined by ECMA International. We have also introduced a new feature to our compiler which
we currently refer to as "Inline JavaScript" for the browser side. Its purpose is to fill in the
gaps between currently missing features in the supported OO languages and JavaScript.
Using the combination of these two we can benefit from using JavaScript specific features
within Morfik projects:

Consider the following example: As you can see we have defined a function called
"CreateJSArray" for which the body is written in JavaScript. It returns a native Javascript Array
object (TArray). So we prepare the associative Array inside the "CreateJSArray" function and
then consume its content based on the array keys within our normal Pascal environment.
Since TArray has all the javascript Array methods defined you can execute any of its routines
inside your Morfik Pascal code (You can do the same in C#, Basic and Java too).

Please keep in mind that although the Inline JavaScript feature can allow writing a big portion
of your application in JavaScript, excessive use of it may at times introduce weaker coding
precision because the code will not be checked by the compiler. And finally because the Inline
JavaScript feature is a very new addition to the Appsbuilder, there may still be some
uncovered areas which we must address and your feedback can help us better improve this
feature.

Unit Index;

Interface

T ype
Index=Class(Form)
Button1 : Button;
Procedure Button1Click(Event: T DOMEvent); Mess
age;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
End;

Implementation

function CreateJSArray : T Array; Javascript;


(*!
var x = {"x" : 22, "y" : false, "z" : "hello"};
return x;
*)

P rocedure Index.Button1Click(Event: T DOMEvent);


Var
MyJSrray : T Array;
Begin
MyJSrray := CreateJSArray;

ShowMessage(MyJSrray['x']);
ShowMessage(MyJSrray['y']);

Page 456
ShowMessage(MyJSrray['z']);
End;

End.

See also
 Tips
 Tutorials

External links
 Morfik Forum: associative array or hashmap on the browser side
Category:Programming

Page 457
Conditional importing of units

Introduction
Have you ever wanted to do a conditional import? That is, import different units based on a
particular global variable?

Part 1
This is possible in Morfik Pascal as follows

INT ERFACE

Uses
Globals, MyModule1, MyModule
2,

{$IFDEF PROD}
CreditsMYWSDL_P rod;
{$ENDIF}

{$IFDEF NOT P ROD}


CreditsMYWSDL_Dev;
{$ENDIF}

IMP LEMENT AT ION

Part 2
To define the value of prod, use the syntax:

{$DEFINE P ROD
}

and

<{$UNDEF PROD
}

Note that this technique only works for parameters that are effectively equivalent to simple
boolean types, where DEFINE sets it to TRUE, and UNDEF sets it to false.

Note again, that this is a compile-time concept and not a run-time concept. You will find this
syntax throughout the Morfik framework where we do conditional defintions based on the
which type of compiler is being used to compile your project.
For XApp developers, this design-time conditional compiling may be useful, for example, if you
wish to be testing specific parts of the XApp code during a particular stage of the design
process.

See also

Page 458
 Tips
 Tutorials

External links
 Morfik Forum: Imports with condition
Category:Programming

Page 459
Inserting hyperlinks into TextLabel
captions

Introduction
Have you ever wanted to insert a hyperlink into the contents of a TextLabel, either at
design-time or programatically?

Related Code
You can simply insert HTML content into a TetLabel. For example, here is how you can insert a
hyperlink.

T extLabel1.Caption := 'T his is a <a href="www.morfik.com">link</a> to the Morfik w


ebsite';

See also
 Tips
 Tutorials

External links
 Morfik Forum: TextLabel formatting
Category:Presentation

Category:Programming

Page 460
Calling a WebMethod from
the server

Introduction
This shows how to call a WebMethod from within server-side code.

Notes
 This tip has been taken directly from Tim Woordward's blog, which can be found at: .
 All included code is written in Morfik Basic.

Solution
Suppose you have a webmethod named WebMethod1 which takes a string parameter as
input and returns a string parameter as output

to write the value returned by the webmethod into a textlabel of a form, you could write code
such as the following:

Imports WebMethod1

...

P ublished Message Sub FooterMessageBeforeP rint(Sender As T WebControl, Canvas As T WebCanvas, ByRef P rint A
s Boolean)
Dim S As String
S = ""
WebMethod1_(HttpServer, "abc", S)
FooterMessage.Caption = S
End Sub

in contrast to calling a webmethod from browser-side code, the call is synchronous (i.e. the
function call WebMethod1_ does not return until the webmethod has finished its work), and
the webmethod's HandleResponse method never gets called

one situation in which this may be useful is if you want to retrieve a record from a table

every datasource in an xapp has a system webmethod "Get < DataSourceName>" associated
with it

in order to retrieve the value of Table1.Field1 and write it into a textlabel, you could write
code such as the following:

Imports T able1

...

P ublished Message Sub FooterMessageBeforeP rint(Sender As T WebControl, Canvas As T WebCanvas, ByRef P rint A
s Boolean)
Dim P As List Of T able1Record
Dim R As Integer
R=0
P.Init
GetT able1(HttpServer, P , "", "", 0, 1, R)
If R > 0 T hen
FooterMessage.Caption = P (0).Field1

Page 461
End If
P.Dispose
End Sub

Further details
Elaborating a bit on the GetTable1 example ...

GetTable1 (or, more generally, Get < DataSourceName>) takes the following parameters:

P rocedure GetT able1(__SOAPSERVER : P oint


er;
Dataset : T able1P age;
SQLFilter : String;
Parameters : String;
StartingOffset : Integer;
PageSize : Integer;
Var RecordCount : Integer);

it can be quite versatile, as the following examples show

(1) to obtain a specific record from the datasource, supply an sql filter:

Dim P As List Of T able1Record


Dim R As Integer
R=0
P .Init
GetT able1(HttpServer, P , """fID""=2", "", 0,
1, R)
If R > 0 T hen
FooterMessage.Caption = P (0).fT ext
End If
P .Dispose

(2) to retrieve values from a parametric query, pass the list of parameters like so:

Dim P As List Of Query1Record


Dim R As Integer
R=0
P .Init
GetQuery1(HttpServer, P , "", """p1=1"",""p2=2""", 0,
1, R)
If R > 0 T hen
FooterMessage.Caption = P (0).fT ext
End If
P .Dispose

(3) to retrieve, say, the 3rd, 4th and 5th records from a table (in order of creation timestamp),
specify the StartingOffset and PageSize parameters:

Dim P As List Of T able1Record


Dim R As Integer

Page 462
Dim I As Integer
Dim S As String
R=0
P .Init
GetT able1(HttpServer, P , "", "", 2, 3
, R)
S = ""
For I = 0 T o P .Count - 1
S = S & P (I).fT ext & ","
Next I
FooterMessage.Caption = S
P .Dispose

See also
 Tips

 Tutorials

External links
Category:Programming

Page 463
Creating and Calling Firebird
Stored Procedures

Introduction
This tutorial aims at describing the steps needed to create a simple Stored Procedures within
a Morfik Project and call it through a Webmethod. This tutorial has only been tested with
projects that use the default Firebird database server, which is shipped with the AppsBuilder.
You can find information about working with Stored Procedures and external SQLServer here
.

Benefits of using Stored Procedures


The following are quoted from the Firebird Book by Helen Borrie (Chapter 28, page 565):
Modular design: All applications that access the
same database share stored procedures, thus
centralizing business rules, reusing code, and
 reducing the size of the applications.
Streamlined maintenance: When a procedure is modified, changes propagate automatically
to all applications without the need for further recompiling on the application side, unless
 changes affect input or output argument sets.
Improved performance: Execution of complex
processing is delegated to the server, reducing
network traffic and the overhead of operating on
 external sets.
Architectural economy: Client applications can focus on capturing user input and managing
 interactive tasks delegating complex data refinement and dependency management engine.
Extra functionality: Tricky accessing and
messaging of the data that cannot be achieved
with regular SQL usually can be managed with
 one or a suit of stored procedure.

Example
To get started we need to create a table in the database. This one is called " MY_TABLE " with
two fields, " FIELD1 " of Text type and " FIELD2 " of Number type.

The following store procedure inserts a new record with a simple 'HelloWorld' message and
number 200 into the table every time called.

CREAT E P ROCEDURE DO_DUMMY_INSERT


AS
BEGIN
INSERT INT O MY_T ABLE (FIELD1, FIELD2) VALUES ('HELLO WORLD',
200);
END;

To use a stored procedure we need to first define it within the database. In Morfik we can use
the Pass Through query designer. We use it because it lets us manually execute code against
the database. The image below shows the selected item is the Pass Through query designer.

Page 464
After defining the Stored Procedure we can call it by executing the following SQL statement in
another Pass Through query.

EXECUT E P ROCEDURE DO_DUMMY_INSER


T;

Calling Stored Procedures is like calling a Select statement. So it means that we should be
able to call it through the TSQLCommand class which is used for executing DML statements.

Unit WebMethod1;

Interface

T ype
WebMethod1=Class(WebMethod)
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
Procedure Execute; override;
End; ['Published=False'];

Implementation

P rocedure WebMethod1.Execute;
Var
Command : T SQLCommand;
SQL : String;
Begin
SQL := 'EXECUT E P ROCEDURE DO_DUMMY_INSERT ';
Command := DefaultDBConnection.CreateSQLCommand(S
QL);

T ry
Command.P repare;
Command.Execute;
Finally
DefaultDBConnection.DestroySQLCommand(Command);

End;
End;

End.

Page 465
Above example demonstrates creating TSQLCommand to execute the "DO_DUMMY_INSERT"
stored procedure from a WebMethod which is callable from the browser.

See also
 Tips
 Tutorials

External Links
Category:Database

Category:Programming

Page 466
Specifying column names in the Query Builder

Introduction
This tip outlines how to override the columns names when designing a Query using the Visual
Query Builder

Solution
To override the column names in the Query builder, in the Field: row of the grid, place your
column alias before the column name followed by a colon.

So to achieve the following:

SELECT "MyColumn" AS "MyAlias" FROM "MyT a


ble"

Place

MyAlias: MyColum
n

in the query builder's Field row.

See also
 Tips
 Tutorials
Category:Database

Page 467
Making .png images transparent in
Internet Explorer

Introduction
Is there any way to make PNG images transparent in IE (5.5-6.0)?

There are several workarounds in the Internet, but how do I implement them in Morfik?

Part 1
As you've might have realized the Alpha transparency is,by default, not enabled for image
controls in versions of IE prior IE7.

However IE6 allows the loading of transparent .png images via their special loader routine. I
will explain how shortly, however the catch/bug is that the loader can only apply the image as
the background of a control. For example, for an image control if you have used the loader, it
would apply the image as the background of the image control and not as the actual image.
My opinion is that this is really meant for use on other elements such as DIV/Containers.

.GIF images certainly do not produce as nice result as .PNG files when it comes down to
gradual transparency effect in the image, but otherwise they are a good workaround. As a
first recommendation if possible I suggest you stick with transparent GIF files.

One more workaround that I could think of is to use Image controls to show images for those
browsers capable of showing transparent .PNG files and use 'filter' property for the rest of the
versions. This typically involves finding the version of the browser in which the xapp may run
and activating the image loader.

The following code sets image picture to transparent GIF (to make the background of image
visible) and loads the appropriate PNG image to the background of the image control using
filter, in IE prior IE7.

Related Code

Unit Index;

Interface

T ype
Index=Class(Form)
Image1 : Image;
Button1 : Button;
Procedure Button1Click(Event: T DOMEvent); Message;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
End;

Implementation

P rocedure Index.Button1Click(Event: T DOMEvent);


Begin
Image1.P icture:='PNG IMAGE ADDRESS';

// Find if xapp is running in IE6


If (Browser.EngineID = 'MS') and (Browser.Version < 7) T hen
Begin

Page 468
// set the picture to the GIF containing only one transparent pixel.
Image1.P icture := 'blank.GIF';
// Apply the loader
Image1.DOMStyle.filter := 'progid:DXImageT ransform.Microsoft.' +
'AlphaImageLoader(src=''P NG IMAGE ADDRE
SS'')';
End;
End;

See also
 Tips
 Tutorials

External links
 Morfik Forum: PNG transparency in IE
Category:Presentation

Page 469
Input mask routine

Introduction

Part 1
How can I do a InputMask routine ? For example, in the contexdt of the onKeyDown event of
a TextEdit control. How can I do it?

Part 2
Here is one way of doing it, but currently it only works in internet explorer. Change the
keydown event handler to look like this:

Function Index.T extEdit1KeyDown(Event: T DOMEvent) : bo


olean;
Begin
if event.keycode = '65' then // this blocks the letter 'a'
begin
event.keycode := '';
result := false;
end
else
result := true;
End;

See also
 Tips
 Tutorials

External links
 Morfik Forum: InputMask
Category:Programming

Page 470
Using Scriptor - basic
example

Introduction
This describes a basic application using Scriptor, which demonstrates method of
communicating with server.

Notes
This tip has been taken directly from Arman's blog, which can be found at: .

It comes with an project that you can download, study and modify.

-> <span style=" text-decoration:none;cursor:pointer">Download the example here</span>


(882kb)

Background
There are two major parts to this example:

* the Scriptor P roject - UI or the Client (P roject 15 placed inside Project16


folder)
* the AppsBuilder P roject - T he server (Project 16)

Minor parts:

* very little DOM programming - (Project 15)


* a simple pre-made HT ML file - (P roject 15) it has a Combobox and a T extedit. When the Combobox value cha
nges it sends a request to the server and writes the response to the T extEdit.
* custom servers - (P roject 16) put in place which effectively cripples the Xapp, so that it can only respond to c
ertain calls. T hese Custom Servers are examples of what I've talked about in my previous blogs.

Obviously using the AppsBuilder is my closest bet to getting a server up and running.
Nevertheless any server technology out there like the asp.net, php, ruby, java servelets and
etc will be just as good for feeding data into the UI which we build with the Scriptor.

The Cross Domain communication is generally not the case for most people but if you're not
aware of it you may end up spending a while figuring what's wrong. Essentially it is browser's
way of making sure that scripts can only operate within their own domain space. This means
that we can only request data from a server which served our UI or servers with sub domains
under the same Domain Name as the server that served the UI. So if the UI was served out of
www.morfik.com it can communicate with www.morfik.com or it's sub domains such as the
labs.morfik.com.

Currently when programming with the Scriptor, it appears to be really low level and not much
of the library seems to be available to work with. This is because the browser framework
makes certain assumptions about it's server (being an Xapp). These assumptions are minimal
and shall be removed in the future. In fact just with a little bit of trickery you should be able to
start using the framework just like you would when developing an AppsBuilder project.

See also
 Tips
 Tutorials
Category:Programming

Page 471
Page 472
Inserting a new line into a TextEdit

Introduction
How can I do a carriage return in a multiline TextEdit programmatically?

Part 1
TextEdit formatting can be done via standard HTML formatting. In your case the backslash n
syntax is what you need.

MyT extEdit.T ext :='First Item\nSecond Item\nT hird I


tem';

See also
 Tips
 Tutorials

External links
 Morfik Forum: Carriage return in text edit
Category:Programming

Category:Presentation

Page 473
Optimizing initial loading times of XApps

Introduction
The tips below provide techniques to reduce the time taken to initially load an XApp and
improved on-going responsiveness.

Using the options in the AppsBuilder


 Make use of the "Compress HTTP data using gzip" in Tools/option/Webserver.
Make use of the "Obfuscate JavaScript" flag in
 Tools\Options\Compiler.
Make use of the "Optimize
JavaScript" flag in
 Tools\Options\Compiler.

Development/Programming
The server and browser caching of the forms and reports can be applied
to further optimize speed. Careful analysis is required (in particular with
the server caching), as this will affect the displaying of the contents that
are updated. The cached forms on the server need to be removed after
 any content updates used within a cached form.
Prefetch of forms to be included in the design. This needs to be applied carefully as it could
 affect the first impression of the users. (See example below).
Replacing subforms used in the main form with Container controls could
optimize speed. The contents of the form that is opened within a
subform could be placed within the container and the visible property
used to display/hide contents in the container. One example where this
 could be applied is in the Login form.
Minimizing the usage of the “OpenMode=Refresh” parameter in the OpenForm function. This
 parameter results in the re-loading of a form every time.
Analyzing and timing the layout manager routine
 using the Profiler monitor.
If Flash files are being
used, try reducing its file
 size.

Prefetching
Prefetching is a technique that could be implemented by a developer to enhance XApp
performance by loading the frequently used forms within a subform in the background. This is
possible as every subform can store (cache) a number of forms (set by the "FormBufferLimit"
property of a subform) and get activated as necessary.

Following example shows how "frmContacts" and frmOverview are loaded but not activated in
the MainSubForm of the Mainform of the project. This action takes place when the home page
(frmHome) is shown.

P rocedure frmHome.WebFormShow(Var Show: Boolean); Begin


If Not DoneP refetch T hen
Begin
OpenForm('frmContacts'
,'Mainform:MainSubForm','"OpenMode=DONOT ACT IVAT E"');
OpenForm('frmOverview'
,'Mainform:MainSubForm','"OpenMode=DONOT ACT IVAT E"');
DonePrefetch := T rue; \\ Defined as a P ublic (Boolean) property of th
e form.
End;
End;

Page 474
This means that the frmContacts or frmOverview opens instantly when they are requested.

A word of warning : This technique should be used with care as if not used correctly, the
resulting time it requires to prefetch some forms could negatively affect XApp
responsiveness.

See also
 Tips
 Tutorials
Category:Deployment

Page 475
Formatting dates and
times in TextLabels

Introduction
When you bind a TextLabel to a dateTime field, you can specify how the date and/or time is
displayed.

Part 1
When displaying dates using a TextLabel, in the PropertySheet there is a property called
'Format'. Included below are some syntactic examples of how to format the displayed date
and time, as well as the corresponding run-time output.

Note that the delimiters that we used (spaces, hyphens and slashes) in the first column are
not part of the syntax and could be replaced with any other character that you may choose.

For the output, we assume that the date is Wednesday 2nd August 2006, 1:30pm

Syntax Ouput
d-m-yy 2-8-06
dd-mm-yy hh:mm 02-08-06
mm-dd-yy hh:mm 08-02-06
ddd d mmm yyyy Wed 2 Aug 2006
dddd dd mmmm yyyy Wednesday 02 August 2006
hh:mm 13:30
hh:mm:ss 13:30:00
hh:mm am/pm 1:30pm
dd/mm/yy hh:mm am/pm 02/08/06 1:30pm

Notes
This is only applicable to Continuous Forms.

See also
 Tips
 Tutorials

External links
 Morfik Forum: TextLabel with databinding format
Category:Presentation

Page 476
Retrieving the control that triggers an
event

Introduction
Often you may wish to use the re-use event handlers across multiple controls. However, in
this situation, it is common that you need to know which particular control was fired when
event was called.

Solution
This example shows how to retrieve the control that triggers the event, and how process its
characteristics such as class type, name and caption.

Note : that if you refer to an attribute that is specific to a particular class that has descended
from TWebControl (eg Caption) then you will need to typecast the control first.

P rocedure MyForm.MyMethod(Event: T DOMEvent);


Var
aWebControl : T WebControl;
aControlName : String;
Begin
aWebControl := GetEventSource(Event);
If Not (aWebControl Is T extLabel) T hen
Begin
ShowMessage('Not a T extLabel');
Exit;
End;
aControlName := aWebControl).Name;

If aControlName = 'BookT itle' T hen


ShowMessage( 'Book title is '+ T extLabel(MyWebControl).Capti
on );
End;

See also
 Tips
 Tutorials

External links
 Morfik Forum: How can I get the object that fire an event?
Category:Programming

Page 477
Invoking an event OnClose of browser
window

Introduction
There are times when you wish to invoke some code just prior to the window closing due to
the user pressing the close window or close browser icon (eg save some data).

Background
This example is a direct port of the following code which was contributed by a pioneer, Jesus
Yanez Miranda.

<HT ML>
<HEAD>
<SCRIP T >
function unload()
{
alert("unload")
}

function beforeunload()
{
alert("beforeunload")
}

<T >

<SCRIP T for="window" event="onload


">
window.onunload = unload;
window.onbeforeunload = beforeunload;

</SCRIP T >

</HEAD>
</BODY>
</BODY>
</HT ML>

Solution

Unit Index;

Interface

T ype
{..............................................................................}
Index=Class(Form)
Procedure WebFormReady(Var Ready: Boolean); Message;
P rivate
{ P rivate declarations }
P ublic

Page 478
{ P ublic declarations }
Procedure SaveOnClose(Event : T DOMEvent);
End;
{..............................................................................}

Implementation

{..............................................................................}
P rocedure Index.SaveOnClose(Event : T DOMEvent);
Begin
ShowMessage('onbeforeunload');
End;
{..............................................................................}

{..............................................................................}
P rocedure Index.WebFormReady(Var Ready: Boolean);
Begin
Window.onbeforeunload := GetMethodP ointer(Index,@SaveOnCl
ose);
End;
{..............................................................................}

End.

See also
 Tips
 Tutorials

External links
 Morfik Forum: If I close the browser, is fire some event that can be captured?
Category:Programming

Page 479
Using Zapatec Tree
Control

This short example will show how to configure the Zapatec Tree control.

The complete structure of the Node objects must be placed in the items property
of the Zapatec tree control. Node and sub nodes are built as HTML-list elements.
Each node-object is one entry in this list:

<li> Node 1
<ul>
<li> SubNode 1.1 </l
i>
<li> SubNode 1.2 </l
i>
<li> SubNode 1.3 </l
i>
<li> SubNode 1.4 </l
i>
</ul>
</li>

As you can see, sub node-objects are placed in a UL-element. Once you have a
structure that fits your needs, you can copy the whole string into the items
property. Next time you start the application the tree-structure will be show in the
control.

After you have built the structure you will want to catch events, such as if the user
clicks on a node. Therefore create a new event handler for the OnItemSelect
event in the Configuration of the tree control:

Function Index.ZapatecTree1ItemSelect(const ItemID: String): Bo


olean;
Begin
ShowMessage('Node Clicked ' + ItemID);
End;

Every time a node is clicked, the handler fires the event.

In the ItemID parameter (which is of type string) of the method you will find the
name of the clicked node. It is an automatically generated ID. If, for example,
node four was clicked, then the ItemID will contain zapatec-tree.item-4. If you
want to override this automatic ID, you will need to to place an id-tag in the open
tag of the li element (id="ITEM1ID").

<li> Node 1 </a>


<ul>
<li id="ITEM1ID"> SubNode 1.1 </
li>
<li id="ITEM2ID"> SubNode 1.2 </
li>
</ul>

This way, when you click the node you will get the custom-defined name that is

Page 480
defined from the tag id in the ItemID parameter of the event.

See also
 Tips
 Tutorials

Page 481
Using custom servers

Introduction
I want to quickly go over something that I call "Custom Server" (CS), what it is and why it is
useful. It really deserves an article which I will write soon but for now this will do.

Essentially, building a CS is writing a specialized script that produces a result other than the
normal (Form, Report and etc) and could be directly requested by the browser. Also the
returned content can be dynamic by passing parameters to the server to produce results
accordingly.

Here a quick list of things that you may wish to use a CS for:
 .CSV file containing data from a certain table - example here
 Generating Captcha Security images

 JASON formatted data

Notes
This tip has been taken directly from Arman's blog, which can be found at: .

Details

How are Custom servers implemented?

Unit MyCustomServer;

Interface

Uses
SystemServer,
SystemUtilities;

T ype

T MyCustomServer = Class(T HT T P Server)


Constructor Create(aRequest : T HT T P Request; aResponse : T HT T P Response);
Procedure ValidateRequest; Override;
Procedure Execute; Override;
End;

Implementation

Constructor T MyCustomServer.Create(aRequest : T HT T P Request; aResponse : T HT T P Res


ponse);
Begin
Inherited Create(aRequest,aResponse);
End;

P rocedure T MyCustomServer.ValidateRequest;
Begin
// T hrow an exception if an error was detected with the request
End;

P rocedure T MyCustomServer.Execute;
Var

Page 482
S : String;
Begin
S := '';
S := S + Request.GetURLParameterValue('param1');
S := S + Request.GetURLParameterValue('param2');

Response.WriteLnString(S);
Response.ContentT ype := 'text/plain';
End;

End.

How are custom servers instantiated?

Unit MyXApp;

Interface

T ype
T MyXApp = Class(T XApp)
P ublished
{ Events }
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
Function GetHttpServer(Request : T HttpRequest; Response : T HttpResponse): T HttpServer; O
verride;
End;

Implementation

Uses
MyCustomServer;

Function T MyXApp.GetHttpServer(Request : T HttpRequest; Response : T HttpResponse): T HttpS


erver;
Begin
If Request.GetURLParameterValue('cls') = 'MyCustomServer' T hen
Result := T MyCustomServer.Create(Request,Response)
Else
Result := Inherited GetHttpServer(Request,Response);
End;

End.

...

// you can have a hyperlink with a url like this

<a href="MyServer.txt?cls=MyCustomServer&param1=param1Value&param2=param2
Value"

Page 483
target="_blank">Show Custom Server Result</a>

...

Further notes
Arman says on his blog: " By the way, I haven't compiled this code yet, because it really late in
the morning, but a working example can be found in the "Morfik Features" sample projects. It's
called "Progressive Lookup Search Bar". It should convey the message across. "

See also
 Tips

 Tutorials

External links
 Morfik Forum: PNG transparency in IE (sic.)

 Morfik Forum: core functions Category:Programming

Page 484
Browser Not Refreshing

Introduction
If you have tried to refresh the browser and end up with an empty page, chances are you
need to switch to long URL names.

Solution
In the Apps Builder IDE, open Project Options and choose the Application tab. Make sure the
checkbox Long URL is checked.

See also
 Tips
 Tutorials

External links
Category:Deployment

Category:IDE

Page 485
Debugging Client-side

Introduction
There are some issues with debugging client-side that are worth knowing. If you set a
breakpoint and step through the code you may experience weird line synchronisation. This is
caused by the JavaScript obfuscation setting.

Also note that while you are debugging client side, SQL monitoring is disabled, even if you
have that option checked in the debugger options.

Solution
If you want to step through the code on the browser side - turn off code obfuscation. To do
this, open the Project Options dialog and on the Compiler tab turn off Obfuscate JavaScript by
unchecking the checkbox.

See also
 Tips
 Tutorials

External links
Category:Programming

Category:IDE

Page 486
Defining composite primary keys

Introduction
Some times you need to define a primary key that is a combination of two fields. This is called
a primary composite key.

Part 1
To define a composite Primary key,
1 open up the Table Designer,
2 right click on the first field and select "Primary key",

3 right click on the second field and click on "Composite Primary key".
You should now see two key images next to the two fields which indicates that they form a
composite primary key.

See also
 Tips
 Tutorials

External links
Category:Database

Page 487
Modifying font attributes on
the server-side

Introduction
There are many cases when you wish to modify the font attributes of, say a TextLabel, on the
server-side. This will most likely occur in context of the server-side event handlers such as
OnAfterPrint, OnBeforePrint, etc.

Some of the control properties can not be modified in the same way that you would
typically do in the browser-side logic. This includes font, position and size attributes .

This issue may be addressed in future releases, however ,until then, here is how you can do
it.

Solution
The following code is an example of how you can change font color and position of a
TextLabel control in the Server Side:

Unit Index;

Interface

T ype
Index=Class(Form)
T extLabel1 : T extLabel;
Procedure T extLabel1BeforePrint(Sender: T WebControl; Canvas: T WebCanvas; Var P rint: Boolean);
Message;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
End;

Implementation

P rocedure Index.T extLabel1BeforePrint(Sender: T WebControl; Canvas: T WebCanvas; Var P rint: Boolean


);
Var
Font : T Font;
Begin
// Change the font color

Font := T extLabel1.Font;
Font.Color := $00000FF;
T extLabel1.Font := Font;

// Changes the pixel position of the control;

T extLabel1.stcT op := P ixel(200);
T extLabel1.stcLeft := Pixel(500);
End;

End.

Page 488
See also
 Tips
 Tutorials

External links
 Morfik Forum: Server-Side FontColor
Category:Presentation

Page 489
Using Google APIs in
XApps

Introduction
Google Maps and Google Search controls can be incorporated into your XApp. This tip
mentions some points to help you implement this in your project.

Method
In order to use Google Map or Google Search controls in your xApp you need to drag and
drop the appropriate controls onto your form then sign up for a Google Maps API key to be
added to your xApp.

Google Maps
To register for the Google MAP API keys go to the following link www.google.com/apis/maps/
and follow the steps to sign up.

For your initial development process on your pc you could get a key for

'localhost' URL (http://localhos


t/).

Copy the automatically generated key and place it in the XAppPrintHTMLHeader event of your
xApp as shown below:

P rocedure GoogleControlsXApp.XAppP rintHT MLHeader(Response: T HT T P Response; Var P rint: Boolean);


Begin
Response.WritelnString('<script
src="http://maps.google.com/maps?file=api&v=1&key=ABQIAAAA0IfQsKSu7rXA-rzI8NbZghT 2yXp_ZAY8_ufC3
CFXhHIE1NvwkxQHBJ2OQeUBUrbdbm7cSBSJka2WGA"
type="text/javascript"></script>');
End;

Once this is added to your project you should be able to run the xApp and view the map
information in the the Google Map control. You can change the configuration of the map
through the control configuration properties.

Google Search
Similar steps are required in order to add Google Search capabilities to an xApp. Place the
Google Search control on a Morfik form and add an entry in the XAppPrintHTMLHeader event
of the xApp with the supplied Google Search key from code.google.com/apis/ajaxsearch/ .

See also
 Tips
 Tutorials

Links
Category:Programming

Page 490
Firewall Compatibility

Firewalls
Symantec - Everytime there is a newly compiled
XApp you have to OK the program by clicking - a
minor annoyance but no big deal. (Temporarily
disabling Transaction Security does away with
1 this annoyance.)
ZoneAlarm - As a result of testing and user reports this firewall is incompatible with Morfik -
2 Avoid.

See also
 Tips
 Tutorials
Category:Deployment

Category:IDE

Page 491
Formatting numbers

Introduction
Morfik AppsBuilder does not currently have a full implementation for fomattting numbers in
TextLabels.

Various forum responses have been written to address this issue.

This tip, shows how to add comma separators for large numbers and currencies. eg 314159
-> 3,141,592

Comma Separators
The following code allows large numbers and currencies to have comma separators every 3rd
digit.

Function addCommas(nStr : String) : String;

Function getRegXP : T RegExp; JavaScript;


(*!
return /(\d+)(\d{3})/;
*)

Var
S1,S2 : String;
RegExp : T RegExp;
Arr : T Array;
Begin
Arr := T String(nStr).Split('.');
S1 := String(Arr[0]);
RegExp := GetRegXP ;

If Arr.Length > 1 T hen S2 := '.' + String(Arr[1])


Else S2 := '';

While RegExp.test(S1) Do
S1 := T String(S1).Replace(RegExp, '$1' + ',' + '$
2');

Result := S1 + S2;
End;

P rocedure Form1.Button2Click(Event: T DOMEvent);


Var
c : Double;
Begin
c := 5000000.89256;
T extEdit1.T ext := addCommas(T Number(c).toFixed
(4));
End;
// will output: 5,000,000.8926

Page 492
Displaying rounded numbers
The Format property does not work on the non-databound.

Following function should display numbers to two(2) decimal points, which is very frequently
required especially for currencies.

P rocedure Form1.WebFormReady(Var Ready: Boolean);


Function eval(exp : String) : string External;
Var
SubT otal : Real;
Begin
SubT otal := 1234.2345;
SubT otalLabel.Caption := eval('(' + FloatT oStr(SubT otal) + ').toFixed
(2)');
End;

See also
 Tips
 Tutorials

External links
 Comma Separators Morfik Forum: formating text number
Morfik Forum: Formatting
 Numbers
Morfik Forum: Formatting
 Numbers
 Morfik Forum: Number (currency) Formatting
Category:Programming

Category:Presentation

Page 493
Creating timers
programmatically

Introduction
This shows how to create a timer programatically without using the AppsBuilder's built-in
Timer control.

Notes
This tip has been taken directly from Arman's blog, which can be found at: .

Solution

Interface

T ype

Index=Class(Form)
Button1 : Button;
Procedure Button1Click(Event: T DOMEvent); Message;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
End;

Implementation

P rocedure Index.Button1Click(Event: T DOMEvent);


Begin
RunOnT ime(0);
End;

Function RunOnT ime(StartValue : Integer);


Var
Interval : Integer;
Begin
Interval := 1000; // one second
ShowMessage(IntT oStr(StartValue));
Window.SetT imeOut(FunctionName(RunOnT ime) + '(' + IntT oStr(StartValue + 1) + ')',Interval,'java
script');
End;

End.

See also
 Tips
 Tutorials

External links
Category:Programming

Page 494
Page 495
Searching a Table

Introduction
This tip outlines a few methods for doing search in a project table.

Filter By Form
You could use the "Filter by Form" technique in a databound single form by making use of the
"Menu" option in the Navigator. At run time use the "Filter by Form" to enter the criteria of
the search and then "Apply Filter" option to filter records. Finally to clear filter and see all
records, use the "Remove Filter" to show all records.

There are examples for this method in the "issue tracker" sample project which is available in
the Morfik Labs for download. In this case, look at the frmBugEdit Form.

Query with Parameters


The second method is to use a non-data bound form and through some TextEdit controls
collect any required information and on clicking the search option, use OpenForm command to
open a continuous form which is based on a Query that takes the entered values as
parameter values and use the datasource query to filter out records.

There are examples for this method in the "issue tracker" sample project which is available in
the Morfik Labs for download. In this case, check the frmAdvanceSearch form (accessed by
clicking on "Advanced Search" link in frmSearch form).

Query without Parameters


There is another method, which is used in the frmSearch Form of the Issue tracker sample
project. You can see how the technique is used by viewing the code and clicking on the "Go"
button. This technique has some similarities to the second method but you don't need to
define any parameters in the query behind the SearchResult form. There is a small server
side coding in the server module of the form that is required where you specify the
datasource fields to search. This technique however may be more suitable for entering one
value and wanting to search within a few fields.

See also
 Tips
 Tutorials

Links
Category:Programming

Category:Database

Page 496
Retrieving the filename
entered in the FileUploader

Introduction
This tip describes how to obtain the filename entered in a file uploader control

Method
Use code such as the following:

P ublished Message Sub Button1Click(Event As T DOMEvent)


T extEdit1.T ext = Ctype(FileUploader1.FileBrowserArray.Handle(BandIndex), T HT ML_InputElemen
t).Value
End Sub

Notes
Due to security restrictions implemented by all major web browsers; only the end user may
set the filename.

See also
 Tips
 Tutorials

Links
Category:Programming

Category:IDE

Page 497
Retrieving WebMethod exception messages

Introduction
If an exception is raised during the execution of the server-side code of a webmethod, details
of the exception may be obtained in the browser-side code by checking the FaultCode and
FaultDetails variables

Example webmethod
This is an example code in Morfik Basic

server-side code

P ublic Overrides Sub Execute


...
T hrow New Exception("this is an excepti
on")
...
End Sub

browser-side code

P ublic Overrides Sub HandleResponse


If FaultCode <> "" T hen
ShowMessage("ERROR:\n" & FaultDetai
ls)
Else
ShowMessage("SUCCESS")
End If
End Sub

See also
 Tips
 Tutorials

External links

Category:Programming

Page 498
Changing the hint property at run-time

Introduction
This tip shows how to change the value of the hint property at run-time

Code

Unit Index;

Interface

T ype
Index=Class(Form)
Button1 : Button;
Button2 : Button;
Procedure Button1Click(Event: T DOMEvent); Mess
age;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
End;

Implementation

P rocedure Index.Button1Click(Event: T DOMEvent);


Begin
Button2.DomHandle.title := 'hello world';
End;

See also
 Tips
 Tutorials

External links
 Morfik Forum: hint property
Category:Presentation

Page 499
Working With XML Data

Morfik Web Application projects are tightly integrated with the database to help
you quickly build sophisticated Web-based appliations. Morfik Browser Application
projects do not provide direct access to databases as they are intended to be
pure browser applications. However, they do allow you to take advantage of a lot
of database-oriented functionality which is provided by the Morfik Framework. In
order to enable this technology Morfik introduced XML Data Sources.

XML Data Sources are viewed in the Morfik Workspace as tables and treated as
such by the Form designer and the Morfik Framework. They are, however, XML
files which store your information in a with a predefined set of XML tags which lets
the Morfik Framework identify each record and then each field within a record.

The following topics will provide you with a more detailed view of the different
aspects of the usage of XML Data Sources:
 Defining XML Data Sources
 Entering XML Data

 Linking Forms and Controls to XML Data

Page 500
Linking Forms and
Controls to XML Data

XML Data sources are always considered to be tables in Morfik Browser projects.
This means that using these data sources in your projects is very much the same
as using a regular database table in a traditional Morfik project (Web projects in
Morfik AppsBuilder).

Linking Forms to XML Data Sources


Just as with traditional database tables, the way to link a specific Form to an XML Data source is to
associate its Data Source property to that Data Source. This can be done through the Property
Inspector panel which is available on the left side of the Morfik workspace.

Once you have

Figure 1 - Selecting an XML data source for a Form.

Linking Controls to XML Fields


Again, as with regular database tables, linking Morfik controls to specific fields of a data source is as
simple as selecting the field name in the "Data Field" property of the control. All the fields belonging
to the data source that has been linked to the "Data Source" property of the Form which contains the
control will be visible in the drop down list that appears when you click on the property in the
Property Inspector panel.

Page 501
Figure 2 - Selecting a Field from an XML data source for linking to a control.

See Also
 Working With XML Data
 Defining XML Data Sources

 Entering XML Data

Page 502
Working with
WebActions

There are two aspects to working with WebActions: using pre-existing WebActions
and creating your own WebActions. Both of these aspects are discussed in further
detail in specific topics.
 Using WebActions
 Creating WebActions

Page 503
Creating WebActions

It is actually quite simple to create a WebAction. In this topic a simple WebAction is


created to extend the standard OpenForm WebAction with some
application-specific custom behavior. In this case an action is created so that
several pages which use the same Form for their headers can be visually
differentiated by the end users.

The listing below shows the Globals module, in Morfik Pascal with the code for
creating a WebAction called OpenFormEx.

(*
* Global routines for the Rio de Janeiro Hosting sample website.
* - Custom WebActions
*)
Unit Globals ;

Interface

Uses SystemControls , SystemActions ;

{..........................................................................
.....}

(**
* This action has the same general functionality as OpenForm but adds an

* application specific behavior which is to allow the user to specify a tit


le
* which will be displayed in the Header area.
*)
Procedure OpenFormEx ( FormName , Title , Target , Parameters :
String );
[ 'WebAction=True' , 'WACategory=form' ,
'WAParam=name:FormName;displayValue:open;editor:FormName' ,
'WAParam=name:Target;displayValue:in;editor:FormTarget' ,

'WAParam=name:Parameters;editor:OpenParameters;displayValue:with parameters
' ,
'AutoSynchronize=Manual' ,
'optimize=false' ,
'obfuscate=false' ];

Implementation

Uses SiteHeader ;

Procedure SetTitle ( ATitle : string );


Begin
If Not ATitle . IsEmpty Then
SiteHeader ( XApp . Forms [ 'SiteHeader'
]). TitleLabel . Caption := 'Rio de Janeiro Hosting - ' + ATitle
Else
SiteHeader ( XApp . Forms [ 'SiteHeader'
]). TitleLabel . Caption := 'Rio de Janeiro Hosting' ;
End ;

Procedure OpenFormEx ( FormName , Title , Target , Parameters :

Page 504
String );
Begin
SetTitle ( Title );
OpenForm ( FormName , Target , Parameters );
End ;

End .

Notice that in the Interface section of this module, the declaration for the
OpenFormEx function which actually implements the WebAction, of the same name,
is followed by a metadata tag. It is this metadata that instructs the Morfik compiler
to treat this function as an action an tells it how to treat each of the parameters.
Bellow you can see the isolated code for this tag.

[ 'WebAction=True' , 'WACategory=form' ,
'WAParam=name:FormName;displayValue:open;editor:FormName' ,
'WAParam=name:Target;displayValue:in;editor:FormTarget' ,

'WAParam=name:Parameters;editor:OpenParameters;displayValue:with parameters
' ,
'AutoSynchronize=Manual' ,
'optimize=false' ,
'obfuscate=false' ];

In creating this sample WebAction we have repeated all the metadata information
for the OpenForm WebAction as the parameters of that WebAction are of special
types which have specialized editors in the WebAction Wizard. Our new parameter
is a simple string and does not require any additional metadata information. The
order in which the WebAction parameters appear in the WebAction wizard dialog is
determined by the order of the parameters in the actual function declaration.

Procedure OpenFormEx ( FormName , Title , Target , Parameters :


String );

As our additional parameter, called "Title" was introduced as the second


parameter of the standard OpenForm WebAction, the wizard displays it also in the
middle position as shown in Figure 1.

Page 505
Figure 1 - The WebAction Wizard displaying the parameters page. The form field
for entering the new title parameter for the form is highlighted.

See Also
 Working with WebActions
 The Workspace

Page 506
Using WebActions

WebActions are predefined actions, which can be assigned to execute when a


specific even is triggered by a control or document. To assign a WebAction to an
event of a specific control, just go to the Events Inspector panel and select the
desired event.

Click on the ellipsis button that appears to the right of the event’s row in the
Inspector and the WebAction Wizard will be displayed, as shown in Figure 1.

Figure 1 – Starting page of the WebAction wizard.

When the wizard starts you can select from a variety of WebActions which are
divided up into categories, as seen in Figure 1. Once you have selected the action
you would like to be invoked, you need to specify parameters to that WebAction,
as shown in Figure 2.

Page 507
Figure 2 – Specifying parameters for a WebAction.

In this particular case the WebAction that was selected was the OpenForm action
and it works exactly like when you write code that calls the OpenForm method.
Actually, the WebAction wizard generates a small code snippet inside the
appropriate event handler. The code for the parameters specified in 2 can be seen
in the following code snippet.

P rocedure ArticleSummaryList.T extLabel2Blur(Event: T DOMEvent);


Begin
OpenForm('ViewOneArticle', 'MainP age:SubForm1', '"ParamId=' + T extLabel4.Caption
+ '"');
End;

Once a WebAction has been assigned to a specific event handler you can still
visually edit them by just clicking on the start of the appropriate line in the code
editor and select the “WebAction Editor” from the smart tag menu. Figure 3 shows
the WebAction editor.

Page 508
Figure 3 –The WebAction editor.

Navigating with WebActions


You can implement simple navigation through your website or application by using simple
WebActions such as the OpenForm action in the Form category. This action can be used to
instruct the application to navigate to another Form that you have created in your project.
Form navigation is optimized, by the Morfik Framework, and no unnecessary roundtrips to the
server will be made if the new page includes one or more Forms which have already been
downloaded.

Figure 3 – Specifying parameters for the OpenPage WebAction.

Manipulating Controls with WebActions

Page 509
You can choose to use WebActions to work such small actions as Highlighting or showing and
hiding controls. This is made possible through the Control category of WebAction, as seen in
figure 4.

Figure 4 – Actions in the Control category in the WebAction Wizard.

In this case, if you choose to Show a control using the ShowControl WebAction, you will be
asked for the parameters of the action as shown in Figure 5.

Figure 5 – Parameters for the ShowControl WebAction.

Note

Page 510
This list is not yet complete and does not represent all the WebActions which will
be available in Morfik AppsBuilder R2.

Page 511
Managing Resources

Most websites and Web-based applications will use some image files. They can
represent company logos, bullets or other graphical elements that compose the
design you want to create. These images need to be included in your Morfik
project as resources.

There are other types of files which can be included in an application such as
JavaScript, text and HTML files. How to add these files to a Morfik project and how
to use them is covered in the following topics.
 The Resource Explorer
 Adding Resources to the Project

 Types of Resources

Page 512
Demos

Morfik AppsBuilder comes with a number of sample


applications.

BookCollector

MappingDevice
Tetris

BookCollector
This project provides basic units that illustrate many of the core features of Morfik
AppsBuilder: including Single and Continuous Forms, PDF reports, sorting and grouping,
tables, parameter queries, event handling, and lots more!

MappingDevice
This project mimicks the appearance of a portable mapping device, and shows how you can
utilize Google Maps functionality in your Morfik project.

Tetris
Enjoy hours of fun with this classic game! As each block falls, use the cursor keys to guide it
into the correct position.

Page 513
Database
Programming

This topic will provide you with a general overview of how to plan your application
’ s interface based on a database model you have previously constructed. In this
particular case we will see how to plan a generic site interface for the publication
of articles, grouped under sections. Our primary objective is to create a simple but
flexible application which will allow all of the website ’ s contents to be edited
without the requirement of changing the supporting database.

In order to achieve this goal, while maximizing the effective of Morfik AppsBuilder
and the Morfik Framework we will see how to use simple but effective queries and
small snippets of code to link everything together into the desired behavior for a
website. Through out this topic we will be using the database that was created in
the Database Modeling as the basis for our small CMS application.

Planning a Site’s Layout


Creating the Interface
The SiteMain Page
The Header Form
The Footer Form
The SideBar Form
The SideBar Data Source
The SectionContent Form
The SectionContent Data
Source
The ArticleContent Form
The ArticleContent Data
Source
The ViewOneArticle Form
The ViewOneArticle Data
Source
Wrapping it up
See Also

Planning a Site’s Layout


A website ’ s layout is generally associated with its purpose and with the aesthetic sense of the
designer in charge of its creation. In our case, we will be relying mostly on practical sense and in
creating a layout which can be applied to almost any kind of topic or subject about which someone
might want to publish information. We chose to follow a popular layout for websites, where we have
a menu of options on the left side, a header at the top with the title and informational content in a
larger portion of the page.

This general layout has been quite popular with websites for many years, being practical while not
the most sophisticated of designs. Figure 1 shows our sample application running in the Morfik built-in
Debug browser. Each of the three areas that we have just mentioned can be seen marked with
rectangles and identifying numbers.

This particular layout matches very well the information we want to present in our generic website.
First there is the name of the website, which must be presented. Second there are different areas of
interest for topic publication, or in our database model ’ s terms: sections. It stands to reason that if
have topics classified into sections we might want to choose which section ’ s articles we want to
see/read.

Page 514
The new layout tools which were introduced in Morfik R2, make it quite simple to apply a layout to a
page and later, if you wish change the layout to a totally different one. To that effect you can simply
choose a layout from the gallery in the Page designer, as we will see further ahead in this topic.
Figure 1 shows the basic layout that we wish to implement, with the final application running within
the Morfik Debug Browser.

Figure 1 – Morfik CMS project running within the Morfik Debug Browser. Areas which present
information from different data sources are highlighted by red rectangles.

Beyond what can be seen in Figure 1, our sample site ’ s home page should have a footer, which will
present the website ’ s copyright message. The website ’ s footer is highlighted in Figure 2.

Figure 2 – Footer section of the home page of the


Morfik CMS sample project.

Page 515
To create this layout data comes from several tables: WebsiteInfo , Section , Article and UserCat .

Information shown in the header and footer come from the WebsiteInfo table. This table always holds
only one record which has the basic information about the website: Title, Subtitle, copyright message,
etc. The list of topics or sections that appears to the left of the page (in the area marked with the
number 2) comes from the Section table and the titles, summaries of articles and the names of
authors (in the area marked with the number 3) come from two tables Article and UserCat .

Creating the Interface


The first step in creating the interface for this application is creating the main Page and applying the
desired layout to it. This will be the starting point for users coming into the application/website and
the starting point of our design as well.

The SiteMain Page


That starting point for our application will be the SiteMain Page. This page will effectively bring
together all the interface components in the appropriate layout for displaying the MorfikCMS "Home"
page.

By default Morfik projects are created with one page and three forms: Header , Footer and Content .
We will be using these initial forms as part of our application. In this case, however, we need to have
one more area in our layout because we need to display two different types of content in the page.
We want to have a list of sections and a list of articles. The list of articles being defined by which
section is selected by the user.

In order to have such a layout we need to go to the newly created page and choose to apply a
layout which corresponds to what we need. In Figure 3 you can see this option selected in the gallery
that is presented in the Design Tab of the Ribbon when you are in the Page designer.

Figure 3 - The two column layout is selected from the gallery.

This page will, by default be statically linked to just two forms, the Header and Footer forms. It will,
however, dynamically load other forms into its middle sections/Subforms.

Page 516
Figure 4 - The SiteMain Page, statically linked to the Header and Footer Forms..

The Header Form


This form will fill the role of the site's header area and will be included in the header section/subform
of the layouts of both of the application's pages. In the MorfikCMS sample project this form is the
Header form and it is shown in design mode within the AppsBuilder Workspace in Figure 5.

Figure 5 – Header form of the MorfikCMS sample project.

The Header Form will be showing data from the WebsiteInfo table. In the header area, at the top, the
site ’ s title and subtitle will be displayed in two TextLabel controls formatted for that purpose. An
additional TextLabel control, with its Visible property set to false will be bound to a field of the
WebsiteInfo table called HomeSection (foreign key in the WebsiteInfo table which defines a relationship
with the Section table) which holds the Id of the Section whose content should be initially displayed
when users access this website.

Through out the construction of this application we will use this invisible TextLabel control bound to a
field which holds an identifier, many times. This is a repeating pattern in Morfik applications which is
used to make this information readily available when it is needed with minimal coding.

All the content in this Form has been placed in the Header band. This design provides greater
flexibility in case more information is to be added to the website's header in the future.

When the Header Form is completely loaded into the browser an event called OnReady is triggered. In
this event a couple of lines of code must be inserted to display the appropriate content in the
SubForm1 and SubForm2 SubForms/sections of the SiteMain Page. The following code snippet is the
source code for this event in this project.

procedure ShowSection ( SectionId : string ); overload ;

Page 517
begin
CurrentSection := StrT oInt ( SectionId );
XApp . OpenForm ( 'SectionContent' , 'SiteMain:Subform2' , '"P aramId='
+ SectionId +'",
" OpenMode = Refresh "');
XApp . OpenForm ( 'SideBar' , 'SiteMain:Subform1' , '"P aramP arent='
+ SectionId +'",
" OpenMode = Refresh "');
end ;

procedure ShowSection ( SectionId : integer ); overload ;


begin
CurrentSection := SectionId ;
XApp . OpenForm ( 'SectionContent' , 'SiteMain:Subform2' , '"P aramId=' +
IntT oStr ( SectionId )+ '", "OpenMode=Refresh"' );
XApp . OpenForm ( 'SideBar' , 'SiteMain:Subform1' , '"P aramP arent=' +
IntT oStr ( SectionId )+ '", "OpenMode=Refresh"' );
end ;

Both implementations of the ShowSection procedure are essentially identical in functionality, differing
only in the parameter type and consequently in the internal type conversions.

Note
Both instances of the OpenForm command, in both overloaded versions of the
ShowSection procedure add the "openmode=refresh" parameter. This parameter is
particularly useful in this case because it is instructing the OpenForm function to request
this Form from the server, instead of using a version of it previously cached by the Morfik
browser side framework. This is important in the MorfikCMS, project since all content
editing is done with a live site, so that all data modifications are immediately reflected to
the end users.

Note the two OpenForm commands in this procedure. These commands are responsible for showing
the SectionContent Form in the SubForm2 SubForm and the SideBar Form in the SubForm2 SubForm of
the SiteMain page. In this code you will notice that in the third parameter of the OpenForm command,
in both cases, the value of the HomeSectionIdLabel control ’ s caption is passed as a Form parameter.
This is done so that the content form the correct Section can be shown in these Forms. Both Forms
have as their data sources queries which require as parameter the Id of a section.

Just before requesting the Forms which will be shown in the two central areas of the SiteMain Page
this code stores in the CurrentSection variable the integer value of the identifier of the initial section
to be displayed. We will see further in this chapter how this variable is used to track which section is
currently being displayed in the browser.

The Footer Form


The Footer Form is linked to the WebsiteInfo table, in order to retrieve the copyright message which is
displayed in that area. This is a very slim form which displays just a copyright notice and an option for
Site Management, once the user is signed-in more on site management will be seen in other topics of
this reference.

Figure 6 - The Footer Form as seen in the Morfik Workspace.

The SideBar Form


The SideBar Form is opened into the left SubForm (SubForm1) of the application's main Page: SiteMain
. This form will be responsible for navigation through all the end user accessible content in the
website.

Page 518
Content displayed in the SideBar Form is divided through the Header and Details bands. In the Header
band a single option will be presented to return to the startup content of the home page. In the
Details band an option for each of the Subsections of the current Section will be displayed. Note that
the options in both the Header and Details bands have been made to look the same and to the end
user will appear to be a part of the same options set.

Figure 7 – The SideBar Form seen in Design mode within the Morfik Workspace.

The need to actually create the separate options in the Header and Details bands comes from the fact
that they use information from different sources to choose which content to display in the SubForm2
section/SubForm of the SiteMain Page.

The following is code snippet is the event handler associated with the OnClick event of the TextLabel
control used to represent the Home Option.

P rocedure SideBar . HomeOptionClick ( Event : T DOMEvent );


Begin
ShowSection ( Header ( Xapp . Forms [ 'Header'
]). HomeSectionIdLabel . Caption );
End ;

You might note that the code in this snippet is very similar to the code in the OnReady event of the
Header Form. This is due to the fact that they are essentially doing the same thing: requesting that
content from a particular section be displayed in the SubForm1 and SubForm2 Sections/SubForms. In
this particular case they are even requesting the very same section.

The event handler for the Section option is just a little different due to the necessity of establishing
which of the displayed options (one for each section in the Section table) was clicked on. The
following code snippet is the source code for the OnClick event of the TextLabel control which is used
to represent the Section Option.

P rocedure SideBar . SectionOptionClick ( Event : T DOMEvent );


Begin
SectionIdLabel . BandIndex := GetEventSource ( Event ). BandIn
dex ;
ShowSection ( SectionIdLabel . Caption );
End ;

To establish which value should be used in the call to the ShowSection procedure this event uses the
BandIndex property of the control which triggered the event. Once the BandIndex of the control
whose value we want to retrieve has been set to the same value as that of the control which
triggered the event, we can comfortably use it in requesting that the section be show.

The SideBar Data Source


The SideBar Form is connected to the GetSubSections query which takes one parameter. This query,
which is defined as shown in Figure 8, recovers information about Sections which have a specific
section as their parents. In our current case it will be the Subsections of the Section requested in the
call to the ShowSection procedure.

Page 519
Figure 8 – The GetSubSections query definition in the Query designer of the Morfik Workspace.

Observe in Figure 8 that in the criteria row for the ParentId field the word ParamParent has been
typed and that in the IsPublic field the value of 1 as been entered. The ParamParent string is
understood by the AppsBuilder Workspace to be a parameter for this query which will be provided at
runtime while the literal value 1 is understood as a constant which will always apply. The value of 1 in
the IsPublic field means that we only want records which have been marked as Public.

When this query is tied in as the data source for the SideBar Form, its ParamParent parameter is
automatically added as a parameter of the SideBar Form. Figure 9 shows the parameter list for the
SideBar Form where the ParamParent identifier is present as the last member of the list.

Page 520
Figure 9 – Parameter list for the SideBar Form, showing the parameter of its data source which has
been added as its own.

When the SideBar Form is loaded and the ParamParent is part of the parameter string received, it
requests the execution of the Query with the corresponding parameter value.

The SectionContent Form


This Form is actually very simple since most of the work done to display information within the
SubForm2 of the SiteMain Page is actually delegated to another form. Figure 10 shows the
SectionContent Form in Design mode within the Morfik AppsBuilder Workspace.

Figure 10 – The SectionContent Form in Design mode.

The SectionContent Form will show in its Header band the section ’ s title in an appropriately formatted
TextLabel control and hold the value of that Section ’ s identifier in the an invisible TextLabel control,
using the same implementation pattern used in the SideBar Form.

When this Form is completely loaded in the Browser its OnReady event will be triggered, as seen
when discussing the Header Form. It is in this moment that another Form will be opened within the
ArticleArea SubForm which completely fills SectionContent ’ s Details band.

The following code snippet contains the full source code for the OnReady event handler of the
SectionContent Form.

P rocedure SectionContent . WebFormReady ( Var


Ready : Boolean );
Begin
OpenForm ( 'ArticleContent' , 'SectionContent:ArticleArea' ,
'"P aramId=' + SectionIdLabel . Caption + '"' );
End ;

Page 521
The SectionContent Data Source
The SectionContent Form has its data source defined as the GetOneSection query. This query recovers
all the particular information of a single section specified as its parameter. Figure 11 shows the
definition of the the GetOneSection query.

Figure 11 – Definition of the GetOneSection query.

The ArticleContent Form


The ArticleContent Form is shown inside the Details band of the SectionContent Form and is actually
responsible for displaying the titles, authorship and summaries of the articles available in a specific
section. Figure 9 shows the ArticleContent Form in Design mode within the Morfik AppsBuilder
Workspace.

The ArticleContent Form does not have a Header since it is embedded inside the SectionContent Form
which does present a Section header. It does however have a Footer band in which it displays a
NavigationBar .

The NavigationBar is necessary in this case because naturally the number of articles in a single section
will be more than would be desired in a single page. In this case we result to what is commonly know
as "paging" which is a technique which allows us to specify how many records will be shown in each
"page". In order to customize how the paging will work the PageSize of the Form should be set to a
number which provide the best result for each specific application. In the case of MorfikCMS, as a
general content management application, the default value of 10 was considered adequate. This
means that ten records will be presented in each "page".

Page 522
Figure 12 – ArticleContent Form in Design Mode.

The ArticleContent Data Source


This Form is responsible displaying the Title and Summary of each article, as well as the author ’ s full
name. Since the Article table does not have the author ’ s name this Form needs to be connected to a
data source which is a query which retrieves data from both the Article and UserCat tables. In this
case the ArticleContent Form is using the GetSectionArticles query as its data source.

Figure 13 – GetSectionArticles query definition.


This query recovers all the basic information that might be required from the Article table, plus the
article ’ s author full name from the UserCat table. This query, as the one which have been used in the
SideBar and SectionContent Forms takes one parameter which is the Section for which we want to
recover the articles. In figure 13 the presence of the string ParamId in the criteria row of the SectionId
field indicates that is the parameter which defines what to retrieve.

Page 523
As with the other Forms, once the ArticleContent Form was linked to the GetSectionArticles query, this
parameter was automatically created in the Form so that whenever we call OpenForm specifying it, it
is automatically passed on to the query which gets executed automatically by the Morfik Framework.

ArticleContent makes each article title into a hyperlink which, if when clicked will result in the
substitution of the SectionContent , inside the SubForm2 of SiteMain Page by another Form called
ViewOneArticle . The following code snippet contains the entire source code for the OnClick event for
the TextLabel control which displays an article ’ s title.

P rocedure
ArticleContent . ArticleT itleLabelClick ( Event : T DOMEvent );
Begin
ArticleIdLabel . BandIndex := GetEventSource ( Event ). BandInd
ex ;
OpenForm ( 'ViewOneArticle' , 'SiteMain:SubForm2' ,
'"P aramId='
+ ArticleIdLabel . Caption + '","openmode=refresh"' );
End ;

Notice that this event ’ s code uses the same invisible TextLabel control pattern as in previous code
samples we have looked at in this chapter.

The ViewOneArticle Form


Once the end user or visitor to the application ’ s website clicks on one specific article he/she wants
to read in full, a complete version of the body of the article ’ s text must be displayed.

In order to create this display the ViewOneArticle Form is used. This Form replaces the SectionContent
Form within the SubForm2 section/SubForm of the SiteMain Page presenting the complete text to the
user.

Figure 14 shows the ViewOneArticle Form. Notice that this Form also contains a Footer band. In this
case a small link is used to return to the previous view with the SectionContent Form exhibiting the
articles of a single section.

Figure 14 – The ViewOneArticle Form in Design mode.

Figure 15 shows the website in Apple's Safari browser, with the ViewOneArticle Form being shown in
the SubForm2 SubForm of the SiteMain Page.

Page 524
Figure 15 – View of the MorfikCMS application displaying the full contents of the Body field.

The ViewOneArticle Data Source


The ViewOneArticle Form uses the GetOneArticle query as its data source. This query recovers all data
from the one specific record in the Article table. The following snippet shows the SQL language code
for this query.

SELECT ALL
"Article" . "Id" ,
"Article" . "T itle" ,
"Article" . "Body" ,
"Article" . "DateCreated"
,
"Article" .
"DateP ublished" ,
"Article" . "CreatedBy" ,
"Article" . "Summary" ,
"Article" . "IsP ublished" ,
"Article" . "SectionId"
FROM
"Article"
WHERE
"Article" . "Id" =
P aramId

Notice that this is a very simple and straight forward query which will always return a single record
from the Article table .

A closer examination of the picture in Figure 16 will reveal a small pencil icon and the word "Edit" by
the title of the article. This can be used to alter the information in that specific article.

Figure 16 highlights this small detail to make it easier to notice.

Page 525
Figure 16 – The Edit link by the title of an article.

Clicking on this link will result in an error message, unless the site ’ s visitor has previously signed in
by clicking on the Sign In link at the top of the page. We will see more information about the login
process in the next Chapter.

The following snippet contains the full source code of the OnClick event associated with the TextLabel
control which is used to represent the "Edit" link.

P rocedure
ViewOneArticle . EditRecordOptionClick ( Event : T DOMEvent );
Begin
If not UserIsAuthenticated T hen
ShowMessage ( 'Operation not allowed. P lease, sign in first.' )
Else
Begin
ArticleIDLabel . BandIndex := GetEventSource ( Event ). BandInde
x;
OpenForm ( 'EditOneArticle' , 'P OP UP ' , '"P aramId='
+ ArticleIdLabel . Caption +'", " title = Edit Article ",
" modal = true "');
End ;
End ;

Note that the OpenForm command in this case is a bit different from has been used elsewhere in this
sample. The first difference is that the target is not any specific SubForm but the word "Popup". This
is understood by the Morfik Framework as a command to display a the form as a popup "window".
The Title parameter for the form will be used as the title of the "popup window" and the modal=true
parameter will shade everything else in the browser limiting user interaction to the new Form.

Page 526
Wrapping it up
Creating the interface for an application which is totally database driven is not a difficult task with
Morfik AppsBuilder. It is actually quite a simple task, considering that an adequate database model
was previously created.

In this the next couple of chapters we will look at how to handle the need to authenticate users and
to update all the information in the website. These tasks must be done in way which compatible with
the overall design of the application/website.

See Also
 Morfik Database Programming
 Database Modeling

 Database Connections
 Editing and Searching

 SQL Statements
 Using Stored Procedures

 System Objects in a Database


category:Database

Page 527
Release Notes

Morfik AppsBuilder Release 2 (build 2.0.4.77)

Recommended actions when upgrading from prior versions of Morfik


AS WITH ALL SOFTWARE UPGRADES, IT IS HIGHLY RECOMMENDED THAT YOU MAKE A FULL
BACKUP OF YOUR PROJECT BEFORE LOADING AND COMPILING IT WITH A NEW VERSION OF
MORFIK. If upgrading from Morfik AppsBuilder version 1, it is recommended that you review
the release notes on version 2.0.0.63 which describes the changes that you may have to
apply to your project.

New Features
The page and form concepts have been merged. All features previously available in pages
are now available in forms. Pages in existing projects will be automatically converted to
1 forms.
Support for Custom controls. This release includes two custom controls with more to follow in
2 the upcoming releases.
New Publish Page, allowing developers to create Clean URLs for their
3 applications.
New State feature to radically enhance working with
4 Forms in a project.
Major improvements to themes: Morfik now includes a greatly expanded set of
5 pre-defined themes.
 Themes now include control effects (gradient, corner, etc) as well as colors and fonts.
The new Styles panel allows many aspects of a control's run-time appearance and behavior
 to be customized at theme level.
New
Calend
ar
control.

New Popup dialog control. This control is automatically used on your Popup
 forms.
New
Progress
Bar
 control.
Google Map and WYSIWYG are now available
 as custom controls .
New “Edit parts” option in the form designer allows the developer to further customize the
appearance and behaviour of multi-part controls such as ListBox, File Uploader, Calendar, and
 ProgressBar.
Right-click menu command Export as Image is now available for controls in the form
 designer.
An Effects Configuration dialog has been added for further customization and enhancement of
 control effects.
Text Alignment options have been
 added to the Ribbon.
Fonts combobox in the
 ribbon has been improved.
The Transparent property has been removed; controls can now be made transparent by
 setting their Color property to "No Color".
The Button control's BackgndImage property has been replaced by the Icon property, which
 includes options to control how the image is positioned within the Button.
The ComboBox control now includes AutoComplete, AutoDropDown and AutoFilter
 properties.
The Combobox control now includes a Style property, which specifies whether the user is
 limited to choosing items from the drop-down list, or may type in a custom value.
Listbox control
 may now

Page 528
include icons.
Tab Control buttons may now be
 formatted and include icons.
Textlabel control is now
 transparent by default.
TextEdit control now has a
 SelectOnFocus property.
Padding property has been added to the Button, TextEdit and ComboBox
 controls.
The new GroupIndex property of the Button control may be used in conjunction with the
 Default, Down and Enabled properties to work with a set of buttons in an intelligent way.
Subform controls now display the content of their target
 form at design time
The Subform control now allows the parameters of its target form to be specified at design
 time, in its Parameters property.
New "Split Vertically" and "Split Horizontally" commands have been added to the form
 designer to assist with form layout design.
Transparent Forms are now easily identifiable by their checked background
 pattern.
Form wizard is now run automatically when a blank subform
 control is placed.
Target form may now be specified before placing a
 subform control.
New project
templates have
 been updated.

Bug Fixes
Fixed issues with
compiling an application
1 as an Apache Plug-in.
Fields from aggregate queries can now
2 be included within other queries.
Data bound queries with no records are now displayed correctly in a
3 continuous form.
Fixed Unicode issues that were affecting applications using
4 Chinese characters.
Morfik compiler now flags an error when the assignment operator statement is missing
5 the "=" (e.g. AOb : TCustomObject.Create;)
Resolved plastic layout issues
related to the "CanGrow"
6 property.
Show Hidden Items option (Morfik Options dialog, General tab) now
7 works correctly.
Optimizati
on of
memory
usage in
Morfik
applicatio
8 ns
Error caused as a result of file system case sensitivity
9 in Linux has been fixed.
Debug browser
message box
now supports
10 Unicode.
The “component returned failure code”
11 exception in Firefox 3.0 is resolved.
Field values containing non-ascii characters now save correctly in browser XApp
12 tables.
The Optionbutton's OnClick event was firing before the Checked property had been
13 updated; this has been corrected.
The Checkbox control's OnClick event was firing before the Checked property had been
14 updated; this has been corrected.

Page 529
Morfik Express and Morfik AppsBuilder Public Beta Release 2 (build 2.0.3.16)
New Expiry date is set to November 30 2008.

Morfik Express and Morfik AppsBuilder Public Beta Release 2 (build 2.0.3.15)
New Expiry date is set to October 30 2008.

Morfik Express and Morfik AppsBuilder Public Beta Release 2 (build 2.0.3.14)
New Expiry date is set to September 30 2008.

Morfik Express and Morfik AppsBuilder Public Beta Release 2 (build 2.0.3.13)
New Expiry date is set to July 29 2008.

Morfik Express and Morfik AppsBuilder Public Beta Release 2 (build 2.0.3.11)

Known issues
1 The OnFocus event for a TextEdit control is not functional.

New Features
Image bundling. Images generated to implement effects are
now combined together. This greatly reduces loading time and
1 improves overall user experience when working with XApps
"Stop on script errors" added to Debugger Options. When enabled, XApp will engage the
debugger whenever an error is encountered in JavaScript, even if it's being handled by
2 try/catch handler.
If the custom theme is used, it is now saved with the project.
This makes it possible to open project on another computer
3 where the theme used might not be installed.
4 Two new functions are available in Browser framework: double.toFixed and double.toPrecision
It is now possible to reset the panels layout to default using
5 View | Panels | "Reset to default" command
Auto-deployment now uses
compression to improve files
6 uploading speed
The Firebird database engine is updated to version 2.1. (In
order to keep running Morfik 1.4.0.1 on the same computer as
Morfik 2.0.3.11 you will need to patch the Morfik 1.4.0.1
7 installation to work with Firebird 2.1 .)

Bug Fixes
Background image for the project
1 could not show through pages
Refreshing the page in Express sometimes stalled the page at
2 the "Loading..." stage
Using Xor in browser-side code caused the XApp to get stuck on 'loading...' in the
3 browser
4 IDE would freeze during start-up if Windows default printer was misconfigured or unavailable
Odbc data
connector
caused
compiler
5 errors
Attempting to view the content of widestring fields in ODBC linked tables would cause the IDE
6 to crash
IsHyperlink property of TextLabel was not
7 exposed in Properties panel
Report property of Subreport control was not exposed
8 in Properties panel
When a Morfik Basic project was created using the default template, controls were
9 incorrectly declared as public
IE only: grow-and-shrink was not working for pages, resulting in cropping
10 of content

Page 530
IE only: image effects
were not working
11 properly

Morfik Express and Morfik AppsBuilder Public Beta Release 2 (build 2.0.2.3)

New Feature
1 A new set of control image effects such as Glow, Shadow, Corners, Reflection and Anti-aliasing.

Bug Fixes
The report property "ReportOrientation" is now accessible
1 through property inspector
The Auto indent is
now working
2 correctly.
The issues with Morfik service connector wizard writing to RDB$DESCRIPTION
3 field of external Firebird databases is resolved.
Imported or Linked tables were displaying table fields in a different order than in the original
4 database. This has been fixed.
No more "unavailable database" error message, when using the data connector
5 wizard to connect to a Firebird database running on a Linux server.
The intermittent access violation bug when
6 saving tables has been fixed.
The new mfkudf.dll is now
7 backward-compatible

Morfik Express and Morfik AppsBuilder Public Beta Release 2 (build 2.0.1.2)

Bug Fixes
Improved backward compatibility with Version 1.x projects - resolving 'Cannot delete UDF
1 GENERATEGUID error' when upgrading projects from Morfik 1.x to 2.x.
Correcting the disappearing of form contents and code when modifying document properties in
2 IDE.
Resolving the issue with data-bound DateTimeEdit control not showing field's
3 date value correctly.
Resolving the exception raised at design time 'EConvertError raised with message "{autogen}"
4 is not a valid GUID value' when inserting a new record in a single form.
Non-Ascii characters can now be entered directly into the Properties panel
5 when setting the value of a control's Caption property.
Correcting combobox bahviour in a pop up window, now the dropdown is correctly appearing in
6 front of the window.
Can now create new projects with "embed project source files in project
main file" ticked without giving error 'cannot open database
7 "...projectX.mxs"'
Project themed fonts now change
8 correctly when selecting a new theme.
The ComboBox ItemIndex property now returns the
9 correct value (not -1)
Tab order for controls
in the RSS dialog is
10 corrected.

Morfik Express and Morfik AppsBuilder Public Beta Release 2 (build 2.0.0.63)

New Features
Please review ' What's New ' for a summary of what is new in Morfik Express and Morfik
AppsBuilder public beta release.

Known issues
Please m ake sure you do a backup of your project(s) before com piling it with Morfik
1 Express or Morfik AppsBuilder.

Page 531
You can install Express and/or AppsBuilder R2 with AppsBuilder R1.4 and compile your projects
2 with Express or AppsBuilder R2
Following are a list of function and objects that have been renamed: TServerDateTime ->
3 TDateTime
 AsServerDateTime -> AsDateTime
TXMLDateTime ->
 TDateTime
ReadArray
 -> ReadList
WriteArray ->
 WriteList
DelphiN
ow ->
 Now
TIB_Column.AsServerDateTime ->
 TIB_Column.AsDateTime
DWord ->
 TRequestResult

 RequestResult:= HSE_STATUS_SUCCESS; -> RequestResult:= rrOk;


 SetTransparencyValue -> SetOpacityValue
Error: The Close command for a Floating form is not
 recognized.
Resolution: TWindow(Xapp.GetFloatingSubform(InstanceName)).Close; (import
 SystemWindow)

 Error: ModuleName(Server xx,x): Cannot override a static method,


 Resolution: REMOVE Override;

 Error: ModuleName(Server 415,40): Undeclared Identifier: TSoapHttpClient.


 Resolution: Add SystemXML to uses.
Error: “undeclared identifier!Runwebservice” error message when using RunWebService
 function like following Runwebservice("myWebMethod","""prmID="&PrmCustID&"""")
 Resolution: Most likely the code is not being called from a form. Please try changing it to this:

 XApp.Runwebservice("myWebMethod","""prmID=" &PrmCustID&"""")
 If it still doesn't work, try adding Import SystemControls at the top of the module.
Error: When using “strVar=textedit2.DomHandleArray.Handles.items(i)”,you get the
 following error:Undeclared Identifier:items
Resolution: Please try it without the explicit Items property: “h =
 textedit2.DomHandleArray.Handles(i)”
Error: Project would not compile if Using
 “Class(TSoapHttpClient)”.
Resolution: Try adding SystemXml to the uses
 clause.
Error: “Undeclared identifier : refreshPage” error message appears when using the
 following line of code Form1(Xapp.Forms("Form1")).OwnerForm.RefreshPage(Nothing)
Resolution:The RefreshPage method has moved to the Form class, so you need an extra
 typecast: Form(Form1(Xapp.Forms("Form1")).OwnerForm).RefreshPage(Nothing)

AppsBuilder Release 1 (build 1.4.0.1)

Known issues
When previewing XApps in the new debug browser, certain xApps may display error messages
that are related to "Parsing" or "Unknown" CSS properties. These messages will not have any
negative impact on your applications. We are aware of them and working on these issues
which will be resolved in upcoming releases. We are taking the utmost care in addressing each
 individual message to ensure that cross-browser compatibility is not affected.
In order to run WebOS AppsBuilder successfully on MS Windows Vista, you may have to turn
 the Windows Vista's UAC (User Account Control) off.
Intermittent error message ('Already stopping
debugger') when stopping a project by closing
the debug browser. Stopping the project from
within the IDE would minimize this issue. This
 issue will be addressed in the upcoming release.

Page 532
Run time errors such as "HTMLElement undefined" are displayed if the WYSIWYG control is used
in your project. Please replace the "wysiwyg.js" file in the following folder "C:\Program
Files\Morfik\WebOS v1.4.0.1\System\Adapters\Wysiwyg\" with an updated version of the file
 within the attached zip file. Wysiwyg.zip

New Features
This release includes a new help system which combines information from several different
sources, including languages reference, Developer's Handbook, Database Programming Guide,
wiki and blog articles, into a single resource available directly from your desktop. New
Framework reference material has been added to the code completion, expanding considerably
 the number of elements which are now covered in this fashion.
Additional sample project called MorfikCMS. This new sample project is a bare bones, but fully
funcional, Content Management System which can be extended to run almost any content
driven web site. This example is extensively discussed, from the table structures to how to build
 the interface, in articles which are now part of the bundled help system.

Bug Fixes
Resolved the issue with not being able to enter "New Lines" in the TextEdit controls, if used
 within IE browser.
Images in the WYSIWYG control
 are now displayed correctly.

 Fixed issues with incorrect display of large images in reports.

AppsBuilder Release 1 (build 1.3.1.18)

Known issues
When previewing xApps in the new debug browser, certain xApps may display error messages
that are related to "Parsing" or "Unknown" CSS properties. These messages will not have any
negative impact on your applications. We are aware of them and working on these issues
which will be resolved in upcoming releases. We are taking the utmost care in addressing each
1 individual message to ensure that cross-browser compatibility is not affected.
If the WordWrap property for a TextEdit control is set to true, it will not be possible to enter
"New Lines" in the TextEdit controls if used within IE browser. This issue does not exist in other
2 browsers. The fix for this will be included in the next release.
In order to run WebOS AppsBuilder successfully
on MS Windows Vista, you may have to turn the
3 Windows Vista's UAC (User Account Control) off.

New Features
This release will provide a much improved debugging experience. At the heart of all the
improvements is the switch in the underlying technology of browser side debugging. Instead
of using the Microsoft Script Debugger Morfik is now using Mozilla technology.

This change has made it possible to debug both browser and server side code at the same
time in a seamless manner. Until now the AppsBuilder IDE could only debug on portion of the
application, either browser or server, at the same time. This should greatly enhance
productivity as at any time during execution of an application the developer can just click on a
line to set a breakpoint.

To view the intermediate source in this version, go to "Debug\Debugger Options …" and tick
the Intermediate source debugging check box. You will see two new tabs next to Properties
and Explorer tabs with a list of the intermediate source files.

Bug Fixes
Multi-Column continuous forms now work
1 correctly when browsing through pages.
The menu view/debug views and the log type checkboxes are
2 now displayed correctly.
No more SQL errors when copying tables from one project to another project with
3 different charset used for the tables in the databases.
The vertical scroll bar for forms in the form designer now gets updated correctly to show the full
height of the form. Also issues with not being able to scroll down to the bottom of the form
4 have been resolved.
It is now possible to add more than one instance of SET-COOKIE to the HTTP response

Page 533
5 header.
Error and Search Panels can now
be turned on or off through View
6 menu.
It is now much faster to display a report that include
7 large numbers of static images.
Morfik applications
now compile
correctly with
8 Delphi 2007.
Updates to Firebird configuration file for correct
9 operation in MS Vista environment.
Naming a table as
'System' does not cause a
10 compile loop anymore.
Expressions used in return statements are now checked to ensure they are of the
11 correct data type.
Fixed issues with aligning the contents of a TextLabel at run time which looked slightly different
12 from the design time.
Paintbox
controls
now
appear
correctly in
13 Reports.
14 It is now possible to add more than one instance of SET-COOKIE to the HTTP response header.
Intermittent multiple page printing issues with reports on color printers has
15 been fixed.
Background compiler no more reports access violation error when
16 creating a new table
The word-wrap style property is now compatible with W3C standard and as a result
17 Firefox no longer reports errors in its error console.
Resolved the high CPU usage issues on the client side, if an xApp was left running for a long
18 period of time.
Morfik compiler now displays error messages when overriding a non-virtual method in
19 the browser side
Resolved issues related to compiling\running IIS and Apache Plugin projects. The Clear Compiler
20 Cache command is now automatically called to ensure correct compilation.
No more access violation errors when repeatedly opening external Firebird tables in
21 data view.

AppsBuilder Release 1 (build 1.2.1.5)

AppsBuilder Release 1 (build 1.2.0.13)

Recommendations & Notes


As noted in the release notes, there is now a version of the Morfik Framework available in
Basic. Projects using the Basic language automatically switch to the Basic version of the
Framework. As a result of this change, if you have used Exit command in your Basic code please
1 replace it with Return command.
In order to get the latest version of the sample projects, It is recommended that you either
2 remove or rename the \My Documents\Morfik07\Samples folder prior to the installation.
As noted in the earlier release, the process of
converting code from Pascal syntax to another
language, does NOT create a new copy of the
project but rather converts the existing one. IT IS
HIGHLY RECOMMENDED THAT YOU MAKE A FULL
BACKUP OF YOUR PROJECT BEFORE
3 CONVERTING.

Known issues
XApp as a plug-in to Apache 1.x does not work correctly in this release. The reverse i.e. Apache
1 1.x as plug-in to a XApp (the default) works fine.

New Features
1 Completion of porting of Morfik Framework into Basic (beta release). Basic Framework is

Page 534
automatically chosen when project language is Basic.
IIS
2 support.
Significant improvements to the Plastic layout
3 feature in the IDE.
XApp as a plug-in to Apache
4 2.x under Windows.
Ability to enter foreign languages in the code editor and caption property and in the
5 table/query data view.
Enhancements to easily connect to more advanced
6 POP3-SMTP servers.
Ctrl+Shift + Down, Ctrl+Shift + Up for navigating between function
7 body/header.
It is now possible to use # notation for color constants in all languages. For example
8 Button.Color := #FF0000; It uses RGB like html.
ODBC connectivity within the AppsBuilder has been updated and
9 improved.
New project item image is now displayed on each tab to make it easier to recognize the open
10 documents in the project.
It is now possible to preview a form from the browser or server code
11 editor.
New structure in the sample project folder. Additional projects are added in all supported
12 languages in Morfik.
Firebird engine has been
13 updated to version 2.0.1.
Support for
character set
14 win1251.
New fast navigation tools in the code editor - Two Comboboxes have been added to
15 module view, for navigating through classes and methods.
Added a CloseQuery event to the form class to allow intervention when a popup form is being
16 closed.
The default character set for Morfik
17 applications is UTF-8 now.
PDF report generator now works for XApps
18 running under Linux.
Open file dialog is
19 now resizable in IDE
Implement the concept of active window/table when user is defining the DB
20 schema

Bug Fixes
Compiling projects with external databases are much faster as table information is now cached
1 locally.
Fixed issues with importing from or linking to MS Access
2 2007 projects.
New EncodeParameter-DecodeParameter functions to resolve issues related
to SQLFilter parameters in Firebird. Following is how the function is used:
OpenForm('frmSupplier','frmMain:Subform','"SQLFilter='+EncodeParameter(my
3 Filter)+'"');
In MSSQL projects it is now possible to: Submit records that have null values for a unique
4 identifier field type that is set to allow for Null values.
Submit a (blank/null) date value when the checkbox is un-ticked on the
 DateTimeEdit control.
Method overriding
now works in
 server-side code.
XApps can now have a variable
 declared as "WhiteSpace".

AppsBuilder Release 1 (build 1.1.0.6)

Recommendations & Notes


AppsBuilder Release 1 (build 1.0.0.7) introduced the feature that allowed you to convert all the
code from one language syntax to another. As this feature has still not fully matured:- IT IS
1 HIGHLY RECOMMENDED THAT YOU MAKE A FULL BACKUP OF YOUR PROJECT BEFORE

Page 535
CONVERTING.
This process does NOT create a new copy of the project but rather converts the existing one.
 Note that in this version of AppsBuilder it is NOT possible to convert to Pascal syntax.

New Features
Morfik framework has been upgraded from Indy 9 to use Indy 10. Among other things, this
1 means that it is now possible to call 3rd-party web services from an XApp running on Linux.
Format Painter. This feature allows automatic formatting of Controls at design time. Simply
select a control to copy formatting from, click on the Formatting Brush and click on a second
2 control to copy formatting to.
Jump start new projects. New projects have
additional Forms to assist developer with the
3 development process.
Continuous Forms generated in Form wizard now include page navigator options by default
4 instead of record navigator.
Enhanced database security by not allowing
external access to the database engine. By
default, only local access to the database engine
5 is allowed.

Bug Fixes
File-Uploader control related issues in
1 Firefox, Opera and Safari.
Obfuscation caused intermittent
2 JavaScript runtime errors.
The side margin where it shows line numbers in code view did not display properly
3 when the last line number is something such as 10, 100, 1000.
Resizing of TextLabel font sizes and borderwidths at runtime did not work in
4 Firefox 2.0
In the Data view grid of a table it was not possible to enter '0' and '1's for a Yes/No
5 type field.
Issues related to navigation through pages in a
6 stand-alone continuous Form.
The CheckSyntax property of non-visual queries is now set to
7 false by default.
External Database The SQLFilter property was not working correctly in Forms and Reports
8 bound to external databases
In MS SQL database projects, checkbox did not show correct values in a continuous
 Form.
SHR and SHL operators were not handled correctly in Pascal to Basic
 convector.
Select Case did not work correctly on keyword
 "to" in Morfik Basic
Caret position was off position in relation to source code indentation when the property
 window took you to the source code.
Morfik J: Compiler errors occurred when using a range of values in a Switch statement
 case.
 Morfik C#: Compiler errors occurred when using a range of values in a Switch statement case
Running the service connector wizard in update mode didn't clear the
 MFK$SYNC_SCHEDULE Table.
Datetime datatype fields
were not handled
 correctly.
Minor
Boolean
datatype
field
 issues.
Null field values
were not handled
 correctly.

AppsBuilder Release 1 (build 1.0.2.5)

Recommendations & Notes

Page 536
AppsBuilder Release 1 (build 1.0.0.7) introduced the feature that allowed you to convert all the
code from one language syntax to another. As this feature has still not fully matured, IT IS
HIGHLY RECOMMENDED THAT YOU MAKE A FULL BACKUP OF YOUR PROJECT BEFORE
1 CONVERTING.
This process does NOT create a new copy of the project but rather converts the existing one.
 Note that in this version of AppsBuilder it is NOT possible to convert to Pascal syntax.

New Features
Smart ‘make’ process resulting in significant improvement in incremental compile times The
1 browser-side compiler has been optimized.
Reduction in the frequency of server-side
 compilation.

Bug Fixes
IDE Issues running AppsBuilder on Microsoft Windows Vista including running XApps in debug
1 mode
Copy/Paste on Table objects
occasionally lead to 'Access
 Violation'.
Using a SQLFilter on WebFormCreate, deleted any other
 user-defined Form parameters.
The Tools / Environment Options, prior to a project
 being loaded, was inaccessible.
Using the Listbox.Text property in the Listbox.OnChange event caused a
 premature exit (and a silent exception to be raised) from the event handler.
It was not possible to display the value of the DateTimeEdit control when the OnChange event
 was fired.
If one created a Table with a field called "x", then Single forms would not show
 the data in its field.
Pointer values were incorrectly displayed (all values had an extra 8 added to the end) in
 Watches while debugging.
The SQLFilter did not work if it contained
 any double quote charcters
Attempting to
break/exit out
of for loop
caused a
 compile error.

AppsBuilder Release 1 (build 1.0.1.5)

Possible code changes to existing XApp Projects


AppsBuilder Release 1 (build 1.0.0.7) introduced the feature that allowed you to convert all
the code from one language syntax to another. As this feature has still not fully matured,

IT IS HIGHLY RECOMMENDED THAT YOU MAKE A FULL BACKUP OF YOUR PROJECT BEFORE
CONVERTING.

This process does NOT create a new copy of the project but rather converts the existing one.
Note that in this version of AppsBuilder it is NOT possible to convert to Pascal syntax.

New Features and Bug Fixes


XApp Enhanced support for
1 large projects using FPC
The menu item in the Navigation bar for filtering records was not functional in IE for top-level
 Forms
Using FileUploader if two files with the same name are uploaded, the second file overwrites
 the first file.
In a continuous form the page count in the navigator was always one less than it should have
 been (which, except under special cases, caused the last page to be inaccessible)
OnChange Event for the DateTimeEdit control
 was not functional
Although the Chart XApp runs under Linux, most
 functions didn't work

Page 537
 A message now appears in all XApps built using Morfik Express (ie for non-commercial use).
It was not possible to do data entry on a MSSQL UniqueIdentifer field type. Data entered in a
 Uniqueidentifier field was discarded when submitted to the table.
MS Access External DB: Visual Query designer did not display records from the linked MS
 Access tables.
Parameter "SQLFilter" was wrong on SystemControls.mmd file (line
 4232)
The equivalent construct of (Morfik Pascal): Type TNumberSet = Set Of (eOne, eTwo, eThree)
 now added
Array declarations did not conform to the convention that it specifies the uppermost index
 (rather than the number of elements)
The shift-right and shift-left operators
 caused compiler errors
 Declaration of MustOverride (abstract) method in Basic is generated compile errors.
Compiler metadata associated with function declarations was not loaded
 correctly
 Couldn’t compile a project as a plugin (DLL) if the language for the project was Basic.
Local typed constant
declarations caused compiler
 errors
Inline array declarations not
 accepted for record fields
Inline array declarations
not accepted for class
 fields
Compiler error
when string literal
 starts with //
Any reference to exception.message
 caused compiler errors
Using a range of values in a switch statement case caused compiler
 errors
The shift-right and shift-left operators
 caused compiler errors
In a constructor, having any statements prior to super.new caused a compile
 error
In a destructor, having any statements after super.dispose caused compiler
 errors
Declaring multiple variables in the one line caused
 compiler errors

 The following local array variable sometimes caused compiler errors: Char 0..1023 Folder;
Any code after a c#-style constant
 declaration was be ignored
Added
support for
type
assignment
 s
Compiler metadata associated with function declarations were not loaded
 correctly
Using 'select' as an
identifier caused compiler
 errors
Combined variable declaration and assignment was discarded by the
 compiler
Class forward declarations without public/private caused
 compiler errors
Having 'public' or 'private' before enum caused
 a compiler error
The In
operator
was case
 sensitive
Using 'final' instead of 'const' for constant
 function parameters
Statements after a try ... finally clause were treated

Page 538
 as being inside it
 Couldn’t compile a project as a plugin (DLL) if the language for the project was Java.
Arra
y
prop
ertie
s
not
supp
orte
 d.
Declaring an
array
constant not
 possible
No
suppo
rt for
type
assign
ments

The equivalent construct of (Morfik Pascal): Type TNumberSet = Set Of (eOne, eTwo, eThree)
 has been added.
Having an identifier named 'param'
 caused compiler errors
Declaring multiple variables in the one line caused
 compiler errors
Using a range of values in a switch statement case caused compiler
 errors
Local constant
declarations caused
 compiler errors
Any reference to exception.message
 caused compiler errors
Inline array declarations not
 accepted for record fields
Inline array declarations
not accepted for class
 fields
Compiler error when
string literal began
 with //
Statements after a try ... finally clause were treated
 as being inside it
 Couldn’t compile a project as a plugin (DLL) if the language for the project was C#.
Now possible to
declare an
 array constant
The equivalent construct of (Morfik Pascal): Type TNumberSet = Set Of (eOne, eTwo, eThree)
 has been added.

 The following local array variable sometimes caused compiler errors: Char 0..1023 Folder;
Compiler metadata associated with function declarations were not loaded
 correctly
The in
operato
r was
case
sensitiv
 e
Changes made to
project
conversion
 wizard
If only the server or browser side of a dual module is used in the original project, a comment
is now written into the other side of the module explaining why its code was not converted
 (Basic, C#, Java)
 Pascal -> Basic Conversion : Browser-side code in Sweeper sample project did not get

Page 539
converted at all

 Inline JavaScript functions were being converted to empty functions; (Basic, C#, Java)
Backslashes in string literals were not being
 escaped; (C#, Java)
External function declarations were
 being omitted; (C#, Java)
Function return values were always ending up as undefined;
 (C#, Java)
Initialization and finalization clauses were being omitted;
 (Basic, Java)
Function types were being converted to function variables;
 (C#, Java,)
Double quotes in string literals were being escaped as ""; now \" (C#,
 Java)
Function parameters declared as metatype were being converted to untyped parameters (C#,
 Java)

 Dynalist variable declarations were missing a space before the variable name; (C#, Java)
When a pascal repeat until loop was converted to a c#/java do while loop, it failed to negate
 the condition; (C#, Java)
Constant declarations were being converted to an invalid syntax (C#,
 Java)
Identifiers with spaces were not being enclosed in delimiters;
 (C#, Java)

AppsBuilder Release 1 (build 1.0.0.7)

Recommended actions when upgrading from prior versions of AppsBuilder


This version of AppsBuilder converts your existing project files to XML format.

IT IS HIGHLY RECOMMENDED THAT YOU MAKE A FULL BACKUP OF YOUR EXISTING PROJECTS

BEFORE LOADING AND COMPILING THEM WITH THE NEW VERSION OF THE APPSBUILDER.

Required code changes to existing XApp Projects


As AppsBuilder Release 1 (build 1.0.0.7) contains many significant changes to prior versions,
some changes may be needed to older projects in order for them to compile and run correctly
Databases In order to improve performance in AppsBuilder Release 1, the automatically
generated system tables (table names starting with MFK$) are not generated anymore for new
projects and any framework routines related to these system tables have been removed. If you
have used these tables, please refer to the attached notes on how to update your project with
1 a few simple changes in your code.
If you are using the SystemDatabaseODBC module in your project you will need to replace it
 with SystemdatabaseSQLDB and also use SystemDatabaseDb.
If you have used the ODBCExpress connectivity in your server module “codes”, you will
need to update them with the equivalent codes used in SQLDB. For example, following
 code

 Hstmt := THstmt.Create(Nil);

 Hstmt.HDBC := TODBCServiceConnection(DBServiceConnection).HDBC;

 Hstmt.SQL := SQL;

 Hstmt.Prepare;

 Hstmt.Execute;
 will need to change to below:

Page 540

 Query := TSQLQuery.Create(Nil);


 Query.Database := TODBCServiceConnection(DBServiceConnection).Connection;


 Query.SQL.Text := SQL;


 Query.Prepare;


Query.Open
 ;

 The serverside-class TException has been renamed to Exception


 C# and Java have new escape string literals


 Old: "this "" is a double quote";


 New: "this \" is a double quote".

 Morfik Basic, C# and Java now use hexadecimal literals.

Possible code changes to existing XApp Projects


AppsBuilder Release 1 (build 1.0.0.7) now allows you to convert all the code from one
language syntax to another.

IT IS HIGHLY RECOMMENDED THAT YOU MAKE A FULL BACKUP OF YOUR PROJECT BEFORE
CONVERTING.

This process does NOT create a new copy of the project but rather converts the existing one.
Note that in this version of AppsBuilder it is NOT possible to convert to Pascal syntax.

New Features
All Morfik project source files are XML format now. This include .mxp, .cfg, .mfr, .mrp, .mqr, .mmd,
1 .mtb, .mws file types.
Morfik debugger has been modified to enable it to debug Free Pascal Compiler (FPC) created
applications. What this means is that FPC has now replaced Virtual Pascal Compiler (VPC) as
2 the default backend compiler for Morfik. As of this release, VPC is no longer supported.
Access control and session management is now an application level operation and can now
be implemented within an XApp. System tables and related routines are not part of the
AppsBuilder anymore. The attached document contains information on how this can be
3 achieved in the new system.
4 The ‘Help Menu’/F1 now takes you to www.MorfikWiki.com
The Developer's Handbook 1.0 is now included as poast of the Morfik AppsBuilder
5 installation.
Converting projects from one language to another. This feature, which is available under ‘
Project Menu’, is currently being used as an in-house tool for converting all sample projects in
6 Morfik Labs to Morfik C#, Java and Basic languages.
Added OnPrintBodyStart and OnPrintBodyEnd events for a project to allow inserting
7 additional scripts to the Start or the End of the XApp Body.
New Column count property available via the PropertySheet for continuous forms to allow for
8 multiple column forms.
TException class name (server-side) has now changed to Exception and the msg property
9 changed to Message.
10 New OnPrintLoadingMessage event for projects to allow modification of the loading message
Salesforce.com related system tables are now only added when creating new
11 Salesforce.com projects (MFK$SYNC_CLUSTER, MFK$SYNC_SCHEDULE).
12 AppsBuilder Framework has been updated to work with the Salesforce.com API 8

Page 541
13 Content of the Output View can now be saved, copied or cleared.
The popup menu of the "Log view's memo control" is set correctly now and it is possible to
14 save, copy and clear contents.

15 "Errors view" now has Copy and Save options in the popup menu.
The Apache User and Group configuration has been added to the httpd.config file. Previously
16 this had to be done manually.

17 Support for .png images


18 Order of the project items has now changed. Form is now the first item in the list.
Added vertical scrollbar to the Memo control in the debugger "Evaluate
19 window".
Support default value for function/method parameters in Morfik Pascal is
20 added.

21 Morfik Basic now supports the following features: Implemented Do ... Loop While
 Implemented Do ... Loop Until

 Dynalists (list of ... syntax)


 Native syntax for hexadecimal literals
Array
 s
 Sets of ordinal type
Subrange
 types
Function
 types

 Class forward declarations


 Class reference types

 Compiler directives
 Compiler metadata

 File types (file of ... syntax)


 Const, Out, and Untyped parameters

 Type declarations nested within a function


 Nested functions

 Thread variables
 Inline JavaScript

 Initialization and finalization clauses (especially important for Scriptor)


 Record declarations

 MorfikDoc comments
Code
 folding

 Statement highlighting

Bug Fixes
Issues related to running XApps from the IDE in Firefox are
1 resolved.

2 The compilation error when using DecodeDate in the server module is now resolved.
Linux fixes: When running under Linux, sometimes the XApp failed to create cache
3 directory and this caused a crash in the XApp. This issue has been fixed.
Project OnStart Event
 now fires correctly.
Linux compilation (compiler
 cache) bug is fixed.

Page 542
COUNT now
works correctly at
 runtime
Queries which make use of field aliases no longer
 cause SQL errors
The run time error when a form that is previewed uses an external 'Table' containing nvarchar
 type field with length longer than 255 characters is fixed
Data from a memo field is now displayed correctly in a continuous
 form.
Issues with previewing a form that has a datasource with UniqeIdentifier field
 type.
Old:
"this ""
is a
double
 quote";
New: "this \"
is a double
 quote".
Compiler error when first character in a string literal is a single quote (‘)
 fixed
Compilation errors to do with
 ctype have been resolved.
Now allow equality expressions to be used as
 Boolean parameter.
Assignment of Dynalist items is handled correctly in
 browser-side code.
Having a dot after Me does not cause a
 compiler error anymore
Fixed the intermittent Access Violation
 while typing codes.

==AppsBuilder Release 1 (build 0.9.16.1)

Recommended actions when upgrading


AS WITH ALL SOFTWARE UPGRADES, IT IS HIGHLY RECOMMENDED THAT YOU MAKE A FULL
BACKUP OF YOUR PROJECT BEFORE LOADING AND COMPILING IT WITH A NEW VERSION OF THE
1 APPSBUILDER.
Uninstall previous versions of the AppsBuilder before installing this release as the database
2 engine in this release has been updated to the latest official release of Firebird 2.0.
Before compiling each of your projects, remove
the ‘_ProjectNameBuild’ folder that is
3 automatically generated in each project folder.
Note that you do not need to copy your existing license across because this version comes with
4 a built-in license.

Required code changes to existing XApp Projects


You may have to update some of the DOM objects that have used in your code due to the
major overhaul of the SystemDOM and SystemDomHTML framework modules. If you are using
TDOMEvent then you will need to add (import) SystemDOM in the module. A list of objects that
are commonly used in the XApp source codes with their new names are listed below.
1 TDOMHtmlControl -> THTML_ElementExt
TDOMHTMLObje
ct ->
 THTML_Element
Event.Target ->
THTML_Element(Event.Target
 )
Event.srcElement ->
 THTML_Element(Event.srcElement)
(DOMSender.Wrapper) ->
 (THTML_ElementExt(DOMSender).Wrapper)
 TWebControl(DOMSender.Wrapper) -> TWebControl(THTML_ElementExt(DOMSender).Wrapper)
CreateRecordSet ->
 DefaultDBConnection.CreateRecordSet
Properties and fields of an object must be defined before the methods of the object. ‘
 Unexpected Token’ error is displayed in the error list in the above case.

Page 543
External directive is now a metadata attribute and should change to the
 following: 'External=xxx' .

New Feature Highlights


WSDL Files : The ability to consume and publish web services, with automatic creation of a
WSDL file generated for every XApp. This is an ultimate method of publishing web services as
1 no additional work is required.
Service Connectors: Major upgrade to the WebOS data
2 connectivity architecture.
Support for Salesforce.com data connectivity and synchronization using Morfik Service
 connectors.
External databases can be added to an existing project using the
 Service Connectors.
New queries display service connection options to ensure data sources are from the
 same source
Connection to External Firebird databases with a choice of a native
 connection or ODBC.
Use of the system ODBC dialogs to obtain connection string. Redesign of the ODBC
 connectivity option.
Code Navigation - Pressing the ctrl key while moving the mouse pointer over your code will
highlight any identifier for which the IDE could take you to the corresponding definition. Clicking
 while holding the ctrl key will take you to the definition.

 Code completion.
Identifier occurrences highlighting – will highlight all occurrences of an identifier where the
 current cursor is positioned within the current scope.
Visual cues to help you identify when editing
 browser or server code.
Code
 folding.
Statement highlighting (needs to be
 enabled in ‘Preferences’).
Automatic error reporting while coding is in progress. Code which the IDE identifies as
potentially wrong gets underlined in red, in the same way as misspelled words are flagged in
most word processors. Errors are, also, added to the Errors tab at the bottom of the IDE
 window. Keep an eye on the new Errors Tab in the list of debugging monitors.
Inline help for classes and
 functions

Other New Features


Compiler Integration of the Free Pascal Compiler (FPC) within WebOS AppsBuilder to allow for
1 compilation of XApps to permit multi-platform support, currently Windows and Linux.
Support for Delphi 5, 6 and Delphi 7 in the Target
 Platform options.
Support for two new data types: Big Integer, Fixed Decimal - with precision and scale
 factors.
New meta-data tag to control
 JavaScript obfuscation
Enhanced support for in-line JavaScript and linking-in external handwritten JavaScript code
 libraries.
New Run Time Library structure for the distribution of Morfik WebOS
 AppsBuilder.
Major overhaul of the SystemDOM and SystemDOMHTML framework modules to fully comply
 with the new W3C standards.
 New Sendemail function allows sending multiple format emails from within an XApp.
The HTTP, IMAP and POP3 protocols are now supported in Morfik, through the
 SystemInternetIndy module.
New Popup dialog features using the standard Openform function. There are also a range of
 Parameters available to allow dialogs to open in modal form or to have different attributes.
The PDF library has been rewritten so as to make it possible to distribute its source as part
 of Morfik Framework.
Sleep ()
function
 added.

Page 544
A new color picker has now replaced the previous one and offers web colors as well as
 additional options to make the color selection/creation process easier.
A new Resource Repository is available to allow developers to have one central repository to
manage project resources such as images, css, flash or pdf files and any other documents used
within the project. The Image Gallery does not exist anymore, as images are now managed
 within the Resource Repository.
Automatic vertical and horizontal lining of controls on
 a form or report.
Tools/Options changes. The Tabbed options under Tools/Options menu has now been divided
into three different categories and under three different menu items. Project Options (under
project menu item), Debugger Options (under Debugger menu item), Environment Options
 (under Tools)
New search tab in the monitors. The search speed is improved significantly and the new
search tab shows more details on the search result. Double clicking on a search result
 takes the developer to the highlighted search text in the source.
An improved data grid in Morfik AppsBuilder to view records in Tables and Queries at design
 time.
Document 'view state' is now saved. When opening the document next time the position of
the cursor in both server and browser modules are remembered. The active module (server
 or browser) is also remembered.
New icons and images are now added to the IDE and some of the existing icons have been
 updated.
It is now possible to right click on a control in a Form and use ‘
 Snap to Grid’.
Right clicking on a Report now shows the "Design Data Source" menu item to view the data
 source for the report.
Improvement to the docking process in the AppsBuilder design environment. This will also
 allow group docking of the Object Inspector ##Explorer and the Object browser.
Faster table load and table save
 at design time.
Major updates to the
 Combobox control




Listbox control
 now included.
Subform names are now more descriptive and allows a developer to identify the name of the
 subform and form that is placed within it.
New Form wizard for the creation of sophisticated (Grid like)
 continuous forms
A new Tool tips property is added for every control. The value in this property is displayed on
 the mouse over event of the control.
When creating a new document (Table, Query, Form, Report, Web Methods and Modules) in
 design view, it is now possible to rename the default name.
 The bundled Firebird database engine is updated to the latest official release of version 2.0.
Ability to choose an existing Firebird 2.0 on a system rather than having to use the default
 database engine in Morfik.
Firebird reserved words are now allowed to be used as names for tables and
 fields.
If Firebird is not running as a service at the time a project is opened, Morfik will
 automatically run Firebird as an application.
Use of the system ODBC dialogs to obtain connection string and redesign of the ODBC
 connectivity option in import data wizards
Macros have been superseded by Web Methods that enable you to create industry
 standard web services in addition to internal remote calls.
It is now possible to consume (import) external Web Services in Morfik. Click on Project menu
and select WebServices / Import ##WebServices to start the import wizard. There is also a
new demo XApp under WebService directory that has three examples of consuming external
 web services.
New conflict resolution methods for reserved words used in Table and Field
 names.

Page 545
Adding ability to select SSL Level3 for
 Web Services.
Support for iso-8859-1/windows-1252 character set. A new option is now added in the new
 project wizard which allows to select an appropriate character set for a project.
New Browser History property for Forms. If set to false, the form does not add duplicate entries
in the browser history. This stops multiple entries for a page if the form is set to refresh
 periodically.
A new internal version tracking system for supporting backward and forward compatibility
 of project files.
New improved and short URIs for Morfik XApps. Developers at design time can choose to have
 long or short URIs depending on the applications.
New Sample projects to showcase some of the new
 features in this release
New options in the Morfik
 installation process.
Preliminary support
 for Safari browser.
A parametric query may now be used as the
1 LookupDataSource
It is now possible to display a descriptive text in a Combo-box and store an associated
non-descriptive value in a form data field. ### LookupTextField, LookupDataField
properties can now be specified by choosing from a drop-down list of field names in the
1 property sheet
The default height and border style of the Combobox have been changed (this is to work
1 around a bug in IE)
The Combobox is now painted correctly at design time under both Windows Classic style
1 and Windows XP Style
Incorrect entries in a data bound Combobox when placed in a single form
1 is fixed.

Bug Fixes
Compiler and Debugger Inability to use recursive calls (calling a method from itself) on browser
1 side has been fixed.
Issues relating to compiling a
project as a Plug-in dll (using
 VP).
"Cannot start debugger!" error message does not appear anymore when trying to preview
 a project when the Main Form option is not set correctly.
Now possible to have non-dual Globals modules and compile a project without any compilation
 errors.
Switching JavaScript optimization ON
 and OFF inconsistencies fixed.
The breakpoints and search items line numbers are updated as a developer change the code in
 the code editor.
Issues related to the debugger leaving behind the breakpoint red lines in the code editor
 fixed.
Issues with accented parameter values in an OpenReport function not getting passed correctly
 to the server fixed.
All showMessage calls are now redirected to DebugOut, which displays the text in the IDE
 Output Panel.
Optimization and improved algorithm in the system Array sorting and handling, String compare
 to handle local setting
Setting parameters in an OpenForm function with Target parameter set to “Blank” is no
 longer problematic anymore.
Calling SystemUtilities.AddMonth() does not causes a type
 mismatch error.
Incorrect behavior in
StrToDateTime function
 has been fixed.
 Functions DateTimeToString and StringToDateTime do not have consistent parameters order.
The Timestamp (Now) functions in the browser and server modules have been made more
 consistent.
The standard Ctrl-A "select all" shortcut now works for both the code editor, form
 editor/designer, and the SQL editor.
Pressing F9 in the IDE now compiles and
 runs the XApp at design time.
 The hexadecimal value of the color property in the property sheet and Formatting tab of the

Page 546
Toolbox can now be edited manually from the property sheet.
When right clicking on the details band of a form, the 'Align to grid' option only appears if a
 control is selected.
Issues with the File/Open menu item to remember the location where it last opened a
 document and checking for the existence of a file to open fixed.
Hotkey
fixes and
improveme
 nts:


 The issue that didn’t allow for an event to be recreated after it was deleted the first time fixed.
Code editor Modified status is now
 cleared after the form is saved.
The auto-insertion of stubs and handlers are more simplified. The property inspector has been
updated with Check boxes instead of the True/False drop downs and ellipses have been placed
 next to each event to make the process more intuitive.
Fuchsia and Aqua color presets are now correctly defined in SystemClasses framework
 module.
The "List index out of bounds" error message that appeared due to a project not being saved
 at the time of closing is fixed.
The Title field in the property inspector of a project can now contain single
 quote.
Inability in previewing new forms on
 intermittent bases has been fixed.
When copying and pasting a module from within the AppsBuilder design environment, the
 new module name is now reflected correctly in the server and browser modules.
 Corrected the order of the OK and Cancel buttons on the parameters editor window for forms.
Attempting to copy a property value of a control or set of controls in the property window
resulted in the copy of the selected controls themselves. This has been resolved and only
 the selected property is now copied.
Type declaration code for objects is now always removed properly
 when deleted.
The horizontal scrollbar in the code editor can now only show more than 257 character on
 one line.
Errors were caused when closing projects while there are tables and queries still open. This
 has been resolved.
The issue of the new line chars within the text, if the text is entered through the memo
 dialog in the Table data view fixed.
Minor issues with running Morfik WebOS AppsBuilder in
 Windows Vista fixed.
Issues with 'List Index Out of Bounds' error, when scrolling on property inspector window
 using the wheel fixed.
Spelling mistakes and typos have been corrected through out the AppsBuilder design
 environment.
Copy and Paste options for controls using the mouse right click in Forms or Reports have
 been reinstated.
 The Print menu item under File and the print icon work as expected for the code editor.
In the Form designer, F2 function key now switches TextLabels
 to edit mode.
 Updated the Hotkeys to Reopen. This now shows a more accurate list of recently viewed files.
Issues related to report containers that are set to Border Style of bsInset or bsOutSet have
 been fixed.
The string property editor of object inspector (the Form with caption 'Edit Caption') is now
 anchored correctly.
Clicking the Rules button in the form/ does not cause access violation error
 anymore.
No intermittent Access violation error message is displayed when the previewed form has its
 banner/footer is set to hide.
The DatetimeEdit and FileUploader controls, incorrectly, allowed other controls to be pasted
 within them. This issue has been resolved.
Objects can now be pasted onto a form if a
 subform is already selected.
Color selection dropdown in the properties window is not constrained by the width of the
 properties window anymore.

Page 547
The names for the most recently used items in the startup page can not be
 changed.
It was not possible to right click on a cell in the Table Data view and use the new copy and
 paste options
The Caret in a text editor now moves
 to the right position on Enter.
Existing images in the resource repository can now be replaced with new images that have
 exactly the same names and the images are displayed correctly.
 Assigning the Picture property of an Image control in the server modules now works correctly.
Passing the default value of parameters in a single form, using OpenForm function, does not
 display zero records anymore.
The behavior of the Headers and Footers in Reports are now similar to Forms when they don’t
 contain any controls.
Firefox incorrectly truncated memo fields longer than 4048 characters. This has been
 resolved.
The content of a band in a form or report were copied even if 'only' the band was selected. This
 issue has been resolved.
Adding/deleting components in form designer (or adding/deleting parameters in a web
 methods) do not change the cursor position in server or browser modules anymore.
The incorrect behavior of property inspector when opening a project where in the previous
 project the property inspector was undocked and closed is fixed.
The Redo option is now added to the code editor when mouse right button is
 clicked.
 FaultCode is now set when making a server-side call to a webmethod of another XApp
Issues with Tabs appear out of order at runtime
 in the TabControl fixed.
Form
option
was
not
 set.
Generating a data-bound PDF report that includes an image field no longer generates a run
 time error if record/s didn’t have an image value.
Forms property of subform control does not list its
 owner form anymore.
As a result of renaming a control in a form, the Combobox with the list of controls in the
 properties window is reset and displayed only one item. This issue has been fixed.
Issues with SubReports and Page Breaks
 in Reports have been fixed.
The following bugs to do with the DateTimeEdit controls have
 been resolved:



Controls within a container control and bands are now locked if the container or the band itself
 is locked.
Disabling a timer control does not remove an impending timer event resulting in an extra
 event being fired. The impending event is now removed.
Next and Previous Page in the navigation bar for Continuous Forms, used as the main page,
 causes "Form "top" does not exist error message. This has been resolved.
Issues related to displaying RecordCount for very large number of records within the
 navigator have been addressed.
 Forms containing Flash presentation would flicker while loading in Firefox; this has been fixed.
Improvements
made in form
bands resizing
 methods.
The picture property for a new
image control is now set to
 blank.
A scrollbar is now added to the string list editor, which allows adding of items to a
 Combobox.
 Record

Page 548
Navigator
improvements
and fixes:






Major fixes and updates to the native connectivity to external Firebird
 databases.
Users with their own installation of Firebird were unable to use Morfik if the SYSDBA password
 was changed to something other than masterkey; this has been resolved.
The extension block is moved from the MTB/MXS file to firebird's
RDB$RELATIONS.RDB$DESCRIPTION field. This makes it easier to connect to the MXDs of
 other projects using the service connector wizard.
It was problematic to alter a table that was renamed. If tried to alter the table, one got an
 error message which referred to a generator with a name similar to the original table name.
Issues with UTF8 character set XApps refusing to connect to UTF8 firebird databases, using
 a Firebird service connectors, have been resolved.
There is a table field limit of
100 for mySQL ODBC
 connection.
The default firebird database extension in import data wizard or the service connector is
 .fdb as well as .gdb.
The Data view grid limit of
maximum 100 fields per table is
 fixed.
Query changes take effect in the forms instantly. No need to re-build or re-save query
 bound forms after altering the queries.
 Using a more lightweight system that composes the SQL statements for continuous forms.
Fixed the issues with creating a new record in a linked MS Access table that contains an
 AutoNumber field.
Issues with default values of database fields causing compiler errors (intermittent) are
 resolved.
Issues related to saving
parameters in pass-through
 queries, fixed.
Issue with displaying an image in a Single Form
 based on a Query fixed.
In the query wizard, the incorrect Total options in the
 Fields step, is fixed.
The default value for the "Yes/No" field in table design can now be set to ‘Yes’ or ‘No’ text
 without resulting in errors at the data entry time.
Issues with the pass-through queries executing the Insert statements multiple times have
 been resolved.
Queries with renamed data sources (tables and nested queries) now display a message on the
 name changes and allow the developer to view the query in design mode.
The Table wizard now does not allow a memo field to be set as a primary key as soon as
 the field is selected.
 The inaccurate renaming process for external ODBC tables within the IDE has been corrected.
Autonumber fields of GUID Class now work correctly. New GUID values are generated as
 new records are added to a table.
It is now possible to open a project if any of the external databases used are
 offline.
At design time, data from floating-point number fields always display as currency (preceded
 by $ sign) is fixed.
Issues with data in memo fields of external Firebird databases not displaying at design time are
 fixed.
Picture fields of

Page 549
external MXD files
now display at run
 time.
The inconsistencies with alternative methods of accessing the Relationship tab in the
 AppsBuilder have been fixed.
Fixed problems with altering tables which were
 renamed at design time.
Issues related to importing Firebird
 databases into Morfik are resolved.
Intermittent problem with the table data view and design view not being in synch after
 fields were deleted in a table have been resolved.
 The incorrect start and increment options for the Autonumber GUID fields have been removed
Defining a web method, without any parameters, generated the following error at run time
 "firstChildElement of SOAP-ENV:Body null = Nil". This has been fixed.
Parameters with space between "=" sign and the Parameter name of a Web method works
 correctly now.
Using incorrect parameters in the RunWebService function generates an error message at
 the time of execution.
The FaultCode for a Web Method is now set when using browsers
 other than IE.
The issue of declaring a class under the Implementation section of a Form causing
 unwanted results is resolved.
All sample projects have been updated to compile and run with the latest
 release.
Issues with handle
leaks when an XApp
 is running resolved.
 General improvement to Morfik created applications in order to make them fully W3C compliant.
In the new project wizard, the project name is now checked to ensure a valid
 name.
 The default value of the ThreadsPerChild Apache directive has been increased to 500.
The sample demo ‘Northwind’ has been updated with fixes applied to
 the reports.
Fixed the JPEG
error #38
error
 message.

 Issues with the main form not loading and the 'Loading...' not disappearing in some XApps .
The 'Add Watch', 'Toggle Breakpoint' and 'Breakpoint at' option under the Debug menu is now
 only enabled when required.
CTRL+O
is now
for
File|Ope
1 n
Alt + D
should show
the Debug
1 menu
The dfShort date format was not working; this has been replaced with two options, "Short
DDMMYYYY" and "Short MMDDYYYY" which display the date in the DD/MM/YYYY and
1 MM/DD/YYYY formats respectively
The ShowCheckBox property is now working. Checking/unchecking the checkbox enable/disable
1 the edit box.
The state of the checkbox now correspond to the NULL/non-NULL state of the underlying
1 DataField
Today in the drop-down calendar is now always the
1 expected correct date.
Issues related to repositioning and aligning the navigator as the form size changes has
1 been resolved.
Double clicking on the total records edit box on a navigator does not generate any error
1 messages.
Resolved issues related to Firefox browser displaying blank page if the Last page button on
1 the navigator was clicked in a continuous form.
New tool tip is
displayed for all
1 buttons within the

Page 550
Navigator.
The Next and Previous page buttons now work at run time if the PageSize property for a
1 single form is set to –1.
Issues with the navigator buttons not being disabled correctly after the page are loaded for the
1 second time is fixed.
Not having the current page and page count in the navigation bar causes the form
1 navigator to behave incorrectly. This is fixed
The First and Last record buttons on the navigation bar now move to the absolute First and last
1 records.

Release Timeline
Historical timeline of releases

Page 551
patch the Morfik 1.4.0.1
installation to work with
Firebird 2.1

In order to run Morfik 1.4.0.1 in the same computer as Morfik 2.0.3.11 or later, you
will need to patch the Morfik 1.4.0.1 installation. The procedure is fairly simple but
it is important to note that projects saved in a computer which has been patched
to use Firebird 2.1 will NOT be opened in a computer that is running an unpatched
version of Morfik 1.4.0.1 which is still using Firebird 2.0.

To patch your installation you should download the following file and copy it to the
system folder of your Morfik 1.4.0.1 installation.

MFKUDF.SQL

Page 552
External Databases

Morfik Database Connectivity


Primary Databases vs. External
Databases
Why Use External Databases?
Database Mashups
External Databases and Service
Connectors
Working with External Firebird
Databases
Creating a Connection
Querying an External Connection
Working with Different Databases
Which Databases are Supported?
Connecting to an MS SQL Database
Querying an External MS SQL
Connection
Using ODBC DSN Data Sources
Accessing External Databases Through
Code
Wrapping it up
Related Video

Morfik Database Connectivity


Database connectivity is a major point in any modern application. Databases have become so
ubiquitous that most people do not even stop to think about them. Databases are mainly taken for
granted as part of any developer ’ s arsenal of tools to attack any specific problem.

With that in mind Morfik not only chose to provide a fully integrated relational database server, but to
also offer support for connecting to other databases such as MS SQL Server, MySQL and Oracle.

Since database connectivity is essentially a server based task, this topic does not apply to Morfik
Browser Application projects. All the features described in this topic apply only to Morfik Web
Application projects.

Primary Databases vs. External Databases


One of the first things to understand in working with external databases in Morfik is what the
differences between primary databases and external databases are. Primary databases are always
Firebird Databases and these accompany your project from the beginning. Morfik stores some system
information in these databases and they are an integral part of how the Morfik framework functions.

An external database is a plain and simple database, with no system tables or any intrinsic use by
the Morfik Framework.

Why Use External Databases?


The most common reason to use an external database would be because you already have it. In this
case, even existing Firebird databases would be good candidates as external databases.

Another reason could be adherence to corporate standards. If your company has standardized on

Page 553
another database, Morfik can access it, provided that it has an ODBC driver (native connectivity is
under development).

Database Mashups
Data mashups between different databases is one area in which Morfik really excels at. You could be
combining data from a primary Firebird database, with an external MS SQL Server database, with
data coming directly from Salesforce.com. In this kind of situation you will, in fact, have not one but
several external databases tied to your application.

External Databases and Service Connectors


Morfik brings to your application development world the concept of the Service Connector. A Service
Connector allows your application to have access to data made available by an online service
(Salesforce.com, eBay, etc), a database management system (MS SQL, Oracle, Firebird, MySQL, etc)
or a standard Internet service such as email. Service Connectors allow you to treat disparate data
sources as if they were sets of database tables. In this chapter we will concentrate on the external
database related Service Connectors.

Working with External Firebird Databases


As an external database, Firebird would be just one more, except that Morfik uses its built-in native
database access layer. So, when working with an external Firebird database you use all the same
classes you would use to programmatically access the Primary database, just a different connection.

Creating a Connection
The first step to connect to any kind of external database is to create a connector for it. This can be
done by going to the Project | Service Connectors menu option. This option will bring up the dialog
you see on Figure 1.

Figure 1 – First page of the Service Connector Wizard

In the dialog that appears in Figure 1 you can see the "External Firebird Data Sources" option
selected in the first page of the Service Connector Wizard.

Once you choose to work with an External Firebird Data Source you are taken to the second page of
the Wizard in which you must indicate the location and connection parameters for your external
database, as you can see in Figure 2.

Page 554
Figure 2 – Second Page of the Service Connector Wizard when connecting to an External Firebird
Data Source.

Once you have successfully connected to your database (you can test the connection by clicking on
the "Test Connection" button) you are taken to the third page of the Wizard which will ask you to
select which tables you wish to have access to, in this project. The third page of the Wizard can be
seen in Figure 3.

Figure 3 – Third Page of the Service Connector Wizard when connecting to an External Firebird Data
Source.

Just to demonstrate how this works, I created a database with a single small table. In Figure 3 you
can see this table selected. If more tables where available, you could choose several, or just one as
in this case. We will see an example with a larger database, when we look at connecting with an MS

Page 555
SQL database.

On the third page of the Wizard, when you click on the "Advanced" button, it will bring up a window
in which you can attribute aliases to the tables you are bringing into the project. This window can be
seen in Figure 4. You might want to change the names of data objects to conform to internal
corporate policy or to avoid name clashes with objects you have already created within your project.

Figure 4 – Window for creating aliases for objects in external databases.

Once you have completed the process of choosing the tables with which you work with in your
project, you are taken to the fourth page of the Wizard where you are called upon to name the
Service Connector you are creating. You can see this page in Figure 5, where the Connector receives
the name Firebird Contacts.

Page 556
Figure 5 - Fourth Page of the Service Connector Wizard when connecting to an External Firebird
Data Source.

After you have gone through these steps the Wizard will be complete and you can exit it by clicking
on finish. Once you have gone through the Wizard, you will be able to see a new table in your
project. In Morfik 1.4.x and previous versions, this table would have a special icon of a table with an
overlying arrow which indicates that it is an "external" table. In Morfik AppsBuilder R2, external tables
are represented in the same manner as tables from the application's default database. If you chose
more than one table on running the Wizard, you will have as many new table objects. In Figure 6 you
can see a screenshot of the Morfik Workspace with the external table shown.

Figure 6 – Morfik Workspace with an external table called Contacts, shown in the tables list.
Once the Service Connector as been configured you will be able to use the external tables just about
anywhere where you could use a table from the Primary database.

Querying an External Connection


Creating a query against an external database is almost exactly the same as doing it against the
Primary database. The main difference is that when your project has a Service Connector configured
you will be asked to state which database you wish to query against. This is done by bringing up the
window that you can see in Figure 7.

Page 557
Figure 7 – Select database window in the Morfik Workspace.

If you wish to create a query, visually within the Workspace, after you have selected the appropriate
database in the window shown in Figure 7, you are taken to the Visual Query Designer, just as when
you work with a primary database, as you can see in Figure 8.

Figure 8 – Visual Query Designer showing query design based on an external database table.

Page 558
Working with Different Databases
In order to present you with a complete overview of how to use an external database, I decided to
use MS SQL Server as an example. All that we will see in this chapter can be applied to other
databases as well.

Which Databases are Supported?


You can use with Morfik any database that has an ODBC driver. This opens up possibilities to
connecting to all the major databases, commercial or open source as well as many proprietary data
sources.

Connecting to an MS SQL Database


In order to connect with an MS SQL Server database you will follow a procedure which closely mirrors
that described in the topics regarding the connection to an external Firebird database. In this case, in
starting the Service Connector Wizard, you will choose the "ODBC data sources" option in the first
page of the Wizard as shown in Figure 9.

Figure 9 – Starting up the Service Connector Wizard in order to create a new


ODBC Data sources

Having chosen the ODBC data source option in the Wizard you are asked to choose the ODBC driver
or data source you will be using. This can be seen in Figure 10.

Page 559
Figure 10 – Select an ODBC driver or a data source to use with this Service Connector.

After indicating that you want to work with the Microsoft SQL Server driver you will be asked to
provide connection details, just as is show in Figure 11.

Figure 11a – Service Connector Wizard requests information about the database connection such as
username, password and the name of the plane.

Page 560
Figure 11b.

When you work with MS SQL you are connecting first to the server, then you will be asked to choose
the database on the server, with which you want to work, as shown in Figure 12.

Figure 12 – Choosing a database after initial configuration of the ODBC


Database Service Connector.

Page 561
Figure 12b. – You have the connection string, you are now ready to select the data objects that will
be used in the project.

Just as you could change the names of the tables in an application which used the Service Connector
to the Firebird external database, you can do so when working with the ODBC data source as well. In
order to more clearly illustrate this I have done another example which uses MS SQL Server ’ s
Northwind database in order to have more tables in the database.

In Figure 13 you can see the selection of the desired tables within the Wizard itself and then on
Figure 14 you can see the window brought up by clicking on the "Advanced" button. This window
allows the aliasing of specific external data objects, as we have seen before.

Figure 13 – Choosing which data object will be used in the project.

Page 562
Figure 14 – Creating aliases for tables from different origins, which are used in your project.

Once you have completed all these steps in the Service Connector you will be, again, expected to
name this service connector, as shown in Figure 15.

Chapter_9_Working_With_External_Databases_15_m2.PNG Figure 15 – Service Connector Wizard


asks for the name of the Connector that is
about to be created.

Once all this is done and the Wizard has been concluded you will see a new set of tables within the
Morfik Workspace. These tables will show an arrow over table icon as an indication of their being
external tables. An example of this can be seen in Figure 16.

Chapter_9_Working_With_External_Databases_16_m2.PNG Figure 16 – Several external tables


listed in your project ’ s table list.

Querying an External MS SQL Connection


Creating a query against an external ODBC database is almost exactly the same as doing it against
the Primary database. Once you have selected that you want to work an external database you will
be taken to the Visual Query designer. From the Visual Query designer you can work freely to create
your query. In Figure 17 you can see a query being visually created, based on four tables.

Chapter_9_Working_With_External_Databases_17_m2.PNG Figure 17 – Visually creating a complex


query on external database tables.

Using ODBC DSN Data Sources


Morfik allows you to choose from the ODBC DSN data sources that are configured in your computer or
even from DSN configuration files. In Figure 10 you can see a checkbox that gives you the option of
looking up the DSNs, instead of just choosing an ODBC driver.

In Figure 18, you can see a page of the Create Service Connector Wizard which allows you to choose
a machine DSN configuration for the creation of the connector for the access to your external data
base.

Page 563
Figure 18 – Machine DSN selection page in the Create Service Connector Wizard.

Accessing External Databases Through Code


All we have seen in this chapter is about accessing the external databases through Morfik ’ s built-in
data-awareness. This is very simple and straight forward. In Morfik AppsBuilder, visual, high level,
objects see mapped external tables just as if they were tables in the primary database.

You can access the external databases by writing code in a WebMethod for example. In order to do
that you must go through the process of getting a connection to them. The code you see in listing 1
and listing 2 should give you a general idea of how to do this. The code in both listings does exactly
the same things, using two different service connectors, however. The first one shows you how to
use a connection to an external Firebird database, while the second one shows you how to do the
same thing with an ODBC connection. In this test scenario we used a Microsoft Access external
database. All databases that are accessed through the ODBC service connector would work with the
same source code.

Listing 1 – Server side code of a WebMethod that accesses an external Firebird database.

Unit UserLogin_ExtFB ;

Interface

T ype
UserLogin_ExtFB = Class ( WebMethod )
UserName : String ;
Password : String ;
Authorized : Boolean ;
UserID : Integer ;
CompleteName : String ;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
P rocedure Execute ; override ;

Page 564
End ; [ 'P ublished=False' ]

Implementation

uses
SystemConnectors ,
SystemConnectorsIBO ,
SystemCatalog ,
SystemDatabase ;

P rocedure UserLogin_ExtFB . Execute ;


Var
Connector : T ServiceConnector ;
Connection : T IBOServiceConnection ;
UserRS : T RecordSet ;
SQLstr : string ;
Begin
SQLstr := 'SELECT "UserID", "Name" FROM "tbUser_1" where '
+
'"UserName" = ''' + UserName + ''' and ' +
'"P assword" = ''' + P assword + '''' ;

Connector := Catalog . GetServiceConnectorByID (


'External Firebird' );
If Connector = Nil T hen Exit ;

Connection := T IBOServiceConnection ( Connector . CreateConnec


tion );
T ry
UserRS := Connection . CreateRecordSet ( SQLStr );
UserRS . P repare ;
UserRS . Active := T rue ;
UserRS . First ;
Authorized := False ;
UserID := - 1 ;
CompleteName := '' ;
if not ( UserRS . Bof and UserRS . Eof ) then
begin
Authorized := T rue ;
UserID := UserRS . FieldByName ( '"UserID"' ). AsInteger ;
CompleteName := UserRS . FieldByName ( '"Name"'
). AsString ;
End ;
Finally
UserRS . Free ;
Connection . Free ;
End ;
End ;

End .

Listing 2 – Server side code of a WebMethod that accesses an external ODBC database.

Unit UserLogin_ExtAccess ;

Interface

uses

Page 565
SystemCatalog ,
SystemConnectors ,
SystemConnectorsODBC ,
SystemDatabase ,
SystemDatabaseSQLDB ;

T ype
UserLogin_ExtAccess = Class ( WebMethod )
UserName : String ;
Password : String ;
Authorized : Boolean ;
UserID : Integer ;
CompleteName : String ;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
P rocedure Execute ; override ;
End ; [ 'P ublished=False' ]

Implementation

P rocedure UserLogin_ExtAccess . Execute ;


Var
Connector : T ServiceConnector ;
Connection : T ODBCServiceConnection ;
Query : T SQLQuery ;
SQLstr : string ;
Begin
SQLstr := 'SELECT "UserID", "Name" FROM "tbUser_1" where ' +
'"UserName" = ''' + UserName + ''' and ' +
'"P assword" = ''' + P assword + '''' ;

Authorized := False ;
UserID := - 1 ;
CompleteName := '' ;

Connector := Catalog . GetServiceConnectorByID ( 'External Access'


);

If Connector = Nil T hen Exit ;

Connection := T ODBCServiceConnection ( Connector . CreateConnec


tion );
Query := T SQLQuery . Create ( Nil );
Query . Database := Connection . Connection ;

T ry
Query . SQL . T ext := SQLStr ;
Query . P repare ;
Query . Open ;
Query . First ;
if not ( Query . Bof or Query . Eof ) then
begin
Authorized := T rue ;
UserID := Query . FieldByName ( '"UserID"' ). AsInteger ;
CompleteName := Query . FieldByName ( '"Name"' ). AsString ;
End ;
Finally

Page 566
Query . Free ;
Connection . Free ;
End ;
End ;
End .

It is important to note that when you are using an ODBC connection you do not use the same
TRecordSet class that is used when you are accessing a Firebird connection. Instead, you use a class
called TSQLQuery which is quite similar, but not identical. The usage is different because Morfik
believes that you should have the full power of the underlying data access mechanism at your
disposal, not a common subset, if you wish to directly handle data access.

For handling the visual aspects of database interaction, the Morfik Framework does treat all data
connections in a similar way, handling the differences for you.

Note in the code, in Listings 1 and 2, that the way to get access to your external database is to get
an instance of the Connector you have defined and then, from it, you get a Connection object. The
connection objects will be specific for each kind of Connector and the way to use them will be
different as the code examples show.

All databases that are accessed through the ODBC connector will be accessed in the same manner.

Wrapping it up
Morfik allows connection to external data sources for data access from within your applications and
from the Workspace itself. External database connections are handled through the Morfik Service
Connectors which are a part of the Morfik Satellite application architecture.

Related Video
 Link to External Databases
category:Programming

Page 567
Morfik Options

In version 2.0, Morfik AppsBuilder brings all types of options into a single,
integrated, dialog. Through this dialog the user can set environment, project and
debug options without having to look in different windows to find what he
wishes.

The AppsBuilder Options dialog is divided into several different areas which can be
selected from a vertical menu on the left side of the window.

General
Editor Source

Editor
Display
Code Assist
Syntax Color
Application
Server
Compiler
Debugger
Exceptions
Trace
Customize

Page 568
See Also

General
For information on how to configure startup behavior, personalize the look of the IDE and the
look and behavior of the Form and Report designers, please refer to the General section of
the AppsBuilder Options dialog.

Editor Source
For information in configuring the behavior of the AppsBuilder 2.0 IDE and the editing related
aspects of its appearance refer to the Editor Source section of the Options dialog.

Editor Display
For information in configuring the appearance of the AppsBuilder code editor refer to the
Editor Display section of the Options dialog.

Code Assist
For information on how to configure the different aspects of code completion and other
computer aided coding features, please refer to the Code Assist section of the Options
dialog.

Syntax Color
For information on how to personalize the way the source code is highlighted in the
AppsBuilder code editor, please refer to the Syntax Color section of the Options dialog.

Application
To check and set application-wide, startup, parameters for your application, please refer to
the Application section of the Options dialog.

Server
To configure and costumize the behavior of the built-in web server of the XApp built by the
currently open project, please refer to the Server section of the Options dialog.

Compiler
For configuring how the AppsBuilder compiler and the platform compiler behaves in generating
the application, as well as to select the Framework folder which will be used in the
compilation, please refer to the Compiler section of the Options dialog.

Debugger
For configuring how the browser and server side debuggers in Morfik AppsBuilder works,
please refer to the Debugger section of the Options dialog.

Exceptions
In order to select which exceptions are trapped by the debuggers built-in to Morfik WebOS
AppsBuilder, please refer to the Exceptions section of the Options dialog.

Trace
To set preferences on how and what to trace while debugging and designing an application,
please refer to the Trace section of the Options dialog.

Customize
To customize the options available in the Quick Access toolbar you should refer to the
Customize section of the options dialog, in the Morfik Workspace.

Page 569
See Also
 The Workspace

Page 570
Application

Figure 1 - Application section of the Morfik AppsBuilder 2.0 Options dialog.

The Application section of the AppsBuilder 2.0 Options dialog allows the setting of
several application-wide parameters which define the application looks and works
at runtine.

Project
Options
See also
Related Video

Project Options
The Project Options area of the Application section of the AppsBuilder 2.0 options dialog
allows the setting of several parameters that control some basic features and behaviors of
the application.

Page 571
Figure 2 - The Project Options area of the Application section of the Options dialog.

Individual options in the area are:


Main Form - This option allows the user to define the which of the forms
in the application will be its "home" form, the form that is displayed
 initially when the application's URL is accessed
Browser not supported - Form that should be displayed when an end user tries to view the
 XApp using a web browser that is not supported by Morfik.
Long URL - If this option is ticked, then, as the user navigates to
different parts of your XApp, information about its state is written into
the URL, making it possible to bookmark a particular part of your XApp. If
this option is unticked, then the URLs are much more compact, but
 bookmarking is not supported.
Background Startup -
 This option is obselete.
Page Alignment - Pages can either stretch to fill in then entire width of
the browser window or have a fixed width. In case the page has a fixed
width it can be aligned to one of the sides or or centered within the
browser window. Figure 3 shows the Simple Blog application with its
 "page" centered in the browser window.
Background Color - Pages can either stretch to fill in the entire width of the browser window or
have a fixed width. In case the page has a fixed width the area around the page will be filled
 with the color specified by this property.
Background Image - Pages can either stretch to fill in then entire width
of the browser window or have a fixed width. In case the page has a
fixed width the area around the page will be filled with the image
specified by this property. The image will be repeated to fill out the
entire area. This property will override the color specified in the
 Background Color.
Background Image Style - CSS code that controls how the background image should be
 repeated across the page.
Page Margins - This option is not yet
 implemented.

Page 572
Figure 3 - Simple blog application showing screen areas filled with background color and using
a short URL configuration.

See also
 AppsBuilder 2.0 Options

Related Video
 Compiler and Application Options

Page 573
Code Assist

Figure 1 - Code Assist section of the Morfik AppsBuilder 2.0 Options dialog.

In the Code Assist section of the AppsBuilder 2.0 Options dialog, parameters
which define how the Intellisense features of Morfik work.

Intellisense
Options
See also

Intellisense Options
The Intellisense Options area of the Code Assist section of the AppsBuilder 2.0 options dialog
allows the setting of several parameters that govern how Morfik's Intellisense features work.

Page 574
Figure 2 - The Intellisense Options area of the Code Assist section of the options dialog.

Individual options in the area are:


Code Outlining - This option inserts an outline guide at the left margin of the source code
allowing complex code entities to be collapsed. Statement Outlining - This option inserts an
outline guide at the left margin of the source code allowing individual statements in the code to
 be collapsed.

See also
 AppsBuilder 2.0 Options

Page 575
Compiler

Figure 1 - Compiler section of the Morfik AppsBuilder 2.0 Options dialog.

In the Compiler section of the AppsBuilder 2.0 Options dialog, allows the
configuration of parameters which define how the AppsBuilder compilers and
platform compiler behave. This section also allows the setting of the path for the
Morfik Framework.

Compiler Options
Framework Options
Platform Compiler
Options
See also
Related Video

Compiler Options
The Compiler Options area of the Compiler section of the AppsBuilder 2.0 options dialog allows
the setting of several options to configure how the AppsBuilder compilers behave when

Page 576
compiling the project.

Figure 2 - The Compiler Options area of the Compiler section of the options dialog.

Individual options in the area are:


Obfuscate Javascript - This option instructs the
AppsBuilder compilers to generate obfuscated
Javascript code. Obfuscated code, besides
helping to prevent unauthorized viewing of
browser side code, helps to improve performance
by reducing the size of the code that gets
 downloaded to the browser.
Optimize Javascript - This option instructs the AppsBuilder compilers to remove unused entities
from browser-side code before generating the Javascript. This helps to improve performance by
 reducing the size of the code that gets downloaded to the browser.
Package Resources - This option allows the user
to choose if the files added to the resource
repository are packaged into a single file for
deployment along with the application or remain
as independent files in the repository folder for
the project. In the latter case, all the files in the
folder must be deployed along with the
 application.
Enable Profiler - This option will enable the profiler for the current project. The profiler collects
execution times for portions of the application. This can be helpful to track down portions of the
application which might be taking more time to execute than desired. Note: profiling is not
 supported in the current release.
Startup log - If this option is enabled, an
XApp.log file will be created in the XApp's
_ProjectNameCache folder, which logs the steps
the XApp goes through during startup. This can
 be useful for debugging.

Framework Options
The Framework Options area of the Compiler section of the AppsBuilder 2.0 options dialog
allows the user to specify paths for the Morfik Framework and other libraries.

The options in this area are the following:


Framework Path - This field allows the user to
specify an alternate path for the Morfik
Framework which will be used in compiling the
 current project.

Page 577
Search Paths - This field allows the user to specify a series of folders in which the AppsBuilder
 will look for modules which are referenced in the project but not a part of it.

Platform Compiler Options


The Platform Compiler Options area of the Compiler section of the AppsBuilder 2.0 options
dialog allows the setting of the parameters on how the application will be generated.

The options in this are the following:


Target Platform - This option allows the user to
choose which platform will be targeted at the
 platform compiler level.
Binary Kind - This option allows the user to choose which kind of binary should be created from
the current project, when compiled. The available options are: Stand-alone XApp, Morfik Plug-in
 XApp, IIS Plug-in XApp, Apache Plug-in XApp.

See also
 AppsBuilder 2.0 Options

Related Video
 Compiler and Application Options

Page 578
Customize

Figure 1 - Customize section of the Morfik AppsBuilder 2.0 Options dialog.

The customize options allows the user to specify which functions will be available
directly from teh Quick Access toolbar, above the Ribbon in the Morfik Workspace.

Quick Access Toolbar


Options
Keyboard Shortcuts
See also

Quick Access Toolbar Options


The Quick Access Toolbar options in the Customize section of the Options dialog allow the
user to precisely specify what are the functions you want to be added to the Quick Access
Toolbar that, by default, is shown above the Ribbon.

Page 579
Figure 2 - The Quick Access Options area of the Customize section of the Options dialog.

Figure 3 - The Quick Access toolbar of the Morfik Workspace with two new options added:
Project Options and New Form .

The options in this area are the following:


Show Quick Access Toolbar bellow Ribbon - This options, if set, moves the Quick Access
Toolbar to a position bellow the Ribbon, instead of above it, in the title are a of the main
 window of the Morfik Workspace.

Figure 4 - The Quick Access toolbar in a position bellow the Morfik Workspace Ribbon.
Keyboard shortcut - This option allows you to change the keyboard shortcut that is assigned
 to a specific function or command in the Morfik Workspace.

Page 580
Keyboard Shortcuts
As seen above you can completely customize the keyboard shortcuts assigned to each of the
commands in the Morfik Workspace. The dialog shown in Figure 5 allows you to define each
shortcut by just pressing the correct key combination.

Figure 5 - The dialog that allows you to customize the keyboard shortcut for a specific
command.

See also
 AppsBuilder 2.0 Options

Page 581
Debugger

Figure 1 - Debugger section of the Morfik AppsBuilder 2.0 Options dialog.

In the Debugger section of the AppsBuilder 2.0 Options dialog, allows the
configuration of parameters which define how the XApp's built-in browser and
server side debuggers will behave.

Debugger
Options
Evaluation
Options
See also

Debugger Options
The Debugger Options area of the Debugger section of the AppsBuilder 2.0 options dialog
allows the setting of several options to customize how the XApp's built-in browser and server
side debuggers behave.

Page 582
Figure 2 - The Debugger Options area of the Debugger section of the options dialog.

Individual options in the area are:


Integer Format - This option allows the user to
select in which format integer numbers will be
displayed by the debugger. The available
alternatives are: decimal, hexadecimal or both.
 The default configuration is to display both.
Intermediate Source Debugging - This option enables the debugger to single step through the
 intermediate source code (Javascript or Free Pascal) generated by the Morfik compiler.
Step CPU by Source Line - This option makes
the debugger reposition in the CPU window as
actual line of high-level code are executed
 instead of one instruction at a time.
Auto Switch - While debugging an application, if an exception occurs and the debugger cannot
locate the precise point in the high-level source code the CPU or Javascript view will be shown, if
 this option is selected.

Evaluation Options
The Evaluation Options area of the Debugger section of the AppsBuilder 2.0 options dialog
allows the setting of several options to customize how the IDE's built-in debugger will treat
the evaluation of expressions and variables.

Options in this section are grouped as described bellow:


Tooltip expression evaluation - This option enables automatic evaluation of variables and
expressions by just hovering the mouse pointer over them. Delay - This option allows the user
to specify the amount of time the IDE will take to display the evaluation tooltip. The purpose of
 this option is to keep this feature from becoming inconvenient by poping up too fast.

See also
 AppsBuilder 2.0 Options

Page 583
Editor Display

Figure 1 - Editor Display section of the Morfik AppsBuilder 2.0 Options dialog.

In the Editor Source section of the AppsBuilder 2.0 Options dialog, parameters
which define many of the behaviors of the IDE's source code editor can be set.
Also, several aspects of the editor's appearance which relate to code editing can
be customized.

Code Editor Font Options


Code Editor Gutter and Margin
Options
See also

Code Editor Font Options


The Editing Options area of the Editor Source section of the AppsBuilder 2.0 options dialog
allows the setting of several options to customize how the IDE's built-in source code editor
behaves and interacts with the user.

Page 584
Figure 2 - The Code Editor Font Options area of theh Editor Source section of the options
dialog.

Individual options in the area are:


 Editor Font - This option allows the user to select the font of choice for use in the code editor.
 Editor Color -
Size - This option allows the user to choose the font size of
 choice for the code editor.

Code Editor Gutter and Margin Options


The Code Editor Gutter and Margin Options area of the Editor Source section of the
AppsBuilder 2.0 options dialog allows the setting of several options to customize how the
IDE's built-in source code editor will display some visual editing aids.

Options in this section are grouped as described bellow:


Margin - The margin is a vertical line that is used as a guide as to what might
not get printed in the same line, if the source code were to be printed to paper.
This reference is, by default, based on old style, 80 characters per line, dot
 matrix printers. Visible - Turns on or off the margin in the code editor.
Width - This option allows the
user to choose the width of the
 margin line.
Color - This option allows the user to choose the color in which the margin line
 will drawn in the code editor.
Style - This option allows the user to choose the style in which the margin line will drawn in the
 code editor. There are several different styles available to choose from.
Position - This option allows the user to modify the position (in characters) in
which the margin line will be drawn. The default value for this property is 80
which corresponds to the maximum number of characters per line in an average,
 old style, dot matrix printer.
Gutter - The gutter is a differently colored area to the left of the code editing area of the editor
which is normally used for displaying visual coding aids such as line numbers, breakpoints, etc.
 Visible - Turns on or off the gutter in the editor.

Width - This
option allows the
 user to specify the

Page 585
width of the
gutter area.
Color - This option allows the user to choose a color for
 background of the gutter area.
Style - This option allows the user to specify a fill
 pattern for the gutter area.

See also
 AppsBuilder 2.0 Options

Page 586
Editor Source

Figure 1 - Editor Source section of the Morfik AppsBuilder 2.0 Options dialog.

In the Editor Source section of the AppsBuilder 2.0 Options dialog, parameters
which define many of the behaviors of the IDE's source code editor can be set.
Also, several aspects of the editor's appearence which relate to code editing can
be customized.

Editing Options
Code Editor
Options
See also

Editing Options
The Editing Options area of the Editor Source section of the AppsBuilder 2.0 options dialog
allows the setting of several options to customize how the IDE's built-in source code editor
behaves and interacts with the user.

Page 587
Figure 2 - The Editing Options area of the Editor Source section of the options dialog.

Individual options in the area are:


Auto indent mode - This option, turned on by
default, makes the code editor automatically
indent the source code as the developer types in
 the code.
Smart Tab - This option instrucuts the code editor to replace spaces with tabs, reducing the
 number of characters used to space out code in lines.
Backspace unindents - This option, which is on
by default, defines whether the backspace key
will simply delete the character before the caret
of move the caret all the way back to the
 previous indentation level.
Group undo - This option specifies whether the undo command should reverse a series of
 related edits in one go, or reverse each edit separately.
Cursor beyond EOF - This option defines if the
caret will be allowed to move beyond the last
 character entered in the file.
Cursor beyond EOL - This option defines if the caret will be allowed to move beyond the last
character entered in the current line. Turning this option on makes it easier to enter comments
 to the side of the code, without having to add spaces to separate them from the code itself.
Live Spell - This option turns on or off spell
checking as you type within MorfikDoc style
comments. Words identified as being misspelled
are underlined in blue ot differentiate from errors
 in the source code which are underlined in red.
Persistent Blocks - This option allows text blocks to remain selected as the user moves the
 caret in the code editor.
Overwrite blocks - This option specifies whether
to delete the selected block of text when the
 user starts typing.
Double click line - This option specifies whether double-clicking in the editor should select an
 identifier or a whole line.
Find text at cursor - This option forces the editor
to fill the search input box with the text at the
current cursor position, when the user chooses
 the Find option.
Force cut and copy enabled - This option makes the Cut and Copy commands always enabled,
 even if there is no text selected. Note: this option is non-functional in the current build.
Overwrite cursor as block - Specified that when
in overwrite mode the cursor is displayed as a
 small block instead of a caret.
Disable dragging - This option specifies whether selected text can be moved to another
 position in the editor by dragging and dropping it.
Auto correct - This option specifies whether to
apply spelling corrections automatically as you
type within MorfikDoc style comments. Note: this
 option is non-functional in the current build.

Page 588
Keymapping - This option allows the user to change the basic set of key stroke commands in
the editor to emulate other popular code editors. The available options are: Default (the normal
 Morfik keys), Classic (WordStar like key combinatinations), Brief, Epsilon and Visual Studio.
Tab stops - This option sets the number of
character positions which are "occupied" by a Tab
 character.
 Block indent - This option specifies the number of characters used in automatic indentation.

Code Editor Options


The Code Editor Options area of the Editor Source section of the AppsBuilder 2.0 options
dialog allows the setting of several options to customize how some visual display and coding
aids in the IDE's built-in source code editor behave.

Individual options in the area are:


Show line numbers - Turns on or
off the display of line numbers in
 the code editor.
Show line numbers in gutter - This option moves the display of line numbers into the gutter
 area of the code editor.
Use syntax highlight - This option allows the user to turn off
 syntax highlighting of the source code.
Highlight braces - This option allows the user to turn off the highlighting of the matching pair of
 braces as code is entered into the code editor.

See also
 AppsBuilder 2.0 Options

Page 589
Exceptions

Figure 1 - Exceptions section of the Morfik AppsBuilder 2.0 Options dialog.

In the Exceptions section of the AppsBuilder 2.0 Options dialog, the user can set
which exceptions the debugger will react to (trap).

Exception
Options
See also

Exception Options
The Exception options allows the user to select which Exceptions will be trapped by the Morfik
debuggers and which will be ignored. There are two kinds of exceptions that can be triggered
during program execution: Operating System exceptions and Language exceptions. As shown
in figure 2, a full list of Operating System exceptions is provided in the left-hand side list box of
the Exception section of the Options dialog. The list of language level exceptions includes only
basic database related exceptions. Any exception not in this list that the user wants to be
trapped by the debugger can be added to the right-hand side list.

Page 590
Figure 2 - The Exception Options area of the Exceptions section of the options dialog.

Management of the Language exceptions can be accomplished through the two buttons which
are positioned at the bottom of this section, right bellow the Language exceptions list box.

See also
 AppsBuilder 2.0 Options

Page 591
General

Figure 1 - General section of the Morfik AppsBuilder 2.0 Options dialog.

In this section of the AppsBuilder the user can configure basic startup behavior
parameters for the IDE as well as some Form designer parameters.

This topic describes each of the separate areas in this section in detail providing
all the information required to effectively configure the AppsBuilder IDE as to gain
maximum individual productivity.

Environment
Options
Form/Report
Options
See also
Related Video

Environment Options
The environment area of the General section of the AppsBuilder 2.0 options dialog allows the
setting of several options to customize how the IDE interacts with the users.

Page 592
Figure 2 - The Environment Options area of the General Section.

Individual options in this area are:


Reload last open project on startup - if this
option is ticked the IDE will always lauch with the
 project you last worked in, loaded.
Background compilation - by default Morfik AppsBuilder 2.0 does all of its compilation in
background threads. This means that the system is never blocked by compilations. If you prefer
to just have the IDE provide feedback of the compilation process but not allow you to interact
with project options during a compile run, tick this option. A blocking windows will appear if this
option is selected and display the compilation process status, similar to how previous versions of
 Morfik AppsBuilder worked.
Show hidden items - this option which is off by
default keeps the IDE from displaying any item
 which has been marked as hidden.
Show system items - this option which is off by default keeps the IDE from displaying any item
 which has been marked as belonging to the "system".
Show system fields - this option which is off by
default prevents the IDE from displaying any table
fields which automatically added by the system to
a project's tables. These fields are required for
the proper working of several "automatic"
features of the Morfik Framework. Do not remove
these fields from the tables or alter their definition
 unless you are very sure of what you are doing.
Can edit system tables - off by default, this option will allow the user to edit, in the IDE,
 information about Table documents which have been marked as belonging to the system.
Color scheme - Changes the entire color scheme
used by the main window and all designers of the
AppsBuilder 2.0 IDE. There are several different
 options available from which to choose.

Form/Report Options
The Form/Report Designer area of the General section of the AppsBuilder 2.0 options dialog
allows the setting of several options to customize how these two designers, in IDE, interact
with the users.

Page 593
Figure 3 - The Form/Report Designer options area of the General section.

Individual options in the area are:


Show Visible Grid - This option, on by default, turns on a dotted
 grid on in both the Form and Report designers.
Snap to Visible Grid - This option, unticked by default, forces controls which are moved around in
the designer to align to the nearest position in the grid. X - Defines horizontal spacing for the
 visible grid.
Y - Defines vertical spacing for the
 visible grid.
Keep Away - This option sets the distance the designer will atempt to leave between controls as
 it snaps a control to the Smart Grid.
Threshold - This option sets the proximity or alignment
"threshold" distance which once crossed will make the designers
 attempt to snap the control to the Smart Grid.

See also
 AppsBuilder 2.0 Options

Related Video
 General Options Review

Page 594
Server

Figure 1 - Server section of the Morfik AppsBuilder 2.0 Options dialog.

In the Server section of the AppsBuilder 2.0 Options dialog, allows the
configuration of parameters which define how the XApp's built-in web server will
behave at runtime. This section also displays the parameters for the XApp's
database and the database server.

Web Server Options


Database Server
Options
See also

Web Server Options


The Web Server Options area of the Server section of the AppsBuilder 2.0 options dialog
allows the setting of several options to customize how the XApp's built-in web server behaves
at runtime.

Page 595
Figure 2 - The Web Server Options area of the Editor Source section of the options dialog.

Individual options in the area are:


HTTP Protocol HTTP Port - This option allows
the user to specify which port the XApp's built-in
 web server will be responding on, at runtime.
HTTPS Port - This option allows the user to specify which port the XApp's built-in web server
 will be responding on, for encrypted communication, at runtime.
Certificate file - This fields is intended for the
user to specify the full path to a certificate file to
 be used by the application.
Private key file - This fields is intended for the user to specify the full path to a private key file
 to be used by the application.

Database Server Options


The Database Server Options area of the Server section of the AppsBuilder 2.0 options dialog
displays several parameters for the current project's database and of the database server, as
well allowing the user to specify that a login must be provided with every use, or stored with
the project.

Options in this section are grouped as described bellow:


Sweep Interval - This value specifies the time
interval in which the Firebird automatic garbage
 collection will be started.
Forced writes - This option specifies that the server will not cache writes to ensure no data
 loss can occur.
Database Login Details User Name - In this
field the database user name which the
application will use to login to the database
 server should be informed.
Password - In this field the database password which the application will use to login to the
 database server should be informed.
Always prompt for login at start up - This
option, if checked, will require that a user name

Page 596
and password combination be provided every
 time the application is started.

See also
 AppsBuilder 2.0 Options

Page 597
Syntax Color

Figure 1 - Syntax Color section of the Morfik AppsBuilder 2.0 Options dialog.

In the Syntax Color section of the AppsBuilder 2.0 Options dialog, the user can set
parameters which define how the the color syntax highlighting will be rendered on
screen.

Syntax Highlighting Color


Options
See also

Syntax Highlighting Color Options


The Syntax Highlighting Color options allows each element of the supported programming
languages to be properly identified by a different color scheme.

Page 598
Figure 2 - The Syntax Highlighting Color Options area of the Syntax Color section of the options
dialog.

The Morfik WebOS AppsBuilder IDE has two different configurations for color syntax highlighting,
one for the browser side code and the other for the server side code. By default these tow
configurations are identical except for the font color of reserved words which is maroon on the
browser side and navy blue on the server side. The difference in color for the reserved words is
intended as a simple, and almost subliminal, way of letting the user know in which portion of
the application he is working on.

See also
 AppsBuilder 2.0 Options

Page 599
Trace

Figure 1 - Trace section of the Morfik AppsBuilder 2.0 Options dialog.

The Trace options allows the user to specify the level of trace desired during
debugging sessions. Morfik WebOS AppsBuilder can trace general HTTP Requests,
XML Web Service calls and a series of different database operations. By default
database operations are not enabled for tracing.

Trace
Options
See also

Trace Options
The Trace options in the Trace section of the Options dialog allow the user to precisely specify
what are the items that should be traced.

Page 600
Figure 2 - The Trace Options area of the Trace section of the Options dialog.

The options in this area are the following:


Monitor HTTP Request/Response - This options allows the user to specify if the HTTP requests
and responses of the XApp should be traced while debugging. HTTP Headers only - This
option allows the user to choose to trace only the the HTTP headers instead of the the entire
 requests and responses.

See also
 AppsBuilder 2.0 Options

Page 601
Controls

Morfik AppsBuilder offers a comprehensive set of controls for the creation of


sophisticated web-based applications. The following is a list of the controls found
in Morfik.
Morfik Controls -
 Button
 Morfik Controls - Calendar

 Morfik Controls - CheckBox


 Morfik Controls - ComboBox

 Morfik Controls - Container


 Morfik Controls - DateTimeEdit

 Morfik Controls - FileUploader


Morfik
Contro
ls -
 Flash

 Morfik Controls - GoogleMap


Morfik
Controls -
 Image
Morfik Controls -
 ListBox
 Morfik Controls - OptionButton

 Morfik Controls - PopupWindow


 Morfik Controls - ProgressBar

 Morfik Controls - Rectangle


 Morfik Controls - RSSButton

 Morfik Controls - SubForm


 Morfik Controls - TabControl
Morfik Controls - TextEdit

 Morfik Controls - TextLabel
Morfik
Controls -
 Timer
 Morfik Controls - Wysiwyg

See Also
 Working with Controls
 Control Effects

Page 602
Morfik Controls - Button

Figure 1 – Different Button controls.

In Morfik AppsBuilder the Button control is used in places where the user is clearly
supposed to make a choice between actions or as an indicator that by clicking on
that control an action (other than simple navigation) will be triggered.

Usage
Frequently used
Properties
BorderStyle
BorderColor
BorderWidth
Color
Other Properties
Alignment
Caption
Cursor
Default
Down
Enabled
Font
GroupIndex
Height
Hint
HorizontalPlacement
Icon
Left
Name
Opacity
Padding
TabOrder
Top
VerticalPlacement
Visible

Page 603
Width
Frequently used Events
OnClick
Other Events
OnAfterPrint
OnAfterPushedOrPulled

OnBeforePrint

OnBeforePushedOrPulled
OnBlur
OnDoubleClick
OnFocus
OnKeyDown
OnKeyUp
OnMouseDown
OnMouseOut
OnMouseOver
OnMouseUp
OnPrintStyle
Sample Code
See Also
Related Video

Usage
The Button control is used in just about every Morfik application. A good example of using
buttons in an application can be found in the user sign in Form of the MorfikCMS application.
This Form can be seen in figure 2.

Page 604
Figure 2 – UserSignIn Form of the MorfikCMS sample application, showing two Button
controls.

For a more detailed description of how this application was built, please refer to Working with
Database Connections which explains in greater detail how this specific Form was designed.

Due to its formatting flexibility Morfik Button controls can also be used in simple navigation, in
place of simpler links. A example of this usage of Buttons can be found in the navigation of the
Administrative area of the MorfikCMS sample application.

Figure 3 – AdminSideBar Form of the MorfikCMS sample application, showing several Button
controls being used as navigation links.

The Button controls you see in Figure 3 have been configured to use the Corners and
Gradient effects. For more information on all the effects that can be applied to Morfik
controls, please refer to Control Effects .

Frequently used Properties


The following is a list of the most commonly used properties of the Button control with a short
description of their function.

Page 605
BorderStyle
The BorderStyle property of the Button control defines how and if a border will be drawn
around the control. The available style options are: 3D, Flat and None. The 3D style gives the
Button a light 3D effect. The Flat option gives the Button a solid, thin, line as a border.

BorderColor
The BorderColor property can be used to set the color in which an outline will be drawn
around the Button. As Buttons, by default, have the BorderStyle property set to a Flat border,
this property is a very important part of defining "the look" of the control.

BorderWidth
The BorderWidth property specifies the line width used to draw the Button's outline.

Color
The Color property is used to set the color in which the control will be drawn on the
Form/Page. This property is only effective if the Form which is being shown within the
SubForm control has is transparent.

Other Properties
The following is a list of the less commonly used properties of the Button control with a short
description of their function.

Alignment

Caption
The Caption property specifies the text to be displayed in the Button.

Cursor
The Cursor property, if set, causes the appearance of the cursor to change as it moves over
the Button.

Default
If the Default property is set to true, the user may "click" the button by pressing the Enter
key, even if another non-Button control has input focus. Note: currently this property is only
functional in Internet Explorer.

Down

Enabled
If the Enabled property is set to false, the Button will not accept keyboard focus, and no
OnClick event will be generated when the Button is clicked.

Font
The Font property, and its sub-properties Color and Name, specify the font to be used for
displaying the Button's Caption.

GroupIndex

Height
The Height property specifies the vertical extent of the Button.

Hint

Page 606
The Hint property, if set, specifies the text of a tooltip that is displayed when the user moves
the cursor over the Button.

HorizontalPlacement
The HorizontalPlacement property, if set, governs how the Button adjusts its size and position
in response to changes in the horizontal dimensions of its parent.

Icon

Left
The Left property specifies the horizontal position of the Button.

Name
The Name property specifies the identifier used to reference the Button from browser- or
server-side code.

Opacity
The Opacity property determines the extent to which the Button obscures any controls placed
in its background. A value of 0 means that background controls are fully visible, whereas a
value of 100 means that background controls are completely obscured.

Padding

TabOrder
The TabOrder property allows the developer to specify the order in which controls should
receive input focus when the user steps through them using the tab key.

Top
The Top property specifies the vertical position of the Button.

VerticalPlacement
The VerticalPlacement property, if set, governs how the Button adjusts its size and position in
response to changes in the vertical dimensions of its parent.

Visible
The Visible property is used to make Button controls visible or invisible to the end user.

Width
The Width property specifies the horizontal extent of the Button.

Frequently used Events

OnClick
The most commonly used event for a Button control is the OnClick event, which should be
handled to execute whatever action is intended when the button is clicked.

The following is a sample event handler which calls a separate procedure to take some action
when a specific Button is clicked.

P rocedure
UserSignIn . SignInBtnClick ( Event : T DOMEvent );
Begin
DoAuthenticate ;
End ;

Page 607
Other Events

OnAfterPrint
The OnAfterPrint event occurs after the Button is rendered into the form's HTML code.

OnAfterPushedOrPulled
The OnAfterPushedOrPulled event occurs after the Button's position has changed in response
to a grow-and-shrink event.

OnBeforePrint
The OnBeforePrint event occurs before the Button is rendered into the form's HTML code.

OnBeforePushedOrPulled
The OnBeforePushedOrPulled event occurs before the Button's position changes in response
to a grow-and-shrink event.

OnBlur
The OnBlur event occurs when the Button loses keyboard focus.

OnDoubleClick
The OnDoubleClick event occurs when the user double-clicks on the Button.

OnFocus
The OnFocus event occurs when the Button receives keyboard focus.

OnKeyDown
The OnKeyDown event occurs when the user depresses a key while the Button has focus.

OnKeyUp
The OnKeyUp event occurs when the user releases a key while the Button has focus.

OnMouseDown
The OnMouseDown event occurs when the user depresses the left mouse button while the
cursor is over the Button.

OnMouseOut
The OnMouseOut event occurs when the mouse cursor moves out of the Button.

OnMouseOver
The OnMouseOver event occurs when the mouse cursor moves into the Button.

OnMouseUp
The OnMouseUp event occurs when the user releases the left mouse button while the cursor
is over the Button.

OnPrintStyle
The OnPrintStyle event occurs before the Button's style attribute is rendered into the form's
HTML code.

Page 608
Sample Code
Buttons are not frequently referenced in code. Most of the time when it is referenced,
however, is to change its "Enabled" status, in response to an application defined condition.

The following code snippet sets a Button's Enabled property to True. A Button which is
disabled cannot be clicked on by the user.

Button1 . Enabled := tru


e;

See Also
 Morfik Controls
 Most Frequently Used Controls

 Control Effects

Related Video
 Group Index property for buttons

Page 609
Working with
Database Connections

This topic will provide you will a general overview of how to work with database
connections in code. Most of the work that goes into creating a Morfik database
driven application is actually done through visual programming and very little
configuration/parameterization code. There are, however, situations in which you
are still required to write some database access and manipulation code, even
when working with a tool such as Morfik AppsBuilder which was designed
specifically for creating database applications.

As we will see in this topic, even in these situations the actual amount of code
that must be manually written is small and relatively easy to understand.

User Authentication
Databases are Server Side
Database Access with
WebMethods
Web Method Parameters
Reading data with RecordSets
Working with SQLCommands
Receiving Data in the Browser
Invoking the Authentication Code

The UserSignIn Form


Wrapping it up
See Also

User Authentication
A good example of when you have to directly access a database programmatically is when you have
to perform user authentication against a data stored in a database. Of course, other authentication
methods can be used, but it is fairly common for database driven web applications to use their own
databases to store user access information. This is precisely the case of our sample project
MorfikCMS.

As a home made implementation of a Content Management System (CMS) it makes sense for the
MorfikCMS project to use its database to store information about its users. Initially only basic
identification information is stored for each user and its sole purpose is to differentiate between
general users and users who have to right alter the site ’ s content. For the sake of simplicity we will
treat all identified users as being authorized to perform any changes to the site ’ s data, though a
role based authorization scheme would not be to hard to implement. It would, however, add very
little information on how to access the database that is not already covered by our simpler example.

For our purposes then we will be validating the user ’ s login credentials against the data saved in
the UserCatalog table of our database.

Table 1 shows the structure of the UserCatalog table.

Table 1 – Definition for table UserCatalog


Field Type Size
Id AutoNumber (Integer) -
FullName Text 64
Email Text 64
Password Text 20

Page 610
It was exactly due to the frequency in which this kind of solution is used that User Authentication was
chosen to exemplify how to write code to directly access a database.

Databases are Server Side


All database access code is executed on the server side of a Morfik AppsBuilder application. The
reason is simple: the databases cannot be accessed directly from the browser due to security
constraints. This means that even if you are creating a desktop application with Morfik and running
both the server and browser on the same computer, you will still have to write all database access
code on the server side of the application.

When you need information from a database in application logic of your browser side code the way to
get it is through a WebMethod call, which essentially means that most of the code you will ever write
to access a database will be within the server side class of a WebMethod.

Database Access with WebMethods


Creating a WebMethod with Morfik AppsBuilder is a very simple endeavor. For general examples, be
sure to look up chapter 8 of the Morfik Developer ’ s Handbook which covers this in some detail.

Since Morfik AppsBuilder was designed to work with databases, Web Methods have been engineered
to make it easy to access them. From within the server side class of a Web Method you have direct
access to your XApp ’ s default database connection and can invoke any database commands without
even having to worry about establishing a connection to the database, since that is already taken
care of.

Note
The Server side class of a Web Method has a member variable called DefaultDBConnection
which is the application ’ s default database connection and which can be freely used
without the need to worry about creating and/or closing a new connection.

In order to be useful, a Web Method which does some database access, must be able to return the
retrieved information to its invoker. This is particularly useful in our situation where we want to send
two bits of information which we expect will identify the user and get back whether or not those are
a match to a previously registered user. This exchange of information between the browser and
server components of your XApp is done entirely through the WebMethod ’ s parameters.

Web Method Parameters


A Web Method can have both in and out parameters. This means that not only it can receive
information but give some of its own in return. In our sample case we are working with a WebMethod
which has five parameters: 2 "in" parameters ( AUserName and APassword ) and 3 "out" parameters
( CheckedOk , FullName and UserId ). In Figure 1 you can see those parameters in the Web Method
Designer of Morfik AppsBuilder.

Figure 1 – Parameter definition for the AuthenticateUser WebMethod.

In this particular example the AuthenticateUser Web Method takes what is essentially the username
and password as input and replies with the information if these could be verified and if so the user ’ s
full name and id in the system ’ s database.

Page 611
In Listing 1 you can see the complete source code for the server side portion of the AuthenticateUser
Web Method. Notice that all authentication logic is contained within the Execute method of the class.

Unit AuthenticateUser ;

Interface

T ype
AuthenticateUser = Class ( WebMethod )
AUserName : String ;
AP assword : String ;
CheckedOk : Boolean ;
FullName : String ;
UserId : Integer ;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
P rocedure Execute ; override ;
P rocedure LogAccess ;
End ; [ 'P ublished=False' ];

Implementation

P rocedure AuthenticateUser . LogAccess ;


Var
SQLCommand : T SQLCommand ;
Begin
SQLCommand := DefaultDBConnection . CreateSQLCommand (
'INSERT INT O "AccessLog" ("email","AccessT ime") ' +
'VALUES (:EMAILP ARAM,:ACCESST IMEP ARAM)' );
T ry
SQLCommand . P repare ;
SQLCommand . P aramByName ( 'ACCESST IMEP ARAM' ). AsDateT ime := Now ;
SQLCommand . P aramByName ( 'EMAILP ARAM' ). AsString := AUserName ;
SQLCommand . Execute ;
finally
SQLCommand . Free ;
end ;
end ;

P rocedure AuthenticateUser . Execute ;


var
UserCatRS : T RecordSet ;
Begin
UserCatRS := DefaultDBConnection . CreateRecordSet (
'SELECT "Id", "FullName", "email", "Password" FROM "UserCatalog" ' +
'WHERE LOWCASE("UserCatalog"."email")=LOWCASE(:EMAILP ARAM)' );
try
UserCatRS . P aramByName ( 'EMAILP ARAM' ). AsString := AUserName ;
UserCatRS . P repare ;
UserCatRS . Active := T rue ;
UserCatRS . First ;
CheckedOk := False ;
If Not UserCatRS . Eof then
begin
if ( UpperCase ( APassword ) = UpperCase ( UserCatRS . FieldByName ( 'P assword' ). AsString )) then
begin
CheckedOk := true ;

Page 612
FullName := UserCatRS . FieldByName ( 'FullName' ). AsString ;
UserId := UserCatRS . FieldByName ( 'Id' ). AsInteger ;
LogAccess ;
end ;
end ;
finally
UserCatRS . Free ;
end ;
End ;

End .

All the parameters of a Web Method are represented as member variables of both the server and
browser side classes. This makes reading and setting these parameters extremely easy. In our case
we want to use the two "in" parameters of the Web Method as parameters to a SQL Select command
that we will run against the UserCat table of the project ’ s own database and retrieve some other
information in the three "out" parameters.

Reading data with RecordSets


In order to recover data from the database through code we need to have a RecordSet object. This
object is instantiated from the TRecordSet class and should be used to execute "Select" commands
against the Firebird database as these commands actually return a set of records which match the
specified criteria.

The following code snippet shows how a TRecordSet (called UserCatRS ) object can be instantiated
from the SQL command string.

UserCatRS := DefaultDBConnection . CreateRecordSet (

'SELECT "Id", "FullName", "email", "Password" ' +


'FROM "UserCatalog" ' +

'WHERE LOWCASE("UserCatalog"."email")=' +
'LOWCASE(:EMAILP ARAM)' );

In the following line the necessary parameter is passed to the SQL Statement before its execution in
the database.

UserCatRS . P aramByName ( 'EMAILP ARAM'


). AsString := AUserName ;

Setting the actual parameters of a RecordSet object can be done through a call to the ParamByName
method of the class.

In the following snippet the statement is prepared for execution and executed by setting the Active
property to true. Once the statement is executed a call to First positions the resulting RecordSet to
the first of its records. At this point if the RecordSet does not indicate that it is at the "End of File"
position ( EOF ) the stored and supplied values for the user ’ s password are compared.

UserCatRS . Prepare ;
UserCatRS . Active := T rue ;
UserCatRS . First ;
CheckedOk := False ;
If Not UserCatRS . Eof then
Begin
If ( UpperCase ( APassword ) =

Page 613
UpperCase ( UserCatRS . FieldByName ( 'P assword' ). AsString ))
then

The comparison of the password is done in case insensitive manner through the use of the UpperCase
function on both sides. If the password comparison yields a true result, the return, i.e. "out"
parameters are set with the values recovered from the table. The actual reading of the fields of the
returned records can be done through a call to the RecordSet ’ s FieldByName method.

Begin
CheckedOk := true ;
FullName := UserCatRS . FieldByName ( 'FullName'
). AsString ;
UserId := UserCatRS . FieldByName ( 'Id' ). AsInteger ;
LogAccess ;
End ;
End ;
Finally
UserCatRS . Free ;
End ;

When the data that we required has been read we can dispose of the RecordSet object through a
call to its Free method as seen above.

Working with SQLCommands


In order to recover data from the database through code we used a TRecordSet object but the
TRecordSet class is designed exactly for that: to recover data. There are situations when you need to
execute data manipulations which don ’ t really return any data, such as inserting data into a table.
In these situations we will be using the TSQLCommand class. An example of its use can be seen in
the LogAccess method of the server side implementation of the AuthenticateUser WebMethod.

The TSQLCommand is designed specifically to execute commands which do not return sets of records.
In the following code snippets you can see how a TSQLCommand object is instantiated from a SQL
command string, prepared and executed after having its parameters set.

SQLCommand := DefaultDBConnection . CreateSQLCommand (


'INSERT INT O "AccessLog" ("email","AccessT ime") ' +
'VALUES (:EMAILP ARAM,:ACCESST IMEP ARAM)' );
T ry
SQLCommand . P repare ;
SQLCommand . P aramByName ( 'ACCESST IMEP ARAM'
). AsServerDateT ime :=
Now ;
SQLCommand . P aramByName ( 'EMAILP ARAM'
). AsString := AUserName ;
SQLCommand . Execute ;
Finally
SQLCommand . Free ;
End ;

Parameters of the SQLCommand object are set in exactly the same manner as was done with the
UserCatRS (RecordSet) object in the the Execute method of the AuthenticateUser WebMethod.

The LogAccess procedure simply inserts a record into the AccessLog table, each time a successful Sign
in is executed in the application.

Receiving Data in the Browser

Page 614
We have just seen how to recover some data in the server side portion of a Web Method and how to
execute action SQL commands which do not return data. In the first of these situations, there will be
cases in which the recovered information has to go back to the browser side of your XApp. AS
previously mentioned this transfer is achieved by setting the Web Method ’ s "out" parameters.

The "out" parameters can be read in the browser side portion of a Web Method once the remote
procedure call returns from the server. When the call does return the Web Method browser side
class ’ HandleResponse method is invoked.

In Listing 2 you can see the complete source code for the browser side portion of the
AuthenticateUser Web Method.

Listing 1 – Server side portion of the AuthenticateUser Web Method.

Unit AuthenticateUser ;

Interface

T ype
AuthenticateUser = Class ( WebMethod )
AUserName : String ;
AP assword : String ;
CheckedOk : Boolean ;
FullName : String ;
UserId : Integer ;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
P rocedure HandleResponse ; override ;
P rocedure AuthenticationOk ;
P rocedure AuthenticationNotOk ;
End ;

Implementation

Uses Header , Footer , UserSignIn , SystemControls ;

const InvalidLogInMessage =
'Username and password do not match. You provided ' ;

P rocedure AuthenticateUser . AuthenticationOk ;


Begin
UserIsAuthenticated := true ;
CurrentUser := UserId ;
Header ( XApp . Forms [ 'Header' ]). UserNameLabel . Caption :=
'Welcome ' + FullName ;
Header ( XApp . Forms [ 'Header' ]). SignInOutOption . Caption :=
'Sign Out' ;
Header ( XApp . Forms [ 'Header' ]). Separator1 . Visible := true ;
Footer ( XApp . Forms [ 'Footer'
]). SiteManagementOption . Visible := true ;
Header ( XApp . Forms [ 'Header' ]). UserNameLabel . Visible := true ;
UserSignIn ( XApp . Forms [ 'UserSignIn' ]). Close ;
End ;

P rocedure AuthenticateUser . AuthenticationNotOk ;


Begin
UserSignIn ( XApp . Forms [ 'UserSignIn' ]). ErrorMessage . Caption :=
InvalidLogInMessage +
UserSignIn ( XApp . Forms [ 'UserSignIn' ]). UserNameEdit . T ext ;

Page 615
End ;

P rocedure AuthenticateUser . HandleResponse ;


Begin
If CheckedOK T hen
AuthenticationOk ()
Else
AuthenticationNotOk ()
End ;

End .

In this particular case the HandleResponse method just tests to see if the CheckedOk "out" parameter
has returned as true or false. If the check was Ok, then the AuthenticationOk method is called,
otherwise, the AuthenticationNotOk method is called.

The AuthenticationOk method sets a global variable called UserIsAuthenticated to true and hides or
display a few objects. It is the global variable UserIsAuthenticated which is used, through out the
application to allow or disallow operations depending on a registered user having been
authenticated.

One of the visual elements that the AuthenticationOk method makes visible and whose content it sets
is a TextLabel which will hold the user ’ s full name, also returned from the Server as seen in the
following snippet.

Header ( XApp . Forms [ 'Header' ]). UserNameLabel . Caption := 'Welcome '


+ FullName ;
Header ( XApp . Forms [ 'Header' ]). UserNameLabel . Visible := true ;

Invoking the Authentication Code


As we have seen the user authentication is accomplished through the use of a Web Method. That is
the mechanism that we use to send the information to the server and get back a response, but how
to we get the information from the user and how do we start the authentication process which will
lead to the database lookup we have put together.

The UserSignIn Form


The UserSignIn Form is invoked from the Header Form when the user/visitor clicks on the "Sign In"
link. This Form is displayed as a popup instead of being displayed inline as it should be the single
point in which the user focuses during this process. As such the UserSignIn Form is also modal,
restricting all interaction with the application/site to itself.

The following code snippet contains the complete event handler for the OnClick event of the
SignInOutOption TextLabel.

Procedure Header.SignInOutOptionClick(Event: TDOMEvent); Begin

If Not UserIsAuthenticated T hen


OpenForm('UserSignIn', 'P OP UP ', '"title=Sign In", "modal=true"')

Else
Begin
UserIsAuthenticated := false;
SignInOutOption.Caption := 'Sign In';
UserNameLabel.Visible := false;
Separator1.Visible := false;
Footer(XApp.Forms['Footer']).SiteManagementOption.Visible :=
false;
End;

Page 616
End;

Notice that after determining that a user is not currently signed in the event handler invokes
OpenForm causing the UserSignInOut to popup.

Figure 2 shows the UserSignIn Form in Design mode in Morfik AppsBuilder Workspace. This is a simple
Form which is not bound to any data source. All data exchange with the server is done through the
AuthenticateUser Web Method which we have previously reviewed.

Figure 2 – The UserSignIn Form in design mode in the Morfik Workspace.

Once the UserSignIn Form is displayed and the user inputs his data the SignInBtn Button control
invokes the RunWebMethod command in its OnClick event handler.

The following snippet contains the event handler for the OnClick event of the SignInBtn button control
and the DoAuthenticate procedure it invokes.

P rocedure UserSignIn . DoAuthenticate ;


Begin
RunWebMethod ( 'AuthenticateUser' , '"AUserName='
+ UserNameEdit . T ext +
'", "AP assword=' + P asswordEdit . T ext + '"' );
End ;

P rocedure UserSignIn . SignInBtnClick ( Event : T DOMEvent );


Begin
DoAuthenticate ;
End ;

The DoAuthenticate procedure as seen in the previous code snippet invokes the RunWebMethod
command to execute the AuthenticateUser Web Method passing as its parameters the data entered
in the two TextEdit controls of this Form.

Page 617
Figure 3 – The UserSignIn Form at runtime, displayed as a popup.

After invoking the AuthenticateUser Web Method execution the event handler for the SignInBtn button
closes the popup Form as the execution will resume in the browser side part of the Web Method once
the server replies to the call.

The CancelBtn button in the UserSignIn Form only closes the Form if clicked as no further action is
required.

Wrapping it up
Interfacing with the database from code in a Morfik application is not a complex task and is normally
done in the server side portion of a Web Method where the code to execute pure action queries and
data selection queries is quite similar.

See Also
 Morfik Database Programming
 Database Modeling

 Visual Database Programming


 Editing and Searching

 SQL Statements
 Using Stored Procedures

 System Objects in a Database


category:Database

Page 618
Morfik Database
Programming

The AppsBuilder offers native, built-in, support for database programming.


Actually, Morfik AppsBuilder was conceived, right from the start to work with a
database and to create applications which are database driven. This guide will
provide a quick view to all aspects of database programming with Morfik
AppsBuilder, from creating tables to accessing external, third-party, databases.

The creation of the web interface for presenting database information will also be
extensively covered since this is tightly coupled to database access in the Morfik
workspace and Framework.

The information in the topics that compose the Database Guide is focused on
Morfik Web Application projects, as these have a server-side component to them,
enabling the usage of real databases. Only a subset of this information applies to
Morfik Browser Application projects, which use XML Data Sources.

Database Theory
The Built-in Database
Database Driven Applications/Sites

Visual Development
Stored Queries
Content Management
Multi-Database Projects
Mixing Databases
Basic Common View and
Concepts
Wrapping it up
See Also

Database Theory
This guide presumes that you are at least familiar with the general concepts of relational databases
such as tables, indices and queries. Detail will be provided on how to create and use these
constructs in the Morfik workspace and in Morfik applications, but not to the concepts behind them
since it would be beyond the scope of this text.

Concepts with which the reader should be familiar include tables and data types, indices, primary and
foreign keys, relationships and constraints. A basic knowledge of SQL will make some of the text
easier to understand but may not be a requirement since this guide does go over the major SQL
constructs which are normally used from within a Morifk XApp (Morfik built, web based application).

Note
Almost all SQL commands in this guide, except when otherwise specified, are written in
Firebird ’ s specific SQL dialect. Exceptions might exist when covering work with external
databases and will be clearly indicated.

The Built-in Database


Morfik has a built-in database management system which is used in all new AppsBuilder Web
projects. This makes it very easy to start new projects from scratch in Morfik, since there is no need

Page 619
to request database access from a DBA or any such formalities. Of course, you still have to go
through the appropriate steps in order to deploy a production application, but there is no delay in
getting started.

The built-in database is a full featured relational database server called Firebird. Morfik makes use of
many advanced features of Firebird transparently allowing the developer to benefit from them
without having to learn how to use them directly. This allows developers to quickly go from being a
novice to creating sophisticated data driven applications.

Every AppsBuilder Web Project has an associated database, as part of the project ’ s structure. When
you go to the tables view of the AppsBuilder Designer tab, you can create new tables in this, default
database. Morfik AppsBuilder Workspace allows the developer to created tables without having to
resort to an external tool.

For those who are familiar with the Firebird database server and its usage, Appendix A provides
additional details on how certain things are implemented by Morfik at the database level.

Database Driven Applications/Sites


Morfik WebOS AppsBuilder was designed, from the ground up, for the creation of database driven
applications and websites. Since data access is not an addition, but an integral part of the design of
the product, the very manner in which you design an application or site is heavily influenced by what
data is going to be shown. It is possible to create totally dynamic applications, where all content
comes directly from database tables and no static content is used. Again, due to how AppsBuilder
and the Morfik Framework are built this is, actually, the preferred way of creating applications/sites.

It is quite simple, with Morfik, to create sophisticated data-driven applications. This makes Morfik the
tool of choice for any kind of web-base applications which need to dynamically alter its layout, and
content.

Visual Development
The vast majority of work that goes into a Morfik XApp is in the form of visual design and
configuration. This holds true for the database access parts as well. Of course, there will be times
when a developer will need or want to write some database access code, for a specific purpose. Most
of the work, however, can be done through the visual designers and wizards.

Morfik AppsBuilder includes visual designers for Tables, Queries and Relationships as well as Wizards
for creating these objects and the visual interface elements which will be associated with them.

Stored Queries
The Morfik Workspace allows the developer to visually create and edit SQL queries. Once the queries
are created they can be used to link interface elements to actual data in the database without the
developer having to insert SQL command strings in the applications interface code. In this respect,
Morfik treats the stored queries in just the same way it does tables.

Actually, due to its tight coupling to the database Morfik uses database content to help you create
the application/site ’ s interface with a lot less coding than any other web development tool.

In Figure 1 you can see the visual query builder in Morfik AppsBuilder Workspace showing the view
where tables, fields and criteria are selected.

Page 620
Figure 1 – Morfik AppsBuilder Visual Query Builder

Content Management
In the world of the Web, and especially what has come to be considered Web 2.0, content is king.
One of the main factors in considering a company and/or website as being Web 2.0, is that it derives,
in some way, content from its own users, thus creating value from their interaction with their users.
In this world, managing the content of a site is its very reason to exist, so special systems have been
created to help individuals and companies get of the ground quickly. These Systems are generically
called Content Management Systems (CMS).

In the first part of this guide we will look at how an application which is totally dynamic can be
created in as simple a manner as possible. We will create a basic content management systems
(CMS) as way to show how to tap into the power available within Morfik AppsBuilder and Morfik
Framework for creating database driven applications. We will add extra functionality to this
application as it suites our need to cover other aspects of database access which will yield a richer
application in the end.

Multi-Database Projects
Apart from the ability to import data from other databases Morfik AppsBuilder allows you to create
projects that access multiple databases. These can be separate databases in the same database
management system (DBMS) or from entirely different DBMSs. This can useful in many different ways
such as creating a web site that publishes data from a pre-existing corporate database or for
distributing load amongst different servers in high concurrency, high volume online systems.

All access to databases other than Firebird is done through industry standard ODBC drivers.

Mixing Databases

Page 621
Though Morfik AppsBuilder does not enable you to run heterogeneous queries against multiple
distinct databases, it does allow you to very easily retrieve related information in diverse databases
and present it to the end user through a web interface.

There is no limitation in the number and type of databases you can combine in a Morfik project, as
long as the respective DBMS has an ODBC driver.

This topic is covered extensively in chapter 4 of this guide.

Basic Common View and Concepts


Independent of which language database you have chosen for your usage, as I mentioned, you will
work with the same concepts. Morfik AppsBuilder presents all tables used in an application in its Table
View. The only notable difference will be that the external (non-native) tables will have a small arrow
painted over their icons. Conceptually, to the Workspace they are exactly the same. Since the stored
query is a Morfik specific concept all queries will show in the same manner in its Query View. When
working with code there will be some differences between using a Firebird database (be it the default
or an external one) and all other databases.

Figure 2 – Morfik AppsBuilder Table View showing a project


with two external tables.

In Figure 2 you can see a list of tables in Table View which include two external tables. The external
tables show with a different icon in the Table View.

Wrapping it up
Morfik AppsBuilder offers support for creating sophisticated applications using its built-in support for
Firebird. Creating applications with the default database does not depend on any application outside
Morfik AppsBuilder. Support for other DBMSs, from all vendors is accomplished through the industry
standard ODBC interface.

Developers can easily create applications/sites that access multiple databases, including databases
from different vendors, and present the information in a clear and simple manner through a Web
interface.

Page 622
See Also
 Database Modeling
 Visual Database Programming

 Database Connections
 Editing and Searching

 SQL Statements
 Using Stored Procedures

 System Objects in a Database


category:Database

Page 623
Database Connections

This topic will provide you will a general overview of how to work with database
connections in code. Most of the work that goes into creating a Morfik database
driven application is actually done through visual programming and very little
configuration/parameterization code. There are, however, situations in which you
are still required to write some database access and manipulation code, even
when working with a tool such as Morfik AppsBuilder which was designed
specifically for creating database applications.

As we will see in this topic, even in these situations the actual amount of code
that must be manually written is small and relatively easy to understand.

User Authentication
Databases are Server Side
Database Access with
WebMethods
Web Method Parameters
Reading data with RecordSets
Working with SQLCommands
Receiving Data in the Browser
Invoking the Authentication Code

The UserSignIn Form


Wrapping it up
See Also

User Authentication
A good example of when you have to directly access a database programmatically is when you have
to perform user authentication against a data stored in a database. Of course, other authentication
methods can be used, but it is fairly common for database driven web applications to use their own
databases to store user access information. This is precisely the case of our sample project
MorfikCMS.

As a home made implementation of a Content Management System (CMS) it makes sense for the
MorfikCMS project to use its database to store information about its users. Initially only basic
identification information is stored for each user and its sole purpose is to differentiate between
general users and users who have to right alter the site ’ s content. For the sake of simplicity we will
treat all identified users as being authorized to perform any changes to the site ’ s data, though a
role based authorization scheme would not be to hard to implement. It would, however, add very
little information on how to access the database that is not already covered by our simpler example.

For our purposes then we will be validating the user ’ s login credentials against the data saved in
the UserCatalog table of our database.

Table 1 shows the structure of the UserCatalog table.

Table 1 – Definition for table UserCatalog


Field Type Size
Id AutoNumber (Integer) -
FullName Text 64
Email Text 64
Password Text 20

Page 624
It was exactly due to the frequency in which this kind of solution is used that User Authentication was
chosen to exemplify how to write code to directly access a database.

Databases are Server Side


All database access code is executed on the server side of a Morfik AppsBuilder application. The
reason is simple: the databases cannot be accessed directly from the browser due to security
constraints. This means that even if you are creating a desktop application with Morfik and running
both the server and browser on the same computer, you will still have to write all database access
code on the server side of the application.

When you need information from a database in application logic of your browser side code the way to
get it is through a WebMethod call, which essentially means that most of the code you will ever write
to access a database will be within the server side class of a WebMethod.

Database Access with WebMethods


Creating a WebMethod with Morfik AppsBuilder is a very simple endeavor. For general examples, be
sure to look up chapter 8 of the Morfik Developer ’ s Handbook which covers this in some detail.

Since Morfik AppsBuilder was designed to work with databases, Web Methods have been engineered
to make it easy to access them. From within the server side class of a Web Method you have direct
access to your XApp ’ s default database connection and can invoke any database commands without
even having to worry about establishing a connection to the database, since that is already taken
care of.

Note
The Server side class of a Web Method has a member variable called DefaultDBConnection
which is the application ’ s default database connection and which can be freely used
without the need to worry about creating and/or closing a new connection.

In order to be useful, a Web Method which does some database access, must be able to return the
retrieved information to its invoker. This is particularly useful in our situation where we want to send
two bits of information which we expect will identify the user and get back whether or not those are
a match to a previously registered user. This exchange of information between the browser and
server components of your XApp is done entirely through the WebMethod ’ s parameters.

Web Method Parameters


A Web Method can have both in and out parameters. This means that not only it can receive
information but give some of its own in return. In our sample case we are working with a WebMethod
which has five parameters: 2 "in" parameters ( AUserName and APassword ) and 3 "out" parameters
( CheckedOk , FullName and UserId ). In Figure 1 you can see those parameters in the Web Method
Designer of Morfik AppsBuilder.

Figure 1 – Parameter definition for the AuthenticateUser WebMethod.

In this particular example the AuthenticateUser Web Method takes what is essentially the username
and password as input and replies with the information if these could be verified and if so the user ’ s
full name and id in the system ’ s database.

In Listing 1 you can see the complete source code for the server side portion of the AuthenticateUser

Page 625
Web Method. Notice that all authentication logic is contained within the Execute method of the class.

Unit AuthenticateUser ;

Interface

T ype
AuthenticateUser = Class ( WebMethod )
AUserName : String ;
AP assword : String ;
CheckedOk : Boolean ;
FullName : String ;
UserId : Integer ;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
P rocedure Execute ; override ;
P rocedure LogAccess ;
End ; [ 'P ublished=False' ];

Implementation

P rocedure AuthenticateUser . LogAccess ;


Var
SQLCommand : T SQLCommand ;
Begin
SQLCommand := DefaultDBConnection . CreateSQLCommand (
'INSERT INT O "AccessLog" ("email","AccessT ime") ' +
'VALUES (:EMAILP ARAM,:ACCESST IMEP ARAM)' );
T ry
SQLCommand . P repare ;
SQLCommand . P aramByName ( 'ACCESST IMEP ARAM' ). AsDateT ime := Now ;
SQLCommand . P aramByName ( 'EMAILP ARAM' ). AsString := AUserName ;
SQLCommand . Execute ;
finally
SQLCommand . Free ;
end ;
end ;

P rocedure AuthenticateUser . Execute ;


var
UserCatRS : T RecordSet ;
Begin
UserCatRS := DefaultDBConnection . CreateRecordSet (
'SELECT "Id", "FullName", "email", "Password" FROM "UserCatalog" ' +
'WHERE LOWCASE("UserCatalog"."email")=LOWCASE(:EMAILP ARAM)' );
try
UserCatRS . P aramByName ( 'EMAILP ARAM' ). AsString := AUserName ;
UserCatRS . P repare ;
UserCatRS . Active := T rue ;
UserCatRS . First ;
CheckedOk := False ;
If Not UserCatRS . Eof then
begin
if ( UpperCase ( APassword ) = UpperCase ( UserCatRS . FieldByName ( 'P assword' ). AsString )) then
begin
CheckedOk := true ;
FullName := UserCatRS . FieldByName ( 'FullName' ). AsString ;

Page 626
UserId := UserCatRS . FieldByName ( 'Id' ). AsInteger ;
LogAccess ;
end ;
end ;
finally
UserCatRS . Free ;
end ;
End ;

End .

All the parameters of a Web Method are represented as member variables of both the server and
browser side classes. This makes reading and setting these parameters extremely easy. In our case
we want to use the two "in" parameters of the Web Method as parameters to a SQL Select command
that we will run against the UserCat table of the project ’ s own database and retrieve some other
information in the three "out" parameters.

Reading data with RecordSets


In order to recover data from the database through code we need to have a RecordSet object. This
object is instantiated from the TRecordSet class and should be used to execute "Select" commands
against the Firebird database as these commands actually return a set of records which match the
specified criteria.

The following code snippet shows how a TRecordSet (called UserCatRS ) object can be instantiated
from the SQL command string.

UserCatRS := DefaultDBConnection . CreateRecordSet (

'SELECT "Id", "FullName", "email", "Password" ' +


'FROM "UserCatalog" ' +

'WHERE LOWCASE("UserCatalog"."email")=' +
'LOWCASE(:EMAILP ARAM)' );

In the following line the necessary parameter is passed to the SQL Statement before its execution in
the database.

UserCatRS . P aramByName ( 'EMAILP ARAM'


). AsString := AUserName ;

Setting the actual parameters of a RecordSet object can be done through a call to the ParamByName
method of the class.

In the following snippet the statement is prepared for execution and executed by setting the Active
property to true. Once the statement is executed a call to First positions the resulting RecordSet to
the first of its records. At this point if the RecordSet does not indicate that it is at the "End of File"
position ( EOF ) the stored and supplied values for the user ’ s password are compared.

UserCatRS . Prepare ;
UserCatRS . Active := T rue ;
UserCatRS . First ;
CheckedOk := False ;
If Not UserCatRS . Eof then
Begin
If ( UpperCase ( APassword ) =
UpperCase ( UserCatRS . FieldByName ( 'P assword' ). AsString ))

Page 627
then

The comparison of the password is done in case insensitive manner through the use of the UpperCase
function on both sides. If the password comparison yields a true result, the return, i.e. "out"
parameters are set with the values recovered from the table. The actual reading of the fields of the
returned records can be done through a call to the RecordSet ’ s FieldByName method.

Begin
CheckedOk := true ;
FullName := UserCatRS . FieldByName ( 'FullName'
). AsString ;
UserId := UserCatRS . FieldByName ( 'Id' ). AsInteger ;
LogAccess ;
End ;
End ;
Finally
UserCatRS . Free ;
End ;

When the data that we required has been read we can dispose of the RecordSet object through a
call to its Free method as seen above.

Working with SQLCommands


In order to recover data from the database through code we used a TRecordSet object but the
TRecordSet class is designed exactly for that: to recover data. There are situations when you need to
execute data manipulations which don ’ t really return any data, such as inserting data into a table.
In these situations we will be using the TSQLCommand class. An example of its use can be seen in
the LogAccess method of the server side implementation of the AuthenticateUser WebMethod.

The TSQLCommand is designed specifically to execute commands which do not return sets of records.
In the following code snippets you can see how a TSQLCommand object is instantiated from a SQL
command string, prepared and executed after having its parameters set.

SQLCommand := DefaultDBConnection . CreateSQLCommand (


'INSERT INT O "AccessLog" ("email","AccessT ime") ' +
'VALUES (:EMAILP ARAM,:ACCESST IMEP ARAM)' );
T ry
SQLCommand . P repare ;
SQLCommand . P aramByName ( 'ACCESST IMEP ARAM'
). AsServerDateT ime :=
Now ;
SQLCommand . P aramByName ( 'EMAILP ARAM'
). AsString := AUserName ;
SQLCommand . Execute ;
Finally
SQLCommand . Free ;
End ;

Parameters of the SQLCommand object are set in exactly the same manner as was done with the
UserCatRS (RecordSet) object in the the Execute method of the AuthenticateUser WebMethod.

The LogAccess procedure simply inserts a record into the AccessLog table, each time a successful Sign
in is executed in the application.

Receiving Data in the Browser


We have just seen how to recover some data in the server side portion of a Web Method and how to

Page 628
execute action SQL commands which do not return data. In the first of these situations, there will be
cases in which the recovered information has to go back to the browser side of your XApp. AS
previously mentioned this transfer is achieved by setting the Web Method ’ s "out" parameters.

The "out" parameters can be read in the browser side portion of a Web Method once the remote
procedure call returns from the server. When the call does return the Web Method browser side
class ’ HandleResponse method is invoked.

In Listing 2 you can see the complete source code for the browser side portion of the
AuthenticateUser Web Method.

Listing 1 – Server side portion of the AuthenticateUser Web Method.

Unit AuthenticateUser ;

Interface

T ype
AuthenticateUser = Class ( WebMethod )
AUserName : String ;
AP assword : String ;
CheckedOk : Boolean ;
FullName : String ;
UserId : Integer ;
P rivate
{ P rivate declarations }
P ublic
{ P ublic declarations }
P rocedure HandleResponse ; override ;
P rocedure AuthenticationOk ;
P rocedure AuthenticationNotOk ;
End ;

Implementation

Uses Header , Footer , UserSignIn , SystemControls ;

const InvalidLogInMessage =
'Username and password do not match. You provided ' ;

P rocedure AuthenticateUser . AuthenticationOk ;


Begin
UserIsAuthenticated := true ;
CurrentUser := UserId ;
Header ( XApp . Forms [ 'Header' ]). UserNameLabel . Caption :=
'Welcome ' + FullName ;
Header ( XApp . Forms [ 'Header' ]). SignInOutOption . Caption :=
'Sign Out' ;
Header ( XApp . Forms [ 'Header' ]). Separator1 . Visible := true ;
Footer ( XApp . Forms [ 'Footer'
]). SiteManagementOption . Visible := true ;
Header ( XApp . Forms [ 'Header' ]). UserNameLabel . Visible := true ;
UserSignIn ( XApp . Forms [ 'UserSignIn' ]). Close ;
End ;

P rocedure AuthenticateUser . AuthenticationNotOk ;


Begin
UserSignIn ( XApp . Forms [ 'UserSignIn' ]). ErrorMessage . Caption :=
InvalidLogInMessage +
UserSignIn ( XApp . Forms [ 'UserSignIn' ]). UserNameEdit . T ext ;
End ;

Page 629
P rocedure AuthenticateUser . HandleResponse ;
Begin
If CheckedOK T hen
AuthenticationOk ()
Else
AuthenticationNotOk ()
End ;

End .

In this particular case the HandleResponse method just tests to see if the CheckedOk "out" parameter
has returned as true or false. If the check was Ok, then the AuthenticationOk method is called,
otherwise, the AuthenticationNotOk method is called.

The AuthenticationOk method sets a global variable called UserIsAuthenticated to true and hides or
display a few objects. It is the global variable UserIsAuthenticated which is used, through out the
application to allow or disallow operations depending on a registered user having been
authenticated.

One of the visual elements that the AuthenticationOk method makes visible and whose content it sets
is a TextLabel which will hold the user ’ s full name, also returned from the Server as seen in the
following snippet.

Header ( XApp . Forms [ 'Header' ]). UserNameLabel . Caption := 'Welcome '


+ FullName ;
Header ( XApp . Forms [ 'Header' ]). UserNameLabel . Visible := true ;

Invoking the Authentication Code


As we have seen the user authentication is accomplished through the use of a Web Method. That is
the mechanism that we use to send the information to the server and get back a response, but how
to we get the information from the user and how do we start the authentication process which will
lead to the database lookup we have put together.

The UserSignIn Form


The UserSignIn Form is invoked from the Header Form when the user/visitor clicks on the "Sign In"
link. This Form is displayed as a popup instead of being displayed inline as it should be the single
point in which the user focuses during this process. As such the UserSignIn Form is also modal,
restricting all interaction with the application/site to itself.

The following code snippet contains the complete event handler for the OnClick event of the
SignInOutOption TextLabel.
Procedure Header.SignInOutOptionClick(Event: TDOMEvent); Begin

If Not UserIsAuthenticated T hen


OpenForm('UserSignIn', 'P OP UP ', '"title=Sign In", "modal=true"')

Else
Begin
UserIsAuthenticated := false;
SignInOutOption.Caption := 'Sign In';
UserNameLabel.Visible := false;
Separator1.Visible := false;
Footer(XApp.Forms['Footer']).SiteManagementOption.Visible :=
false;
End;

Page 630
End;

Notice that after determining that a user is not currently signed in the event handler invokes
OpenForm causing the UserSignInOut to popup.

Figure 2 shows the UserSignIn Form in Design mode in Morfik AppsBuilder Workspace. This is a simple
Form which is not bound to any data source. All data exchange with the server is done through the
AuthenticateUser Web Method which we have previously reviewed.

Figure 2 – The UserSignIn Form in design mode in the Morfik Workspace.

Once the UserSignIn Form is displayed and the user inputs his data the SignInBtn Button control
invokes the RunWebMethod command in its OnClick event handler.

The following snippet contains the event handler for the OnClick event of the SignInBtn button control
and the DoAuthenticate procedure it invokes.

P rocedure UserSignIn . DoAuthenticate ;


Begin
RunWebMethod ( 'AuthenticateUser' , '"AUserName='
+ UserNameEdit . T ext +
'", "AP assword=' + P asswordEdit . T ext + '"' );
End ;

P rocedure UserSignIn . SignInBtnClick ( Event : T DOMEvent );


Begin
DoAuthenticate ;
End ;

The DoAuthenticate procedure as seen in the previous code snippet invokes the RunWebMethod
command to execute the AuthenticateUser Web Method passing as its parameters the data entered
in the two TextEdit controls of this Form.

Page 631
Figure 3 – The UserSignIn Form at runtime, displayed as a popup.

After invoking the AuthenticateUser Web Method execution the event handler for the SignInBtn button
closes the popup Form as the execution will resume in the browser side part of the Web Method once
the server replies to the call.

The CancelBtn button in the UserSignIn Form only closes the Form if clicked as no further action is
required.

Wrapping it up
Interfacing with the database from code in a Morfik application is not a complex task and is normally
done in the server side portion of a Web Method where the code to execute pure action queries and
data selection queries is quite similar.

See Also
 Morfik Database Programming
 Database Modeling

 Visual Database Programming


 Editing and Searching

 SQL Statements
 Using Stored Procedures

 System Objects in a Database


category:Database

Page 632
Database Modeling

This topic will provide you will a general overview of how to create and work with
your database model inside the Morfik AppsBuilder Workspace. It is presumed that
the user already has some familiarity with the basic concepts of relational
databases or perhaps some experience with a generally available DBMS such as
Microsoft Access, Microsoft SQL Server, Oracle, Firebird, MySQL, etc.

Our focus will be on providing a quick reference for how to use the built in tools
and features of the Morfik AppsBuilder Workspace to construct a relational model
for a complete application which we will build mostly through out the topics of this
guide.

Morfik comes with a built in database which is a full featured database server. This
is an open source database called Firebird which can be freely deployed with no
licensing costs. Morfik simplifies the usage of this powerful database server,
making it very easy to use. This allows developers to benefit from the power of a
full relational database server while having the ease of use of a desktop
database.

Database Model
Content Management System
Database
Tables
Creating a Table
Selecting the Primary Key
CMS Tables
Table Designer
Creating Relationships
Creating Queries
Query Designer
Wrapping it up
See Also

Database Model
Morfik has built into the AppsBuilder Workspace the concept of your database model, represented by
the Relationship View, where you can add your tables and visually the relationships. It is important to
have in mind that the Relationship View only shows the tables that have been explicitly added to it
and so might not represent the totality of the elements that exist in the project ’ s database.

All tables in a Morfik Project can be seen in the Project View. Tables can be hidden, and normally will
not appear on the Table View. This can, however, be configured through the Project Options dialog
which can be called up by selecting Options under the Project menu.

A good database model is important in order to create a well planned application. This is especially
true in a Morfik application as a well planned database will make easier to create the application ’ s
interface.

Note
If you have never worked in depth with a database, you might want to check out a book
specifically on database modeling as it might provide some good insights on how to create
a good design. It is not, however, a required step to proceed on in this guide. It is
required however that you know the basic concepts of relational databases as these will
not be presented here.

Page 633
Content Management System Database
In order to go through all the areas of database access in Morfik AppsBuilder and the Morfik
Framework this guide uses a sample database model for a totally database driven website. This is
the Content Management System (CMS) database. This is the database for a project that will be
created in this guide, starting in this chapter. In fact, it is recommended that you go right ahead and
create a project called MorfikCMS if you intend to follow through the steps described here.

The content management database is as simple as can be made and yet achieve its intended goal of
driving a complete website. It stores information about the site itself, site sections, articles posted
and users.

Tables
The first thing in creating a database is to know which data you want to store. For the purpose of
illustrating this guide, we are going to be building a Content Management System (CMS) so we will
focus on creating the required tables.

In this case, we have stated that we are going to be storing and using information about the
website, its sections, articles posted to it, and its users.

First lets start with a table to store information about the website itself. What kind of information
would that be? A name for the site, a description, copyright notice and general information about the
site ’ s owner be that a company or a person. Those would be, generally, the main things that we
need to store about the website itself.

Creating a Table
We will be creating a new table with the help of the built-in table creation wizard. In order to create
the first table it is necessary to select the Project Tab in the Ribbon on the top portion of the
Workspace. This this option in the Ribbon is highlighted in Figure 1.

Figure 1 – The option to create a table by using the built-in wizard is highlighted on the Project tab
of the Ribbon.

Choosing the New Table option from the New Item submenu of the Morfik menu brings up the wizard
where you will be asked to start by providing a name for the table which is about to be created. In
this case we are going to call the table WebsiteInfo as it will be holding all information which related
to the site itself. Figure 2 shows the first page of this wizard.

Page 634
Figure 2 – First step in the Create Table wizard, entering a table name.

Once you have typed in a name for the table, you can move on to the next step where you will be
asked which fields to include in the table. Figure 3 shows the second step in this wizard.

Figure 3 – Second step in the Create Table wizard, adding fields to the table.

You can add fields/columns to the table by clicking on the Add button. This brings up a small dialog
that lets you type in the name and data type details necessary. You can see this dialog in figure 4.

Page 635
Figure 4 – The two views of the dialog which is used for adding fields to the table
in the Create Table wizard.

As can be seen in Figure 4, you can choose to just provide a field name and select a general type, or
you can specify more details such as the actual size, in case of a text field, default value and its
description.

In this case a description was added to the field, specifying that this field will store the name of the
website we are creating.

We should proceed to create this table with the fields matching the description in Table 1.

The default size for a text field is 64 so you just need to specify a size for the fields with lengths
different to 64.

Table 1 – Field definitions for table WebsiteInfo


Field Type Size
Title Text 64
SubTitle Text 128
OwnerName Text 64
OwnerDescription Text 250
CopyrightMessage Text 128
CatchPhrase Text 128
HomeSection Number (Integer) -

Once all fields have been added to the wizard, matching the definitions in Table 1, you can proceed to
the next step

The third step of the Create Table wizard offers the developer an opportunity to define a primary
key.

Page 636
Figure 5 – Step two of the Create Table wizard with
the fields already added

Figure 6 – Third step of the Create Table wizard offers the opportunity to select a primary key for
this table.

Selecting the Primary Key


Good relational database design practices dictate that every table should have a primary key. A
primary key is a column that uniquely identifies each row, allowing for no duplicate values. A table
might contain more than one column that has unique values for each row, for example it might have a
numeric id and a telephone. In this case both columns are what we call candidate keys and you must
choose one of them to be the primary key.

One good way to evaluate candidate keys is to think about the possibility that they might change

Page 637
their value over time. For example, it is possible for a person to change phone numbers; in fact it is
likely to happen over long periods of time, while a numeric id is under your system ’ s control and
won ’ t change unless the system needs it to. Comparing these two candidate keys in this light the
numeric id is the better choice as a primary key.

Defining a primary key is a very important aspect of table structure design. In many databases, this
task is absolutely necessary as it is the only way to uniquely identify the records in a table. Morfik,
however, defines a hidden field which serves this internal task. In many cases, however, it is still
useful to define a primary key and not rely on the control field. The most common way to define a
primary key is to use the AutoNumber data type.

As you might notice this table we are creating does not contain any fields that match the description
of what would be a good candidate for a primary key. We can, however, go back to the previous step
in the Wizard and include such a field. Please do that and add a field called Id with the definition
presented in Table 2.

Table 2 – Id field definition for table WebsiteInfo


Field Type Size
Id AutoNumber (Integer) -

Once you have added the Id field you can back to the third step and select this field as the table ’ s
primary key. The wizard with the new field selected as primary key can be seen in Figure 7.

Figure 7 – The Id field is selected as primary key in the WebsiteInfo table in the third step of the
Create Table wizard.

This completes the third step of the wizard and we can move on. This will actually conclude the
wizard since the next page indicates that all information has been acquired and asks if the user
wishes to open the table in Data View. This can be seen in Figure 8. Data View allows for direct input
of data into the table. Though we will enter some data further in this guide, we will not dispend time
on it now.

Page 638
Figure 8 – The Create Table wizard is complete. The table will be created as soon as Finish is
pressed.

CMS Tables
In order to proceed through this guide, if you wish to recreate the application that is being used as a
sample here, you should create additional tables with structures as shown in the following tables.

Table 3 – Definition for table Section


Field Type Size
Id AutoNumber (Integer) -
Title Text 64
SubTitle Text 128
IsPublic Yes/No -
ParentId Number (Integer) -

In table Section , again, the Id field should be the primary key.

Note that the structure of the Section table is not very different from the WebSiteInfo table. That is
because a section of a website is essentially a website in itself. Section , however, has a self
referencing relationship where you can specify that a section is a subsection of a previously existing
one. This is done through the ParentId Field.

Table 4 – Definition for table UserCatalog


Field Type Size
Id AutoNumber (Integer) -
FullName Text 64
Email Text 64
Password Text 20

In table UserCatalog , again, the Id field should be the primary key. This table will hold the list of users
that can log in to our website to have access to restricted areas.

Table 5 – Definition for table Article


Field Type Size

Page 639
Id AutoNumber (Integer) -
Title Text 64
Summary Text 250
Body Memo -
DateCreated DateTime -
DatePublished DateTime -
IsPublished Yes/No -
SectionId Number (Integer) -
CreatedBy Number (Integer) -

In table Article , again, the Id field should be the primary key. The Article table will store the individual
articles that compose our website. Article , in this case, is a generic name that I have given to this
specific group of data which might hold a news item, a blog post or anything which can fit the pattern
of having a title, a summary and a full body. This pattern can be found to repeat itself in websites all
across the Internet, no matter what the site ’ s content is. The additional fields in the Article table are
more for internal control of how the website works than for external consumption of the information
they hold. The IsPublished field, for example, will allow for an article to be added to the database
without it becoming immediately visible to the website ’ s visitors.

Note
Another table, called UserCatalog, will be specified in another topic of this reference. This
table will be used to hold user name and password information for sign-in operations and
a Web Method will be defined to work with it. For more information refer to the Working
with Database Connections topic.

Table Designer
Once tables are created, their structure can be modified through the table designer. The Table
Designer allows each and every characteristic of a table to be set or altered in a manner that is
simple and easy.

Through the designer you can: add and remove fields, set and remove the primary key for the table,
create and delete indexes, alter data types, etc. Figure 9 shows a view of the WebsiteInfo table in
Table Designer

Page 640
Figure 9 – The WebsiteInfo table in the Table Designer in the Morfik Workspace.

Using the Table Designer you can even reorder physically the fields in your table through a simple
drag and drop operation. This is the field we added to the WebsiteInfo table, after having added all
the others. In Figure 9 the Id fields of the WebsiteInfo table is the last one in the list. In Figure 10 this
field is now the first one in the list and will stay that way, after you save the changes, each time the
table is opened in the designer.

Page 641
Figure 10 – WebsiteInfo table in the Table Designer showing the Id field as the first in the list.

Through the Table Designer you can also enter data directly into a table. This is done through the
Data View of the Table Designer. To use this feature you should select the "Data" tab of the
designer. This feature is especially useful to enter test data for your application. We will need some
test data for our application so we can enter a record in the WebsiteInfo table. The WebsiteInfo table
will always hold only one record as it contains general information about the website we are creating.
In Figure 11 you can see a screenshot of the Morfik Workspace showing test data being entered for
the WebsiteInfo table.

Page 642
Figure 11 – Data View of the Table Designer in the Morfik Workspace.

Creating Relationships
Once we have created our tables, the next step in creating a database driven application/website is
to create the relationships between those tables. Relationships, as the name suggests indicate how
data in one table relates to data in another table.

Page 643
Figure 12 – List of tables to be added to the Relationships View.

From the View Tab of the Ribbon you can choose the Relationships view which leads to a blank slate,
if relationships have not been created in the application. Tables can be added to the Relationships
View by right clicking the background and selecting "Show Table". This brings up a dialog with the list
of tables in the current project as can be seen in Figure 12.

Page 644
Figure 13 – All tables from the CMS project just added to the Relationships View.

Once all the project ’ s tables have been added to the Relationships View the actual relationships can
be created. In order to create a relationship between two tables the user should drag the primary
key of a table over the corresponding (foreign key) field in the related table.

In the case at hand there are two relationships to be defined. The first is between tables Section and
Article while the second is between Article and UserCatalog . This is because an article will be
published under a section of the website and created by one of the site ’ s users.

Once the drag and drop operation is completed, a dialog box will popup asking for the specific details
of the relationship that is being created. This dialog is shown in Figure 14.

Page 645
Figure 14 – Edit Relationships dialog showing a relationship between tables UserCatalog and Article
.

At this moment the user can specify if referential integrity will be automatically enforced by the
underlying Firebird database server. In Figure 15 these options are highlighted.

Figure 15 – Edit Relationships dialog of the Morfik Workspace with Referential Integrity options
highlighted.

As defined in Figure 15 the relationship between tables UserCatalog and Article will cascade any

Page 646
changes. What this means is that if a User has his Id changed in the UserCatalog table, all
corresponding articles will get updated to reflect the new Id . This avoids the possibility of ending up
with inconsistent data in the database. The cascade delete option means that if any user is deleted
from the UserCatalog table, all articles created by that user will also get deleted.

Note
In this case, in the interest of simplicity of design the Cascade Delete option is being
turned on. Generally speaking this is not a good idea for a production system.
A strong argument can be made that if someone accidentally deletes a record you do not
wish to run the risk of having tons of other records deleted, in other tables.

In Figure 16 you can see the complete relationship map for the tables in the MorfikCMS database,
with the two relationships created.

Figure 16 – Relationships diagram for the tables in the MorfikCMS project.

Note that in Figure 16 you can see a relationship between tables Section and WebsiteInfo . This is due
to the fact that you select one of the existing sections to be your home section, i.e. the section that
will be shown when the end user first types in the application/site ’ s URL.

Creating Queries
Morfik AppsBuilder brings to the creation of Web based applications an interesting approach to
working with databases. Morfik allows developers to save queries which will be used through out an
application so that they can be easily used as the data source for the construction of parts of the
application interface. This is a feature also found in Microsoft Access and users who are familiar with
that tool should feel right at home in working with them in Morfik.

Queries can be created in three different ways in the AppsBuilder: entering the SQL code, using a

Page 647
Wizard or using the Query Designer.

Query Designer
Using the Query Designer in Morfik AppsBuilder ’ s Workspace is very straight forward. When you New
Query option under New Item in the Morfik Menu a small dialog pops up asking for the name of the
query to be created as shown in Figure 17. You are also asked if you will create a a Visual, non-visual
or passthrough query and what Morfik language should be used for the server side components that
accompany each data source, such as a table or a query.

Figure 17 – Specifying a name for a query that is being created.

Once that is done the Workspace goes into the Query Designer. In the query designer the first thing
to do is to add tables to the query. In this example we will create a query to recover a single specific
record from two tables. This query, called GetOneArticle will recover all the information for displaying a
complete view of an Article to the website ’ s visitors. You can add tables to the query by click on the
Show Tables button in the toolbar which will bring up a dialog as shown in Figure 18.

Page 648
Figure 18 – Adding a table to the Query using the Data Sources dialog.

When adding both the Article and UserCatalog tables to the query the relationship between the tables
is brought in automatically and displayed as shown in Figure 19.

Page 649
Figure 19 – Queries fields selected and the relationship between the tables added automatically.

In the case shown in Figure 19 the several fields have been selected for recovery.

From table Article :

Id , Title , Body , DateCreated , DatePublished , DateCreated

From table UserCatalog :

FullName

On field Id of the Article table a parameter has been included in the query so that the developer can
specify exactly what article he/she wants recover. This is called a parameterized query and can be
very useful, especially for usage with forms. This will be covered in more detail in the next chapter. As
the developer makes his/her choices in the Query Designer , Morfik AppsBuilder is creating the SQL
command which will be stored.

Page 650
Figure 20 – SQL command generated by the Query Designer.

Figure 21 shows the AppsBuilder Project View with our first query selected.

In the Visual Database Programming topic, we will see more details about how to use these stored
queries and how they integrate with the visual programming side of Morfik AppsBuilder in a manner
which is, at the same time, simple and powerful.

Page 651
Figure 21 – The GetOneArticle selected in the Project View. The Project view is being filtered as to
only show queries.

Wrapping it up
Morfik AppsBuilder includes a fully featured relational database server which can be generally worked
on through the Morfik Workspace. There are several different ways to create tables and queries, all
of which are quite simple and powerful. Morfik AppsBuilder also allows for the possibility of creating
"pass-through" SQL commands which will essentially allow you to make use of just about any feature
offered by the underlying database.

See Also
 Introduction to Morfik Database Programming
 Visual Database Programming

 Database Connections
 Editing and Searching

 SQL Statements
 Using Stored Procedures

 System Objects in a Database


The
 Workspace

 Working With XML Data

Page 652
category:Database

Page 653
SQL Statements

This chapter will provide you with a general overview of the four main Statements
in SQL language (Select, Insert, Update and Delete) and on how they are
implemented in Firebird, Morfik ’ s built-in database. These are the Statements
developers will be using, most of the time, when creating a Morfik, database
driven, Web application.

The Database Connections topic of this guide has already presented a general
overview on how to use SQL Statements from Morfik source code so this chapter
will focus more on the Statements themselves then on explaining how to call the
from within a Morfik application. This topic will, however, on the aspects of these
Statements which can, normally, used from within a Morfik application leaving
aside, for example, issues which relate to their usage in Stored Procedures or
Triggers.

The Select Statement


Select Statement Syntax
ALL
DISTINCT
FIRST and SKIP
Columns Returned
FROM
<table_or_view_or_procedure_or_select>
JOINS
INNER JOIN
OUTER JOIN
CROSS JOIN
WHERE
GROUP BY
HAVING
UNION [ALL | DISTINCT]
ORDER BY
The Insert Statement
The Update Statement
The SET Clause
The WHERE Clause
The Delete Statement
Wrapping it up
See Also

The Select Statement


The most known Statement in all the different variations of the SQL language is undoubtedly the Select Statem
This Statement, used in just about any relational database server available today, allows you to specify which
information you want to retrieve from the database.

The Database Modeling topic, of this guide, presented the concept of Queries as objects which are a part of y
project. This concept was then extensively used in creating the MorfikCMS sample application as described in t

Page 654
Visual Database Programming topic. All the queries mentioned and created to support the MorfikCMS applicat
based on the Select Statement. In fact, Select queries are the only ones which can be created visually inside t
Morfik AppsBuilder Workspace.

Most of the Select Statements in this application are quite simple and only involve data retrieval from a single t
Such is the case of the GetSubSections query, for example. The following code snippet contains the SQL langua
code of the GetSubSections query.

SELECT ALL
"Section" . "Id" ,
"Section" . "T itle" ,
"Section" . "SubT itle" ,
"Section" . "IsP ublic" ,
"Section" . "P arentId"
FROM
"Section"
WHERE
"Section" . "IsP ublic" = 1 AND "Section" . "P arentId" = :
P aramP arent

Select queries, however, can retrieve data from multiple columns. The following code snippet shows the SQL
language code for the GetSectionArticles query.

SELECT ALL
"Article" . "Id" ,
"Article" . "T itle" ,
"Article" . "Summary" ,
"Article" . "IsP ublished" ,
"Article" . "DateP ublished" ,
"Article" . "SectionId" ,
"UserCatalog" . "FullName"
FROM
( "UserCatalog" INNER JOIN "Article" ON
( "UserCatalog" . "Id" = "Article" . "CreatedBy" ))
WHERE
"Article" . "IsP ublished" = 1 AND "Article" . "SectionId" = :
P aramId

These queries where created visually within the Morfik AppsBuilder Workspace using the Visual Query Designer
obviously requires next to no knowledge of the SQL language.

There will be situations when you might want or need to hand code a query. In the MorfikCMS sample project
example of this is the GetOneArticleCount query. This query was used to replace the GetOneArticle query. The
difference between them is that while one actually specifies all the data to be retrieved from fields and tables,
other retrieves the results of a selectable stored procedure. Since it is not possible to visually create such a qu
the Morfik Workspace, our only recourse is to hand code the Statement.

Select Statement Syntax


In order to better understand the power of the Select Statement, lets have a quick look at its syntax. The Sele
syntax as defined in the Firebird 2.0.1 release notes is the following:

<select statement> ::=


<select expression> [FOR UPDAT E] [WIT H LO
CK]

Page 655
<select expression> ::=
<query specification> [UNION [{ALL | DIST INCT }] <query specificati
on>]

<query specification> ::=


SELECT [FIRST <value>] [SKIP <value>] <select lis
t>
FROM <table expression list>
WHERE <search condition>
GROUP BY <group value list>
HAVING <group condition>
P LAN <plan item list>
ORDER BY <sort value list>
ROWS <value> [T O <value>]

<table expression> ::=


<table name> | <joined table> | <derived tabl
e>

<joined table> ::=


{<cross join> | <qualified join>
}

<cross join> ::=


<table expression> CROSS JOIN <table expression>
<qualified join> ::=
<table expression> [{INNER | {LEFT | RIGHT | FULL} [OUT ER]}] JOIN <table expres
sion>
ON <join condition>

<derived table> ::=


'(' <select expression> '
)'

In summary form:

Page 656
SELECT [FIRST (n)] [SKIP(n)] [ALL | DIST INCT ]
<column_list> [, [column_name] | expression | constant] AS alias_name]
FROM <table_or_procedure_or_view_or_select>
[{[[INNER] | [{LEFT | RIGHT | FULL} [OUT ER]] JOIN }]
<table_or_procedure_or_view_or_select> ON <join_conditions> [{JOI
N…]]
[WHERE <search_conditions>]
[GROUP BY <grouped_column_list>]
[HAVING <search_condition>]
[UNION <select_expression> [ALL]]
[P LAN <plan_expression>]
[ORDER BY <column_list> [[ASC] | DESC]]
[ROWS <expression1 [T O <expression2>]]
[FOR UP DAT E [OF column1 [, column2…]] [WIT H LOCK]]

It is important to note that the clauses in square brackets are optional and that the order in which they appea
the Statement is significant.

We will proceed to proceed to have a quick look at the more frequently used clauses of the Select Statement.

ALL
The inclusion of the ALL clause means that the Select Statement should return all the rows (just the values for
specified columns) which where found. This is the default behavior for the Select Statement so its inclusion is
customarily neglected.

DISTINCT
The DISTINCT clause removes duplicate rows which might have been retrieved by the Select Statement. This m
that any row having the same values for the columns listed in the Select Statement will be condensed into a si
row in the result set.

A good example of the usage of this Statement would be to select the list of countries from which visitors to a
website come from. The following code snippet consists of an alphabetically sorted list of countries present in t
table. No duplicates will exist, no matter how many rows the table contains with the same value in the "Count
column.

SELECT DIST INCT "Country" FROM "Visitor" ORDER BY


"Country"

FIRST and SKIP


The FIRST clause specifies how many rows should be returned from the Select Statement, while the SKIP claus
informs how many rows should be ignored before starting to return rows.

SELECT FIRST 5 "Id" , "Country" , FROM "Visitor" ORDER BY


"Country"

The previous Statement would return the first five Countries and Ids from the Visitor table.

SELECT FIRST 5 SKIP 5 "Id" , "Country" , FROM "Visitor" ORDER BY


"Country"

Page 657
The second Statement would return the "next" five rows, discarding the first five, considering the sorting base
the Country column.

One of the most common uses of these clauses is to paginate the data returned from a Select Statement. It sh
be quite rare to need to use these clauses when working in a Morfik application as the Morfik Framework prov
automatic paging of the data returned by the data sources associated with Forms.

Columns Returned
When creating a Select statement the user must specify which columns should be returned, from the rows tha
match the requested criteria. If an "*" (asterisk) is specified all columns will be returned. The Select statement
not only specify existing columns from the specified tables but, also, calculated columns which are created on t
from existing columns. The following are some examples of Select statements:

SELECT "Id" , "T itle" FROM "Article" WHERE "SectionId"


= 5

This statement returns the Id and Title of all rows in the Article table which have the column SectionId with a va
5.

SELECT "Id" , "T itle" FROM "Article" WHERE "SectionId" = 5 ORDER BY


"T itle"

This second statement will retrieve the same rows as the first one but this time they will be ordered by the con
of the Title column.

SELECT "FirstName" || ' ' || "LastName" AS "FullName" FROM


"UserCatalog"

The above statement returns as a column called FullName , the concatenated value of the FirstName and LastN
columns with a space added in between them for good measure.

SELECT "FirstName" || ' ' || "LastName" AS "FullName" FROM "UserCatalog" ORDER BY


"FullName"

The inclusion of the ORDER BY clause in the above statement shows that calculated columns can also be used
sorting.

SELECT COUNT (*) AS "T otal" FROM


"UserCatalog"

The COUNT function, used in the previous statement is used to count how many rows conform to the specified
criteria. Since in this example no criteria were specified it returns the number of rows in the UserCatalog table.

SELECT MAX ( "ViewCount" ) FROM


"Article"

This simple statement returns the highest value for the ViewCount column in table Article .

Page 658
SELECT "Id" , "T itle" , ( SELECT COUNT (*) FROM "Article" A
WHERE A . "SectionId" = S . "Id" ) AS NUM_ART ICLES FROM
"Section" S

This example uses a sub-query to calculate a new column. In this example the select statement is returning th
and Title of each row in the Section table, as well as the number of articles in the Article table which are related
each section. This example also shows the use of table aliases (in this case A and S).

Note
The user should always involve identifiers such as table names and column names with double quo
unless the usage of all-caps identifiers is considered acceptable. Firebird requires that all identifiers
conform to one of these two standards so identifiers are either all-caps or enclosed in double quote

As a user becomes more familiar with the SQL statements used by the built-in database he/she will naturally b
to create more complex statements, sometimes accomplishing complex tasks with very little code.

FROM <table_or_view_or_procedure_or_select>
The FROM clause in the Select statement is used to identify in which tables the desired data is stored. If data i
being recovered from more than one table the FROM clause will contain a list of tables.

In addition to common tables the developer can specify as the origin of the data views, stored procedures and
other Select statements. The following code snippet shows a Select statement which retrieves data from a
selectable stored procedure, for example:

SELECT * FROM "Article_SEL" (


3)

In creating the FROM clause of Select statements developers are allowed to declare aliases for the tables. It is
common practice to create short aliases in order to reduce the amount of typing required to create more comp
statements. The following example shows the declaration and usage of two table aliases (A and S).

SELECT "Id" , "T itle" , ( SELECT COUNT (*) FROM "Article" A


WHERE A . "SectionId" = S . "Id" ) AS NUM_ART ICLES FROM
"Section" S

Note
The version of Firebird that is used as Morfik ’ s built-in database engine does not support the mixe
usage of table names and aliases when qualifying column names. The following code, for example,
generate and error.
SELECT U.ID, USERC ATALOG.USERNAME FROM USERC ATALOG U
The error will be due to the fact that this statement is qualifying columns using both the tables nam
(USERCATALOG) and its alias (U).

JOINS
The JOIN clause specifies the relationship between tables in a Select statement allowing the retrieval of colum
from different tables in a single result set.

Firebird supports several different types of JOINs: INNER JOIN, OUTER JOINs (LEFT, RIGHT, FULL) e CROSSJOIN
JOIN clause is normally paired with an ON clause. Together these two clauses determine the relationship betw
tables. The information retrieved from each table is called a stream.

Page 659
SELECT S . "Id" , S . "T itle" , A . "T itle" FROM "Section" S JOIN "Article" A ON S . "Id" = A .
"SectionId"

INNER JOIN
The INNER JOIN or exclusive join can be represented by omitting the INNER clause as in the previous example.
essentially means that this is the default JOIN behavior and that the previous example could have been writte
follows.

SELECT S . "Id" , S . "T itle" , A . "T itle" FROM "Section" S INNER JOIN "Article" A ON S .
"Id" = A . "SectionId"

This kind of join will only return information on Sections that do have Articles associated with them. This means
any sections which do not have any articles will be excluded from the result set.

OUTER JOIN
An OUTER JOIN returns rows even when the condition is not satisfied. In this case the columns belonging to th
stream where there was no related data will be returned as NULL.

It is important to note that an OUTER JOIN is composed of two streams (right and left). When multiple JOINs a
used in a single Select statement the right stream of a JOIN can be the left stream of another one.

There are three types of OUTER JOINs: LEFT, RIGHT and FULL. In each case, once one of these clauses has be
specified the OUTER clause itself can be omitted from the Select statement.

The LEFT OUTER JOIN returns all the rows of the left stream, regardless of the specified condition being met.

SELECT S . "Id" , S . "T itle" , A . "T itle" FROM "Section" S LEFT OUT ER
JOIN
"Article" A ON S . "Id" = A . "SectionId"

The RIGHT OUTER JOIN, on the contrary, returns all the rows of the right stream, regardless of the specified co
being met.

SELECT S . "Id" , S . "T itle" , A . "T itle" FROM "Section" S RIGHT OUT ER
JOIN
"Article" A ON S . "Id" = A . "SectionId"

Finally a FULL OUTER JOIN returns all the rows from both streams, once again, regardless of the specified cond
being met.

SELECT S . "Id" , S . "T itle" , A . "T itle" FROM "Section" S FULL OUT ER
JOIN
"Article" A ON S . "Id" = A . "SectionId"

CROSS JOIN
A CROSS JOIN returns the Cartesian product of the related tables. It is important to use this feature with cauti
its result set might be overly large and therefore cause application performance degradation.

Page 660
Have in mind that the returning result set of a CROSS JOIN between two tables with 1,000 rows, each, will hol
1,000,000 rows. The following code snippet shows the syntax for the use of a CROSS JOIN clause.

SELECT A . NAME , B . ID FROM T ABLEA A CROSS JOIN


T ABLEB B

WHERE
The WHERE clause enables developers to specify criteria which must be met in order for a row to be part of the
returning result set of a Select statement. The following code snippet, for example, uses the WHERE clause to
that only rows of the Article table with the column SectionId holding the value of five should be returned.

SELECT "Id" , "T itle" FROM "Article" WHERE "SectionId"


= 5

When specifying criteria for the WHERE clause a number of different operators can be used. Table 1 shows a li
operators and a brief description of how they work and are used in composing Select statements.

Table 1 – Comparison Operators


Property Value
Equality
<> , !=, ~ =, ^ = Non Equality (Different)
> Greater Than
< Less Than
>= Greater Than or Equal To
<= Less Than or Equal To
! > , ~> , ^> Not Greater Than (essentially the same as
Less Than or Equal To)
! < , ~< , ^< Not Less Than (essentially the same as
Greater Than or Equal To)
BETWEEN AND Used to specify a range within which a value
must fall.
SELECT ID, FULLNAME FROM USER WHERE
ID BETWEEN 1 AND
10;
CONTAINING Used to match a substring within a column.
SELECT ID, FULLNAME FROM USER WHERE
NAME
CONTAINING ’ PAUL ’
This statement will return rows where the
FULLNAME column contains the substring ’
PAUL ’ .
IN Used to verify if a column matches any of
the values contained in a list.
SELECT ID, TITLE FROM ARTIC LE WHERE
SEC TIONID IN
( 1,2,3)
This operator allows up to 1,500 values to
be listed.
STARTING WITH Used to match a substring at the start of a
column.

Page 661
SELECT ID, FULLNAME FROM USER WHERE
NAME
STARTING WITH ’ PAUL ’
The above example, contrary to that of the
CONTAINING operator will not return a row
with name such as ’ JEAN-PAUL ’ since it
does not Start with ’ PAUL ’ .
LIKE Used to match substrings with the usage of
wildcard characters. (% and _)
The ’ % ’ character indicates any number
of characters while the ’ _ ’ indicates a
single character.

GROUP BY
The GROUP BY clause specifies by which columns a result set will be grouped. Use of this clause is mandatory
whenever an aggregate functions is used (COUNT, SUM, MAX, MIN, etc) in any of the selected columns.

SELECT U . COUNT RY , COUNT (*) AS USERCOUNT FROM USERCAT ALOG U


GROUP BY
U . COUNT RY ORDER BY USERCOUNT DESC

HAVING
The HAVING clause works in a similar manner to the WHERE clause but works with conditions based on aggreg
The following code snippet shows a variant of the previous example, but in this we are restricting the result se
only those countries which have less than 10 users.

SELECT U . COUNT RY , COUNT (*) AS USERCOUNT FROM USERCAT ALOG U


GROUP BY
U . COUNT RY HAVING COUNT (*) < 10 ORDER BY USERCOUNT DESC

UNION [ALL | DISTINCT]


The UNION clause allows us to bring data from multiple select statements into one single result set. The select
involved in a UNION operation can all reference the same table(s) or entirely different ones in which case Fireb
automatically try to cast the distinct row types in a single compatible type.

SELECT U . FULLNAME FROM USER U


UNION
SELECT S . FULLNAME FROM SUP ERUSER
S

Note
Note that the standard behavior for a UNION operation is to exclude duplicate entries so if there is
name which is present in both the USER and SUPERUSER tables of the previous example, it will app
only once. If the desired result is that "all" rows from both Select statements be returned, the UNIO
clause must be substituted by the UNION ALL clause. Since the default behavior is to suppress dup
the UNION clause is actually a synonym to the UNION DISTINCT clause.

ORDER BY
The ORDER BY clause allows the developer to specify how the rows returned in the result set of a Select statem

Page 662
will be sorted. The sorting can be either ASCENDING (ASC – default) or DESCENDING (DESC).

SELECT "Id" , "T itle" FROM "Article" WHERE "SectionId" = 5 ORDER BY


"T itle" ASC

The previous example returns all rows of the Article table where the column SectionId is equal to 5, in ascendin
alphabetical order of values for the Title column.

The Insert Statement


The Insert statement is used for adding new data into a single table. It is important to note that the SQL lang
does not allow for the insertion of data (rows) into more than one table per Insert statement.

The Insert Statement can take two forms. The first form allows for the insertion of a single row whose column
are specified in the VALUES clause. The second form allows for the insertion of multiple rows at once, the colum
values of which will originate from a Select statement.

INSERT INT O USER ( ID , FIRST NAME , LAST NAME ) VALUES ( 100 , 'JON' ,
'DOE' )

The previous sample shows a row with three columns being inserted into the User table. If we suppose that th
column will actually be an AutoNumber field/column we can dispense with its presence in our code and be conf
that it will receive the appropriate value automatically. ]

INSERT INT O USER ( FIRST NAME , LAST NAME ) VALUES ( 'JON' ,


'DOE' )

In case of inserting multiple rows at once, we need to use another syntax which allows us to specify through a
Select statement which values will be inserted. The following code snippet exemplifies this syntax by retrieving
rows from the SuperUser table that have the column FirstName starting with the letter A and inserting them int
User table.

INSERT INT O USER ( FIRST NAME , LAST NAME ) SELECT FIRST NAME ,
LAST NAME
FROM SUP ERUSER WHERE FIRST NAME ST ART ING WIT H 'A'

The Update Statement


The Update statement is used to change information already stored in the rows of a table. As with the Insert
Statement, the Update Statement cannot affect rows in more than one table at a time.

Though the Update statement can be used in the context of a cursor operation or of a search, in this chapter w
focus exclusively on the later as it is the only way which makes sense for usage from within a Morfik XApp.

UP DAT E USERCAT ALOG SET FIRST NAME = 'Mark' , LAST NAME = 'Harris' WHERE ID
= 5

This example shows a sample Update statement that sets two columns ( FIRSTNAME and LASTNAME ) of a row
the USERCATALOG table which has the ID column with the value of 5.

Update statements identify the rows which they will affect in the same manner as a Select statement identifies
rows it will return.

Page 663
The SET Clause
The SET clause allows the developer to specify a list of coma separated list of value assignments to columns a
shown in the following code snippet.

UP DAT E USERCAT ALOG SET FIRST NAME = 'Mark' , LAST NAME = 'Harris' , P WD =
'SECRET ' , EMAIL = 'mark.harris@companyname.com' WHERE ID = 5

Note that in this example four columns have their values set. Any columns which are not specified in an Update
statement will retain their original values.

The WHERE Clause


The WHERE clause of an Update statement works in exactly the same manner as that of the same clause of th
Select statement.

The previous examples of usage of the Update statement have all included the usage of the WHERE clause.

The Delete Statement


The Delete statement is the most simple of the four main SQL statements which are covered in this chapter. It
purpose is to remove rows from a table. As with the Insert and Update statements the Delete statement can h
an optional WHERE clause which, again, works exactly as the one in the Select Statement.

The following code snippet shows the usage of the Delete statement to remove all rows from the USERCATALO
table which have a value o zero in the ISACTIVE column.

DELET E FROM USERCAT ALOG WHERE ISACT IVE =


0

Note
Great care must be taken when working with both the Update and Delete statements as a missing
incorrectly formulated WHERE clause condition might end up affecting a large number of rows in the
table.

Wrapping it up
In this chapter we have reviewed the basics of the four most used statement of the SQL Language, in a Morfik
Application. There are innumerable other statements and clauses in the SQL language standard and in PSQL,
Firebird ’ s procedure and Trigger language. What was shown here should give developers the basic knowledg
start trying out new uses of these SQL statements.

See Also
 Morfik Database Programming
Database Modeling

 Visual Database Programming


 Database Connections

 Editing and Searching


 Using Stored Procedures

 System Objects in a Database

Page 664
category:Database

Page 665
System Objects in a
Database

Morfik AppsBuilder automatically creates several objects in a projects default


database which are used by the Workspace itself and by the Morfik Framework. If
you are experienced in using Firebird or other major relational databases you
might want to know what these objects are. It is exactly to satisfy this curiosity of
the experienced database professionals that this Appendix has been added to
this guide.

The database used as a sample to examine what objects are automatically


created by Morfik AppsBuilder, in this Appendix, is the MorfikCMS project
database.

Morfik System Fields


MFK$GUID
MFK$CTS
MFK$LMTS
Generators And
Triggers
Generators
Triggers
Indices
Tables
UDFs
Wrapping it up
See Also

Morfik System Fields


Every table that is created within a Morfik project ’ s default database has hidden system
fields which you, normally, do not see. To get a clear view of everything that exists in a
regular project database, we will use a Firebird Administration utility. This utility, called
IBExpert , has a Personal version which is freely available from the manufacturer ’ s website.
This version can be used by any developer looking to satisfy his/her curiosity about what
goes on inside a project ’ s database.
Table 1 presents the list of four system fields which are automatically created in each table
created within a Morfik project database.

All system fields should not be altered or written to by the developer. Their content is
automatically created and maintained by the Morfik Framework and manually altering it can
cause application misbehavior.

Table 1 – Morfik system fields


Field Type Size
MFK$GUID CHAR 36
MFK$CTS TIMESTAMP -
MFK$LMTS TIMESTAMP -

Each of these system fields has its own special uses and you can use access them directly,
once you know they are there.

Page 666
MFK$GUID
The MFK$GUID field is used in different moments when the Morfik Framework requires that
each record be uniquely identified, such as when handling the caching of blob fields.

This field is specifically required to be returned in any query which will retrieve a picture field
for binding with an Image control in a Morfik Form. This is due to the fact that the Morfik
Framework only retrieves blobs, such as images, when they are actually needed in order to
reduce network traffic and bandwidth consumption.

MFK$CTS
The MFK$CTS field is a timestamp which records the moment when the record was first
inserted into the table. You can consider this the "Creation TimeStamp".

MFK$LMTS
The MFK$LMTS field is updated every time the record is updated and thus is a timestamp
which records the moment when the record was last updated. You can consider this the "Last
Modified TimeStamp".

Note
Both the MFK$CTS and the MFK$LMTS system fields are updated through system
created triggers which are shown in greater detail in the topic Generators and
Triggers.

Generators And Triggers


Morfik AppsBuilder automatically creates and maintains generators and the triggers to handle
system and AutoNumber fields.

Generators
Each table which has an AutoNumber field will have a generator associated with it. Since
Firebird does not automatically associate a generator to a table, this is done implicitly through
the generator ’ s name. Morfik AppsBuilder also creates the necessary trigger code for
obtaining a value from the generator and assigning it to the corresponding field.

Page 667
Figure 1 - Database Objects

Note in the Treeview that can be seen in Figure 1, that our sample database has five tables,
five generators and ten triggers. Morfik AppsBuilder creates a generator which follows the
TableName_G1 naming convention for each table which has an AutoNumber field.

If a table has more than one AutoNumber field, Morfik AppsBuilder will create additional
generators following the naming pattern TableName_Gx where "x" is incremented for each
additional AutoNumber field.

The values of the AutoNumber fields are automatically updated through automatically
generated triggers as seen the next topic.

Triggers
Morfik AppsBuilder automatically creates two triggers for each table you create within a
project ’ s default database. Both triggers are always present, regardless of whether the
table has an AutoNumber field or not, since they are used to set values for the Morfik system
fields.

These triggers are created according to the following naming patterns: TableName_TBI for
"Before Insert" triggers and TableName_TBU for "Before Update" triggers. The following code
snippet contains the complete source for the creation of the _TBI (Before Insert) trigger for
the AccessLog table of the MorfikCMS sample project.

SET SQL DIALECT 3 ;

SET NAMES UNICODE_FSS ;

CREAT E GENERAT OR "AccessLog_G1" ;

SET T ERM ^ ;

CREAT E T RIGGER "AccessLog_T BI" FOR "AccessLog"


ACT IVE BEFORE INSERT P OSIT ION 0
AS
BEGIN
NEW . MFK$CT S = GetT ime ();
NEW . MFK$LMT S = GetT ime ();
IF (( NEW . MFK$GUID IS NULL ) OR ( NEW . MFK$GUID = 'GenerateGUID()' ))
T HEN
NEW . MFK$GUID = GenerateGUID ();
NEW . "Id" = GEN_ID ( "AccessLog_G1" , 1 );
END
^

SET T ERM ; ^

Notice that this trigger simply initiates the values of the Morfik system fields. If the table has
AutoNumber fields then the necessary code to obtain the required value from the associated
Generator will be added to the end of this trigger, as seen in this example.

The following code snippet contains the complete source for the creation of the _TBU (Before
Update) trigger for the AccessLog table of the MorfikCMS sample project

SET SQL DIALECT 3 ;

SET NAMES UNICODE_FSS ;

SET T ERM ^ ;

Page 668
CREAT E T RIGGER "AccessLog_T BU" FOR
"AccessLog"
ACT IVE BEFORE UP DAT E P OSIT ION 0
AS
BEGIN
NEW . MFK$LMT S = GetT ime ();
END
^

SET T ERM ; ^

Note that this trigger just updates the MFK$LMTS system field with the current time. This field
is thus always kept up to date with the time the record was last modified.

These are all the system triggers which are automatically created by Morfik AppsBuilder in a
project ’ s default database.

Note
Since Firebird allows for more than one trigger in each of the six positions (i.e.
Before Insert, After Insert, Before Update, After Update, Before Delete, After
Delete) the Firebird savvy user can add his/her own triggers without interference
with the system generated ones.

Indices
Morfik AppsBuilder automatically creates two indices for each table you create within a
project ’ s default database. The automatically created triggers follow the TableName_X1,
TableName_X2 naming convention.

The _X1 index is a unique ascending index on the MFK$GUID field, while the _X2 index is an
ascending index on the MFK$CTS field.

These are the only Morfik specific indices the used will find in a project ’ s default database.
Other indices will either be directly defined by the user, or implicitly defined through the
creation of relationships between tables and their corresponding constraints.

In examining a project ’ s default database you might find several indices with a RDB$ prefix in
their names. These are Firebird system indices which are created to support the Primary and
Foreign key definitions and constraints.

Tables
At this point a Morfik project database does not include any Morfik system tables. Morfik does
however use the Firebird table description for its own purposes, storing in it some data in XML
format.

The following is an example of what you might expect to find in the table description of a table
created by Morfik.

< ? xml version ="1.0" encoding ="windows-1252" ? >


< FBT ableExtensionBlock >
< mfk:section mfk:name ="$T EB_SUBT YP E">
< mfk:section mfk:name ="MFK$GUID"> 1 </ mfk:section >
< mfk:section mfk:name ="Id"> 1 </ mfk:section >
< mfk:section mfk:name ="Body"> 1 </ mfk:section >
< mfk:section mfk:name ="IsP ublished"> 1 </ mfk:section >
</ mfk:section >
< mfk:section mfk:name ="$T EB_DEFAULT VAL">
< mfk:section mfk:name ="MFK$GUID"> GenerateGUID() </ mfk:section
>
< mfk:section mfk:name ="IsP ublished"> 1 </ mfk:section >

Page 669
< mfk:section mfk:name ="SectionId"> 0 </ mfk:section >
< mfk:section mfk:name ="CreatedBy"> 0 </ mfk:section >
< mfk:section mfk:name ="ViewCount"> 0 </ mfk:section >
</ mfk:section >
< mfk:section mfk:name ="$T EB_GEN">
< mfk:section mfk:name ="MFK$GUID"> GUID:1:1 </ mfk:section >
< mfk:section mfk:name ="Id"> &lt;T ABLENAME&gt;_G1:1:1 </
mfk:section >
</ mfk:section >
< mfk:section mfk:name ="$T EB_P OSIT ION">
< mfk:section mfk:name ="Id"> 1 </ mfk:section >
< mfk:section mfk:name ="T itle"> 2 </ mfk:section >
< mfk:section mfk:name ="Summary"> 3 </ mfk:section >
< mfk:section mfk:name ="Body"> 4 </ mfk:section >
< mfk:section mfk:name ="DateCreated"> 5 </ mfk:section >
< mfk:section mfk:name ="DatePublished"> 6 </ mfk:section >
< mfk:section mfk:name ="IsP ublished"> 7 </ mfk:section >
< mfk:section mfk:name ="SectionId"> 8 </ mfk:section >
< mfk:section mfk:name ="CreatedBy"> 9 </ mfk:section >
< mfk:section mfk:name ="ViewCount"> 10 </ mfk:section >
</ mfk:section >
</ FBT ableExtensionBlock >

This XML snippet stores information used by the Morfik table designer. We will not go into the
specifics of the tags used in this snippet since their definition and usage are still subject to
change. It is strongly recommended that the user avoid making any changes to this
information directly.

UDFs
Morfik AppsBuilder makes a large portion of the functions available in the SystemUtilities
module available to the database through a large set of UDFs. The following is a list of the
functions in the mfkudf library.

ACOS ADDMONTH
ADDYEAR AGE
AND_ ASIN
ATAN BIGLRTRIM
BLOBASPCHAR BLOBBINCMP
BLOBLEFT BLOBLINE
BLOBMAXSEGMENTLENGTH BLOBMID
BLOBRIGHT BLOBSEGMENTCOUNT
BLOBSIZE CEIL
CHARS COPY
COS COTAN
CRLF DATEFORMAT
DATESERIAL DAYOFMONTH
DAYOFWEEK DAYOFYEAR
DIFFINDAYS DIFFINMONTHS
DIFFINWEEKS DIFFINYEARS
DIV_ DOLLARTODECIMALTEX
T
DOLLARVAL DOUBLEABS
EXP FACTORIAL
FINDWORD FIXEDPOINT
FLOOR FRAC
GBPARAM GDPARAM
GENERATEGUID GETDATE
GETHOUR GETMINUTE
GETMONTH GETQUARTER

Page 670
GETSECOND GETTIME
GETYEAR GFPARAM
GIPARAM GSPARAM
HEXADECTOINT IIF
INTEGERABS INTG
INTTOHEXADEC ISALPHA
ISDIGIT ISDIVISIBLEBY
ISLEAPYEAR ISLOWER
ISUPPER LEFTCHAR
LNXP1 LOG10
LOG2 LOGN
LONGDAYNAME LONGMONTHNAME
LOWCASE LRTRIM
LTRIM MAXDATE
MAXIMUM MID
MINDATE MINIMUM
MOD_ MONTHNAME
NOT_ ODD
ORD OR_
PADLEFT PADRIGHT
POS POWER
PROPERCASE RAND
REPLACESTRING RIGHTCHAR
ROUND ROUNDFLOAT
RTRIM SBPARAM
SDPARAM SFPARAM
SHL_ SHORTDAYNAME
SHORTMONTHNAME SHR_
SIGN SIN
SIPARAM SPACE
SQRT SSPARAM
STRBLOB STRINGLENGTH
STRIPSTRING STRIPTIME
SUBSTR TAN
TIMESERIAL TRUNCATE
UPCASE XOR_
XSASC XSATAN
XSCHR XSCOS
XSDATESERIAL XSDAY
XSDIV XSEXP
XSHEX XSHOUR
XSIIF XSINSTR
XSINT XSLCASE
XSLEFT XSLTRIM
XSMID XSMINUTE
XSMONTH XSNOW
XSREPLACE XSRIGHT
XSRND XSRTRIM
XSSECOND XSSGN
XSSIN XSSPACE
XSSQR XSTAN
XSTIME XSTIMESERIAL
XSTRIM XSYEAR

Wrapping it up
Morfik AppsBuilder hides away many of the details necessary, when using Firebird, to
accomplish simple things such as having self incrementing fields. In the backstage of a Morfik
XApp is a Firebird database and though Morfik usually hides most of the complexity of using
that database it does allow you to have full access to it. The MorfikCMS project, for example,

Page 671
makes use of three small stored procedures though there is not visible support for accessing
stored procedures in the Morfik AppsBuilder Workspace. This combination of initial ease of use
with full access to the underlying high octane engine of a full fledged relational database
server makes Morfik AppsBuilder a great tool for creating data driven Web applications.

See Also
 Morfik Database Programming
 Database Modeling

 Visual Database Programming


 Database Connections

 Editing and Searching


SQL Statements

 Using Stored Procedures


category:Database

Page 672
Most Frequently Used
Controls

Morfik AppsBuilder provides an extensive set of controls that you can use to build
the interface for your project. Some controls, however, are always present in
every project that is built with Morfik: TextLabel, TextEdit, Button and Image.

These controls form the basis of the interface of all websites and applications and
can be used in conjunction with other controls to achieve different and interesting
results.

Frequently used controls:


 Morfik Controls - TextLabel
 Morfik Controls - TextEdit

 Morfik Controls - Button


Morfik Controls - Image

For a full list of the controls in Morfik AppsBuilder please refer to Morfik Controls .

Page 673
Morfik Controls -
TextLabel

Figure 1 – A TextLabel control.

In Morfik AppsBuilder the TextLabel control is used to display all the text that
composes a page in a Morfik application/website. This control can automatically,
and intelligently, resize itself depending on the text it needs to display. This
characteristic allows the creation of complex and sophisticated views with very
little effort.

Usage
Data binding
Frequently used
Properties
Caption
Color
Font
DataField
IsHyperlink
Visible
Other Properties
Alignment
BorderColor
BorderStyle
BorderWidth
CanGrow
CanShrink
Cursor
Enabled
Format
Height
Hint
HorizontalPlacement
Left
LetterSpacing
Name
Opacity
TabOrder
Top
VerticalPlacement
WantReturns

Page 674
Width
WordWrap
Frequently used Events
OnClick
OnMouseOver
OnMouseOut
Other Events
OnAfterGrowOrShrink
OnAfterPrint
OnAfterPushedOrPulled

OnBeforeGrowOrShrink

OnBeforePrint

OnBeforePushedOrPulled
OnBlur
OnDoubleClick
OnFocus
OnMouseDown
OnMouseMove
OnMouseUp
OnPrintStyle
Sample Code
See also

Usage
The TextLabel control is used in just about every Morfik application. A good example of using
TextLabel controls in an application can be found in the ArticleSummaryList Form of the Simple
Blog sample application. This Form can be seen in figure 2.

Figure 2 – ArticleSummaryList Form of the Simple Blog sample application, showing five
TextLabel controls.

Page 675
To see this control in an application running live in Morfik Labs, click here . For a more detailed
description of how this application was built, please refer to Creating a Blog Application .

Data binding
The TextLabel control can be bound to a database table field in order to create
database-based applications and dynamic web sites. For more information in using the data
bound features of this control and Morfik in general please refer to Visual Database
Programming and Editing and Searching .

Frequently used Properties


The following is a list of the most commonly used properties of the TextLabel control with a
short description of their function.

Caption
Caption is the most frequently used property of a TextLabel control as it allows setting and
reading of the content (all the text) that is displayed by the control.

This property can be bound to a database table field as to automatically display its contents
and allow editing of them.

Color
The Color property is used to set the color in which the TextLabel will be drawn.

Font
The TextLabel's Font property (and its sub-properties Color and Name) is used to indicate
which font should be used for drawing the Caption.

DataField
The DataField property is used to bind the control to a database table field. Either through a
table or a query which is specified through the DataSource property.

IsHyperlink
The IsHyperlink property, when set to true, turns the Caption of the TextLabel into a
hyperlink. This is most often used when the TextLabel is bound to a hyperlink field.

Visible
The visible property is used to make TextLabel controls visible or invisible. Invisible TextLabel
controls are frequently used to allow for easy access to information from a database table
field, if the control is bound to one.

Other Properties
The following is a list of less-commonly used properties of the TextLabel control with a short
description of their function.

Alignment
The Alignment property is used to align the Caption text with the left, right, or center of the
TextLabel.

BorderColor
The BorderColor property specifies the color that should be used for drawing a rectangular
border around the TextLabel. Note: the border will not be visible unless the BorderStyle and
BorderWidth properties are also set.

BorderStyle

Page 676
The BorderStyle property specifies the line style that should be used for drawing a
rectangular border around the TextLabel. Note: the border will not be visible unless the
BorderColor and BorderWidth properties are also set.

BorderWidth
The BorderWidth property specifies the width of a rectangular border to be drawn around the
TextLabel. Note: the border will not be visible unless the BorderColor and BorderStyle
properties are also set.

CanGrow
The CanGrow property determines the behavior when the Caption text is too large to fit into
the TextLabel:
if CanGrow=No, the TextLabel
 retains its design-time height
if CanGrow=Scroll, the TextLabel retains its design-time height, but allows the end user to scroll
 through the text
if CanGrow=Yes, the TextLabel increases its height to
 accommodate the text

CanShrink
The CanShrink property determines the behavior when the Caption text is too small to
completely fill the TextLabel:
if CanShrink=False, the TextLabel maintains its
 design-time height
if CanShrink=True, the TextLabel decreases its height to accommodate the text Note: enabling
 CanShrink has no effect unless CanGrow is also enabled.

Cursor
The Cursor property, if set, causes the appearance of the mouse cursor to change as it moves
over the control.

Enabled
The Enabled property governs whether the TextLabel responds to user input. Note: setting
Enabled=False has no effect for TextLabels in the current release.

Format
The Format property may be used to control the formatting of numeric and date/time values in
databound TextLabels. Note: this property is only functional for continuous forms in the
current release.

Height
The Height property specifies the vertical extent of the TextLabel. Note: if the CanGrow or
CanShrink properties are set, the actual height of the TextLabel at run time may be different.

Hint
The Hint property, if set, specifies the text of a tooltip that is displayed when the end user
moves the mouse cursor over the TextLabel.

HorizontalPlacement
The HorizontalPlacement property, if set, governs how the TextLabel adjusts its size and
position in response to changes in the horizontal dimensions of its parent.

Left
The Left property specifies the horizontal position of the TextLabel.

LetterSpacing

Page 677
The LetterSpacing property, if set, specifies a little extra whitespace to insert between each
character in the Caption text.

Name
The Name property specifies the identifier used to reference the TextLabel from browser- or
server-side code.

Opacity
The Opacity property determines the extent to which the TextLabel obscures any controls
placed in its background. A value of 0 means that background controls are fully visible,
whereas a value of 100 means that background controls are completely obscured.

TabOrder
The TabOrder property has no effect for TextLabels.

Top
The Top property specifies the vertical position of the TextLabel.

VerticalPlacement
The VerticalPlacement property, if set, governs how the TextLabel adjusts its size and
position in response to changes in the vertical dimensions of its parent.

WantReturns
The WantReturns property has no effect for TextLabels.

Width
The Width property specifies the horizontal extent of the TextLabel.

WordWrap
The WordWrap property determines whether the Caption text wraps around to the following
line(s), if it is too long to fit on a single line.

Frequently used Events

OnClick
The most commonly used event for a TextLabel control is the OnClick event, which should be
handled to execute whatever action is intended when the Label is clicked. The most common
usage of clickable TextLabels is for creating hyperlink equivalent functionality.

The following is a sample event handler which opens a new Form into the main SubForm
control for the Simple Blog sample application.

P rocedure ArticleSummaryList . T extLabel1Click ( Event : T DOMEvent );


Begin
T extLabel5 . BandIndex := GetEventSource ( Event ). BandIndex ;
OpenForm ( 'ViewOneArticle' , 'BlogMain:MainArticleArea' , '"P aramId='
+ T extLabel5 . Caption + '"' );
window . scrollT o ( 0 , 0 );
End ;

OnMouseOver
The OnMouseOver event is frequently used in TextLabel controls to create the popular

Page 678
"hover" effect. This event is frequently used in conjunction with the OnMouseOut event.

The following code snippet shows how this event could be used to add a "hover" effect to a
TextLabel in the ArticleSummaryList Form of the Simple Blog application.

P rocedure
ArticleSummaryList . T extLabel4MouseOver ( Event : T DOMEvent );
Begin
T extLabel4 . BandIndex := GetEventSource ( Event ). BandIndex ;
T extLabel4 . FontColor :=# 4682 B4 ;
End ;

OnMouseOut
The OnMouseOut event is frequently used in TextLabel controls to create the popular "hover"
effect. This event is frequently used in conjunction with the OnMouseOver event.

The following code snippet shows how this event could be used to add a "hover" effect to a
TextLabel in the ArticleSummaryList Form of the Simple Blog application.

P rocedure
ArticleSummaryList . T extLabel4MouseOut ( Event : T DOMEvent );
Begin
T extLabel4 . BandIndex := GetEventSource ( Event ). BandIndex ;
T extLabel4 . FontColor :=# B8860B ;
End ;

Other Events

OnAfterGrowOrShrink
The OnAfterGrowOrShrink event occurs after the TextLabel's height has changed in response
to a grow-and-shrink event.

OnAfterPrint
The OnAfterPrint event occurs after the TextLabel is rendered into the form's HTML code.

OnAfterPushedOrPulled
The OnAfterPushedOrPulled event occurs after the TextLabel's position has changed in
response to a grow-and-shrink event.

OnBeforeGrowOrShrink
The OnBeforeGrowOrShrink event occurs before the TextLabel's height changes in response
to a grow-and-shrink event.

OnBeforePrint
The OnBeforePrint event occurs before the TextLabel is rendered into the form's HTML code.

OnBeforePushedOrPulled
The OnBeforePushedOrPulled event occurs before the TextLabel's position changes in
response to a grow-and-shrink event.

OnBlur

Page 679
The OnBlur event does not occur for TextLabels.

OnDoubleClick
The OnDoubleClick event occurs when the user double-clicks on the TextLabel.

OnFocus
The OnFocus event does not occur for TextLabels.

OnMouseDown
The OnMouseDown event occurs when the user depresses the left mouse button while the
cursor is over the TextLabel.

OnMouseMove
The OnMouseMove event occurs when the user moves the mouse while the cursor is over the
TextLabel.

OnMouseUp
The OnMouseUp event occurs when the user releases the left mouse button while the cursor
is over the TextLabel.

OnPrintStyle
The OnPrintStyle event occurs before the TextLabel's style attribute is rendered into the
form's HTML code.

Sample Code
TextLabels are not frequently referenced in code. Most of the time when it is referenced,
however, is to change its "Enabled" status, in response to an application defined condition.

The following code snippet sets a TextLabel's Enabled property to True. A TextLabel which is
disabled cannot be clicked on by the user.

Label1 . Enabled := true


;

See also
 Morfik Controls
 Most Frequently Used Controls

 Control Effects

Page 680
Morfik Controls - TextEdit

Figure 1 – A TextEdit control.

In Morfik AppsBuilder the TextEdit control is used every time the user must input
information which is not chosen from a predetermined list. This control can be
used for entering both short and long texts as well as for entering passwords
without displaying them on screen.

Usage
Data binding
Frequently used
Properties
DataField
IsPassword
Text
Other Properties
BorderColor
BorderStyle
BorderWidth
Color
Cursor
Enabled
Font
Format
Height
Hint
HorizontalPlacement
Left
MultiLine
Name
Opacity
Padding
ReadOnly
SelectOnFocus
TabOrder
Top
VerticalPlacement
Visible
Width
WordWrap
Frequently used Events

Page 681
Other Events
OnAfterPrint
OnAfterPushedOrPulled

OnBeforePrint

OnBeforePushedOrPulled
OnBlur
OnChange
OnClick
OnDoubleClick
OnFocus
OnKeyDown
OnKeyUp
OnMouseDown
OnMouseOut
OnMouseOver
OnMouseUp
OnPrintStyle
Morfik Effects
Sample Code
See also

Usage
The TextEdit control is used in just about every Morfik application. A good example of using
the TextEdit control in an application can be found in the user sign in Form of the MorfikCMS
sample application. This Form can be seen in figure 2. In this Form the TextEdit control is used
in its mode usual short text input mode as well as in its password input mode.

Page 682
Figure 2 – UserSignIn Form of the MorfikCMS sample application, showing two TextEdit
controls.

For a more detailed description of how this application was built, please refer to Working with
Database Connections which explains in greater detail how this specific Form was designed.

Data binding
The TextEdit control can be bound to a database table field in order to create
database-based applications and dynamic web sites. Most uses of TextEdit controls in Morfik
are in data bound situations since this allows for automatic data entry, editing and even
searching. For more information in using the data bound features of this control and Morfik in
general please refer to Visual Database Programming and Editing and Searching .

Frequently used Properties


The following is a list of the most commonly used properties of the TextEdit control with a
short description of their function.

DataField
The DataField property is used to bind the control to a database table field. Either through a
table or a query which is specified through the DataSource property.

IsPassword
The IsPassword property, when set to true, will cause the TextEdit control to display asterisks
on the screen in place of the actual characters which are input by the user. As the name
suggests this property should be used whenever the TextEdit control will be used for entering
a password.

Text
The Text property for the TextEdit control allows direct access for setting or reading the text
that is currently in the control.
This property can be bound to a database table field as to automatically display its contents
and allow editing of them.

Other Properties
The following is a list of the less commonly used properties of the TextEdit control with a short

Page 683
description of their function.

BorderColor
The BorderColor property specifies the color that should be used for drawing a rectangular
border around the TextEdit.

BorderStyle
The BorderStyle property specifies the line style that should be used for drawing a
rectangular border around the TextEdit.

BorderWidth
The BorderWidth property specifies the line width that should be used for drawing a
rectangular border around the TextEdit.

Color
The Color property is used to specify the color in which the TextEdit will be drawn.

Cursor
The Cursor property, if set, causes the appearance of the cursor to change as it moves over
the TextEdit.

Enabled
If the Enabled property is set to false, the user may not edit or select the Text in the TextEdit
control.

Font
The TextEdit's Font property (and its sub-properties Color and Name) is used to indicate
which font should be used for drawing the Text.

Format
The Format property may be used to control the formatting of numeric and date/time values in
databound TextEdits. Note: this property is only functional for continuous forms in the current
release.

Height
The Height property specifies the vertical extent of the TextEdit.

Hint
The Hint property, if set, specifies the text of a tooltip that is displayed when the user moves
the cursor over the TextEdit.

HorizontalPlacement
The HorizontalPlacement property, if set, governs how the TextEdit adjusts its size and
position in response to changes in the horizontal dimensions of its parent.

Left
The Left property specifies the horizontal position of the TextEdit.

MultiLine
If the MultiLine property is enabled, and the Text contains line breaks, it will be displayed over
multiple lines; otherwise, the Text is displayed on a single line. Note: if automatic wrapping of
the Text is desired, the WordWrap property must also be enabled.

Page 684
Name
The Name property specifies the identifier used to reference the TextEdit from browser- or
server-side code.

Opacity
The Opacity property determines the extent to which the TextEdit obscures any controls
placed in its background. A value of 0 means that background controls are fully visible,
whereas a value of 100 means that background controls are completely obscured.

Padding

ReadOnly
If the ReadOnly property is enabled, the user is able to select, but not modify, the content of
the TextEdit.

SelectOnFocus

TabOrder
The TabOrder property allows the developer to specify the order in which controls should
receive input focus when the user steps through them using the tab key.

Top
The Top property specifies the vertical position of the TextEdit.

VerticalPlacement
The VerticalPlacement property, if set, governs how the TextEdit adjusts its size and position
in response to changes in the vertical dimensions of its parent.

Visible
The Visible property is used to make TextEdit controls visible or invisible to the end user.

Width
The Width property specifies the horizontal extent of the TextEdit.

WordWrap
The WordWrap property determines whether text wraps around to the following line(s), if it is
too long to fit on a single line.

Frequently used Events


There are no events of special relevance to the TextEdit control.

Other Events

OnAfterPrint
The OnAfterPrint event occurs after the TextEdit is rendered into the form's HTML code.

OnAfterPushedOrPulled
The OnAfterPushedOrPulled event occurs after the TextEdit's position has changed in
response to a grow-and-shrink event.

OnBeforePrint

Page 685
The OnBeforePrint event occurs before the TextEdit is rendered into the form's HTML code.

OnBeforePushedOrPulled
The OnBeforePushedOrPulled event occurs before the TextEdit's position changes in response
to a grow-and-shrink event.

OnBlur
The OnBlur event occurs when the TextEdit loses keyboard focus.

OnChange
The OnChange event indicates that the text in the TextEdit was changed by the user. Note:
this event does not occur until the TextEdit loses keyboard focus.

OnClick
The OnClick event occurs when the user clicks on the TextEdit.

OnDoubleClick
The OnDoubleClick event occurs when the user double-clicks on the TextEdit.

OnFocus
The OnFocus event occurs when the TextEdit receives keyboard focus.

OnKeyDown
The OnKeyDown event occurs when the user depresses a key while the TextEdit has focus.

OnKeyUp
The OnKeyUp event occurs when the user releases a key while the TextEdit has focus.

OnMouseDown
The OnMouseDown event occurs when the user depresses the left mouse button while the
cursor is over the TextEdit.

OnMouseOut
The OnMouseOut event occurs when the mouse cursor moves out of the TextEdit.

OnMouseOver
The OnMouseOver event occurs when the mouse cursor moves into the TextEdit.

OnMouseUp
The OnMouseUp event occurs when the user releases the left mouse button while the cursor
is over the TextEdit.

OnPrintStyle
The OnPrintStyle event occurs before the TextEdit's style attribute is rendered into the form's
HTML code.

Morfik Effects
TextEdit controls can have a series of special effects applied to them, in order to customize
their appearance. More detailed information on what effects are available and what can be
achieved with them can be found under the Control Effects topic.

In Figure 3 you can see several TextEdit controls with different Morfik Effects applied to them.

Page 686
Figure 3 - TextEdit controls using formatted using different effects.

Sample Code
TextLabels are not frequently referenced in code. Most of the time when it is referenced,
however, is either to change or read the value of its Text property.

The following code snippet sets a TextEdit's Text property to a string with a specific value.

T extEdit1 . T ext :=
'First name' ;

See also
 Morfik Controls
 Most Frequently Used Controls

 Control Effects

Page 687
Morfik Controls -
Image

Figure 1 – An Image control displaying a picture,


with a reflection effect.

In Morfik AppsBuilder the Image control is used in places a graphic element should
be inserted into the application's interface. These images, usually, are simply for
visual effect, such as displaying logos or pictures or used to indicate a clickable
area. In this later case the Image control functions much like the Button control
while on the first one it more closely resembles the simple functionality of a
TextLabel control.

Usage
Data binding
Frequently used
Properties
BorderStyle
BorderColor
BorderWidth
DataField
Picture
Stretch
StretchMode
Other Properties
Color
Cursor
Enabled
Height
Hint
HorizontalPlacement
Left
Name

Page 688
Opacity
TabOrder
Top
VerticalPlacement
Visible
Width
Frequently used Events
OnClick
Other Events
OnAfterPrint
OnAfterPushedOrPulled

OnBeforePrint

OnBeforePushedOrPulled
OnBlur
OnDoubleClick
OnFocus
OnMouseDown
OnMouseOut
OnMouseOver
OnMouseUp
OnPrintStyle
OnUpdate
Morfik Effects
Sample Code
See also

Usage
The Image control is used in most Morfik applications. A good example of using the Image control
in an application can be found in the user sign in Form of the MorfikCMS application. This Form can
be seen in figure 2. In this case the Image control is used for decorative purposes only.

Page 689
Figure 2 – UserSignIn Form of the MorfikCMS sample application, showing an Image control which
is displaying an decorative Key icon.

For a more detailed description of how this application was built, please refer to Working with
Database Connections which explains in greater detail how this specific Form was designed.

Data binding
The Image control can be bound to a database table field in order to create database-based
applications and dynamic web sites. For more information in using the data bound features of
Morfik, in general, please refer to Visual Database Programming and Editing and Searching .

Frequently used Properties


The following is a list of the most commonly used properties of the Image control with a short
description of their function.

BorderStyle
The BorderStyle property of the Image control defines how and if a border will be drawn around
the control. The available style options are: 3D , Flat and None . The 3D style gives the Image a
light 3 dimensional effect. The Flat option gives the Image control a solid, thin, line as a border.

BorderColor
The BorderColor property can be used to set the color in which an outline will be drawn around the
control. As Image controls, by default, have the BorderStyle property set to a Flat border, this
property is a very important part of defining "the look" of the control.

BorderWidth
The BorderWidth property defines the thickness of the border which will drawn around the control.

DataField
The DataField property is used to bind the control to a database table field. Either through a table
or a query which is specified through the DataSource property.

Picture
The Picture property holds the name or full url for the actual image to be displayed inside the

Page 690
control. If the content of property is only a file name, the image is presumed to be included in the
project's repository.

Stretch
The Stretch property defines if the Picture should be stretched (or shrank) to fit the controls
dimensions.

StretchMode
The StretchMode property is used in conjunction with the Stretch property do specify how the
picture should be stretched inside the Image control. The available options are: FitX , FitXY and
FitY which determine in which axis the image will be stretched or if in both.

Other Properties
The following is a list of the less commonly used properties of the Image control with a short
description of their function.

Color

Cursor
The Cursor property, if set, causes the appearance of the cursor to change as it moves over the
Image.

Enabled
The Enabled property has no effect for Image controls.

Height
The Height property specifies the vertical extent of the Image control.

Hint
The Hint property, if set, specifies the text of a tooltip that is displayed when the user moves the
cursor over the Image.

HorizontalPlacement
The HorizontalPlacement property, if set, governs how the Image control adjusts its size and
position in response to changes in the horizontal dimensions of its parent.

Left
The Left property specifies the horizontal position of the Image control.

Name
The Name property specifies the identifier used to reference the Image control from browser- or
server-side code.

Opacity
The Opacity property determines the extent to which the Image obscures any controls placed in
its background. A value of 0 means that background controls are fully visible, whereas a value of
100 means that background controls are completely obscured.

TabOrder
The TabOrder property has no effect for Image controls.

Top

Page 691
The Top property specifies the vertical position of the Image control.

VerticalPlacement
The VerticalPlacement property, if set, governs how the Image control adjusts its size and position
in response to changes in the vertical dimensions of its parent.

Visible
The Visible property is used to make Image controls visible or invisible to the end user.

Width
The Width property specifies the horizontal extent of the Image control.

Frequently used Events

OnClick
The most commonly used event for an Image control is the OnClick event, which should be
handled to execute whatever action is intended when the image is clicked.

The following is a sample event handler which calls a separate procedure to take some action
when a specific Image is clicked.

P rocedure
HomeForm . LogoImageClick ( Event : T DOMEvent );
Begin
NavigateHome ;
End ;

Other Events

OnAfterPrint
The OnAfterPrint event occurs after the Image control is rendered into the form's HTML code.

OnAfterPushedOrPulled
The OnAfterPushedOrPulled event occurs after the Image control's position has changed in
response to a grow-and-shrink event.

OnBeforePrint
The OnBeforePrint event occurs before the Image control is rendered into the form's HTML code.

OnBeforePushedOrPulled
The OnBeforePushedOrPulled event occurs before the Image control's position changes in
response to a grow-and-shrink event.

OnBlur
The OnBlur event does not occur for Image controls.

OnDoubleClick
The OnDoubleClick event occurs when the user double-clicks on the Image control.

OnFocus

Page 692
OnMouseDown
The OnMouseDown event occurs when the user depresses the left mouse button while the cursor
is over the Image control.

OnMouseOut
The OnMouseOut event occurs when the mouse cursor moves out of the Image control.

OnMouseOver
The OnMouseOver event occurs when the mouse cursor moves into the Image control.

OnMouseUp
The OnMouseUp event occurs when the user releases the left mouse button while the cursor is
over the Image control.

OnPrintStyle
The OnPrintStyle event occurs before the Image control's style attribute is rendered into the
form's HTML code.

OnUpdate
The OnUpdate event occurs when the Image control's picture has finished loading in the browser.

Morfik Effects
You can apply a wide range of visual effects to an image control in order to achieve the desired
effect. Morfik Workspace will combine the effects and any picture you have loaded into the control
into a new image. This allows you to achieve great looking effects such as faded or raised
borders.

The when applied to the image control, some effects such as the Gradient will display extra or
more powerful options.

Figure 3 – The same image in its original state and with some effects applied to it.

In Figure 3 you can see two image controls. The first one has absolutely no changes to the
original picture while the second had the Gradient , Corners , and Reflection effects applied. For a
complete listing of the effects which are available in Morfik and to which controls they apply,
please refer to the Control Effects topic.

Sample Code
The Image control is not frequently referenced in code. Most of the time when it is referenced,
however, it is to change the picture property (and therefore the image being displayed), or to

Page 693
handle its click event.

The following code snippet sets an Image control's Picture property to a new value.

Image1 . Picture :=
'icon.jpg' ;

See also
 Morfik Controls
 Most Frequently Used Controls

 Control Effects
 Managing Resources

Page 694
Morfik Controls -
CheckBox

Figure 1 – A CheckBox control.

In Morfik AppsBuilder the CheckBox control is frequently used when the user must
input information which can only be one of two options: Yes/No.

Usage
Data binding
Frequently used
Properties
Caption
Checked
DataField
Other Properties
BorderColor
BorderStyle
BorderWidth
CanGrow
CanShrink
Color
Cursor
Enabled
Font
Height
Hint
HorizontalPlacement
Left
Name
Opacity
TabOrder
Top
VerticalPlacement
Visible
Width
Events
OnAfterPrint
OnAfterPushedOrPulled

OnBeforePrint

Page 695
OnBeforePushedOrPulled
OnBlur
OnClick
OnDoubleClick
OnFocus
OnKeyDown
OnKeyUp
OnMouseDown
OnMouseOut
OnMouseOver
OnMouseUp
OnPrintStyle
Sample Code
See also

Usage
CheckBoxes can be used to offer just two choices of value for the user to select. Essentially it
is a control for choosing between Yes and No values. In Figure 2 you can see an CheckBox
control with the text "IsPublished". This control can toggle a Yes/No field in an underlying
database table, if data bound.

Figure 2 – EditSections Form of the MorfikCMS sample application, showing a ComboBox


control.

For a more detailed description of how this application was built, please refer to The
EditSections Form which explains in greater detail how this specific Form was designed.

Data binding
The CheckBox control can be bound to a database table field in order to create
database-based applications and dynamic websites. This is frequently the case in which this

Page 696
control is used as the data bound features of Morfik make it extremely easy to create dynamic
websites and applications.

Once the Form in which the control is placed has been assigned a data source, it is a simple
matter to bind the CheckBox control by choosing one of the data source's fields in the drop
down options of the "DataField" property.

For more information in using the data bound features of Morfik, in general, please refer to
Visual Database Programming and Editing and Searching .

Frequently used Properties

Caption
The Caption property specifies the string that should be displayed in the Checkbox.

Checked
The Checked property specifies whether the Checkbox should be displayed in the ticked or
un-ticked state. Note: if the Checkbox is databound then its state will depend on the values
in its DataField instead.

DataField
The DataField property is used to bind the control to a database table field. Either through a
table or a query which is specified through the DataSource property of the Form that contains
the control.

Other Properties

BorderColor
The BorderColor property specifies the color of the rectangular border drawn around the
Checkbox. Note: the border will not be visible unless the BorderStyle property is also set.

BorderStyle
The BorderStyle property of the Checkbox control defines how and if a border will be drawn
around the control. The available style options are: 3D, Flat and None. The 3D style gives the
Checkbox a light 3D effect. The Flat option gives the Checkbox a solid, thin, line as a border.

BorderWidth
The BorderWidth property specifies the line width used to draw the rectangular border
around the Checkbox. Note: the border will not be visible unless the BorderStyle property is
also set.

CanGrow
The CanGrow property determines the behavior when the Caption text is too large to fit into
the CheckBox:
if CanGrow=No, the CheckBox
 retains its design-time height
if CanGrow=Scroll, the CheckBox retains its design-time height, but allows the end user to scroll
 through the text
if CanGrow=Yes, the CheckBox increases its height to
 accommodate the text

CanShrink
The CanShrink property determines the behavior when the Caption text is too small to
completely fill the CheckBox:
if CanShrink=False, the CheckBox maintains its
 design-time height
if CanShrink=True, the CheckBox decreases its height to accommodate the text Note: enabling
 CanShrink has no effect unless CanGrow is also enabled.

Page 697
Color
The Color property is used to set the color in which the CheckBox will be drawn.

Cursor
The Cursor property, if set, causes the appearance of the mouse cursor to change as it moves
over the control.

Enabled
If the Enabled property is set to false, the CheckBox's state (ticked or unticked) cannot be
changed by the user.

Font
The Font property, and its sub-properties Color and Name, specify the font to be used for
displaying the CheckBox's Caption.

Height
The Height property specifies the vertical extent of the Checkbox.

Hint
The Hint property, if set, specifies the text of a tooltip that is displayed when the user moves
the cursor over the CheckBox.

HorizontalPlacement
The HorizontalPlacement property, if set, governs how the CheckBox adjusts its size and
position in response to changes in the horizontal dimensions of its parent.

Left
The Left property specifies the horizontal position of the CheckBox.

Name
The Name property specifies the identifier used to reference the CheckBox from browser- or
server-side code.

Opacity
The Opacity property determines the extent to which the CheckBox obscures any controls
placed in its background. A value of 0 means that background controls are fully visible,
whereas a value of 100 means that background controls are completely obscured.

TabOrder
The TabOrder property allows the developer to specify the order in which controls should
receive input focus when the user steps through them using the tab key.

Top
The Top property specifies the vertical position of the CheckBox.

VerticalPlacement
The VerticalPlacement property, if set, governs how the CheckBox adjusts its size and
position in response to changes in the vertical dimensions of its parent.

Visible
The Visible property is used to make CheckBox controls visible or invisible to the end user.

Page 698
Width
The Width property specifies the horizontal extent of the CheckBox.

Events

OnAfterPrint
The OnAfterPrint event occurs after the CheckBox is rendered into the form's HTML code.

OnAfterPushedOrPulled
The OnAfterPushedOrPulled event occurs after the CheckBox's position has changed in
response to a grow-and-shrink event.

OnBeforePrint
The OnBeforePrint event occurs before the CheckBox is rendered into the form's HTML code.

OnBeforePushedOrPulled
The OnBeforePushedOrPulled event occurs before the CheckBox's position changes in
response to a grow-and-shrink event.

OnBlur
The OnBlur event occurs when the CheckBox loses keyboard focus.

OnClick
The OnClick event occurs when the user clicks on the CheckBox.

OnDoubleClick
The OnDoubleClick event occurs when the user double-clicks on the CheckBox.

OnFocus
The OnFocus event occurs when the CheckBox receives keyboard focus.

OnKeyDown
The OnKeyDown event occurs when the user depresses a key while the CheckBox has focus.

OnKeyUp
The OnKeyUp event occurs when the user releases a key while the CheckBox has focus.

OnMouseDown
The OnMouseDown event occurs when the user depresses the left mouse button while the
cursor is over the CheckBox.

OnMouseOut
The OnMouseOut event occurs when the mouse cursor moves out of the CheckBox.

OnMouseOver
The OnMouseOver event occurs when the mouse cursor moves into the CheckBox.

OnMouseUp
The OnMouseUp event occurs when the user releases the left mouse button while the cursor
is over the CheckBox.

Page 699
OnPrintStyle
The OnPrintStyle event occurs before the CheckBox's style attribute is rendered into the
form's HTML code.

Sample Code
CheckBox controls are not frequently referenced in code.

The following code snippet reads the selected value of a CheckBox control.

If CheckBox1 . Checked = true


then
...

It is also possible to toggle the state of a CheckBox control through code. The following
snippet shows how to accomplish this.

...
CheckBox1 . Checked := not
CheckBox1 . Checked ;
...

See also
 Morfik Controls
 Control Effects

Page 700
The EditSections Form

This topic will provide you with a general overview of how to maintain data in your
application/website. Up to this point we have seen how to create the
end-user/visitor ’ s point of view. Now we are going to have a look at how to add
and edit the data that drives this application. This topic describes functionalities
which are not available in Morfik Browser Application projects. It is important to
note that the features described in this topic depend on portions of server-side
code from the Morfik Framework, and are thus not available in Morfik Browser
Application projects.

Managing Content
The Data Editing Forms
The EditSections Form
Choosing Control Type in the
Wizard
The EditSections Data Source
The EditArticles Form
The EditArticles Data Source
The EditUsers Form
The EditSiteInformation Form
The EditSiteInformation Data
Source
Adding Search Capabilities to a Form
Editing Data Without a NavigationBar
Filtering Data from a Table
The EditOneArticle Form
Wrapping it up
See Also

Managing Content
In our current example, MorfikCMS, we have made some effort to make sure that the end-user/visitor
’ s view of the content looked like a normal website, despite Morfik ’ s employment of Ajax
everywhere. In this part of this guide maintaining this "normal" website look will not be goal, instead
we are going to address this task directly, using as much of the Morfik Framework ’ s built in
functionality as possible.

Another topic in this documentation has already covered the user authentication process for the
MorfikCMS project. This process is fundamental in making sure that unauthorized users cannot alter
your website ’ s content, so all that we are going to see in this topic lies behind the authentication
barrier of our application. That means that only after the users sign-in will they be allowed to see the
link which will take them into the site management section of the application.

Figure 1 highlights the Site Management link which appears in the site ’ s footer once the user has
been authenticated. This link takes the user into what might seem to be an entirely different website
from the portions which are publicly accessible. The general layout remains the same since, in fact,
we are only changing which two Forms are displayed in the two SubForms of the Index Form.

Once the user chooses to enter Site Management the displayed content in the LeftArea SubForm
changes to the AdminSideBar Form and in the MainArea SubForm it changes to the EditSections Form.

Page 701
Figure 1 – The "Site Management" link in the application ’ s Footer.

The AdminSideBar Form which handles navigation within the Site Management portion of the
MorfikCMS project is actually a quite simplified version of the SideBar Form we are using in the public
section of the application. AdminSideBar is a fully static Form, with no database binding of its own.
Though it looks quite similar to the SideBar Form it employs common buttons instead of the TextLabel
+ Container scheme used in the SideBar Form, since this portion of the website is more focused on
being practical than in design.

Figure 2 shows the AdminSideBar Form. Notice that the color scheme is a bit different from the one
used in the SideBar Form due to the different nature of the controls used.

Page 702
Figure 2 – The AdminSideBar Form in design mode in Morfik Workspace.

On entering Site Management the EditSections Form is displayed in the MainArea SubForm is displayed
in the MainArea Form because "Sections" is the first option to appear in the list of the AdminSideBar
Form as seen in Figure 2. In this case it is obviously better to display that view than it would have
been to maintain the original content which would have been displayed in MainArea since this way it
is very clear that the user has entered the Management portion of the application. Figure 3 shows
the initial view of the "Site Management" portion of the application.

Figure 3 – Initial view of the Site Management portion of the MorfikCMS project.

Page 703
The Data Editing Forms
The MorfikCMS project will have 4 data editing Forms within its "Site Management" area: EditSections ,
EditArticles , EditUsers and EditSiteInformation . All these Forms are automatically generated through
the "Create New Form" Wizard and then lightly customized to achieve the effect we desire.

We will go through the customization done to the EditSection Form, in more detail, to explain what
was done and to what effect. The remaining Forms went through exactly the same customization
steps, except for the EditSiteInformation Form which requires a slightly different approach due to the
unique situation of handling a table which should always have a single record.

The EditSections Form


As previously mentioned the EditSections Form was automatically generated through the use of the
"Create New Form" Wizard and then slightly customized. The more obvious customization which is
the Title and images in the Header band is totally cosmetic and has no effect on the usage of the
Form, except to make clear to the user what the data which is currently being edited is.

The next customization much more important since it allows us to introduce a Morfik Framework
feature which is quite useful in creating data entering and editing forms: the data lookup capabilities
of ComboBox control.

Figure 4 shows the EditSections Form in design mode in the Morfik AppsBuilder Workspace. Notice
that the last control in the Form is a ComboBox, right besides a TextLabel control which reads "Parent
Section".

Figure 4 – the EditSections Form in design mode in the Morfik Workspace.

Choosing Control Type in the Wizard


When running the "Create New Form" Wizard you can select which types of controls will be created
for each of the table fields to which you have selected to bind your Form.

Page 704
Figure 5 – Option to automatically add controls the Form being created.

Once you choose to automatically add controls to the Form you can use the "Customize" button to
specify which controls will be used for each field. This option will bring up the dialog box which is
shown in Figure 6.

Figure 6 – Changing the type of a control through the popup menu.

In the picture shown in Figure 6 you can see the control selection for the Id field of the Section table.
Since Id is an AutoNumber field and thus automatically handled by the database it was decided that it
should be displayed in a TextLabel control so that the user cannot alter its value.

As can be seen in Figure 6 the default control suggestion for The ParentID field is a TextLabel which,
though usable, does not meet with our requirements for usability since it requires that the user have
previously looked up the value of the Id Field of another Section. This control type should then be
changed to being a ComboBox.

Once the Form is created by the Wizard, the ComboBox control is not yet ready to be effectively used.
The ComboBox ’ s lookup data binding properties must be set in order for it to work effectively.

Page 705
Figure 7 – Configuring the Lookup Data properties of the ComboBox bound to the ParentId field of
the Section table.

Immediately after the creation of the Form by the wizard only the DataField property is set, to bind
the control to the underlying field in the database. We need then to manually reconfigure the
LookupDataSource to choose where the data lookup data will come from, the LookupDataField which is
the information we want to copy onto our bound DataField and LookupTextField which is the field
whose values we want to display in the ComboBox for the user to choose from.

In this specific case we want to display the titles of the sections and once the user has chosen one,
store the value of its Id field in the current records ParentId field so we ’ ve configured these
properties as shown in table 1.

Table 1 – Data related properties for the ComboBox


Property Value
DataField ParentId
LookupDataField Id
LookupDataSource Section
LookupMaxRecords 50
LookupTextField Title

Note that in Table 1 we list the value of a property that was not previously mentioned:
LookupMaxRecords . This property controls the maximum number of records which will be fetched from
the database to populate the dropdown list of the ComboBox. In this case: 50 records.

Since these are topic groups, 50 might be a sufficiently large quantity. If you feel you might have
websites with a larger number of sections than this value should be appropriately adjusted to reflect
your needs.

In Figure 8 you can see the EditSection Form at runtime in the Morfik Debug Browser.

Page 706
Figure 8 – The EditSection Form at runtime in the Morfik Debug Browser.

The ComboBox control for editing the ParentId field can be seen with its dropdown list visible in the
screenshot that is shown in Figure 8. As can be seen from this example the ComboBox control can be
extremely useful in editing fields which relate one table to another. We make extensive use of this
feature in all the data editing Forms in the MorfikCMS project.

The EditSections Data Source


The EditSections Form is directly bound to the Section table allowing access to all the records in the
table. This is a simple and immediate approach which is easily implemented through the use of the
AppsBuilder "Create New Form" wizard.

The EditArticles Form


Since we have discussed all the specific detail on how to customize the automatically generated
Forms in our discussion of the EditSections Form, we will just quickly mention what customizations
were done to the EditArticles Form.

Figure 9 shows the EditArticles Form in design mode in the Morfik AppsBuilder Workspace. The
"Create New Form" Wizard automatically suggests the appropriate controls for the date fields and
once we have configured, as we did for the EditSections form, will generate ComboBoxes for the
SectionId (indicated by the "Section" TextLabel)and CreatedBy Fields.

Page 707
Figure 9 – EditArticles Form in design mode in the Morfik Workspace.

Once the Form is created it the Lookup data properties of the two ComboBox controls need to be set
as to bring up information from the Section table, exactly as done in the EditSections Form and to
bring up data from the UserCatalog table where the FullName field will be used in the LookupTextField
property so that the users ’ full names are displayed in the corresponding dropdown list.

The EditArticles Data Source


Analogous to the EditSections Form, the EditArticles Form is directly bound to the Article table allowing
access to all the records in the table. This is a simple and immediate approach which is easily
implemented through the use of the AppsBuilder "Create New Form" wizard.

The EditUsers Form


The EditUsers Form is very simple in nature since the table on which it is based is, also, a simple one.
Only one special customization, apart from adding the Title and accompanying images to the Header
band of the Form is required which is to configure one of the TextEdit controls for password display.
In this case, the control will only display small circles in place of actual characters when the user
types in a password.

This ensures that a person with access the site management area of the website can change a user ’
s password but cannot read the previously registered one.

Figure 10 shows the EditUsers Form in design mode in the Morfik AppsBuilder Workspace and Figure
11 shows the same Form at runtime in the Morfik Debug Browser.

Page 708
Figure 10 – The EditUsers Form in design mode in the Morfik Workspace.

In order to configure the TextEdit which is bound to the Password field to mask its content all that is
needed is to check the IsPassword property in the Property Window.

Page 709
Figure 11 – The EditUsers Form at runtime in the Morfik Debug Browser.

Note in Figure 11 that the Password field is displaying placeholders instead of the actual characters
from the field ’ s contents.

The EditSiteInformation Form


The EditSiteInformation Form is a special case within our content maintenance Forms because it is
bound to a table which always contains a single record.

In this Form, since there is always only one record, there is really no reason to have an Id Field
visible so after the Wizard created the Form that TextLabel was made invisible. You can see the
EditSiteInformation form in design mode in the Morfik AppsBuilder Workspace in Figure 12.

Figure 12 – The EditSiteInformation Form in design mode in the Morfik Workspace.

Note that since this Form should not be able to add new records to the underlying table the
NavigatorBar in the Footer Band has been configured to show only the Refresh, Submit and Edit
buttons.

Page 710
Figure 13 – The EditSiteInformation Form at runtime in Internet Explorer.

The EditSiteInformation Data Source


Analogous to the EditSections Form, the EditArticles Form and the EditUsers Form, the
EditSiteInformation Form is directly bound to the WebsiteInfo table allowing access to all the records in
the table. This is a simple and immediate approach which is easily implemented through the use of
the AppsBuilder "Create New Form" wizard. The fact that the WebsiteInfo table has a single record
does not require any specific action to make the EditSiteInformation Form work perfectly. The only
customization necessary is, as previously discussed, a configuration of the NavigationBar so that it
does not display any buttons which are not necessary.

Adding Search Capabilities to a Form


Morfik AppsBuilder and the Morfik Framework offer us several ways to work with database searches
in almost transparent ways. Every time we use a stored query as a data source for our Forms we are
using the databases intrinsic search features. These features allow us the end-user/visitor to
websites managed by our MorfikCMS project to drill down through the site ’ s content down to the
single article level.
Now we are going to see a very simple, and totally codeless, way of adding simple search and
filtering capabilities to our application. In order to do this we are going to go back to the EditArticles
Form and add a new button to its NavigationBar : the menu button.

This little button is all we need to add to the Form in order to add search and filtering capabilities to
it. When the menu button is clicked it displays a small popup menu with three options: Filter by Form,

Page 711
Apply Filter and Remove Filter.

Figure 14 – The Search/Filter menu in the NavigatorBar of the EditArticles Form.

In Figure 14 the Filtering menu is highlighted in red. Clicking on the "Filter by Form" option the
contents of all fields are cleared and the user can type whatever they want to search for, in the
corresponding TextEdit.

Figure 15 shows a user entering data for filtering in the TextBox bound to the Title field of the Article
table. Once the filtering criteria have been typed in all that is necessary is to click on the "Apply Filter"
option of the menu button.

Page 712
Figure 15 – The EditArticles Form in "Filter by Form" mode.

Note that once the "Apply Filter" option is selected the Form displays only the records which match
the criteria. Observe in the highlighted portion of Figure 16 that the NavigationBar indicates record 1
of 1.

Page 713
Figure 16 – The EditArticles Form with a filter set for articles with the word "PHP" in the title.

This is because with the filtering activated the Form sees only the one record in the table which does
have the word "PHP" in its Title field. This feature allows the developer to quickly add filtering and
basic searching into an application without actually writing a single line of code.

In the MorfikCMS sample project, considering the data load that each of the tables will probably have
in an average website, only the Article table seems to be a candidate for a search feature as it is the
only table which should have a large number of records.

Editing Data Without a NavigationBar


Up to this point, in this chapter, we have seen how to edit information without writing any code,
through the use of a NavigationBar. We will now take a quick look at how to edit some of the content
of the website, one record at a time.

Filtering Data from a Table


When we are just displaying data, we can work with all variations of Queries to get exactly the data
we want. When we are going to alter the data we must work with a table, however. In order to limit
the data which is going to be presented to the user to a specific record we must use a filter. In this
case this is done through the use of a single line of code, instead of through the visual interface of
the NavigationBar ’ s Menu button.

Using a filter is actually quite simple and follows closely what we have been doing with the queries.
In this case, however, we must manually create the parameter in the Form in which we will filter the

Page 714
data.

The EditOneArticle Form


In our current sample application we will be filtering the data presented by the EditOneArticle Form. As
just mentioned in this case we must manually declare the appropriate parameter and then write the
necessary code in the OnReady event, which is triggered when the form completes loading in the
Browser. Figure 17 shows the parameter list for the EditOneArticle Form with the added parameter at
the end.

Figure 17 – Parameter list of the EditOneArticle Form.

The following code snippet contains the entire event handler for the OnReady event of the
EditOneArticle Form, which is quite simple: one single line of code.

P rocedure EditOneArticle . WebFormReady ( Var


Ready : Boolean );
Begin
ChangeFilter ( '"Id"=' + P aramId );
End ;

This single line event handler forces the filtering of the records from the Form ’ s data source as
described in the filter expression. In this case the data source for the Form is the Article table.

Figure 18 shows the EditOneArticle Form open as popup for editing the record corresponding to a
specific article. Note how everything outside the EditOneArticle is now dimmed. Everything outside the
Form cannot be directly accessed thus simulating the behavior of a modal dialog in Windows.

Page 715
Figure 18 – The EditOneArticle Form as a popup.

In the EditOneArticle Form as we are always dealing with a single record, instead of using a
NavigationBar, which can display update controls, two normal buttons were used to confirm or cancel
the changes. The following code snippet contains the event handler for the SubmitBtn button which
confirms the edit of the data and sends the modified data back to the server.

P rocedure
EditOneArticle . SubmitBtnClick ( Event : T DOMEvent );
Begin
UpdateRecord ( Event );
SubmitP age ( Event );
OpenForm ( 'ViewOneArticle' , 'Index:MainArea' ,
'"P aramId='
+ Control_Id . Caption + '", "openmode=refresh"' );
Close ;
End ;

The following code snippet is the entirety of the event handler for the CancelBtn button which cancels
any changes made to the record currently being edited.

Page 716
P rocedure
EditOneArticle . CancelBtnClick ( Event : T DOMEvent );
Begin
CancelRecordChanges ( Event );
Close ;
End ;

Both of these even handlers close the Form. The event handler for the SubmitBtn button commands
the re-opening of the ViewOneArticle Form showing the article currently being edited, forcing its
refresh since the data will have been modified.

Wrapping it up
In this chapter we have seen that providing the end-user/visitor to your website with simple data
entry and editing functionality, as well as searching and filtering capabilities can be achieved with
minimal coding.

The Morfik AppsBuilder Workspace and the Morfik Framework provide a solid base on which to build
data management applications which are intrinsically simple.

See Also
 Morfik Database Programming
 Database Modeling

 Visual Database Programming


 Database Connections
SQL
 Statements
 Using Stored Procedures

 System Objects in a Database


 Working with Forms
category:Database

Page 717
Morfik Controls -
ComboBox

Figure 1 – A ComboBox control.

In Morfik AppsBuilder the ComboBox control is frequently used when the user
must input information which is chosen from a predetermined list.

Usage
Data binding
Lookup ComboBoxes
Frequently used
Properties
DataField
Items
LookupDataSource
LookupDataField
LookupTextField
LookupMaxRecords
Other Properties
AutoComplete
AutoDropDown
AutoFilter
BorderColor
BorderStyle
BorderWidth
Color
Cursor
EditorPadding
Enabled
Font
Height
Hint
HorizontalPlacement
ItemIndex
Left
Name
Opacity
Sorted

Page 718
Style
TabOrder
Text
Top
VerticalPlacement
Visible
Width
Events
OnAfterPrint
OnAfterPushedOrPulled

OnBeforePrint

OnBeforePushedOrPulled
OnBlur
OnChange
OnClick
OnDoubleClick
OnFocus
OnKeyDown
OnKeyUp
OnMouseDown
OnMouseOut
OnMouseOver
OnMouseUp
OnPrintStyle
Sample Code
See also

Usage
The ComboBox control is used in most Morfik applications. ComboBoxes can be used to offer a
fixed set of choices to the user or it can be bound to database table field for looking up the
information (choices) it should display.

Good examples of using ComboBox controls in an application can be found in the site
administration Forms of the MorfikCMS application. One of these Forms can be seen in figure
2. In this Form the ComboBox control is used in its data bound and lookup modes, which
means that the control will lookup choices from one table or query and then save the
selection in to the field it is bound to.

Page 719
Figure 2 – EditSections Form of the MorfikCMS sample application, showing a ComboBox
control.

For a more detailed description of how this application was built, please refer to The
EditSections Form which explains in greater detail how this specific Form was designed.

Data binding
The ComboBox control can be bound to a database table field in order to create
database-based applications and dynamic websites. This is frequently the case in which this
control is used as the data bound features of Morfik make it extremely easy to create dynamic
websites and applications. For more information in using the data bound features of Morfik, in
general, please refer to Visual Database Programming and Editing and Searching .

Lookup ComboBoxes
One special kind of a usage of the ComboBox control is the Lookup ComboBox. A Lookup
ComboBox is control which is bound to a database table field and at the same time has a
reference to another database table field (generally in another table). This second database
table field is called the Lookup source and is identified by several properties as described
bellow.

Frequently used Properties


The following is a list of the most commonly used properties of the ComboBox control with a
short description of their function.

DataField
The DataField property is used to bind the control to a database table field. Either through a
table or a query which is specified through the DataSource property.

Items
The Items property of the ComboBox contains a list of strings with the values which will be
displayed in the drop down list, if the choices will be a fixed.

LookupDataSource
The LookupDataSource property identifies the data source (table or query) from which the
ComboBox will retrieve its reference and display information.

Page 720
LookupDataField
The LookupDataField property identifies which field from the LookupDataSource the
ComboBox will retrieve its reference data.

LookupTextField
The LookupTextField property identifies which field from the LookupDataSource the ComboBox
will retrieve its display data.

LookupMaxRecords
The LookupMaxRecords property of the ComboBox defines how many records will be fetched
from the LookupDataSource.

Other Properties
The following is a list of the less commonly used properties of the ComboBox control with a
short description of their function.

AutoComplete

AutoDropDown

AutoFilter

BorderColor
The BorderColor property specifies the color of the rectangular border drawn around the
ComboBox.

BorderStyle
The BorderStyle property of the ComboBox control defines how and if a border will be drawn
around the control. The available style options are: 3D, Flat and None. The 3D style gives the
ComboBox a light 3D effect. The Flat option gives the ComboBox a solid, thin, line as a
border.

BorderWidth
The BorderWidth property specifies the line width used to draw the rectangular border
around the ComboBox.

Color
The Color property is used to set the color in which the ComboBox will be drawn.

Cursor
The Cursor property, if set, causes the appearance of the mouse cursor to change as it moves
over the ComboBox.

EditorPadding

Enabled
If the Enabled property is set to false, the user will not be able to change the value stored in
the ComboBox. Note: this is not working in the current release.

Font
The Font property specifies the font used to display the text in the ComboBox.

Height

Page 721
The Height property specifies the vertical extent of the ComboBox.

Hint
The Hint property, if set, specifies the text of a tooltip that is displayed when the user moves
the cursor over the ComboBox.

HorizontalPlacement
The HorizontalPlacement property, if set, governs how the ComboBox adjusts its size and
position in response to changes in the horizontal dimensions of its parent.

ItemIndex

Left
The Left property specifies the horizontal position of the ComboBox.

Name
The Name property specifies the identifier used to reference the ComboBox from browser- or
server-side code.

Opacity
The Opacity property determines the extent to which the ComboBox obscures any controls
placed in its background. A value of 0 means that background controls are fully visible,
whereas a value of 100 means that background controls are completely obscured.

Sorted

Style

TabOrder
The TabOrder property allows the developer to specify the order in which controls should
receive input focus when the user steps through them using the tab key.

Text

Top
The Top property specifies the vertical position of the ComboBox.

VerticalPlacement
The VerticalPlacement property, if set, governs how the ComboBox adjusts its size and
position in response to changes in the vertical dimensions of its parent.

Visible
The Visible property is used to make ComboBox controls visible or invisible to the end user.

Width
The Width property specifies the horizontal extent of the ComboBox.

Events

OnAfterPrint
The OnAfterPrint event occurs after the ComboBox is rendered into the form's HTML code.

OnAfterPushedOrPulled

Page 722
The OnAfterPushedOrPulled event occurs after the ComboBox's position has changed in
response to a grow-and-shrink event.

OnBeforePrint
The OnBeforePrint event occurs before the ComboBox is rendered into the form's HTML code.

OnBeforePushedOrPulled
The OnBeforePushedOrPulled event occurs before the ComboBox's position changes in
response to a grow-and-shrink event.

OnBlur
The OnBlur event occurs when the ComboBox loses keyboard focus.

OnChange
The OnChange event indicates that the selected value in the ComboBox was changed by the
user.

OnClick
The OnClick event occurs when the user clicks on the ComboBox.

OnDoubleClick
The OnDoubleClick event occurs when the user double-clicks on the ComboBox.

OnFocus
The OnFocus event occurs when the ComboBox receives keyboard focus.

OnKeyDown
The OnKeyDown event occurs when the user depresses a key while the ComboBox has
focus.

OnKeyUp
The OnKeyUp event occurs when the user releases a key while the ComboBox has focus.

OnMouseDown
The OnMouseDown event occurs when the user depresses the left mouse button while the
cursor is over the ComboBox.

OnMouseOut
The OnMouseOut event occurs when the mouse cursor moves out of the ComboBox.

OnMouseOver
The OnMouseOver event occurs when the mouse cursor moves into the ComboBox.

OnMouseUp
The OnMouseUp event occurs when the user releases the left mouse button while the cursor
is over the ComboBox.

OnPrintStyle
The OnPrintStyle event occurs before the ComboBox's style attribute is rendered into the
form's HTML code.

Page 723
Sample Code
ComboBox controls are not frequently referenced in code.

The following code snippet reads the selected value of a ComboBox control.

If ComboBox1 . Value = 'Green'


then
...

See also
 Morfik Controls
 Control Effects

Page 724
Morfik Controls -
Container

Figure 1 – A Container control with several controls inside.

In Morfik AppsBuilder the Container control is used mainly for aggregating other
visual controls.

Usage
Frequently used
Properties
BorderStyle
BorderColor
BorderWidth
Color
Other Properties
BackgndImage
CanGrow
CanShrink
Cursor
Enabled
Font
Height
Hint
HorizontalPlacement
Left
Name
Opacity
ShrinkOnHide
TabOrder
Top
VerticalPlacement
Visible
Width

Page 725
Events
OnAfterGrowOrShrink
OnAfterPrint
OnAfterPushedOrPulled

OnBeforeGrowOrShrink

OnBeforePrint

OnBeforePushedOrPulled
OnBlur
OnClick
OnDoubleClick
OnFocus
OnMouseDown
OnMouseOut
OnMouseOver
OnMouseUp
OnPrintStyle
Morfik Effects
Sample Code
See also

Usage
The Container control is generally used in Morfik applications to aggregate several controls
into a single package that can be moved together in a Form while keeping the relative
position of individual controls. The container also visually represents the logical grouping of
controls when your application is run withing the browser.

Frequently used Properties


The following is a list of the most commonly used properties of the Container control with a
short description of their function.

BorderStyle
The BorderStyle property of the Container control defines how and if a border will be drawn
around the control. The available style options are: Dashed , Dotted , InSet , None , OutSet and
Single . The InSet and OutSet styles give the Rectangle a light 3D effect. The Single option
gives the Container a solid line as a border.

BorderColor
The BorderColor property can be used to set the color in which an outline will be drawn around
the control. As Image and Rectangle controls, by default, have the BorderStyle property set to
a Flat border, this property is a very important part of defining "the look" of the control.

BorderWidth
The BorderWidth property defines the thickness of the border which will drawn around the
control.

Page 726
Color
The color property defines how the Container's interior will be painted on the page.

Other Properties
The following is a list of the less commonly used properties of the Container control with a
short description of their function.

BackgndImage
The BackgndImage property may be used to specify a picture to be displayed by the
Container.

CanGrow
The CanGrow property determines what happens when the Container's contents are larger
than the Container itself:
if CanGrow=No, the Container
 retains its design-time height
if CanGrow=Scroll, the Container retains its design-time height, but allows the user to scroll
 through its contents
if CanGrow=Yes, the Container increases its height to
 accommodate its contents

CanShrink
The CanShrink property determines the behavior when the Container's contents are smaller
than the Container itself:
if CanShrink=False, the Container maintains its
 design-time height
if CanShrink=True, the Container decreases its height to accommodate its contents Note:
 enabling CanShrink has no effect unless CanGrow is also enabled.

Cursor
This property is non-functional for Containers in the current release.

Enabled
This property is non-functional for Containers in the current release.

Font
This property is non-functional for Containers in the current release.

Height
The Height property specifies the vertical extent of the Container. Note: if the CanGrow or
CanShrink properties are set, the actual height of the Container at run time may be different.

Hint
The Hint property, if set, specifies the text of a tooltip that is displayed when the end user
moves the cursor over the Container.

HorizontalPlacement
The HorizontalPlacement property, if set, governs how the Container adjusts its size and
position in response to changes in the horizontal dimensions of its parent.

Left
The Left property specifies the horizontal position of the Container.

Page 727
Name
The Name property specifies the identifier used to reference the Container from browser- or
server-side code.

Opacity
The Opacity property determines the extent to which the Container obscures any controls
placed in its background. A value of 0 means that background controls are fully visible,
whereas a value of 100 means that background controls are completely obscured.

ShrinkOnHide

TabOrder
The TabOrder property has no effect for Containers.

Top
The Top property specifies the vertical position of the Container.

VerticalPlacement
The VerticalPlacement property, if set, governs how the Container adjusts its size and
position in response to changes in the vertical dimensions of its parent.

Visible
The visible property is used to make Container controls visible or invisible.

Width
The Width property specifies the horizontal extent of the Container.

Events

OnAfterGrowOrShrink
The OnAfterGrowOrShrink event occurs after the Container's height changes in response to a
grow-and-shrink event.

OnAfterPrint
The OnAfterPrint event occurs after the Container is rendered into the form's HTML code.

OnAfterPushedOrPulled
The OnAfterPushedOrPulled event occurs after the Container's position has changed in
response to a grow-and-shrink event.

OnBeforeGrowOrShrink
The OnBeforeGrowOrShrink event occurs before the Container's height changes in response
to a grow-and-shrink event.

OnBeforePrint
The OnBeforePrint event occurs before the Container is rendered into the form's HTML code.

OnBeforePushedOrPulled
The OnBeforePushedOrPulled event occurs before the Container's position changes in
response to a grow-and-shrink event.

Page 728
OnBlur
The OnBlur event occurs when the Container loses keyboard focus.

OnClick
The OnClick event occurs when the user clicks on the Container.

OnDoubleClick
The OnDoubleClick event occurs when the user double-clicks on the Container.

OnFocus
The OnFocus event occurs when the Container receives keyboard focus.

OnMouseDown
The OnMouseDown event occurs when the user depresses the left mouse button while the
cursor is over the Container.

OnMouseOut
The OnMouseOut event occurs when the mouse cursor moves out of the Container.

OnMouseOver
The OnMouseOver event occurs when the mouse cursor moves into the Container.

OnMouseUp
The OnMouseUp event occurs when the user releases the left mouse button while the cursor
is over the Container.

OnPrintStyle
The OnPrintStyle event occurs before the Container's style attribute is rendered into the
form's HTML code.

Morfik Effects
You can apply almost any of the Morfik Effects to a container. This allows for great flexibility
in getting you containers to look just like you want them to look.

Page 729
Figure 2 – A Container control with a group of controls for creating a Sign In page, with
several effects applied to it.

It is important to realize that when Morfik Effects are applied to certain controls, special
images are dynamically created by the Morfik compiler. Because these images are created at
compile time, changing some of the properties of a container at runtime, might not yield the
results you expect.

Sample Code
Usually there is no particular reason to refer to a Container control through code. Most of the
control's purpose is fulfilled at design time by aggregating controls for placement on a Form or
by its visual appearance and logical aggregation of controls at runtime.

In some situations you might want to make a Container invisible as that will make all the
controls it contains become invisible as well. The following code snippet is an example of this:

Containter1 . Visible := fals


e;

See also
 Morfik Controls
 Most Frequently Used Controls

 Control Effects

Page 730
Morfik Controls -
DateTimeEdit

Figure 1 – DateTimeEdit control.

In Morfik AppsBuilder the DateTimeEdit control is used in places where the user
needs to enter a date and/or time value.

Frequently used
Properties
DataField
Format
Mode
Other Properties
BorderColor
BorderStyle
BorderWidth
Color
Cursor
EditorPadding
Enabled
Font
Height
Hint
HorizontalPlacement
Left
Name
Opacity
Top
VerticalPlacement
Visible
Width
Events

Page 731
OnAfterPrint
OnAfterPushedOrPulled

OnBeforePrint

OnBeforePushedOrPulled
OnBlur
OnChange
OnClick
OnDoubleClick
OnFocus
OnKeyDown
OnKeyUp
OnMouseDown
OnMouseMove
OnMouseOut
OnMouseOver
OnMouseUp
OnPrintStyle
See Also

Frequently used Properties


The following is a list of the most commonly used properties of the DateTimeEdit control with a
short description of their function.

DataField
The DataField property is used to bind the DateTimeEdit control to a database field. Either
through a table or a query which is specified through the DataSource property of the Form
that contains the control.

Format
The Format property specifies the style in which the DateTimeEdit displays its value. There are
four choices:
 Long (e.g. Wednesday, 29 Jul 2008)
 Medium (e.g. 29 Jul 2008)

 Short DDMMYYYY (e.g. 29/7/2008)


 Short MMDDYYYY (e.g. 7/29/2008)

Mode
The Mode property specifies the type of value to be entered. There are three choices:
 Date
 Time

 TimeStamp

Other Properties
The following is a list of the less commonly used properties of the DateTimeEdit control with a
short description of their function.

Page 732
BorderColor
The BorderColor property specifies the color of the rectangular border drawn around the
DateTimeEdit control.

BorderStyle
The BorderStyle property of the DateTimeEdit defines how and if a border will be drawn
around the control. The available style options are: 3D, Flat and None. The 3D style gives the
DateTimeEdit control a light 3D effect. The Flat option gives the DateTimeEdit a solid, thin, line
as a border.

BorderWidth
The BorderWidth property specifies the line width used to draw the rectangular border
around the DateTimeEdit control.

Color
The Color property is used to set the color in which the DateTimeEdit control will be drawn.

Cursor
The Cursor property, if set, causes the appearance of the cursor to change as it moves over
the DateTimeEdit control.

EditorPadding

Enabled
If the Enabled property is set to false, the DateTimeEdit control's value cannot be changed by
the user. Note: this is not working in the current release.

Font
The Font property, and its sub-properties Color and Name, specifies the font to be used for
displaying the date/time value.

Height
The Height property specifies the vertical extent of the DateTimeEdit control.

Hint
The Hint property, if set, specifies the text of a tooltip that is displayed when the user moves
the cursor over the DateTimeEdit control.

HorizontalPlacement
The HorizontalPlacement property, if set, governs how the DateTimeEdit control adjusts its
size and position in response to changes in the horizontal dimensions of its parent.

Left
The Left property specifies the horizontal position of the DateTimeEdit control.

Name
The Name property specifies the identifier used to reference the DateTimeEdit control from
browser- or server-side code.

Opacity
The Opacity property determines the extent to which the DateTimeEdit control obscures any
controls placed in its background. A value of 0 means that background controls are fully

Page 733
visible, whereas a value of 100 means that background controls are completely obscured.

Top
The Top property specifies the vertical position of the DateTimeEdit control.

VerticalPlacement
The VerticalPlacement property, if set, governs how the DateTimeEdit control adjusts its size
and position in response to changes in the vertical dimensions of its parent.

Visible
The Visible property is used to make DateTimeEdit controls visible or invisible to the end user.

Width
The Width property specifies the horizontal extent of the DateTimeEdit control.

Events

OnAfterPrint
The OnAfterPrint event occurs after the DateTimeEdit control is rendered into the form's HTML
code.

OnAfterPushedOrPulled
The OnAfterPushedOrPulled event occurs after the DateTimeEdit control's position has
changed in response to a grow-and-shrink event.

OnBeforePrint
The OnBeforePrint event occurs before the DateTimeEdit control is rendered into the form's
HTML code.

OnBeforePushedOrPulled
The OnBeforePushedOrPulled event occurs before the DateTimeEdit control's position changes
in response to a grow-and-shrink event.

OnBlur
The OnBlur event occurs when the DateTimeEdit control loses keyboard focus.

OnChange
The OnChange event indicates that the value in the DateTimeEdit control was changed by the
user.

OnClick
The OnClick event occurs when the user clicks on the DateTimeEdit control.

OnDoubleClick
The OnDoubleClick event occurs when the user double-clicks on the DateTimeEdit control.

OnFocus
The OnFocus event occurs when the DateTimeEdit control receives keyboard focus.

OnKeyDown
The OnKeyDown event occurs when the user depresses a key while the DateTimeEdit control

Page 734
has focus.

OnKeyUp
The OnKeyUp event occurs when the user releases a key while the DateTimeEdit control has
focus.

OnMouseDown
The OnMouseDown event occurs when the user depresses the left mouse button while the
cursor is over the DateTimeEdit control.

OnMouseMove

OnMouseOut
The OnMouseOut event occurs when the mouse cursor moves out of the DateTimeEdit
control.

OnMouseOver
The OnMouseOver event occurs when the mouse cursor moves into the DateTimeEdit control.

OnMouseUp
The OnMouseUp event occurs when the user releases the left mouse button while the cursor
is over the DateTimeEdit control.

OnPrintStyle
The OnPrintStyle event occurs before the DateTimeEdit control's style attribute is rendered
into the form's HTML code.

See Also
 Morfik Controls
 Most Frequently Used Controls

 Control Effects

Page 735
Morfik Controls -
FileUploader

Figure 1 – A FileUploader control.

In Morfik AppsBuilder the FileUploader control is used, as its name suggests, to


upload one or more files to the server.

Usage
Frequently used
Properties
DataField
MaxFileSize
Other Properties
BorderColor
BorderStyle
BorderWidth
Color
Cursor
Font
Height
Hint
Left
Name
Opacity
Top
Width
Events
OnFileQueued
OnFileUploadComplete

Sample Code
See also

Note

Page 736
This control relies on special support code in the server side components of
the Morfik Framework. Because of this dependency, this control is not
currently available in Morfik Browser Application projects.

Usage
FileUploader controls can be used to upload files to the server from within your web-based
application. There are many uses for this such as sharing documents or backing up information
from the user's local computer. The FileUploader control works integrated with Morfik's database
access infrastructure so that uploaded files are either "registered" or stored in a database table.

By "registered" we mean that there is a record in a table, with information about the file and a
pointer for its recovery from the server's file system.

Figure 2 – The frmUpload Form from the MorfikDemo sample, with a FileUploader control.

If you want to see this control in use, please refer to the MorfikDemo sample program that is
distributed with Morfik AppsBuilder R2.

Frequently used Properties

DataField
The DataField property allows you to set which field in the data source that has been selected for
the Form that contains the control.

MaxFileSize
The MaxFileSize property imposes a limit on the size of the individual files which will be uploaded.

Page 737
Other Properties
The following is a list of the less commonly used properties of the FileUploader control with a
short description of their function.

BorderColor
The BorderColor property specifies the color to be used to draw the rectangular border around
the FileUploader control.

BorderStyle
The BorderStyle property of the FileUploader control defines how and if a border will be drawn
around the control. The available style options are: 3D, Flat and None. The 3D style gives the
FileUploader a light 3D effect. The Flat option gives the FileUploader a solid, thin, line as a
border.

BorderWidth
The BorderWidth property specifies the line width used to draw the FileUploader control's
outline.

Color
The Color property specifies the color to be used to draw the FileUploader control.

Cursor
The Cursor property, if set, causes the appearance of the cursor to change as it moves over the
FileUploader control.

Font
The Font property, and its sub-properties Color and Name, specifies the font to be used for
displaying text in the FileUploader control.

Height
The Height property specifies the vertical extent of the FileUploader control.

Hint
The Hint property, if set, specifies the text of a tooltip that is displayed when the user moves the
cursor over the FileUploader control. Note: this property is non-functional in the current release.

Left
The Left property specifies the horizontal position of the FileUploader.

Name
The Name property specifies the identifier used to reference the FileUploader from browser- or
server-side code.

Opacity
The Opacity property determines the extent to which the FileUploader obscures any controls
placed in its background. A value of 0 means that background controls are fully visible, whereas a
value of 100 means that background controls are completely obscured.

Top
The Top property specifies the vertical position of the FileUploader control.

Width

Page 738
The Width property specifies the horizontal extent of the FileUploader control.

Events

OnFileQueued

OnFileUploadComplete

Sample Code
Usually there is no need to write code to use the FileUploader control as it is a simple matter of
configuring the properties mentioned in the above section. All the rest is handled by the control
itself.

See also
 Morfik Controls

Page 739
Morfik Controls - Flash

The Flash control allows you to display Macromedia Flash files in a Form . It can
either show a unbound (static) flash file or it can be databound to a table which
contains a datafield that is a Multimedia data type.

Placing a Flash control on the Canvas


To place a Flash control on the Canvas ;
Select the Flash icon from the Toolbox and then
either: single-click where you would like the top
left-hand corner of the Flash icon to be on the
 canvas; or
click-and-drag the mouse from where you want the top left-hand corner of the Image to the
 bottom right-hand corner.
The first method produces a Flash control which is exactly 105 pixels high and 105 pixels
wide. In the case of the second method, the width and height of the Flash control will then be
based on the size of the rectangle that you drew.

Displaying databound images.


To display databound images;
Ensure that the Form or Report is bound to a
1 Table or Query .
2 Link the Flash control to a particular datafield that must be of data type "Multimedia".
To display unbound (static) images:
1 Select the Flash control
2 From the Property sheet either select the "All" tabsheet

3 Select the property "Source" and click on the small three dots
If the name of the Flash file is shown then simply click on it. Otherwise, select Browser and
4 locate the desired image.

5 Click OK.
An important, and possibly unique, aspect of Morfik AppsBuilder is that once you have located
an multimedia file and placed it in an Image or Flash control , a copy of it is internally stored
in one the Morfik AppsBuilder files. From then on, you do not ever have to worry about
whether you refer to this file in an absolute manner or relative manner. You simply select the
file from the menu and Morfik AppsBuilder does the rest for you! You may of course, organize
your static files into a system of folders on your hard drive, but as soon as you have imported
them into Morfik AppsBuilder you do not need to worry about path names at all! Note

Frequently used Properties


The following is a list of the most commonly used properties of the Flash control with a short
description of their function.

DataField
The DataField property is used to specify the field in the Form's DataSource that contains the
.swf file. Note: if the .swf file is coming from a static file, leave DataField blank and set the
Source property instead.

Source
The Source property is used to specify the static file that contains the .swf file. Note: if the
.swf file is coming from a database, leave Source blank and set the DataField property
instead.

Page 740
Other Properties
The following is a list of the less commonly used properties of the Flash control with a short
description of their function.

ClassID

CodeBase
The CodeBase property specifies a URI for automatic download of the Flash player if the web
browser does not have it installed. It is not usually necessary to modify this property.

Color
The Color property has no effect for Flash controls.

Cursor
The Cursor property has no effect for Flash controls.

Enabled
The Enabled property has no effect for Flash controls.

FlashVars
The FlashVars property may be used to pass variables to the Flash player. It is not usually
necessary to modify this property.

FullMenu
The FullMenu property specifies whether to display a complete context menu, or an
abbreviated context menu (with only the Settings and About Flash commands), when the user
right-clicks on the Flash control.

Height
The Height property specifies the vertical extent of the Flash control.

Hint
The Hint property has no effect for Flash controls.

HorizontalPlacement
The HorizontalPlacement property, if set, governs how the Flash control adjusts its size and
position in response to changes in the horizontal dimensions of its parent.

Left
The Left property specifies the horizontal position of the Flash control.

LiveConnect
The LiveConnect property specifies whether Javascript will have access to and from the Flash
player. It is not usually necessary to modify this property.

Loop
The Loop property specifies whether the video should stop when it reaches the end, or keep
playing in an endless loop.

Mode
The Mode property controls how the Flash Player appears in the browser. There are three

Page 741
possible values:
fwWindow: the video is rendered
in a separate window,
 superimposed on the web page.
fwOpaque: the video is rendered directly onto the web page; any controls behind the Flash
 control are obscured.
fwTransparent: the video is rendered directly onto the web
page; any controls behind the Flash control are visible through
the transparent portions of the video. Note: this may impair
 performance.

Name
The Name property specifies the identifier used to reference the Flash control from browser-
or server-side code.

Opacity
The Opacity property determines the extent to which the Flash control obscures any controls
placed in its background. A value of 0 means that background controls are fully visible,
whereas a value of 100 means that background controls are completely obscured.

PlayOnLoad
The PlayOnLoad property specifies whether the video should begin playing as soon as it
finishes downloading.

PlugInPage
The PlugInPage property specifies a URI for manual download of the Flash player if the web
browser does not have it installed. It is not usually necessary to modify this property.

Quality
The Quality property allows the developer to optimize the video for playback speed at the
expense of playback quality, or vice versa.
fmBest: performs anti-aliasing
 and bitmap smoothing
 fmHigh: performs anti-aliasing and some bitmap smoothing
fmMedium:
performs some
 anti-aliasing
 fmAutoHigh: performs anti-aliasing initially, but disables it if performance is unacceptable
fmAutoLow: performs no anti-aliasing initially, but enables it if performance is
 acceptable
fmLow: performs no anti-aliasing or bitmap
 smoothing

Scale
The Scale property specifies how the video fits into the available area of the Flash control:
 fsShowAll: original aspect ratio is maintained; borders may appear on two sides.
fsNoBorder: original aspect ratio is maintained; some cropping
 may occur.
fsExactFit: video fills entire area;
original aspect ratio may be
 distored.

Top
The Top property specifies the vertical position of the Flash control.

VerticalPlacement
The VerticalPlacement property, if set, governs how the Flash control adjusts its size and
position in response to changes in the vertical dimensions of its parent.

Page 742
Visible
The Visible property is used to make Flash controls visible or invisible to the end user.

Width
The Width property specifies the horizontal extent of the Flash control.

Events

OnAfterPrint
The OnAfterPrint event occurs after the Flash control is rendered into the form's HTML code.

OnAfterPushedOrPulled
The OnAfterPushedOrPulled event occurs after the Flash control's position has changed in
response to a grow-and-shrink event.

OnBeforePrint
The OnBeforePrint event occurs before the Flash control is rendered into the form's HTML
code.

OnBeforePushedOrPulled
The OnBeforePushedOrPulled event occurs before the Flash control's position changes in
response to a grow-and-shrink event.

OnBlur
The OnBlur event occurs when the Flash control loses keyboard focus.

OnClick
The OnClick event occurs when the user clicks on the Flash control.

OnDoubleClick
The OnDoubleClick event occurs when the user double-clicks on the Flash control.

OnFocus
The OnBlur event occurs when the Flash control receives keyboard focus.

OnMouseDown
The OnMouseDown event occurs when the user depresses the left mouse button while the
cursor is over the Flash control.

OnMouseOut
The OnMouseOut event occurs when the mouse cursor moves out of the Flash control.

OnMouseOver
The OnMouseOver event occurs when the mouse cursor moves into the Flash control.

OnMouseUp
The OnMouseUp event occurs when the user releases the left mouse button while the cursor
is over the Flash control.

OnPrintStyle

Page 743
The OnPrintStyle event occurs before the Flash control's style attribute is rendered into the
form's HTML code.

OnUpdate
the OnUpdate event occurs when the Flash control's .swf file has finished loading in the web
browser.

See also
 Toolbox

Page 744
Form

Forms are the fundamental way to allow users to enter and edit data, as well as
one of the best ways to display all kinds of information across the internet. With
Forms you can create web pages that are fully interactive, data-centered and
dynamic with extreme simplicity. Forms are the foundation of the presentation
layer for your Morfik AJAX application.

Designing Forms is simple and can be done either via the Visual Form Designer or
the Form Wizard.

Morfik AppsBuilder Forms are designed to natively run in a web browser. This
means that anyone who has access to the web can view your Forms. They do not
need proprietary software, they do not need to download any further plug-ins.
They can simply view your Form, as it is.

Creating a Morfik Form


Creating Form consists of developing the presentation layer, the browser logic and the server
logic. These three aspects are developed via the Design, Browser and Server tabs,
respectively. Further, unlike many other applications where the language to program the
browser side-code is different to the language for the server-side code, Morfik WebOS
AppsBuilder allows you to program both the browser and server-side application logic in a
supported high-level language of your choice.

Morfik Form Design Methodology


form design

The Morfik applications that are created using Morfik AppsBuilder are not page-centric, and
have an AJAX engine as their foundation. A direct consequence of these two fundamental
architectural aspects of Morfik Applications is that developers need to consider the following
three tightly-integrated aspects of Form creation as a single process and solution: the
presentation layer, the browser logic and the server logic. These three aspects are developed
via the Design, Browser and Server tabs, respectively. (Morfik Reports, since they are native
PDF documents do not have the user-interaction layer and so only have a design and server
component.) Further, unlike many other applications where the language to program the
browser side-code is different to the language for the server-side code, Morfik AppsBuilder
allows you to program both the browser and server-side application logic in a supported
high-level language of your choice.

Form Wizard
main:wizard

You can create a Document ( Form , Report , or Table ) yourself using the design view or you
can use the Creation Wizard s. These wizards initially good to get a feel of what options are
available to you for each of these Documents. It is most likely that after using the wizard a
few times, you will want to create Documents using the Design View method as it provides a
lot more flexibility and is possibly faster for people who are experienced

See also
 property sheet
 types of forms

 textlabel and textedit comparison

Page 745
Document

Morfik AppsBuilder revolves around the concept of fully-interactive


database-driven Ajax application. A major implication of this that you no longer
need to write script-language code such as Java to create interactivity on your
page nor do you need to write in languages such as Perl to add database
capabilities.

Morfik AppsBuilder is a rapid-application development environment which pivots on


the central ideas of visual programming and seamless integration. The
presentation layer of your application is developed via the Forms and Reports, the
data layer via the Tables and Queries, and the deep application logic via the web
services and modules.

Morfik AppsBuilder is centred around six types of objects called documents, the
first four being visual document, and the latter two being non-visual.

Form s : for entering, displaying and editing information via the web. These are
the documents that will compose your applications interface and define how users
interact with it.

Table s : for storing data


Queries : for asking questions to the database to obtain a subset of data


Report s : are documents for presenting information in a way suitable for printing
and previewing how it would look on paper.

Web Method s: define ways for communicating between the browser and web
servers, allowing your application to publish services for internal or public
consumption.

Module s: are for developing building blocks of programmed code such as classes
and data types that will be used throughout your application.

Page 746
Module

Regardless of the programming syntax of your choice, whether it be Pascal, C #,


Basic or Java, the WebOS AppsBuilder will create and work with exactly the same
modules. The modules will be declared with the appropriate syntax of each
language but will all, functionally, be totally equivalent.

Code modules are, generally, treated as the normal types of modules defined in
each of the target syntaxes. In Object Pascal they are units, in C# and Basic they
are namespaces and in Java they are packages. These "types" of modules are
normally used in everyday applications by developers who are used these
languages and should pose no mystery to those with some experience in the
language of choice.

When you choose to create some types of code modules such as forms and
reports you are actually creating two modules with the same name. One will be
used on the Browser side and the other in the Server side of your application. The
Morfik IDE treats these modules as a single entity which has a dual view; one
containing the browser code and one containing the server code.

Page 747
types of forms

In Morfik AppsBuilder there are two types of forms, and even though they may
look quite similar on the surface, they are in fact fundamentally different creations.
These two types of Forms will be compared and contrasted.

Firstly, of fundamental importance is that both Single Form s and Continuous Form
s are native to the browser and appear just like normal web pages. That is, any
type of browser on any platform can view them. They do not require any type of
plug-in.

Note

A Single Form is very much like a database interface. From a user's perspective
the defining characteristic of a Single Form is that, at any particular moment, it
can only display fields associated with a single record. In contrast, a Continuous
Form can be considered as a hybrid of an advanced data-grid and a Report. It
can display in row-form a set of fields from multiple records. When a form is
selected the Form property "View mode" defines whether it is single or
continuous.

The concept of Bands


Central to both types of Forms is the concept of Bands . Bands are a fundamental aspect of a
Morfik Form and Report . There are three types of bands: the header band, the details
band and the footer band.

The details Band


The details band is the central area of a Form's or Report's canvas. The key feature of a
details band is that, in contrast to headers and footers which are generally only displayed
once, if a Continuous Form or Report is connected to a data source, then the details band is
displayed once for each record of the data source. This allows the designer to design each of
the layout of the core controls just once, and the Morfik WebOS AppsBuilder will automatically
at run-time create a grid-like format that displays the core layout in each row.

For a single Form, it effectively makes little difference if controls are placed in the header, the
details or the footer band. However, note that a record NavigationBar can NOT be placed in
the details band. It can only be placed in the header or footer bands.

The header and footer bands


How the header and footer bands are used depends on if it is in context of
1 a single Form, or
2 a continuous form or Report
In a single Form, the major purpose of a header and footer is as an area to display the record
navigation bar, whereas in a continuous Form or report, it is use to display headings and
other information that you do not wish to repeat for every record.

Note

See also
 Single Form
 Continuous Form

Page 748
Single Form

A Single Form is very much like a database interface. From a user's perspective the
defining characteristic of a Single Form is that, at any particular moment, it can
only display fields associated with a single record.

Note

Note

Page 749
To add the controls to allow a user to navigate between the records, see
NavigationBar .

The Concept of Bands


Central to to both types of Forms is the concept of Bands

Bands are a fundamental aspect of a Morfik Form and Report . There are three types of
bands: the header band, the details band and the footer band.

The details Band For a single Form, it effectively makes little difference if controls are placed
in the header, the details or the footer band. However, note that a record NavigationBar can
NOT be placed in the details band. It can only be placed in the header or footer bands.

The header and footer bands In a single Form, the major purpose of a header and footer is
as an area to display the record NavigationBar.

See also
 Form
 Continuous Form

 Form Types

Page 750
Continuous Form

A Continuous Form can be considered as a hybrid of an advanced data-grid and


a Report . It can display in row-form a set of fields from multiple records. When a
form is selected the Form property "View mode" defines whether it is single or
continuous. Note: When you wish for users to enter or edit data it is best to use
Single Form s, because it is more difficult to edit data when it is displayed in a
Continuous Form. Note that for a Continuous Form , there is a one-to-many
relationship between the controls that are placed on the Form (or Report) Canvas
at design-time and those that appear at runtime.

To add the controls to allow a user to navigate between the records, see
Navigation Bar .

Page 751
Central to to both types of Form s is the concept of Bands Bands are a
fundamental aspect of a Morfik Form and Report . There are three types of
bands: the header band, the details band and the footer band.

The details Band The details band is the central area of a Form's or Report's
canvas. The key feature of a details band is that, in contrast to headers and
footers which are generally only displayed once, if a Continuous Form or Report is
connected to a data source, then the details band is displayed once for each
record of the data source. This allows the designer to design each of the layout of
the core controls just once, and the Morfik WebOS AppsBuilder will automatically
at run-time create a grid-like format that displays the core layout in each row.

The header and footer bands In a continuous Form or report, it is use to display
headings and other information that you do not wish to repeat for every record.

Sorting and Grouping in Continuous Forms and Reports If Sorting and Grouping is
turned off, then the header and footer will only be displayed once on the Form :
the header at the topmost part of the Form and the footer as the bottom-most
part of the Form.

However, if sorting and Grouping is turned on, as well as the sub-option to display
headers and footers, the a header will appear at the top of each section and a
footer at the bottom of each section. That is, a form may end up including
numerous headers and footers.

Note that the headers and footers can contain virtually all the controls that can be
placed in the details band, except a subform.

Of fundamental importance is to realize that both Single Form s and Continuous


Form s are native to the browser and appear just like normal web pages. That is,
any type of browser on any platform can view them. They do not any require any
type of plug-in. In contrast to Single Forms, a Continuous Form can be considered
as a hybrid of an advanced data-grid and a Report. It can display in row-form a
set of fields from multiple records. It is from this perspective that a Continuous
Form has some unique properties and features. It is possible, but not necessarily
useful to anyone to display a thousand records, as this would lead to a very slow
download time and an extremely large viewing page. Therefore, the most
important feature is that you must define how many records are simultaneously
displayed. The primary property that defines this limit is "MaxRecordsPerPage".
The power of a Continuous Form is that is represents the ultimate generalized

Page 752
version of a Data Grid. In a Data Grid, the data is displayed in a table-like manner
with each record being displayed in a different row. However, with Continuous
Form s, each record can be a fully-detailed Form in its own right each with its own
data, formatting, and interactivity controls. The other advantage of a Continuous
Form is that you only define the Form once and Morfik AppsBuilder automatically
repeats the band for every record, up to the limit as defined by
MaxRecordsPerPage.

See also
 Single Form
 Form

 Form Type

Page 753
NavigationBar

The NavigtionBar allows users to navigate between records as well as perform


actions to the database, such as Submit, Delete and New. It is especially useful
for Single Forms.

Page 754
textlabel and textedit
comparison

At the core of Form functionality lies two controls: the TextLabel , the workhorse
for displaying data; and the TextEdit , the workhorse for allowing users to enter
and edit data. Virtually all the functionality of the Form is contained within these
two controls. Most of the other controls merely provide convenient shortcut
methods of doing things that these two controls can do. Note

+ Morfik Static Data-bound


Read TextLabe TextLabel(datafield
only l defined)
Editable TextEdit TextEdit (datafield
defined)

+ Microsoft Static Data-bound


Access
Read only Label TextBox (recordsource defined, Locked ->
True)
Editable TextBo TextBox (recordsource defined)
x

Page 755
TextLabel

The Morfik AppsBuilder TextLabel allows you to display either static text or
data-bound text. The data type associated with the bound text data may either
be Text, Number, or Memo.

Placing a TextLabel on the Canvas


To place a TextLabel on the Canvas :
Select the TextLabel icon from the Toolbox,then
either: single-click where you would like the top
left-hand corner of the TextLabel to be on the
 canvas; or
click-and-drag the mouse from where you want the top left-hand corner of the TextLabel to the
 bottom right-hand corner.
The first method produces a TextLabel which is exactly 18 pixels high and 109 pixels wide. In
the case of the second method, the width and height of the TextLabel will then be based on
the size of the rectangle that you drew.

Entering Static Text into a TextLabel (at Design Time)


Since a TextLabel is read-only at run-time, all text that is displayed in a Text box must either
come from a Table, or have been entered at design time as static text. To enter static text
into a TextLabel:
select the TextLabel control: the corner and edge
1 dots should appear
Click inside the TextLabel: this puts the TextLabel into Edit mode, an I-bar cursor appears, and
you can enter or edit the static text. This static text is stored as the caption property of the
2 TextLabel. You can exit the Edit mode by clicking outside the TextLabel control.
Note

See also
 word wrapping
 textlabel and textedit comparison

 ToolBox

Page 756
word wrapping

When considering text flow over multiple lines there are two issues to consider:
soft line-breaks and forced/hard line-breaks. Word wrapping involves inserting
soft-line breaks in the text when the text does not fit on a single line. It ensures
that words are not split over multiple lines. Paragraphs, in the usual sense,
involve inserting hard line-breaks into the text (such as carriage returns or
markers) to force the text to begin on a new line. The TextLabel and TextEdit
controls address these issues in very similar ways, but with subtle differences. As
a rule of thumb, WantReturns is an attribute associated with paragraph markers,
whereas multiline is an attribute associated with physical lines.

+ TextLabel Wordwrap=True Wordwrap=False


WantReturns=Tru Like most word processors. Text Like Microsoft NotePad. Text
e flows onto a new line either due flows onto a new line only from
to hard line breaks or soft line forced/hard line-breaks via
breaks. carriage returns.
WantReturns=Fals For single paragraphs. Words For single-line captions. Text
e begin on a new line due to soft does not flow onto multiple lines.
breaks. Does not allow hard
breaks.

+ TextEdit Wordwrap=True Wordwrap=False


MultiLine=True Like Text flows onto a new line Like Microsoft NotePad. Text flows
most word either due to hard line onto a new line only from
processors. breaks or soft line breaks. forced/hard line-breaks via carriage
returns.

Note

Default Values for Wordwrap, WantReturns, and MultiLine


At the moment of placing a TextLabel , Morfik AppsBuilder dynamically sets default property
values for WordWrap and WantReturns/MultiLine based on the intial height of the control. If
the control is larger than 20 pixels high, Wordwrap, MultiLine and WantReturns are all set to
True; If the control height is 20 pixels or less, Wordwrap, MultiLine an dWantReturns are all
set to False.

Page 757
TextEdit

The Morfik AppsBuilder TextEdit allows you to enter or edit either static text or
data-bound text. The data type associated with the bound text data may either
be Text, Number, or Memo.

Placing a TextEdit control on the Canvas


To place a TextEdit on the Canvas :
Select the TextEdit icon from the Toolbox , and then either: single-click where you would like
the top left-hand corner of the TextEdit to be on the canvas; or **click-and-drag the mouse
 from where you want the top left-hand corner of the TextEdit to the bottom right-hand corner.
The first method produces a TextEdit which is exactly 20 pixels high and 195 pixels wide. In
the case of the second method, the width and height of the TextEdit will then be based on
the size of the rectangle that you drew.

Entering Static Text into a TextEdit


Static Text can be entered into a TextEdit either at design-time or at run-time. To enter static
text into a TextEdit:
if you are in the IDE (ie at design-time) you must first select the
1 TextEdit control, in which case the corner and edge dots should appear;
click inside the TextEdit: this puts the TextLabel into Edit mode, an I-bar cursor appears and
2 you can enter or edit the static text.
This static text is stored
as the Text property of
3 the TextEdit.
You can exit the Edit mode by clicking outside the
4 TextEdit control.

Entering Databound Text into a TextEdit


Databound Text can be entered into a TextEdit either at design-time or at run-time. At
design-time, data is not entered into the Form, but rather entered via the Visual Table
Designer and than that form is linked to the particular Table, and the TextEdit is linked to the
particular field. If the developer has linked the Form to a Table and the TextEdit to a
datafield, then entering data into a TextEdit at run-time is exactly the same as entering static
text.

Note

See also
 Toolbox

Page 758
Canvas

The default settings for the canvas of a Form are that it is 850 pixels wide by 300
pixels high,with its header and footer dimensions set at zero. The dimensions of
the main part of the Form can be changed by placing the cursor at any of the
boundaries of the Form and dragging the edge either inwards or outwards. The
Header can be enlarged by dragging the fine line just below the header title bar
(but above the Details title bar). The Footer can be enlarged by dragging the fine
line that is displayed just below the Footer Title Bar. Also it will display withing the
Design View, a grid pattern comprising of markers every 15 pixels in the horizontal
and vertical direction. This grid pattern can be turned off or altered via the Tools
menu. Select Options and then the General Tab. If the "Display Grid" CheckBox is
ticked then you can alter the size of the grid. This grid may be used as a visual
aid, or you can automatically align controls to the grid. In this case, you should
also tick the next CheckBox "Snap To Grid".

note

See also
 control placement

Page 759
control placement

After you have created a Form (or Report), you might find that it has all the
desired functionality but does not quite look as good as you like. Controls might
need to be resized, lined-up with other controls, the colors may not be what you
want and some of the controls may need borders. At the Form-level, you may wish
to resize the canvas to allow more space between the controls, change the
background color, or add a header and/or footer. All these actions can be
accomplished in the Form Design View. Using this view, you can edit the structure
of any form, report or control.

Resizing controls
There are five ways to resize controls.

Visual drag-and-drop via the mouse:


Select the desired control. Eight small dots should appear, four on each corner and four on each
1 edge.
Select one of these dots and drag it to resize the
2 control
Visual control via the keyboard:
Select a set of desired controls either by selecting each one in turn whilst holding down the
1 SHIFT key, or by using the Selection icon.
Press SHIFT and one of the Arrow-cursor keys to
2 change the size of the control.
Property sheet :

This method is numeric and provides an excellent way to define exact sizes for one or multiple
controls:
Select a set of desired controls either by selecting each one in turn whilst holding down the
1 SHIFT key, or by using the Selection icon.
In the Property Sheet select the "Format" tab
2 sheet.
Edit the numbers in either the "Height" property or the "Width" property, or both. (The
dimensions can be in pixels, mm, pts, pc, or inches. For example, you can enter ' 18 px ' or ' 30
mm ' or ' 1.2" ', (but without the single quote marks) Morfik AppsBuilder will automatically
3 convert them to pixels using the conversion 96 pixels per inch and 25.4 mm per inch.)
Resize function:
Select a set of desired controls either by selecting each one in turn whilst holding down the
1 SHIFT key, or by using the Selection icon.
2 Select Format -> Resize
For each of the horizontal and vertical dimensions you have four choices, giving you a total of
3 16 possible choices.
Scale factor:
1 Select Format -> Scale
Enter the desired percentage to scale (eg 50 means half everything and 200 means double
2 everything).

Aligning controls
To align a set of controls so that they are positioned in a clearly-defined geometric manner,
you should use the Morfik AppsBuilder align function. This can be accessed either through the
Morfik AppsBuilder Align Toolbar or the Menu option. It is only active, when multiple controls
are selected.
Select a set of desired controls either by
selecting each one in turn whilst holding down
1 the SHIFT key, or by using the Selection icon.
From the Format -> Align option and then select one of the options. The most powerful option is
2 the "Align" option.
You can now choose from 6 horizontal alignment
patterns and 6 vertical patterns, giving you a
3 total of 36 different patterns to choose from.

Page 760
Note: If you choose an option such as AlignLeft, then Morfik AppsBuilder will reposition all the
selected controls so that their left position is the same as the left position of the first control
that you selected. This convention to base alignment on the properties of the first select
control occurs for most of these align controls

Positioning Controls
There are four ways to position controls.

The first method is visual and is the typical drag-n-drop method: Select the desired control.
Place the cursor inside the control and drag it to a new position

The second method is visual and utilizes keyboard control: Select the desired control. Press
CTRL and one of the Arrow-cursor keys to change the position of the control.

The third method is to numeric and provides and excellent way to define exact positions:
Select the desired control, and in the Property Sheet select the "Format" tab sheet. Edit the
numbers in either the "Height" property or the "Width" property, or both. The dimensions can
be in pixels, mm, pts, pc, or inches. For example, you can enter ' 18 px ' or ' 30 mm ' or ' 1.2" ',
(but without the single quote marks) Morfik AppsBuilder will automatically convert them to
pixels using the conversion 96 pixels per inch and 25.4 mm per inch.

The fourth method is to automatically position it according to other Controls, that is, align it
with other controls. (eg you wish to position a set of controls so their left hand edges are all
in a line) Although this can be done manually, it is best done automatically. For details see the
section "Aligning Control

Page 761
Toolbox

The toolbox comprises of the set of components, usually called controls, which
may be placed on a Form or Report . The full set of tools are as follows:

TextLabel : displays static headings as well as data-bound alphanumeric text.

TextEdit : displays static and data-bound alphanumeric text that can be edited
by the user.

OptionButton : if there are several responses available but only one can ever
be chosen.

CheckBox : if there are several responses available and each choice is


independent.

Combobox : if there are several very common responses, but the user is not
to be limited to these ones.

Button : provides an easy and intuitive way for the user to initiate an event.

Picture : displays either a static or data-bound image.

Flash control : displays either a static or data-bound Flash (TM) file.

Tab control : displays a set of Tabs, each of which can contain its own
controls

Subform / Subreport : a placeholder which defines where a secondary


Form/Report is to be displayed within a main one.

Container : to group a set of controls within a prescribed canvas region

DateTimeEdit Control: to display a static or data-bound date and/or time


value.

FileUploader : allows the user to submit a file from their computer to the
server

Timer : the most natural way to define a time-based event

Page 762
Rectangle : a purely graphical control used to enhance the presentation of
Forms and/or Reports.

PageBreak : used to force a page break.

note For a report, only TextLabel, CheckBox (read-only), Image Control,


Subreport, PageBreak, and Rectangle are available.

Page 763
OptionButton

An OptionButton also provides the user with a single box which can either be
selected or unselected. It can not be bound to data. A CheckBox provides the
user with a single box which can either have a tick in it or no tick. It does not have
to be bound to data, however, if it is the data type of the connected data field
must be a yes/no (otherwise known as a Boolean) type.

The major functional difference between CheckBox es and OptionButton s is that if


multiple CheckBoxes are placed on a Form (or inside a Container ) than they all
function independently. That is, more than one CheckBox may have a tick in it. In
contrast, if there are multiple OptionButtons on a Form (or inside a Container) only
one OptionButton can be selected/chosen at any one time - if the user selects a
particular OptionButton then all other OptionButtons on the Form (or inside the
Container) are automatically de-selected.

See also
 Toolbox

Page 764
CheckBox

A CheckBox provides the user with a single box which can either have a tick in it
or no tick. It does not have to be bound to data, however, if it is the data type of
the connected data field must be a yes/no (otherwise known as a Boolean) type.
An OptionButton also provides the user with a single box which can either be
selected or unselected. It can not be bound to data. The major functional
difference between CheckBox es and OptionButton s is that if multiple CheckBoxes
are placed on a Form (or inside a Container ) than they all function
independently. That is, more than one CheckBox may have a tick in it. In contrast,
if there are multiple OptionButtons on a Form (or inside a Container) only one
OptionButton can be selected/chosen at any one time - if the user selects a
particular OptionButton then all other OptionButtons on the Form (or inside the
Container) are automatically de-selected.

See also
 Toolbox

Page 765
Combobox

A ComboBox or ListBox can come in handy if you find yourself in the need of
repeatedly needing to type certain values into a field. For example, when entering
book details in to your Book Table you may have to enter the name of one of half
a dozen publishers. You may find it easier to create a list containing these 6
publishers and the when you are entering data at run-time you can simply select
from one of these list items. The major presentation difference between a
ComboBox and a ListBox is that a ComboBox acts like a pull-down menu. That
is, unless you select the menu, you can only see one item at a time. A ListBox,
however, is like a permanently pulled-down menu. You can always see all the
items, regardless of which one is chosen. To create the item list at design time,
Place either a Combobox or ListBox on the
1 Canvas
2 Click on the three small dots next to Property called "Items"

3 Enter each of the desired items, placing each of the items on a separate line.
4 Click OK.

See also
 Toolbox

Page 766
ListBox

A ComboBox or ListBox can come in handy if you find yourself in the need of
repeatedly needing to type certain values into a field. For example, when entering
book details in to your Book Table you may have to enter the name of one of half
a dozen publishers. You may find it easier to create a list containing these 6
publishers and the when you are entering data at run-time you can simply select
from one of these list items. The major presentation difference between a
ComboBox and a ListBox is that a ComboBox acts like a pull-down menu. That is,
unless you select the menu, you can only see one item at a time. A ListBox,
however, is like a permanently pulled-down menu. You can always see all the
items, regardless of which one is chosen. To create the item list at design time,
Place either a ComboBox or ListBox on
1 the Canvas
2 Click on the three small dots next to Property called "Items"

3 Enter each of the desired items, placing each of the items on a separate line.
4 Click OK.

Page 767
Button

Morfik AppsBuilder has been designed to allow any control can trigger an event
when the user clicks it. However, the Button has been designed with this
single-function as its sole purpose and when you choose the button, it not only
carries out the appropriate action, it also looks as if it's being pushed in and
released. It is a very simple control, but is used very frequently due to its
specialized nature.

See also
 Toolbox

Page 768
Picture

The Image control allows you to display pictures in your Form or Report . The
images can either be JPG / JPEG, BMP, or GIF (static and/or animated and/or with
transparency). The Image control can either show a static picture or it can be
databound to a table which contains a datafield that is of Picture data type.

Placing an image control on the Canvas


To place an Image control on the Canvas:
Select the Image icon from the Toolbox, and then either: single-click where you would like the
top left-hand corner of the Image to be on the canvas; or **click-and-drag the mouse from
 where you want the top left-hand corner of the Image to the bottom right-hand corner.
The first method produces an Image control which is exactly 105 pixels high and 133 pixels
wide, which includes a 2 pixel wide border. In the case of the second method, the width and
height of the TextLabel will then be based on the size of the rectangle that you drew.
To display databound images:
Ensure that the Form or Report is bound to a
1 Table or Query.
2 Link the Image control to a particular datafield that must be of data type "Picture".
To display unbound (static) images:
1 Select the Image control
2 From the Property Sheet either select the "Format" or "All" tab sheet
Select the property "Picture" and click on the small three
3 dots
If the name of the image is shown then simply click on it. Otherwise, select Browser and locate
4 the desired image.

5 Click OK.
An important, and possibly unique, aspect of Morfik AppsBuilder is that once you have located
an multimedia file and placed it in an Image or Flash control, a copy of it is internally stored in
one the Morfik AppsBuilder files. From then on, you do not ever have to worry about whether
you refer to this file in an absolute manner or relative manner. You simply select the file from
the menu and Morfik AppsBuilder does the rest for you! You may of course, organize your
static files into a system of folders on your hard drive, but as soon as you have imported them
into Morfik AppsBuilder you do not need to worry about path names at all!

Note

See also
 Toolbox

Page 769
Tab control

You can use a tab control to present several pages of information as a single set.
This is especially useful when you're working with many controls that can be
sorted into two or more categories. For example, you might use a tab control on
an Employees form to separate employment history and personal information.

By default a Tab Control only shows a single tab sheet. However, you can add as
many tab sheets as you want. To add another Tab Sheet:
Select the entire Tab Control. Ensure that you have not simply
selected the top tab sheet. If you have selected the entire Tab
control then the top corner and edge dots should encompass
1 the little tab markers as well as the tab sheets.
Right-click and select
"New Page" from the
2 contextual menu
Click on the new Tab marker (which will say something like
3 Tab2, Tab3, etc). This selects this new Tab
Click a little lower on the actual tab sheet
4 associated with this new Tab.
You can change the text that appears in the Tab marker by
5 editing the Caption property
You can change the name of the actual tab by editing the "Name" property. This is
only important for advanced users who might wish to reference this tab sheet
6 programmatically or as part of a parametric query.
Insert some low-level controls such as TextLabels and TextEdit
7 controls inside the tab sheet area.

See also
 Toolbox

Page 770
Subform

A subform is a Form control that allows you to to insert another form into a
subregion of the main form's canvas area. The primary form is called the main
form or parent form, and the form within the form is called the subform or child
form. The two main uses for a Subform are: as part of a master-detail relationship
- this method is very common in the database world; and as a method for dividing
complex pages into distinct functionally-independent sub-windows or panes(a.k.a.
'frames') - this method is very common in the web world.

Using a subform
The best way to place a subform on a page is to first think about which form you want to
have as the main form and which form you want as the smaller secondary form. Once you
have done this, then the process is as follows:
Open the main form
that you wish to
1 place the control in.
Click the Subform icon and define its position and size using the Selection Tool icon and/or the
2 Property Sheet.
Click on the "All" tab sheet of the
3 Property Sheet and select "Form"
Using the drop-down menu select the Form that you wish
4 to use as the secondary Form.
You can then right-click the Subform control and select "Design sub-item" to
5 open the Child Form canvas.

note

Page 771
See also
 Form creation

Creating a master-detail relation


Subforms are especially effective when you want to show data from tables or queries with a
one-to-many relationship. For example, you could create a form with a subform to show data
from a Categories table and a Products table. The data in the Categories table is the "one"
side of the relationship. The data in the Products table is the "many" side of the relationship
— each category can have more than one product.

To create a master-detail relation, first create a subform as described above. The


master-details relationship between two forms can be done via the OpenForm function and
the parameters that are passed from the master-form to the details-form.

For example, say you have two forms, Form1 (Master) and Form2(Details). Form2 needs to be
based on a parametric query data-source. Then as you browse through Form1 records, you
call the Openform function to open form2 and pass the Master-Link-Field (which should be
bound to a TextLabel control - invisible if not part of the desired form layout) value from form1
as parameter to form2.
OpenForm(Form2,HomeForm:Subform,'"prmOne='+MasterLinkFieldLabel.Caption +'"');

An example of this can be found in the AjaxSMB sample project. The "Categories Form" form in
this project shows a list of products that belong to a particular category as you navigate
through the categories. You find this project in the Samples folder (...\My Documents\Morfik
07\Samples).

See also
 Toolbox

Related Video
 Subform control in Morfik

Page 772
Form creation

Creating a Form consists of developing the presentation layer, the browser logic
and the server logic. These three aspects are developed via the Designer,
Browser and Server tabs, respectively. Further, unlike many other applications
where the language to program the browser side-code is different to the
language for the server-side code, Morfik WebOS AppsBuilder allows you to
program both the browser and server-side application logic in a supported
high-level language of your choice. The most powerful and flexible method to
create a Form in Morfik AppsBuilder is via the Form Design View. In this view, you
decide exactly where to place each component and how to format it. Morfik
AppsBuilder has made viewing a form in Design view like sitting at a workbench
surrounded by useful tools.

The four main components of designing a Form are: The Form Canvas , which is
where you place all your components. The Toolbox , which can either be displayed
either as a Toolbar or a floating palette. The Sheet ], which is where you can view
and edit the properties of each section of the Form and any of its controls. These
properties determine its appearance, behaviour, structure and its connection with
any data. The toolbars: Align and Formatting.

By default, Morfik AppsBuilder provides you with one ready-made Form called
index. To design a simple Form, you can either open up this existing one or create
a new one. To create a new Form:
1 Select Forms from the Documents Pane.
Click in the Documents
2 window

3 Right-click and select "New" or Select New from the Commands Pane.
4 Type in the desired name for the Form and then click OK.
Displayed below is an example of the design, the browser-side and the
server-side components of a Form.

Page 773
See also
 Form s
 Types of Forms

 Navigation Bar
 Pages and subforms

Pa ge 7 7 4
 Grouping and Sorting
 Plastic Layout

Page 775
Grouping and Sorting

Morfik AppsBuilder allows you to display the multiple records in a grouped and
sorted manner. For example, you may have entered all membership information
about members in your club. In some instances, it would be reasonable to list
them according to the default order, which is based on the internal Autonumber
field. However, it may be more benefit to sort them alphabetically by country
(either in ascending or descending order). Further, if multiple members come from
the same country then you might wish to sort according them alphabetically by
surname. Morfik AppsBuilder allows you to do nested sorts utilizing up to a depth
of nine (9) levels. Typically, if your data was displayed using a simple data grid or
table then this is about all you could do to refine the presentation of your data -
every row would have exactly the same number of field elements. For example,
every row would have the country field, and there may be two hundred
consecutive rows with the country field as "Australia" and then another five
hundred rows with "United States of America". This method of displaying data is
very crude and, in terms of internet transferral, very bandwidth inefficient due to
the high amount of repetition. However, Morfik AppsBuilder allows you to have
group your data. For example, every time a record represents a different country
to the previous record, then a Country header can appear indicating the name of
the country. The details band then, does not need to contain the country field, as
it is displayed in the header! Thus, the name of each distinct country is only
displayed once. Within each group you might wish to group them according the
first letter of their surname. This level of grouping within groups can be
implemented up to a depth of nine (9) levels.

Note

See also
 Sorting
 Grouping

Related Video
 Grouping and Sorting in Forms

Page 776
Sorting

Sorting Morfik WebOS AppsBuilder allows you to do nested sorts at design-time


utilizing up to a depth of nine (9) levels.

At run-time the output is typically something like this, noting that the records are

Page 777
now sorted according to the values in the UnitsInStock data field.

See also
 Grouping
 Grouping and sorting

Page 778
Grouping

Typically, if your data was displayed using a simple data grid or table then this is
about all you could do to refine the presentation of your data - every row would
have exactly the same number of field elements. For example, every row would
have the country field, and there may be two hundred consecutive rows with the
country field as "Australia" and then another five hundred rows with "United
States of America". This method of displaying data is very crude and, in terms of
internet transferral, very bandwidth inefficient due to the high amount of
repetition. However, Morfik WebOS AppsBuilder allows you to have group your
data. For example, every time a record represents a different country to the
previous record, then a Country header can appear indicating the name of the
country. The details band then, does not need to contain the country field, as it is
displayed in the header! Thus, the name of each distinct country is only displayed
once.

Page 779
Within each group you might wish to group them according the first letter of their
surname. This level of grouping within groups can be implemented up to a depth
of nine (9) levels. At run time, the output could typically look like this. Note how
there are two groups : "paperback" and "hardcover" and within each group the
records are sorted according to the author's name.

See also

Page 780
 Sorting
 Grouping and sorting

Page 781
Plastic Layout

Page 782
Plastic Layout

Page 783
Plastic Layout

Page 784
Plastic Layout

Page 785
Grow-and-Shrink

Morfik allows you to design the layout of your Form using a fixed or absolute
positioning paradigm, and yet allow the layout to behave in a fluid-like manner at
design-time. The level of plasticity (that is, how fixed or how fluid) can be specified
both at design-time as well as run-time.

The key to Morfik's plastic layout, is the Grow-and-Shrink capability, which is


complemented with the Push-and-Pull capability.

The following controls have specialized plastic layout features:


 TextLabels,
 Containers,

 Images and
 Subforms
Each of these controls have a two properties: CanGrow and CanShrink , which
only have a meaning if the control is bound to data.

Plastic Layout at Design-Time


Consider a Form with two data-bound TextLabel s. At design-time we define the layout using
absolute coordinates and dimensions for these TextLabel s. We place a button directly below
the second TextLabel .

Morfik's content-driven plastic layout allows the size and positions of these TextLabel s, (as
well as the position of the Button ) to dynamically adapt to the content that is contained
within them. The level of plasticity (the balance between the fixed design-time layout and the
flow-layout at run-time) can be specified both at design time as well as at run-time.

Here are the possible combinations:

CanGrow=False CanShrink=False: The size of the control is fixed and determined solely
by the dimensions that were set at design-time. If there is little or no content then the
contents of the control will appear significantly empty. Further, if there is a large amount
of content, not all of it may be visible.

CanGrow=False CanShrink=True: The maximum size of the control is fixed and


determined solely by the dimensions that were set at design-time. If there is little or no
content then the height of the control will shrink so that it elegantly encloses the content.
However, if there is a large amount of content, not all of it may be visible.

CanGrow=True CanShrink=False: The minimum size of the control is fixed and


determined solely by the dimensions that were set at design-time. If there is little or no
content then the contents of the control will appear significantly empty. However, if there
is a large amount of content, the height of the control will increase so that it elegantly
displays all the content.
CanGrow=True CanShrink=True:The size of the control is determined solely by the
amount of content that appears in the control at run-time. If there is little or no content
then the height of the control will be reduced so that it elegantly encloses the content.
Further, if there is a large amount of content, the height of the control will increase so
that it elegantly displays all the content.

The Cascading nature of CanGrow and CanShrink


Note that if a Form , say Form1, contains a Subform and that subform is connected to
another Form, Form2 that contains a TextLabel . Suppose further that the TextLabel, the
Subform and the Forms' all have their CanGrow and CanShrink properties set to True.

If the TextLabel needs to grow so large that its lower edge extends beyond the lower edge
of Form2, then it will automatically enlarge the height of the Subform, which in turn will
enlarge Form1 if required.

That is, the grow and shrink features of the controls cascade upwards as required. To limit
the cascading effect of grow and shrink simply requires setting a control's CanGrow property

Page 786
to False. In this case, if the contents are too large to displayed in the Form then the height
will not change, but not all the content will be visible.

The effect of CanGrow and CanShrink on neighbouring controls


CanGrow and CanShrink has the potential to not only affect the parent controls of a particular
control, but can potentially affect all controls in the browser! This is because when a control
grows or shrinks it will affect all other controls whose top edge is lower than the lower edge
of the particular control.

Note that this rule applies to all controls that are currently displayed in the browser, and not
just to those on the same Form. (The technical exception to this rule is now given. Consider
the following example. In this example, if Subform1 grows, then it will affect the position (by
pushing them down) TextLabel3 and TextLabel4. Note that because the effect is based on the
top edge of the neighbouring controls, it will not affect TextLabel2, despite its lower edge
being below that of the subform.

To clarify this point even further, a table is included showing which controls are affected
based on which control is growing or shrinking.

Control Controls Affected


Subform1 TextLabel3, TextLabel4
TextLabel1 TextLabel2, TextLabel3, TextLabel4
TextLabel2 TextLabel3
TextLabel3 (none)
TextLabel4 (none)

Using Containers to isolate theCanGrow and CanShrink behaviour


Using Containing controls (Containers or Subforms) allows you to control even further which
elements are affected when a particular element grows or shrinks. For example, in the
illustration above, if you do not wish for TextLabel3 to move, regardless of whether the
Subform grows or shrinks, then by placing TextLabel2 and TextLabel3 in a Container, as
shown. This is because the grow and shrink rules for when the subforms grows or shrinks is
now applied to TextLabel1, Container1, and TextLabel4, and since the top edge of the
Container is above the lower edge of the Subform, then it will not be affected by the plastic
layout. The same effect can be created by placing a Subform control in place of the Container,
and then linking it to another Form that contains TextLabel2 and TextLabel3.

The OnBeforeGrowOrShrink and OnAfterGrowOrShrink events


The effects of CanGrow and CanShrink properties in creating a content-driven plastic layout,
can be further enhanced through the events OnBeforeGrowOrShrink and
OnAfterGrowOrShrink. These events allow even finer control over the layout when CanGrow
and CanShrink are not quite sufficient. Consider the following Form, frmPlastic.

The top edge of the Subform is set at 40 px, and its height is 280 px. In many instances the
developer may wish for the layout to conform to a grid. That is, the coordinates of all the
controls' corners should lie on an imaginary pre-defined grid points. This is how we can allow
the Subform to Grow or Shrink and yet, maintain its grid layout. Note that
OnBeforeGrowOrShrink and OnAfterGrowOrShrink have no menaing if the control's properties,
CanGrow and CanShrink are both set to False. In the following code snippet, the parameter
deltaY is how much the Subform control will be changed due to growing or shrinking. A
negative value indicates that it will shrink, whilst a positive value indicates that it will grow.

// Morfik Pascal
Function CalculateGridPoint( i : Integer) : Integer;
Const
GridStep = 20;
Begin
If (i Mod GridStep) > 0 T hen
Result := i
Else

Page 787
Result := i + i - (i Mod GridStep);
End;
P rocedure frmPlastic.Subform1BeforeGrowOrShrink(Var deltaY: Inte
ger);
Begin
deltaY := CalculateGridPoint(deltaY);
End;

The OnAfterPushedOrPulled and OnBeforePushedOrPulled events


However, due to the nature of CanGrow and CanShrink, if the Subform grows or shrinks then
it will automatically reposition the button. It will be re-positioned so that the distance
between the lower edge of the Subform and the Top edge of the Button as defined at
design-time is maintained at run-time. However, if the button was not placed on a grid point
at design-time, or for any other reason, the button when it is repositioned may not lie on a
grid point. The following event ensures that the button's top edge will lie on the grid.

// Morfik Pascal
P rocedure frmPlastic.Button1BeforePushedOrP ulled(Var deltaY: Inte
ger);
Begin
deltaY := CalculateGridP oint(deltaY);
End;

Plastic Layout example


The ability to invoke layout changes at run-time via the OnAfterGrowOrShrink,
OnBeforeGrowOrShrink, OnAfterPulledOrPushed or OnBeforePulledOrPushed events offers
developers significant versatility and control over the layout of a Form. Suppose we wish to
reposition the images based on the height of the Subform. This is straight-forward and
exemplifies the power and versatility of Morfik's plastic layout methodology. Consider the
following Form layout, frmPlastic.

// Morfik Pascal
P rocedure frmPlastic.Subform1AfterGrowOrShrink(deltaY: Integer);
Begin
If SubForm1.Height < Image1.Height T hen
Image1.Visible :=False
Else
If SubForm1.Height < Image1.Height + Image2.Height + 20 T hen
Begin
Image2.Visible := False;
Image1.T op := Subform1.T op + (Subform1.Height - Image1.Height) Div 2;
End
Else
Begin
Image1.T op := Subform1.T op + (Subform1.Height - Image1.Height- Image2.Height) Div 3;
Image2.T op := Subform1.T op + 2*(Subform1.Height - Image1.Height - Image2.Height) Div 3 + Image1
.Height;
End;
End;

The effect of this code at run-time is shown below. Note that the images are equally spaced
along the height of the Subform, ensuring a controlled layout.

Page 788
ShrinkOnHide
The Container control has a specialized property on it called ShrinkOnHide. This unique
property plays a central role in designing Forms that have plastic layout characteristics. By
placing controls in a container, not only does the position of each of them dynamically change
when the container's position is altered, but possibly more importantly, but making the
container not visible, all the controls are automatically made not visible and effectively of zero
height. For example, in the following Form, the controls for the "Properties" and "Data"
section are all contained within a Container. Dynamic Shrinking on Hide

If the Container's property ShrinkOnHide is set to True, and the visibility is set to False -
whether it be a design-time or at run-time, then the result will be that the "Presentation" and
the "Logic" sections will be dynamically 'pulled' up - thus eliminating any extraneous blank
spaces.

Hiding without Shrinking


Note that if the ShrinkOnHide is set to False and the visibility is set to False, then the
"Properties" and the "Data" sections will not be visible, however, the position of the
"Presentation" and the "Logic" sections will remain unchanged - thereby creating a blank
space, as shown below

Exploiting ShrinkOnHide with Subforms


One of the most common uses of this technique is when a Form, say Form1, contains a
subform Subform1. In most cases Subform1 will be connected to another Form, and using the
OpenForm syntax one can alter which Form appears in it at run-time. However, if you want no
Form to appear in it, then most of the time, you would the layout to defined as if the subform
was not there. This effect can be easily produced by placing Subform1 in a container. For the
majority of the time, the Container's visibility would be set to True, however, when you wish
for no Form to be shown in Subform1, then simply set the Container's visibility to False (and of
course ShrinkOnHide to True).

See also
 horizontal placement

Page 789
horizontal placement

Horizontal Placement, and aspect of plastic layout , allows the controls to be


re-positioned and/or resized based on the size of the viewport, which in this case
is the browser window. In other words, the left- and right-hand edges of the
control can be dynamically re-positioned and hence the width of the control can be
also altered to adapt to the change in the browser window. This feature which is
triggered not on content but rather on the resizing of the browser window, makes
it a complementary feature to the content-driven plastic layout features that are
available via the grow-shrink functionality.

Summary of the Behaviour of Horizontal Placement


Note that in this table, the first column is the value of the Horizontal Placement. The second
cloumn is the nature of the relative distance between the edge of the control and the
corresponding edge of the bounding Form.

Value Left-hand Right-hand edge Width


edge
hpNone constant constant constan
t
hpJustify constant constant dynamic

hpRightJustify dynamic constant dynamic

hpCenter dynamic dynamic constan


t
hpRelative
hpLeftJustify

For example, with the HorizontalPlacement set to hpRightJustify, the distance between the
right-hand-edge of the control and the right-hand edge of the Form at run-time will remain
constant and equal to that specified at design-time. In contrast, the left-hand edge of the
control will dynamically vary to ensure that the the width of the control remains constant and
equal to that specified at design-time.

note

note:horizontal placement are cascading in nature. That is, if a Form utilizes horizontal
placement and it contains a subform, then the controls contained in the connected Form may
also dynamically alter if their horizontal placement settings are defined appropriately.

Examples of HorizontalPlacement
The best way to describe horizontal placement property is to use an example. For the
textLabels that are bound to data, we set the CanGrow and CanShrink properties to True.
For future reference we list some of the positions and dimensions of the controls.
Form: Width 620
 px
 Data-bound TextLabels: Width 460 px, Left 120 px

 Static Labels : Width 60 px, Left 40 px


 Header Rectangle: Width 620 px, Left 0 px

 Header TextLabel : Width 600 px, Left 10 px


Button : Width 40 px, Left 540
 px.
By default at run-time, this Form will appear as follows:

We mention a few characteristics of how this Form appears at run-time

 The width of the actual Form is 620 px, however since the

Page 790
browser's width is greater than this, the 'extra' space is seen as
a light-grey background.
The width of all the Form's
controls are the same as at
 design time.
The coordinates (relative to the left-edge of the Form) of the
left- and right-edges of all controls are the same as at
 design-time.
The height of the Text Label associated with the Review is greater than what was specified at
 design-time because the CanGrow feature has enlarged the TextLabel to fit the content.
However, we can allow the position and dimensions of the controls to alter based on the size
of the browser window. For the following controls we set their HorizontalPlacement property
as follows:
 Form: hpJustify
 Data-bound TextLabels: hpJustify

 Static Labels : hpNone


 Header Rectangle: hpJustify

 Header TextLabel : hpCenter


 Button : hpRightJustify
We mention a few characteristics of how this Form now appears at run-time due to the
Horizontal Placement feature:
The width of the Form has now
enlarged to the same as the browser
 window
The width of the data-bound controls have increased so that the distance between their
 right-hand edge and the right-hand edge of the Form is the same as at design-time
Since the width of the Review Text Label has increased, its height is reduced,
due to the CanShrink-CanGrow properties which resize its height based its
 content
The static labels
remain unchanged
both in position and
 size
The button has been moved in a way that the distance between its
right-hand edge and the right-hand edge of the Form is the same as at
design-time. However, its left-hand edge has moved accordingly to ensure
 that its width remains unchanged.
The width of the header rectangle has now enlarged to
 the same as the browser window
The left- and right-hand edges of the Header TextLabel have been
re-positioned to ensure that it is centered relative to the browser window,
 and that its width remains unchanged.

See also
 Plastic layout
 grow and shrink

Page 791
CanGrow

Using this property only makes sense if the control will contain data bound
controls.

If there is a large amount of content, to be displayed within the control its height
will increase so that it elegantly displays all the content. More information on how
controls can grow and shrink at runtime is available under the topic Plastic
Layout.

Page 792
CanShrink

Using this property only makes sense if the control will contain data bound
controls.

If there is only a small amount of content to be displayed within the control, its
height will be reduced so that it elegantly displays the content without leaving
large blank areas in the page. More information on how controls can grow and
shrink at runtime is available under the topic Plastic Layout.

Page 793
Subreport

See also
 Toolbox

Page 794
Container

A Container is a sophisticated way of grouping multiple controls together. You can


place a Container onto a canvas and then place numerous lower-level controls
such as TextLabels , TextEdit controls, ComboBox es, etc within the Container.
Then, when you wish to move all these controls as a set, you only need to move
the position of the Container, and all of the controls that are contained within it,
will be automatically moved.

If you alter the position of a container, then all controls contained within it are
automatically repositined, as their positions are defined relative to the the top-left
hand corner of the Container. Further, the container has a specialized property
on it called ShrinkOnHide. This makes it very easy to not only hide all containing
controls in a single call, but it will Pull all neighbouring controls up the Form so that
the white space where the Container was originally located is eliminated.

note

See also
 Toolbox

Page 795
DateTimeEdit

DateTimeEdit
control

See also
 Toolbox

Page 796
FileUploader

This control allows users to upload files to the server. This is most useful if the
control is linked to a datafield with datatype of Document, Picture, Multimedia, or
Blob.

See also
 Toolbox

Page 797
Timer

Let us suppose we wish to have a TextLabel that displays the time and updates
it every second. To do so:

Open the desired Form, and place a TextLabel somewhere on it. Then select the
Timer control icon and place it anywhere on the Canvas . On the Property sheet
select the "All" tabsheet and select enter 1000 into the "Interval" property. This
is the time interval as measured in milliseconds. On the Property sheet select
the Events tab and then select OnTimer. Morfik AppsBuilder will automatically
switch to the code editor view. It will also include some auto-generated code,
such as declaring the function, and the wrapper required to define the function.
Between the "Begin" and "End" statement insert a line of code so that the entire
module looks like this:

Function Index.WebTimer1Timer(Event : TDOMEvent);


Begin
TextLabel1.Caption := DateTimeToString(Now_Local,dfLong,eTimeStamp,F
alse);
End;

See also
 Toolbox
 Form

 programming

Page 798
programming

The browser-side and the server-side code in a Morfik WebOS application are
characterized by two distinct programming models. The server-side code is highly
concurrent while the browser-side code is completely asynchronous. Whilst Morfik
Integrated Design Environment (IDE) removes many of the programming chores
associated with these two types of programming an understanding of these two
concepts are fundamental to efficient programming within Morfik.

Morfik's implementation of WebOS applications uses a completely stateless


approach to the programming of the server side. This means the data within the
server side code does not change during the course of execution of the program.
Any data that changes is either committed to the database or will be lost. This to
a large degree mitigates the onerous requirements of multi-threaded
programming. This approach needs to be followed by application developers.
Global variables must be avoided as much as possible as they are normally not
'thread safe' and they would break the stateless model of Morfik WebOS
applications. However if it is needed to have stateful global variables one has to
use the appropriate programming techniques for thread synchronization.

The programming model for the browser side is on the other hand completely
asynchronous. This would particularly feel different for those who are accustomed
to traditional desktop applications that are highly synchronous. The main cause of
this is the HTTP communications between the browser-side and the server-side.
Sophisticated activities within the browser side often require multiple calls to the
server side. However every time a call is made to the server side a 'callback' must
be set up so that the execution of the task could continue. Since the 'state' of the
execution is not kept from the point that the call was made relative to the point
where the call back function is invoked, it is the responsibility of the programmer
to manage the execution state within the browser. The Morfik IDE and the AJAX
code hide most of these activities from the programmer. However there are
situations that one may require to do the setting up of the call back functions as
well as preserving the context of execution.

Another aspect of Morfik's browser side programming that requires a mention is


the way in which the AJAX code is downloaded into the browser. Upon start, the
core of the AJAX engine is sent to the browser. This is enough to get the AJAX
user interface up and running. Then the first time a module is being accessed
within the browser, the associated JavaScript must be downloaded. This allows for
a higher level of scalability but at the same time it means extra programming work
before calling functions within other modules. Morfik has a number of functions
that hides the code that is responsible for downloading the JavaScript.

The event-driven nature of Morfik applications


Unlike the server-centric architecture of current web-applications, Morfik applications are
browser-centric. Amongst other things this means all the user-interface events are handled
within the browser. The server-side events are program generated and not related to the
user interface. The browser-centric nature of the Morfik application model makes the 'binding
logic' that is required for combining various user interface elements a lot more intuitive than
the current server-centric models. Events such as click, mouse down, mouse move, etc are all
handled within the browser similar to the visual programming environments used to for
desktop applications. Within the associated event handlers of such events lies the bulk of the
binding logic needed for binding various elements of the user interface.

Event handlers

See also
 Opening and linking Forms
 WebMethods

Page 799
Event handlers

Event properties cause an associated procedure or function (formally called the


event handler) to run when a particular event occurs.

In many cases, the event handler comprises of a very small number of lines of
code, as it tasks is to simply alter a control property or variable.

For example, if you enter the name of a procedure in a command button's OnClick
property, that procedure runs when the command button is clicked.

The types of events that Morfik AppsBuilder incorporates can be divided into
several categories according to how the event is initiated:

mouse-initiated events: Most likely the most common type of event. These include
OnClick, OnDblClick, OnMouseDown, etc. document creation events: These are
associated with different stages of the process of creating forms and reports.
These include OnFormat, OnReady, OnDestroy, etc database-related events:
These include On FirstRecord, OnSubmit, On Refresh, etc. timer-related events:
this is a specialised category associated with the Timer control. It allows you to
call a specific procedure at periodic time intervals. In virtually all cases, the event
handler comprises of a very small number of lines of code, as it tasks is to simply
alter a control property or variable.

Mouse-activated Event Handling


Let us suppose we wish to alter the font colour of a TextLabel when the mouse hovers over
it, and then return it back to its original color when the mouse leaves the TextLabel region. To
do so:

Mouse Rollovers
Here is a simple way to alter the font colour of a TextLabel when the mouse hovers over it,
and then return it back to its original color when the mouse leaves the TextLabel region. To
do so:
1 Select the TextLabel

Page 800
Via the Property Sheet and code-editor define two event handlers: OnMouseOver and
2 OnMouseOut as follows:

// Morfik Pascal
Function Form1.T extLabel1MouseOver(Event: T DOMEv
ent);
Begin
T extLabel1.BorderColor := $00000FF;
End;

Function Form1.T extLabel1MouseOut(Event: T DOMEve


nt);;
Begin
T extLabel1.BorderColor := $0000000;
End;

Note

// Morfik P ascal
Function Form1.T extLabel1MouseOut(Event: T DOMEv
ent);;
Begin
T extLabel1.BorderColor := T extLabel1.Attrs.BorderC
olor;
End;

If you are to use this syntax note that the syntax is slightly different for font attributes.

// Morfik P ascal
Function Form1.T extLabel1MouseOut(Event: T DOMEv
ent);;
Begin
T extLabel1.FontColor := T extLabel1.Attrs.Font.Colo
r;
End;

The BookTrader sample project gives an example of a mouse-rollover that toggles the visibility
of a container.

Page 801
See also
 Programming
 Opening and linking Forms

 BandIndex es
 WebMethod s

Page 802
 Module s

Page 803
Opening and linking
Forms

Opening and Linking Forms Opening Forms in Morfik is fundamentally different to


hyperlinking to a set of spatially and computationally separate HTML files that
reside on a remote server. Opening Forms is more like invoking a request to
morph the user interface from one state to another. In most cases, you only wish
for a small fraction of the user interface to update. Morfik allows you to make
incremental structural changes, which thanks to the Morfik plastic layout
technology may have significant effects to the presentation layer.

The way to invoke these changes is through OpenForm.

OpenForm(form, context, parameters);


| |
| |__ blank - new browser window with new instance of script
process (AJAX engine)
| |
| |__ same - same browser window with new instance of script
process (AJAX engine)
| |
| |__ popup - new popup window
| |
| |__ FormInstanceName:SubformName[(bandindex)]
| | | |__ if not specified it's set to zero
| | |
| | |
| | |
| | |__ special strings : '_' ('_' denotes the containing sub
form)
| |
| |__ special strings :'self','parent','top'
|
|
|
|__ URL (this will result in a new instance of the script pro
cess to be instantiated)
|
|__ instancename:classname
|
|__ classname (in this case the instance name is implicitly s
et to be the same as the class name)

See also
 OpenForm, examples
 Openform Parameters

Page 804
OpenForm, examples

Here are some of the most common examples of what you may wish to
do.

Open a Form in a Subform


This opens 'Form B' inside 'Subform1', within 'Main Form'.

OpenForm ( 'Form B' , 'Main Form:Subform1' ,


' ' );

Open a Form in a Subform using special strings


To open 'FormB' into the current form, you can use the special string "Self" instead explicitly
stating it as "Main Form". Other special strings that could be used are "Parent" and "Top".
The significance and power of these special strings becomes clearer if the Form that your are
currently working with (in this case "Main Form") is also embedded or nested in a subform.

OpenForm ( 'Form B' , 'Self:Subform1' ,


' ' );

Open a Form in the current window


This command is identical to the traditional HTML hyperlink functionality. It opens the desired
Form or web site in the current browser window. If you only want to open it in the current
form, then use the special string "Self" instead of "Top".

Warning: Viewing the result of this command will take you out of this front-end interface!

OpenForm ( 'Form B' , 'Self:_' ,


' ' );

Open a Form utilizing parameters, example 1


To open a form or report that is connected to a datasource that is based one or more
parameters, you need to specify the details in the third set of parameters of OpenForm. In
this case, the BookForm is connected to a Parameter Query which is expecting a value for the
parameter 'CategoryIDParam'. 'BookForm' will then display all records from the datasource
with Category ID = 2. If no parameters are defined, the form will be filtered by the default
value of the Query Parameter.

OpenForm ( 'BooksForm' , 'Main Form:Subform1' ,


'"CategoryIDP aram=2"' );

Open a Form utilizing parameters, example 2


To open a form or report that is based on parameters, you need to specify the details in the
third set of parameters of OpenForm. In this case, PageSize which is the total number of
records to be displayed on the form at once is set to 2. If you don't specify this parameter,

Page 805
then BookForm assumes its default value.

OpenForm('BooksForm','Main Form:Subform1','"PageSize=
2"');

Open a web site in a new window


To open a web site in a new window, use the word "Blank". This command results in an
entirely independent Browser window appearing. That is, if you close the original form, then
this new window will remain and is fully functional.

OpenForm ( 'http://www.google.com' , 'Blank' ,


' ' );

Open a web site within a Subform


This example displays the Google web site within Subform1. By changing your Context
parameter in OpenForm (second parameter) you can either open a full URL in a separate
window or within a subform in your form.

OpenForm ( 'http://www.google.com' , 'Main Form:Subform1' ,


'"cls=file"' );

Open a document
This opens a PDF document that is not stored in a table, in a new browser window. As you
would expect, if you close the original browser window, this new browser window will remain
fully functional. This syntax works for virtually any kind of file that has a recognized MIME type
and parent application.

OpenForm ( 'http://localhost/Files/PressRelease.pdf' , 'Blank' ,


'"cls=file"' );

Open a document within a Subform


This opens a PDF document that is not stored in a table, into 'Subform1' within 'MainForm'.
This syntax works for virtually any kind of file that has a recognized MIME type and helper
application.

OpenForm ( 'http://localhost/Files/PressRelease.pdf' , 'Main Form:Subform1' ,


'"cls=file"' );

Open a document within a Subform


This opens a PDF document that is not stored in a table, into 'Subform1' within 'MainForm'.
This syntax works for virtually any kind of file that has a recognized MIME type and helper
application.

OpenForm ( 'http://localhost/Files/PressRelease.pdf' , 'Main Form:Subform1' ,

Page 806
'"cls=file"' );

See Also
 Working with Forms

Page 807
Openform Parameters

Introduction
The OpenForm function allows you to specify a double-quote-delimited, comma-separated list of
parameters as its third argument:

' Morfik Basic

OpenForm("MyForm", "Self:Subform1", """P aram1=X"",""P aram2=Y"


",...")

{ Morfik P ascal }

OpenForm('MyForm', 'Self:Subform1', '"P aram1=X","P aram2=Y",...');

// Morfik C#/J

OpenForm("MyForm", "Self:Subform1", "\"Param1=X\",\"P aram2=Y\",


...");

So, what can you put there?

System Parameters
OpenMode

Description: This parameter is related to the operation of morfik's subform cache. It can be used to
ensure that your xapp displays up-to-date content, or to perform pre-fetching of commonly requested
forms.

Possible values:

Refresh -- causes the xapp to download a new copy of the specified form, and display it on the
screen; any earlier copy of the form which may exist in the subform cache is discarded

DoNotActivate -- causes the xapp to download a copy of the specified form into the subform cache,
without displaying it on the screen

Applies to: all forms (excluding popup forms)

Draggable

Description: Specifies whether the popup form can be dragged around the page by the user.

Possible values: False , True

Applies to: popup forms

Modal

Description: Specifies whether the popup form is modal i.e. whether the user is blocked from
interacting with other controls while it is visible.
Possible values: False , True

Applies to: popup forms

Title

Page 808
Description: Specifies a string to display in the title bar of the popup form.

Possible values: any string

Applies to: popup forms

Closable

Description: Specifies whether the popup form should have a close (X) button in the top-right corner.

Possible values: False , True

Applies to: popup forms

Border

Description: Specifies the kind of border the popup form should have.

Possible values: Default , Rounded , None

Applies to: popup forms

Left

Description: Specifies the x coordinate against which the left-hand-side of the form should be
aligned.

Possible values: any integer

Applies to: popup forms

Top

Description: Specifies the y coordinate against which the top side of the form should be aligned.

Possible values: any integer

Applies to: popup forms

Center

Description: Specifies whether the form should initially be positioned in the center of the page.

Possible values: False , True

Applies to: popup forms

Transition

Description: Specifies the visual effect to use during the loading of the form.

Possible values: OverlayFadeIn , None

Applies to: popup forms

Form Parameters
Any parameters that you have added to the form's parameters dialog may be passed to the
OpenForm function.

Example:

OpenForm('MyForm', 'Self:Subform1', '"P aram1=XYZ


"');

Page 809
Query Parameters
If the datasource of your form is a parametric query, any of the query's parameters may be passed to
the OpenForm function.

Example:

OpenForm('MyForm', 'Self:Subform1', '"IDP aram=4


"');

Page 810
Page 811
Rectangle

This control is purely for presentation purposes. It allows you to create rectangles
in all their Form s. The default output is just an outline of a rectangle.

To create a filled in rectangle, which many call a box, simply define the
BackgroundColor property. To create a vertical line draw a rectangle and set the
horizontal width to be exactly 1 pixel. Likewise, if you want a horizontal line, set
the Height property to exactly 1 pixel.

Note

See also
 Toolbox

Page 812
PageBreak

See also
 Toolbox

Page 813
Report

A report is used to present data in the database. It displays the data on the page
in a highly readable format. Reports, though they can be read via the browser, are
primarily designed to be printed. Morfik AppsBuilder Reports are created natively
as Portable Document Format (PDF) documents. That is, they can be read via the
web browser through plug-ins such as Adobe Acrobat Reader, however, are
perfect for printing because it is printed in exactly the same manner that is shown.
This method of printing is universal over all platforms, computers, operating
systems, and printers. That is, virtually anyone can print a Morfik AppsBuilder
Report without having to download any extra pieces of software - and even if they
do, it is free.

The reports that you create in Morfik AppsBuilder are dynamic documents. Many
applications such as Virtual Printer Drivers can convert a document such as a
Microsoft Word Document into a PDF document. This results in static PDFs, that is,
the content of final PDF virtually identical to that of the original design, and only
the format is different.
Morfik AppsBuilder is a lot more powerful than this. It allows you to define the
content of the PDF documents on-the-fly based on Queries, user-interactions or
programming conditions. For example, if you have a Form that asks a user for a
Book title, Morfik AppsBuilder could search relevant tables and create a PDF report
that contains all the Publication information for the book as well as any reviews. If
the user then changes his or her mind and enters a different book title, then
another PDF report will be created with different content - but all from the same
Report design!

This exemplifies the Morfik AppsBuilder principle that if your Web pages and
Reports are data-driven than you only need to create them once, but they can be
used in an endless number of different ways.

Report Designer
Designing a Report is virtually identical to designing a Form, especially a Continuous Form. You
can place different types of controls, remembering that a PDF report is for presenting and not
entering or editing data. Therefore you are limited to the following simple controls:
TextLabels, Image, CheckBox, and Rectangle. You can also use the composite or higher-level
controls: Subreports and Panels. The concept and method of using Subreports is identical to
that of using Subforms.

Page 814
Report Headers and Footers
One difference between a Form and a Report is that a Report has two sets of headers:
Report header and page header. A Report header only appears once in the entire report,
regardless of whether the report is a single page or spans multiple pages. The page header,
on the other hand, will be repeated at the top of every page. That is, the first page will have
a Report header and a page header, whilst every successive page will only have a page
header. Similarly for the Report footer and the page footer.

Grouping and Sorting


Morfik AppsBuilder allows you to display the multiple records in a grouped and sorted manner.
For example, you may have entered all membership information about members in your club.
In some instances, it would be reasonable to list them according to the default order, which is
based on the internal Autonumber field. However, it may be more benefit to sort them
alphabetically by country (either in ascending or descending order). Further, if multiple
members come from the same country then you might wish to sort according them
alphabetically by surname. Morfik AppsBuilder allows you to do nested sorts utilizing up to a
depth of nine (9) levels.

Typically, if your data was displayed using a simple datagrid or table then this is about all you
could do to refine the presentation of your data - every row would have exactly the same
number of field elements. For example, every row would have the country field, and there may
be two hundred consecutive rows with the country field as "Australia" and then another five
hundred rows with "United States of America". This method of displaying data is very crude
and, in terms of internet transferral, very bandwidth inefficient due to the high amount of
repetition.

However, Morfik AppsBuilder allows you to have group your data. For example, every time a
record represents a different country to the previous record, then a Country header can
appear indicating the name of the country. The details band then, does not need to contain
the country field, as it is displayed in the header! Thus, the name of each distinct country is
only displayed once.

Within each group you might wish to group them according the first letter of their surname.
This level of grouping within groups can be implemented up to a depth of nine (9) levels.

Page 815
See also
 Grouping and sorting

Related Video
 How to work with Reports

Page 816
Table

Tables are the raison d'etre of databases. It is where all your data is stored. The
most common way to visualize a table is one that consists of rows and columns.
(This is not to say, that every table is a database!) Morfik AppsBuilder stores each
database entry (for example, each book) in its own row; this is a record. Each
record contains specific information related to one person, place or thing.

Each record is broken up into discrete pieces of information, called fields. Each field
consists of a separate column in the table Each field contains a different piece of
information that, taken all together, makes up a particular record. For example,
Surname is a field. All the surnames in the entire table (all in the same column) are
collectively known as the Surname field.

Technically, you only need a single table to make a database. However, because
Morfik AppsBuilder is powered by a relational database engine, it is much more
efficient and less problematic in the long run to design a database that separates
your data into multiple tables (this process is called 'normalization'). Each table
groups information by a particular theme, such as book information, or author
information, and then each of the tables that are related to one another are
linked via a relationship.

Data in tables can be entered, edited and displayed by the you as the developer
within the Morfik integrated design environment. This is called the Design Time.
Alternatively, the data within these tables can be entered when the database is
accessed by other people. This is called entering data at run time.

Creating Tables
creating tables

Morfik AppsBuilder gives you complete control over all aspects of the table's design, in an
manner that allows you to create Tables with extreme simplicity.

When you are creating a table in the Design View, you are creating the structure for the
table; you create a list of the fields that will be in the table. You also select the data type for
each field. (Fields can hold, text, numbers, dates, times, graphics and many other types of
multimedia.) You also have the option of entering a description for each field. Field
descriptions are useful in that they provide a quick summary of the type of data that goes into
the field.

Importing Tables
importing tables

Morfik can import data from a variety of data sources, including databases, spreadsheets and
text files. All available data source types that can be imported are listed below. Note that the
import process creates a local copy of the data and does not subsequently maintain a
connection to the original source.

Entering Data at Design-time


entering data

As stated before, with Morfik AppsBuilder you must define the table structure before entering
data. Entering data at this design stage is often called Entering data at design-time. You do
not need to enter any data into the tables during design time. Likewise, you could enter all of
your data here. Realistically, you will probably enter some at design time, and allow more
data to be entered by other users at run-time via a Form.

Once you have defined the Table structure there are numerous ways to begin entering data
via the datasheet: If you are in the Table Designer View then either:
 by selecting the Data Tab, or
 clicking on the Table icon and selecting Data view from the pull-down menu
If you are in the project window then select the Tables icon and then either

Page 817
 Select the Table that you wish to open and click on the Preview Action Button,or
right-click the icon and select from the contextual
 menu, "Preview".

Relationships between Tables


table relationship

To create a relationship between tables, open the Relationships window. There are three
ways of doing this. Either:
 Click on the relationships tab, which is located next to the Designer, Browser and Server tabs;
 Click on the system Tab and then select Relationships
select Relationships from the
 Tools menu.
The next step in defining relationships is adding all the relevant tables to the relationship
window. To do this
right-click and select
1 "Show Tables".
2 Click a table that you wish to add to the Relationships Window, and then select Add

3 Repeat this step for every table that you wish to show.
4 Click close on this Show Table dialog box.
Now that all the tables are displayed in the Relationships window, you may wish to resize
them so that you can see any desired fields.
To define the actual link between two tables simply select the primary key field and drag it
onto the foreign key field. After deciding whether you wish to enforce referential integrity, click
OK.

To indicate that the link was created a line is displayed that joins the primary key field with
the secondary key field. A number '1' appears near the primary key field and an 'infinity' sign
appears new the secondary field, this is is to indicate the one-to-many nature of the
relationship.

Page 818
creating tables

Morfik AppsBuilder gives you complete control over all aspects of the table 's
design, in an manner that allows you to create Table s with extreme simplicity.

When you are creating a table in the Design View, you are creating the structure
for the table; you create a list of the fields that will be in the table. You also select
the data type for each field. (Fields can hold, text, numbers, dates, times, graphics
and many other types of multimedia.) You also have the option of entering a
description for each field. Field descriptions are useful in that they provide a quick
summary of the type of data that goes into the field.

However Morfik, believes that in everything you do, the logic layer should be
clearly separated from the data. Therefore, you must first design the structure of
the table, and then enter data into it. To create a Table in the Design View:
1 Click the Table Document icon

and the click New (or right-click the mouse and select from the contextual menu)
Give the new table a name and then click OK. Do worry
too much about the name as it can easily be changed at
1 any time.
Type the field name for the first field in your Table. Then press Tab or Enter to move
2 to the Data Type column.
When you move to the Data Type column, an arrow
appears for a drop-down list. The default data type is
Text; but several other data types are available. The
different data types are discussed in the next section
3 "Understanding Data Types and Formats"

After selecting the data type, press Tab or Enter to move to the Description Column;
and type a description for this field. This is optional and is for your benefit and other
4 people who may wish to look at your database design. The database functionality is

Page 819
in no way whatsoever affected by what you enter.
Enter other fields and their
5 field types as needed.

See also
 Table

Related Video
 New Tables using Builtin Database

Page 820
importing tables

Morfik can import data from a variety of data sources, including databases,
spreadsheets and text files. All available data source types that can be imported
are listed below. Note that the import process creates a local copy of the data and
does not subsequently maintain a connection to the original source.
 Microsoft SQL Server
 Morfik

 Firebird
 Microsoft Access Driver

 Microsoft Text Driver


 Microsoft Excel Driver

 Microsoft dBase
 Microsoft Paradox

 Microsoft Visual FoxPro


 Microsoft FoxPro VFP

 Microsoft Access-Treiber
 Microsoft Excel-Treiber

 Microsoft dBase-Treiber
 Microsoft FoxPro-Treiber
When Morfik imports a table, it automatically appends about four specialized
Morfik fields to each table, including DateCreated, DateLastModified, and
GlobalUniqueIdentifier.

Page 821
entering data

As stated before, with Morfik AppsBuilder you must define the table structure
before entering data. Entering data at this design stage is often called Entering
data at design-time. You do not need to enter any data into the tables during
design time. Likewise, you could enter all of your data here. Realistically, you will
probably enter some at design time, and allow more data to be entered by other
users at run-time via a Form.

Once you have defined the Table structure there are numerous ways to begin
entering data via the datasheet:
If you are in the Table Designer View then either: Selecting
 the Data Tab, or
Clicking on the Table icon and selecting
 Data view from the pull-down menu

 Select the Table that you wish to open and click on the Preview Action Button, or
Right-click the icon and
select from the
contextual menu,
 "Preview".

Navigating in the Datagrid


Possibly the easiest way to enter data is enter data, one record at a time, field by field. Each
time you have entered data into a cell, then pressing the TAB key will advance you to the next
field. The following keys may also be useful

To Move to Press
Next Field TAB
Next Field, same record LEFT arrow-key
Previous field, same record RIGHT arrow-key
Previous Field SHIFT+TAB
Same field, next record DOWN arrow-key

Page 822
Same field, previous record UP arrow-key
First Record, same field CTRL+UP arrow-key
Last Record, same field CTRL+DOWN arrow-key
Last Field END key
First Field HOME key

Inserting and Deleting Records


To most common way to add a record, is to place the insertion point in the first blank row of
the Table Designer and enter the record at this point. You can achieve the same result by
clicking the "Insert New Record" icon. To insert a new record in the middle of the existing
table, press SHIFT+INSERT An asterisk sign appears next to a row if it is a new record
without any data in it. To remove a record, click the Delete Record" icon. Although it is easy to
delete fields, you must be very careful. When you delete a record, all the information stored in
each of its fields is deleted forever. Also if your Table has an AutoNumber field than that
number from the AutoNumber sequence lost forever. For example, if the AuthorID numbers
are 1, 2, 3, 4, 5, 6, 7 and you delete record number 5 and then add a new record, the new
sequence will be 1, 2, 3, 4, 6, 7, 8.

Hiding table fields


When you are entering data into the table, you might find that you have not actually collected
the data that you need to into a particular field. This means that you must skip this field in all
the records as you enter you data. (Of course, this isn't permanently - just until you have
collected the data!) You can hide a field or fields in the Table DataSheet. This doesn't delete
the field column or alter any of the field properties that you set when designing your table. It
just hides the field from your view as you enter your data. To hide a filed, follow these steps:
In the Datasheet View, either right-click and select "Edit Column Properties" or
1 click the Option icon.
2 Ensure that the Display Tab is showing. This displays all the fields associated with the Table
Select the field that you wish to
3 hide
4 Click the hide

5 Repeat these steps for each column that you wish to hide.
6 Click OK to close the Options Window.

Copying, cutting and pasting data


The following formatting shortcuts are fully functional in Morfik AppsBuilder: Sometimes the
shortcuts CTRL+C, CTRL+X and CTRL+V do not work fully. We are currently working on this
bug. You can select multiple objects by holding the SHIFT key down as you select objects.

Function Key Combination


Copy | CTRL+INSERT, CTRL+C
Cut | SHIFT+DELETE, CTRL+X
Paste | SHIFT+INSERT,
CTRL+V
Delete | CTRL+DELETE

Note

See also
 Table

Page 823
table relationship

To create a relationship between tables, open the Relationships window. There


are three ways of doing this. Either:
Click on the relationships tab, which is located next to the Designer, Browser and
 Server tabs;
 Click on the system Tab and then select Relationships
select Relationships from the
 Tools menu.
The next step in defining relationships is adding all the relevant tables to the
relationship window. To do this
right-click and select
1 "Show Tables".
Click a table that you wish to add to the Relationships Window, and then select
2 Add

3 Repeat this step for every table that you wish to show.
4 Click close on this Show Table dialog box.
Now that all the tables are displayed in the Relationships window, you may wish
to resize them so that you can see any desired fields.
To define the actual link between two tables simply select the primary key field
and drag it onto the foreign key field. After deciding whether you wish to enforce
referential integrity, click OK.

To indicate that the link was created a line is displayed that joins the primary key
field with the secondary key field. A number '1' appears near the primary key field
and an 'infinity' sign appears new the secondary field, this is is to indicate the
one-to-many nature of the relationship.

Understanding table relations


Technically, you only need a single table to make a database. However, because Morfik

Page 824
AppsBuilder is powered by a relational database engine, it is much more efficient and better in
the long run to design a database that separates your data into multiple tables. Each table
groups information by a particular theme, such as book information, or author information.
Morfik AppsBuilder enables you to build relationships between tables. These relationships are
based on a field that is common to two tables. For example, BookTable,might contain a
GenreID field that identifies each genre by a unique number. You might also have a table that
holds your information about different genres called GenreTable. To link the BookTable to the
GenreTable, you include the GenreID field in both tables. This identifies each book by genre
and links the BookTable to the GenreTable data via a one-to-many relationship. That is, for
any one genre there can be many books but for any book there is only one genre.

+ BookID Author Surname Title GenreID


BookTable
1 Covey The 8th Habit 2
2 Frank The Hour 1
Game
3 Agatso The South 2
n Beach Diet
4 Ellis His Excellency 4

+ GenreID Genre
GenreTable
1 Fiction
2 LifeStyle
3 Politics
4 Biograph
y

We can see what genre the "South Beach Diet" is by following the relationship to see that it
is genre 2, or "LifeStyle". Notice that this linking system eliminates the need to repeat the
entry "LifeStyle" in the BookTable. This careful designing of tables, can lead to efficient
updates. For example, if we want to change the second genre from "LifeStyle" to "Personal
Development" then only one field of one record needs to be changed. This would not be the
case if all this book data was designed within a single table. These two tables relate through

Page 825
the GenreID field in both tables. In the GenreTable, the GenreID is called the Primary Field
and in the BookTable it is called the Foreign field. Data in tables can be entered, edited and
displayed by the you as the developer within the Morfik integrated design environment. This
is called the Design Time. Alternatively, the data within these tables can be entered when the
database is accessed by other people. This is called entering data at run time. The key to
creating relationships revolves around primary keys for your tables.

Referential Integrity
referential integrity

Referential integrity is a system of rules that relational databases such as Morfik AppsBuilder
uses to ensure that the data between records in related tables are valid, and that you don't
accidentally delete or change related data. The following rules apply when you use
referential integrity: You can't enter a value in the foreign key field of the related table that
doesn't exist in the primary key of the primary table. For example, you can not have a record
in the Book Table with an GenreID of 5, because this is not defined in the GenreTable. You
can't delete a record from a primary table if matching records exist in a related table. For
example, you can not delete the second record from the GenreTable because it is liked to the
first and third record in the BookTable. However, you could delete the third record in the
Genre Table, as it has no matching record in the BookTable. You can't change a primary key
value in the primary table, if that record has related records. For example. you can't change
the GenreID value in the second record of GenreTable because it has linked data in the Book
Table.

Editing a relationship
To edit any of the relationships that you have created simply double-click on the relationship
link, which is the line joining the two tables, and the Edit Relationships window will appear.

Removing a relationship
To remove or delete any of the relationships that you have created simply select and then
right-click on the relationship link, which is the line joining the two tables, and then choose
the "Delete" option.

Note

Deleting and Copying tables that involve relationships


Morfik AppsBuilder does not let you delete or copy Tables that involve relationships.
Therefore, to delete a Table you must first delete all of its links with other Tables. If you wish
to copy or duplicate a Table (which might just be the Table design or it might be the Table
Design and all of its data) then you will need to temporarily delete any links that the Table
has with other Tables. After copying the desired Table(s) you will then need to create
previously existing links again.

Page 826
referential integrity

Referential integrity is a system of rules that relational databases such as Morfik


AppsBuilder uses to ensure that the data between records in related tables are
valid, and that you don't accidentally delete or change related data.

The following rules apply when you use referential integrity: You can't enter a
value in the foreign key field of the related table that doesn't exist in the primary
key of the primary table. For example, you can not have a record in the Book Table
with an GenreID of 5, because this is not defined in the GenreTable. You can't
delete a record from a primary table if matching records exist in a related table.
For example, you can not delete the second record from the GenreTable because
it is liked to the first and third record in the BookTable. However, you could delete
the third record in the Genre Table, as it has no matching record in the BookTable.
You can't change a primary key value in the primary table, if that record has
related records. For example. you can't change the GenreID value in the second
record of GenreTable because it has linked data in the Book Table.

Book Table (BookID is set as the primary key, and GenreID is a foreign key)
BookID Author Surname Title GenreID 1 Covey The 8th Habit 2 2 Frank The Hour
Game 1 3 Agatson The South Beach Diet 2 4 Ellis His Excellency 4

Genre Table (GenreID is set as the primary key) GenreID Genre 1 Fiction 2
LifeStyle 3 Politics 4 Biography

For relationships in which referential integrity is enforced, you can specify whether
you want Morfik to automatically cascade update and cascade delete related
records. If you set these options, the delete and update operations that would
normally be prevented by referential integrity rules are allowed. When you delete
records or change primary key values in a primary table, Morfik JST makes
necessary changes to related tables to preserve referential integrity. If you select
the Cascade Update Related Fields check box when defining a relationship, any
time you change the primary key of a record in the primary table, Morfik
AppsBuilder automatically updates the primary key to the new value in all related
records. For example, if you change a GenreID in the GenreTable, the GenreID
field in BookTables is automatically updated for every one of the BookTable
records so that the relationship isn't broken. Morfik AppsBuilder cascades updates
without displaying any message. Note: If the primary key in the primary table is
an AutoNumber field, setting the Cascade Update Related Fields check box will
have no effect, because you can't change the value in an AutoNumber field. If you
select the Cascade Delete Related Records check box when defining a
relationship, any time you delete records in the primary table, Morfik AppsBuilder
automatically deletes related records in the related table. For example, if you
delete a genre (record) from the GenreTable, all linked records in BookTable are
automatically deleted from the BookTable. When you delete records from a form or
datasheet with the Cascade Delete Related Records check box selected, Morfik

Page 827
AppsBuilder warns you that related records may also be deleted. However, when
you delete records using a delete query, Morfik AppsBuilder automatically deletes
the records in related tables without displaying a warning.

Page 828
Query

Queries enable you to retrieve a subset of the data in your database tables. For
example, a query can contain criteria that provide you with a list of books that
have been written more than 10 years ago or with all the books that were written
in a particular genre.

Queries are an excellent way for you to determine the status of your particular
situation. For example, you could create a query to give you the total sales for a
particular month. Queries are questions regarding the data that is stored in your
database.

Designing Queries is very simple using the Visual Query Designer or the Query
Wizard.

Parameter Queries
Queries can involve fields from multiple tables - and even other queries (nested queries). Also queries
can be based on user-inputs. For example, on a web page the user might be asked to enter the
maximum price he is willing to pay for a book. A Parameter Query can take this number and create a
list of all books whose price is less than this value.

Database connectivity is a major point in any modern application. Databases have become so
ubiquitous that most people do not even stop to think about them. Databases are mainly taken for

Page 829
granted as part of any developer's arsenal of tools to attack any specific problem.

With that in mind Morfik not only chose to provide a fully integrated relational database server, but to
also offer support for connecting to other databases such as MS SQL, MySQL and Oracle.

A query is a question that you pose to the database. They are a powerful tool for analyzing and
summarizing database information. For example, you might want to know which Books have been
published by a specific publisher in the last ten years. Queries enable you to specify:

which table or tables are involved in the query the order of the fields from the table(s) filter and sort
criteria for each field in the query.

Note: If you are wishing to use multiple tables in a query, then the tables must already be linked by a
relationship.

In Morfik AppsBuilder 'action queries' such as:

adding a new record deleting an existing record navigating to the next or previous record are
implemented via the Page and Record Navigator, or programmatically through very simple coding and
are not really related to the Query documents or the Visual Query Builder.

Complex Queries
Morfik Appsbuilder is capable of doing complex queries including:
 Nested Queries
 Aggregate Queries

 Filter by example

Non-Visual And Pass-Through Queries


When editing a non-visual or pass-through query, instead of using the visual query designer, the user
must type the SQL code directly.

This is mainly useful for advanced users.

It is important to understand the difference between non-visual and pass-through queries:


with non-visual queries, the SQL code entered by the
user is processed by Morfik's SQL parser before
 being passed to the database engine
with pass-through queries, the SQL code entered by the user is passed directly to the database
 engine without being checked by morfik
This has the following implications:
syntax errors are
notified differently for
non-visual and
 pass-through queries
in non-visual queries, you do not have to put quotation marks around field or table
 names
in non-visual queries, field and table
names in your SQL code are
 case-insensitive
query parameters are automatically detected for non-visual queries, but must be manually specified for
 pass-through queries
in pass-through queries, any parameter names in your SQL
code must be preceded by a colon (:)

Page 830

if your SQL code makes use of constructs that are unknown to Morfik's SQL parser, you must use a
 pass-through query
when a non-visual query is re-opened, its SQL code will be
 reformatted according to Morfik conventions
A non-visual query may be converted to a pass-through query at any time, by changing its
SyntaxChecked property (true corresponds to non-visual; false corresponds to pass-through).

Consider an example.

In the AjaxSMB project, suppose that we want to create an SQL union query that combines data from
the Customers and Employees tables.

The visual query designer does not have the ability to represent such a query.

Navigate to the queries folder of the project, and double-click on the command Create query by typing
SQL code .

This pops up a dialog asking what name to give to the query; let's call it People .

In the SQL editor paste the following code:

SELECT "EmployeeID" AS "P ersonID", "FirstName" || ' ' || "LastName" AS "P ersonName" FROM "Employees" UN
ION SELECT "CustomerID", "ContactName" FROM "Customers"

When you run the query, it returns a dataset with two columns: PersonID and PersonName.

Related Video
 Introduction to Morfik Queries
 Queries with Parameters

 Aggregate and Nested Queries


 Passthrough Queries in Morfik

Page 831
Property sheet

Briefly, the property sheet allows you to view and edit properties associated with
sections of the Report , Form or any of its control s. The Property sheet will
appear every time the control (or section of a Form / Report ) is double-clicked. It
will then disappear when the control loses focus. Alternatively, one can always
bring up the Property Sheet by pressing F11.

If the Property Sheet is visible, pressing ESC will force the Property Sheet to
display the control of the parent component. For example, if the Property Sheet is
displaying the properties of a TextLabel that has been placed on a Form, then
pressing ESC will force the Property Sheet to display the control of the Detail
Form. Pressing it again, will make display the Properties of the Form. Alternatively,
one can select from the pull-down menu which component the Property Sheet will
describe. note

Page 832
Morfik Controls - ListBox

Figure 1 – A ListBox control.

In Morfik AppsBuilder the ListBox control may be used when the user must input
information which is chosen from a predetermined list.

Frequently used
Properties
DataField
Items
Other Properties
BorderColor
BorderStyle
BorderWidth
Color
Cursor
Enabled
Font
Height
Hint
Left
MultiSelect
Name
Opacity
Sorted
TabOrder
Top
Visible
Width
Events
OnAfterPushedOrPulled

OnBeforePushedOrPulled
OnBlur
OnChange
OnClick

Page 833
OnDoubleClick
OnFocus
OnKeyDown
OnKeyUp
OnMouseDown
OnMouseOut
OnMouseOver
OnMouseUp
See also

Frequently used Properties

DataField
The DataField property is used to bind the ListBox to a database table field. Either through a
table or a query which is specified in the Form's DataSource property.

Items
The Items property specifies the list of values that will be displayed in the ListBox.

Other Properties

BorderColor
The BorderColor property specifies the color of the rectangular border drawn around the
ListBox.

BorderStyle
The BorderStyle property of the ListBox control defines how and if a border will be drawn
around the control. The available style options are: 3D, Flat and None. The 3D style gives the
ListBox a light 3D effect. The Flat option gives the ListBox a solid, thin, line as a border.

BorderWidth
The BorderWidth property specifies the line width used to draw the rectangular border
around the ListBox.

Color
The Color property is used to set the color in which the ListBox will be drawn.

Cursor
The Cursor property, if set, causes the appearance of the mouse cursor to change as it moves
over the ListBox.

Enabled
If the Enabled property is set to false, the user will not be able to change the value stored in
the ListBox. Note: this is not working in the current release.

Font
The Font property specifies the font used to display the text in the ListBox.

Height

Page 834
The Height property specifies the vertical extent of the ListBox.

Hint
The Hint property, if set, specifies the text of a tooltip that is displayed when the user moves
the cursor over the ListBox.

Left

MultiSelect
If MultiSelect is false, the user may only select one value from the list. If MultiSelect is true,
the user may select any number of values from the list. Note: multi-select mode is not working
in the current release.

Name
The Name property specifies the identifier used to reference the ListBox from browser- or
server-side code.

Opacity
The Opacity property determines the extent to which the ListBox obscures any controls placed
in its background. A value of 0 means that background controls are fully visible, whereas a
value of 100 means that background controls are completely obscured.

Sorted

TabOrder
The TabOrder property allows the developer to specify the order in which controls should
receive input focus when the user steps through them using the tab key.

Top
The Top property specifies the vertical position of the ListBox.

Visible
The Visible property is used to make ListBox controls visible or invisible to the end user.

Width
The Width property specifies the horizontal extent of the ListBox.

Events

OnAfterPushedOrPulled
The OnAfterPushedOrPulled event occurs after the ListBox's position has changed in response
to a grow-and-shrink event.

OnBeforePushedOrPulled
The OnBeforePushedOrPulled event occurs before the ListBox's position changes in response
to a grow-and-shrink event.

OnBlur
The OnBlur event occurs when the ListBox loses keyboard focus.

OnChange
The OnChange event indicates that the selected item in the ListBox was changed by the
user.

Page 835
OnClick
The OnClick event occurs when the user clicks on the ListBox.

OnDoubleClick
The OnDoubleClick event occurs when the user double-clicks on the ListBox.

OnFocus
The OnFocus event occurs when the ListBox receives keyboard focus.

OnKeyDown

OnKeyUp

OnMouseDown
The OnMouseDown event occurs when the user depresses the left mouse button while the
cursor is over the ListBox.

OnMouseOut
The OnMouseOut event occurs when the mouse cursor moves out of the ListBox.

OnMouseOver
The OnMouseOver event occurs when the mouse cursor moves into the ListBox.

OnMouseUp
The OnMouseUp event occurs when the user releases the left mouse button while the cursor
is over the ListBox.

See also
 Morfik Controls
 Control Effects

Page 836
Morfik Controls -
OptionButton

Figure 1 – An OptionButton control.

In Morfik AppsBuilder the OptionButton control may be used when the user must
choose between a set of fixed, mutually exclusive options.

Frequently used
Properties
Caption
Checked
Other Properties
BorderColor
BorderStyle
BorderWidth
CanGrow
CanShrink
Color
Cursor
Enabled
Font
Height
Hint
HorizontalPlacement
Left
Name
Opacity
TabOrder
Top
VerticalPlacement
Visible
Width
Events
OnAfterPrint
OnAfterPushedOrPulled

OnBeforePrint

OnBeforePushedOrPulled
OnBlur
OnClick

Page 837
OnDoubleClick
OnFocus
OnKeyDown
OnKeyUp
OnMouseDown
OnMouseOut
OnMouseOver
OnMouseUp
OnPrintStyle
See also

Frequently used Properties


The following is a list of the most commonly used properties of the OptionButton control with
a short description of their function.

Caption
The Caption property specifies the text to be displayed in the OptionButton.

Checked
The Checked property specifies whether the OptionButton should be displayed in the ticked or
unticked state.

Other Properties
The following is a list of less-commonly used properties of the OptionButton control with a
short description of their function.

BorderColor
The BorderColor property specifies the color of the rectangular border drawn around the
OptionButton. Note: the border will not be visible unless the BorderStyle property is also set.

BorderStyle
The BorderStyle property of the OptionButton control defines how and if a border will be
drawn around the control. The available style options are: 3D, Flat and None. The 3D style
gives the OptionButton a light 3D effect. The Flat option gives the OptionButton a solid, thin,
line as a border.

BorderWidth
The BorderWidth property specifies the line width used to draw the rectangular border
around the OptionButton. Note: the border will not be visible unless the BorderStyle property
is also set.

CanGrow
The CanGrow property determines the behavior when the Caption text is too large to fit into
the OptionButton:
if CanGrow=No, the OptionButton
 retains its design-time height
if CanGrow=Scroll, the OptionButton retains its design-time height, but allows the end user to
 scroll through the text
if CanGrow=Yes, the OptionButton increases its height to
 accommodate the text

Page 838
CanShrink
The CanShrink property determines the behavior when the Caption text is too small to
completely fill the OptionButton:
if CanShrink=False, the OptionButton maintains
 its design-time height
if CanShrink=True, the OptionButton decreases its height to accommodate the text Note:
 enabling CanShrink has no effect unless CanGrow is also enabled.

Color
The Color property is used to set the color in which the OptionButton will be drawn.

Cursor
The Cursor property, if set, causes the appearance of the mouse cursor to change as it moves
over the OptionButton.

Enabled
If the Enabled property is set to false, the user will not be able to modify the state (ticked or
unticked) of the OptionButton.

Font
The Font property, and its sub-properties Color and Name, specify the font to be used for
displaying the OptionButton's Caption.

Height
The Height property specifies the vertical extent of the OptionButton.

Hint
The Hint property, if set, specifies the text of a tooltip that is displayed when the user moves
the cursor over the OptionButton.

HorizontalPlacement
The HorizontalPlacement property, if set, governs how the OptionButton adjusts its size and
position in response to changes in the horizontal dimensions of its parent.

Left
The Left property specifies the horizontal position of the OptionButton.

Name
The Name property specifies the identifier used to reference the OptionButton from browser-
or server-side code.

Opacity
The Opacity property determines the extent to which the OptionButton obscures any controls
placed in its background. A value of 0 means that background controls are fully visible,
whereas a value of 100 means that background controls are completely obscured.

TabOrder
The TabOrder property allows the developer to specify the order in which controls should
receive input focus when the user steps through them using the tab key.

Top
The Top property specifies the vertical position of the OptionButton.

Page 839
VerticalPlacement
The VerticalPlacement property, if set, governs how the OptionButton adjusts its size and
position in response to changes in the vertical dimensions of its parent.

Visible
The Visible property is used to make OptionButton controls visible or invisible to the end user.

Width
The Width property specifies the horizontal extent of the OptionButton.

Events

OnAfterPrint
The OnAfterPrint event occurs after the OptionButton is rendered into the form's HTML code.

OnAfterPushedOrPulled
The OnAfterPushedOrPulled event occurs after the OptionButton's position has changed in
response to a grow-and-shrink event.

OnBeforePrint
The OnBeforePrint event occurs before the OptionButton is rendered into the form's HTML
code.

OnBeforePushedOrPulled
The OnBeforePushedOrPulled event occurs before the OptionButton's position changes in
response to a grow-and-shrink event.

OnBlur
The OnBlur event occurs when the OptionButton loses keyboard focus.

OnClick
The OnClick event occurs when the user clicks on the OptionButton.

OnDoubleClick
The OnDoubleClick event occurs when the user double-clicks on the OptionButton.

OnFocus
The OnFocus event occurs when the OptionButton receives keyboard focus.

OnKeyDown
The OnKeyDown event occurs when the user depresses a key while the OptionButton has
focus.

OnKeyUp
The OnKeyUp event occurs when the user releases a key while the OptionButton has focus.

OnMouseDown
The OnMouseDown event occurs when the user depresses the left mouse button while the
cursor is over the OptionButton.

OnMouseOut

Page 840
The OnMouseOut event occurs when the mouse cursor moves out of the OptionButton.

OnMouseOver
The OnMouseOver event occurs when the mouse cursor moves into the OptionButton.

OnMouseUp
The OnMouseUp event occurs when the user releases the left mouse button while the cursor
is over the OptionButton.

OnPrintStyle
The OnPrintStyle event occurs before the OptionButton's style attribute is rendered into the
form's HTML code.

See also
 Morfik Controls
 Most Frequently Used Controls

 Control Effects

Page 841
Morfik Controls -
PopupWindow

Figure 1 – A PopupWindow control.

The PopupWindow control is used to customize the appearance of popup windows


in your XApp.

Usage
Frequently used
Properties
BorderColor
BorderStyle
BorderWidth
Other Properties
Cursor
Height
Hint
Left
Name
Opacity
Top
Width
Events
See also

Usage
The PopupWindow control is unusual in that it is not intended to be used directly. Rather, one
is created implicitly every time an OpenWindow statement is executed. In order to customize
the appearance of popup windows in your XApp, follow these steps:
1 place a PopupWindow control on an unused form
set the PopupWindow's
2 properties as desired

3 go to the Style panel and update the Default style.

Frequently used Properties

Page 842
The following is a list of the most commonly used properties of the PopupWindow control with
a short description of their function.

BorderColor
The BorderColor property specifies the color that should be used for drawing a rectangular
border around the PopupWindow. Note: the border will not be visible unless the BorderStyle
and BorderWidth properties are also set.

BorderStyle
The BorderStyle property specifies the line style that should be used for drawing a
rectangular border around the PopupWindow. Note: the border will not be visible unless the
BorderColor and BorderWidth properties are also set.

BorderWidth
The BorderWidth property specifies the width of a rectangular border to be drawn around the
PopupWindow. Note: the border will not be visible unless the BorderColor and BorderStyle
properties are also set.

Other Properties
The following is a list of less-commonly used properties of the PopupWindow control with a
short description of their function.

Cursor
The Cursor property, if set, causes the appearance of the mouse cursor to change as it moves
over the control.

Height
The Height property specifies the vertical extent of the PopupWindow.

Hint
The Hint property, if set, specifies the text of a tooltip that is displayed when the end user
moves the mouse cursor over the PopupWindow.

Left
The Left property specifies the horizontal position of the PopupWindow.

Name
The Name property specifies the identifier used to reference the PopupWindow from browser-
or server-side code.

Opacity
The Opacity property determines the extent to which the PopupWindow obscures any
controls placed in its background. A value of 0 means that background controls are fully
visible, whereas a value of 100 means that background controls are completely obscured.

Top
The Top property specifies the vertical position of the PopupWindow.

Width
The Width property specifies the horizontal extent of the PopupWindow.

Events
The PopupWindow control has no events.

Page 843
See also
 Morfik Controls
 Most Frequently Used Controls

 Control Effects

Page 844
Morfik Controls -
Rectangle

Figure 1 – A Rectangle control.

In Morfik AppsBuilder the Rectangle control is used mainly for decorative purposes,
in order to create a visual effect

Usage
Frequently used
Properties
BorderStyle
BorderColor
BorderWidth
Color
Other Properties
Cursor
Enabled
Height
Hint
HorizontalPlacement
Left
Name
Opacity
Top
Vertical Placement
Visible
Width
Events
OnAfterPrint
OnAfterPushedOrPulled

OnBeforePrint

OnBeforePushedOrPulled
OnBlur
OnClick
OnDoubleClick
OnFocus
OnKeyDown

Page 845
OnKeyUp
OnMouseDown
OnMouseOut
OnMouseOver
OnMouseUp
OnPrintStyle
Morfik Effects
Sample Code
See also

Usage
The Rectangle control is used in Morfik applications, primarily for decorative and visual
organization purposes. A good example of using the Rectangle control in an application can
be found in the user Book_catalog Form of the Booktrader application. This Form can be seen
in figure 2. In this case the Rectangle control is used visual organization.

Figure 2 – Book_catalog Form of the Booktrader sample application, two Rectangle controls
being used to create separator lines (blue and orange).

To see a live version of this application click here .

Frequently used Properties


The following is a list of the most commonly used properties of the Rectangle control with a
short description of their function.

BorderStyle
The BorderStyle property of the Rectangle control defines how and if a border will be drawn
around the control. The available style options are: Dashed , Dotted , InSet , None , OutSet and
Single. The InSet and OutSet styles give the Rectangle a light 3D effect. The Single option
gives the Rectangle a solid line as a border.

BorderColor
The BorderColor property can be used to set the color in which an outline will be drawn around
the control. As Image controls, by default, have the BorderStyle property set to a flat border,
this property is a very important part of defining "the look" of the control.

Page 846
BorderWidth
The BorderWidth property defines the thickness of the border which will drawn around the
control.

Color
The color property defines how the rectangle's interior will be painted on the page.

Other Properties
The following is a list of the less commonly used properties of the Rectangle control with a
short description of their function.

Cursor
The Cursor property, if set, causes the appearance of the cursor to change as it moves over
the Rectangle.

Enabled
The Enabled property has no effect for Rectangle controls.

Height
The Height property specifies the vertical extent of the Rectangle.

Hint
The Hint property, if set, specifies the text of a tooltip that is displayed when the user moves
the cursor over the Rectangle.

HorizontalPlacement
The HorizontalPlacement property, if set, governs how the Rectangle adjusts its size and
position in response to changes in the horizontal dimensions of its parent.

Left
The Left property specifies the horizontal position of the Rectangle.

Name
The Name property specifies the identifier used to reference the Rectangle from browser- or
server-side code.

Opacity
The Opacity property determines the extent to which the Rectangle control obscures any
controls placed in its background. A value of 0 means that background controls are fully
visible, whereas a value of 100 means that background controls are completely obscured.

Top
The Top property specifies the vertical position of the Rectangle control.

Vertical Placement
The VerticalPlacement property, if set, governs how the Rectangle adjusts its size and
position in response to changes in the vertical dimensions of its parent.

Visible
The Visible property is used to make Rectangle controls visible or invisible to the end user.

Page 847
Width
The Width property specifies the horizontal extent of the Rectangle control.

Events
Rectangle controls in Morfik are used primarily in a decorative role, thus making it rare that
any of their events need to be handled. Their events are documented here for the sake of
completeness.

OnAfterPrint
The OnAfterPrint event occurs after the Rectangle is rendered into the form's HTML code.

OnAfterPushedOrPulled
The OnAfterPushedOrPulled event occurs after the Rectangle's position has changed in
response to a grow-and-shrink event.

OnBeforePrint
The OnBeforePrint event occurs before the Rectangle is rendered into the form's HTML code.

OnBeforePushedOrPulled
The OnBeforePushedOrPulled event occurs before the Rectangle's position changes in
response to a grow-and-shrink event.

OnBlur
The OnBlur event does not occur for Rectangles.

OnClick
The OnClick event occurs when the user clicks on the Rectangle.

OnDoubleClick
The OnDoubleClick event occurs when the user double-clicks on the Rectangle.

OnFocus
The OnFocus event does not occur for Rectangles.

OnKeyDown
The OnKeyDown event does not occur for Rectangles.

OnKeyUp
The OnKeyUp event does not occur for Rectangles.

OnMouseDown
The OnMouseDown event occurs when the user depresses the left mouse button while the
cursor is over the Rectangle.

OnMouseOut
The OnMouseOut event occurs when the mouse cursor moves out of the Rectangle.

OnMouseOver
The OnMouseOver event occurs when the mouse cursor moves into the Rectangle.

Page 848
OnMouseUp
The OnMouseUp event occurs when the user releases the left mouse button while the cursor
is over the Rectangle.

OnPrintStyle
The OnPrintStyle event occurs before the Rectangle's style attribute is rendered into the
form's HTML code.

Morfik Effects
You can apply a series of visual effects to a rectangle in the Morfik Forms designer. Figure 3
shows a sample rectangle with the Shadow and Corners effect applied to it.

Figure 3 – A Rectangle control with some effects applied to it.

For more information on all the effects which are available please refer to the Control Effects
topic.

Sample Code
The Rectangle control is not frequently referenced in code. Most of the time when it is
referenced, however, it is to change its visible state or its color.

The following code snippet sets an Rectangle control's Visible property to a new value.

Rectangle1 . Visible := T rue


;

See also
 Morfik Controls
 Most Frequently Used Controls

 Control Effects

Page 849
Morfik Controls -
RSSButton

Figure 1 – An RSS Button control.

In Morfik AppsBuilder the RSS Button control may be used to provide a visual
indication of the RSS feed(s) published by the XApp.

Frequently used
Properties
Caption
Feed
Other Properties
BorderColor
BorderStyle
BorderWidth
Cursor
Font
Height
Hint
HorizontalPlacement
Left
Name
Opacity
Picture
Top
VerticalAlignment
VerticalPlacement
Visible
Width
Events
OnAfterPrint
OnAfterPushedOrPulled

OnBeforePrint

OnBeforePushedOrPulled
OnBlur
OnClick
OnDoubleClick
OnFocus
OnMouseDown

Page 850
OnMouseOut
OnMouseOver
OnMouseUp
OnPrintStyle
See also

Frequently used Properties


The following is a list of the most commonly used properties of the RSS Button, with a short
description of their function.

Caption
The Caption property specifies the text to be displayed in the RSS Button.

Feed
Use the Feed property to specify which of the project's RSS Feed Sources the button should
link to.

Other Properties
The following is a list of the less commonly used properties of the RSS Button control with a
short description of their function.

BorderColor
The BorderColor property specifies the color of the rectangular border drawn around the RSS
Button. Note: the border will not be visible unless the BorderStyle and BorderWidth properties
are also set.

BorderStyle
The BorderStyle property of the RSS Button control defines how and if a border will be drawn
around the control. The available style options are: 3D, Flat and None. The 3D style gives the
RSS Button a light 3D effect. The Flat option gives the RSS Button a solid, thin, line as a
border. Note: the border will not be visible unless the BorderColor and BorderWidth
properties are also set.

BorderWidth
The BorderWidth property specifies the line width used to draw the rectangular border
around the RSS Button. Note: the border will not be visible unless the BorderColor and
BorderStyle properties are also set.

Cursor
The Cursor property, if set, causes the appearance of the cursor to change as it moves over
the RSS Button.

Font
The Font property, and its sub-properties Color and Name, specify the font to be used for
displaying the Caption.

Height
The Height property specifies the vertical extent of the RSS Button.

Hint

Page 851
The Hint property, if set, specifies the text of a tooltip that is displayed when the user moves
the cursor over the RSS Button.

HorizontalPlacement
The HorizontalPlacement property, if set, governs how the RSS Button adjusts its size and
position in response to changes in the horizontal dimensions of its parent.

Left
The Left property specifies the horizontal position of the RSS Button.

Name
The Name property specifies the identifier used to reference the RSS Button from browser- or
server-side code.

Opacity
The Opacity property determines the extent to which the RSS Button obscures any controls
placed in its background. A value of 0 means that background controls are fully visible,
whereas a value of 100 means that background controls are completely obscured.

Picture
The Picture property specifies the image to be displayed in the RSS Button control. (By default,
it uses the standard icon seen on most RSS-enabled websites today.)

Top
The Top property specifies the vertical position of the RSS Button.

VerticalAlignment
The VerticalAligment property specifies whether the RSS Button's Caption and Picture are
aligned with the top, center or bottom of the control.

VerticalPlacement
The VerticalPlacement property, if set, governs how the RSS Button adjusts its size and
position in response to changes in the vertical dimensions of its parent.

Visible
The Visible property is used to make RSS Buttons visible or invisible to the end user.

Width
The Width property specifies the horizontal extent of the RSS Button.

Events

OnAfterPrint
The OnAfterPrint event occurs after the RSSButton is rendered into the form's HTML code.

OnAfterPushedOrPulled
The OnAfterPushedOrPulled event occurs after the RSSButton's position has changed in
response to a grow-and-shrink event.

OnBeforePrint
The OnBeforePrint event occurs before the RSSButton is rendered into the form's HTML code.

Page 852
OnBeforePushedOrPulled
The OnBeforePushedOrPulled event occurs before the RSSButton's position changes in
response to a grow-and-shrink event.

OnBlur
The OnBlur event occurs when the RSSButton loses keyboard focus.

OnClick
The OnClick event occurs when the user clicks on the RSSButton.

OnDoubleClick
The OnDoubleClick event occurs when the user double-clicks on the RSSButton.

OnFocus
The OnFocus event occurs when the RSSButton receives keyboard focus.

OnMouseDown
The OnMouseDown event occurs when the user depresses the left mouse button while the
cursor is over the RSSButton.

OnMouseOut
The OnMouseOut event occurs when the mouse cursor moves out of the RSSButton.

OnMouseOver
The OnMouseOver event occurs when the mouse cursor moves into the RSSButton.

OnMouseUp
The OnMouseUp event occurs when the user releases the left mouse button while the cursor
is over the RSSButton.

OnPrintStyle
The OnPrintStyle event occurs before the RSSButton's style attribute is rendered into the
form's HTML code.

See also
 Morfik Controls

Page 853
Morfik Controls -
SubForm

Figure 1 – A SubForm control statically bound to a Form.

In Morfik AppsBuilder the SubForm control allows the insertion of Forms within
other Forms. This allows the creation of complex and sophisticated views through
the creation of smaller and simpler parts which are then combined.

Usage
With TabControls
Frequently used
Properties
Form
BorderStyle
BorderColor
BorderWidth
Color
CanGrow
CanShrink
Other Properties
Height
Hint
HorizontalPlacement
Left
Name
Opacity
Parameters
Top
VerticalPlacement
Visible
Width
Events
OnAfterGrowOrShrink
OnAfterPrint
OnAfterPushedOrPulled

Page 854
OnBeforeGrowOrShrink

OnBeforePrint

OnBeforePushedOrPulled
OnPrintStyle
Sample Code
Morfik Effects
See also
Related Video

Usage
The SubForm control is used in just about every Morfik application. A good example of its use is the
Simple Blog sample project that is included with Morfik AppsBuilder. Figure 2 shows a one of the
Forms in this project which includes three SubForm controls.

Figure 2 – BlogMain Form of the Simple Blog application, showing several SubForm controls.

To see this control in an application running live in Morfik Labs, click here and observe how the blog's
entire interface is put together using different Forms which are shown within SubForm controls. For a
more detailed description of how this application was built, please refer to Creating a Blog Application
.

With TabControls
SubForm controls can be used in conjunction with TabControls. Inserted into the individual TabSheet
controls that compose the TabControl, SubForms allow the contents of each Tab to access data from
different data sources.

Page 855
Figure 3 – AdminMain Form of the Simple Blog application, showing the Profile Tab.

An example of this type of usage can be seen in the "Admin" section of the Simple Blog application, as
shown above in Figure 3.

Frequently used Properties


The following is a list of the most commonly used properties of the SubForm control with a short
description of their function.

Form
The Form property of the SubForm control allows the SubForm to be statically bound to a specific
Form. If a Form is assigned to this property, this Form will be loaded automatically into the SubForm
at runtine, without the need of any commands being added to the application's code.

BorderStyle
The BorderStyle property of the SubForm control defines how and if a border will be drawn around
the control. The available style options are: Dashed, Dotted, InSet, None, OutSet and Single. The
InSet and OutSet styles give the SubForm a light 3D effect. The Single option gives the SubForm a
solid line as a border.

BorderColor
The BorderColor property can be used to set the color in which an outline will be drawn around the
entire Form which is opened inside it. Forms do not have borders of their own, though the Bands they
contain do. Setting the border of the containing SubForm is the only way to get a border around the
entire Form.

BorderWidth

Color
The Color property is used to set the color in which the control will be drawn on the Form/Page. This
property is only effective if the Form which is being shown within the SubForm control has is
transparent.

CanGrow
Using this property only makes sense if the control will contain data bound controls.

If there is a large amount of content, to be displayed within the control its height will increase so

Page 856
that it elegantly displays all the content. More information on how controls can grow and shrink at
runtime is available under the topic Plastic Layout .

CanShrink
Using this property only makes sense if the control will contain data bound controls.

If there is only a small amount of content to be displayed within the control, its height will be
reduced so that it elegantly displays the content without leaving large blank areas in the page. More
information on how controls can grow and shrink at runtime is available under the topic Plastic Layout
.

Other Properties
The following is a list of the less commonly used properties of the Subform control with a short
description of their function.

Height
The Height property specifies the vertical extent of the Subform.

Hint
The Hint property, if set, specifies the text of a tooltip that is displayed when the user moves the
cursor over the Subform.

HorizontalPlacement
The HorizontalPlacement property, if set, governs how the Subform adjusts its size and position in
response to changes in the horizontal dimensions of its parent.

Left
The Left property specifies the horizontal position of the Subform.

Name
The Name property specifies the identifier used to reference the Subform from browser- or
server-side code.

Opacity
The Opacity property determines the extent to which the Subform obscures any controls placed in its
background. A value of 0 means that background controls are fully visible, whereas a value of 100
means that background controls are completely obscured.

Parameters
The Parameters property specifies parameter values for the Form hosted in the Subform control. The
parameters are written in the same format as the third parameter of the OpenForm function.

Top
The Top property specifies the vertical position of the Subform.

VerticalPlacement
The VerticalPlacement property, if set, governs how the Subform adjusts its size and position in
response to changes in the vertical dimensions of its parent.

Visible
The Visible property is used to make Subform controls visible or invisible to the end user.

Width

Page 857
The Width property specifies the horizontal extent of the Subform.

Events
Most of the SubForm control's events are related to the resizing that the control undergoes when a
Form is opened inside it. Since the Mofik Framework takes care of automatically resizing and
repositioning controls, these events are seldom required to have any code. However, for the sake of
completeness, all events are documented here.

OnAfterGrowOrShrink
The OnAfterGrowOrShrink event occurs after the Subform control's height has changed in response to
a grow-and-shrink event.

OnAfterPrint
The OnAfterPrint event occurs after the Subform control is rendered into the form's HTML code.

OnAfterPushedOrPulled
The OnAfterPushedOrPulled event occurs after the Subform control's position has changed in
response to a grow-and-shrink event.

OnBeforeGrowOrShrink
The OnBeforeGrowOrShrink event occurs before the Subform control's height changes in response to
a grow-and-shrink event.

OnBeforePrint
The OnBeforePrint event occurs before the Subform control is rendered into the form's HTML code.

OnBeforePushedOrPulled
The OnBeforePushedOrPulled event occurs before the Subform control's position changes in response
to a grow-and-shrink event.

OnPrintStyle
The OnPrintStyle event occurs before the Subform control's style attribute is rendered into the form's
HTML code.

Sample Code
Being controls with a strong tie to the visual layout of a Form, the SubForm controls are not
frequently referred to in application code, except as the target location for Opening a Form with a call
to OpenForm . The following is an example of how a SubForm might be referenced as the target in a
call to OpenForm

OpenForm ( 'AdminMain' , 'Index:FullSite' ,


'' );

This code snippet instructs the Morfik Framework to open the Form called AdminMain inside the
SubForm called FullSite which is located inside the Form called Index .

Morfik Effects
Morfik SubForm controls act as target locations for the display of Forms. SubForms have no actual
runtime representation and therefore none of the Morfik Effects apply to it when the control is placed
on a Form.

See also

Page 858
 Morfik Controls
 Most Frequently Used Controls

Related Video
 Subform control in Morfik

Page 859
Plastic Layout

Page 860
Morfik Controls -
TabControl

Figure 1 – A TabControl with 3 tabs/pages.

The TabControl is used to create regions within a Form/Page whose content can
be alternated by the selection of a named tab. A TabControl is a container for a
set of TabSheet controls, each of which works as containers for controls which
will appear as determined by the currently active page.

Usage
With SubForm Controls

Frequently used
Properties
HideTabs
BorderColor
BorderStyle
BorderWidth
Color
CanGrow
CanShrink
Other Properties
Cursor
Font
Height
Hint
HorizontalPlacement
Left
Name
Opacity
TabHeight
Top
VerticalPlacement
Visible

Page 861
Width
Frequently used Events
OnChange
Sample Code
See also

Usage
The TabControl is used in the Simple Blog sample project that is included with Morfik WebOS
AppsBuilder. Figure 2 shows a partial screenshot of that application running within the browser. This
type of control is very commonly used for editing different sets of related data such as different
aspects of an application's configuration.

Figure 2 – AdminMain Form of the Simple Blog application, showing the Profile Tab.

To see this control in an application running live in Morfik Labs, click here and then select the "Admin"
option in the upper right-hand corner of the page. For a more detailed description of how this
application was built, please refer to Creating a Blog Application .

With SubForm Controls


TabControls can be used in conjunction with SubForm controls, inserted into the individual TabSheet
controls that compose the TabControl to allow the contents of each Tab to access data from different
data sources. An example of this type of usage can be seen in the "Admin" section of the Simple Blog
application.

The use of this technique can be seen in the tabs shown in Figure 2.

Frequently used Properties


The following is a list of the most commonly used properties of the TabControl with a short
description of their function.

HideTabs
This property controls wether or not the tabs of the TabControl are visible. If the tabs are not visible
they can still be changed by setting the value of the ActivePage property.

Page 862
BorderColor
The BorderColor property is used to set the color in which the outline of the TabControl, including
inactive tabs, will be drawn on the page.

BorderStyle

BorderWidth

Color
The Color property is used to set the color in which the active page, including the tab, of the
TabControl will be drawn on the page. The color of the inactive tabs is automatically set as being a
"lighter" version of this color.

CanGrow
Using this property only makes sense if the control will contain data bound controls.

If there is a large amount of content, to be displayed within the control its height will increase so
that it elegantly displays all the content. More information on how controls can grow and shrink at
runtime is available under the topic Plastic Layout .

CanShrink
Using this property only makes sense if the control will contain data bound controls.

If there is only a small amount of content to be displayed within the control, its height will be
reduced so that it elegantly displays the content without leaving large blank areas in the page. More
information on how controls can grow and shrink at runtime is available under the topic Plastic Layout
.

Other Properties
The following is a list of the less commonly used properties of the TabControl with a short description
of their function.

Cursor
The Cursor property, if set, causes the appearance of the cursor to change as it moves over the
TabControl.

Font
The Font property, and its sub-properties Color and Name, specify the font to be used for displaying
the Caption of each child TabSheet.

Height
The Height property specifies the vertical extent of the TabControl.

Hint
The Hint property, if set, specifies the text of a tooltip that is displayed when the user moves the
cursor over the TabControl.

HorizontalPlacement
The HorizontalPlacement property, if set, governs how the TabControl adjusts its size and position in
response to changes in the horizontal dimensions of its parent.

Left
The Left property specifies the horizontal position of the TabControl.

Page 863
Name
The Name property specifies the identifier used to reference the TabControl from browser- or
server-side code.

Opacity
The Opacity property determines the extent to which the TabControl obscures any controls placed in
its background. A value of 0 means that background controls are fully visible, whereas a value of 100
means that background controls are completely obscured.

TabHeight

Top
The Top property specifies the vertical position of the TabControl.

VerticalPlacement
The VerticalPlacement property, if set, governs how the TabControl adjusts its size and position in
response to changes in the vertical dimensions of its parent.

Visible
The Visible property is used to make TabControl controls visible or invisible to the end user.

Width
The Width property specifies the horizontal extent of the TabControl.

Frequently used Events

OnChange

Sample Code
Being controls with a strong tie to the visual layout of a Form, the TabControl is not frequently
referred to in application code. The following is an example of how a property of the TabControl can
be set through source code.

T abControl1 . ActiveP age :=


'P osts' ;

See also
 TabSheet
 Morfik Controls

 Most Frequently Used Controls

Page 864
TabSheet

Figure 1 – A TabControl containing three TabSheet controls.

A TabSheet control corresponds to an individual page within a TabControl .


Tabsheets cannot be placed directly in the Form designer. Rather, a TabSheet is
implicitly created by running the New Page command from the TabControl's
right-click menu.

Frequently used
Properties
Caption
Other Properties
Color
Cursor
Height
Hint
Left
Name
Opacity
Top
Width
See Also

Frequently used Properties


The following is a list of the most commonly used properties of the TabSheet control with a
short description of their function.

Caption
The Caption property specifies the text to be displayed on the page's tab at the top of the
TabControl.

Other Properties
The following is a list of the less commonly used properties of the TabSheet control with a
short description of their function.

Page 865
Color
The Color property specifies the color to be used for drawing the TabSheet.

Cursor
The Cursor property has no effect for TabSheets. Set the Cursor property of the parent
TabControl instead.

Height
The Height property has no effect for TabSheets. Set the Height property of the parent
TabControl instead.

Hint
The Hint property, if set, specifies the text of a tooltip that is displayed when the user moves
the cursor over the TabSheet.

Left
The Left property has no effect for TabSheets. Set the Left property of the parent TabControl
instead.

Name
The Name property specifies the identifier used to reference the TabSheet from browser- or
server-side code.

Opacity
The Opacity property determines the extent to which the TabSheet obscures any controls
placed in its background. A value of 0 means that background controls are fully visible,
whereas a value of 100 means that background controls are completely obscured.

Top
The Top property has no effect for TabSheets. Set the Top property of the parent TabControl
instead.

Width
The Width property has no effect for TabSheets. Set the Width property of the parent
TabControl instead.

See Also
 TabControl
 Morfik Controls

 Most Frequently Used Controls


 Control Effects

Page 866
Morfik Controls - Timer

Figure 1 – A Timer control.

In Morfik AppsBuilder the Timer control is used to trigger an event at regular


intervals.

Usage
Frequently used
Properties
Interval
Enabled
Name
Frequently used Events
OnTimer
Sample Code
See also

Usage
Timer controls can be used for just about any use that requires periodic execution of code.
The Timer control is very easy to use requiring that you implement a single event and set two
properties.

Figure 2 – A Form with a timer control as it is viewed in the Form designer in the Morfik
Workspace.

Frequently used Properties

Page 867
Interval
The Interval property is the number of milliseconds you wish to have pass between the
control triggering its associated event. If you wish the event to be triggered every five
seconds, for example, you should set this property to 5000.

Enabled
This property controls whether the Timer event will be triggered at the time interval specified
in the Interval property. If the Enabled property is set to false , the Timer event will not be
triggered.

Name
The Name property specifies the identifier used to reference the Timer from browser- or
server-side code.

Frequently used Events

OnTimer
The OnTimer event is triggered at regular time intervals determined by the setting of the
Interval property. This even must always be implemented if the Timer control is to have any
effect on the application.

Sample Code
When working with a Timer control you will always want to implement the OnTimer event. This
is the event that the Timer control will trigger at regular intervals.

The following code snippet shows an OnTimer event implementation that sets the text being
displayed in the caption of a TextLabel control to reflect the current time. As the OnTimer
event is triggered the caption of the TextLabel will continuously be updated, thus working as
a clock.

P rocedure
Content . T imer1T imer ( Event : T DOMEvent );
Begin
T imeLabel . Caption := Now . toLocaleT imeString
;
End ;

The following code snippet shows the OnClick event handler for a Button control which is
toggling the state of the Enabled property of a Timer control. This has the effect of turning on
or off the timer as the OnTimer event will not be triggered if the Enabled property is set to
false. This code also changes the Caption property for the Button control to indicate whether
clicking on it will start or stop the OnTimer events from being triggered.

P rocedure
Content . StartStopBtnClick ( Event : T DOMEvent );
Begin
T imer1 . Enabled := not T imer1 . Enabled ;
If T imer1 . Enabled then
StartStopBtn . Caption := 'Stop'
else
StartStopBtn . Caption := 'Start' ;
End ;

Figure 3 shows the same Form that appears in Figure 2, but at runtime and within the Morfik

Page 868
Debug Browser. In this figure you can see that the Timer control has been enabled and the
TextLabel is showing the current time.

Figure 3 – Screenshot of the Morfik Debug Browser running a demo of the Timer control
which displays the current time, updating the corresponding TextLabel control every five
seconds.

See also
 Morfik Controls

Page 869
Pages by categories

IDE

These tips all relate to the Morfik AppsBuilder Integrated Deveopment


Environment (IDE)

Browser Not Refreshing


Debugging Client-side
Debugging SQL Statements
Firewall Compatibility
Keyboard shortcuts
Retrieving the filename entered in the
FileUploader
Tips and tutorials

Presentation

These tips all relate to working with the presentation layer of your Morfik
AppsBuilder project (XApp).

Changing the appearance of controls


Changing the hint property at run-time
Creating an image map
Creating cookies
Embedding YouTube videos
Formatting dates and times in TextLabels
Formatting numbers
Handling MouseOver and MouseOut efficiently
Inserting a new line into a TextEdit
Inserting hyperlinks into TextLabel captions
Iterating through BandIndexes
Making .png images transparent in Internet
Explorer
Modifying font attributes on the server-side
Pretty up the 'Loading...' message
Tips and tutorials
Working with external Firebird databases

Programming

These tips all relate to Programming in Morfik


AppsBuilder.

Page 870
Adding items to a ListBox via the DOM
Calling a method from another Form
Calling a WebMethod from the server
Calling JavaScript from Morfik
Calling Morfik functions from JavaScript
Conditional importing of units
Connecting to an external database on localhost
Creating an image map
Creating and Calling Firebird Stored Procedures
Creating cookies
Creating cookies
Creating timers programmatically
Creating Virtual Parameters
Debugging a Morfik AppsBuilder Application
Debugging Client-side
Debugging SQL Statements
Detecting if a Form is dirty
Displaying a confirm message on browser close
Doing more with Forms
Embedding YouTube videos
Exporting a Table to a CSV file
Fetching data programmatically from Tables
Formatting numbers
Handling MouseOver and MouseOut efficiently
Implementing drag-and-drop
Input mask routine
Inserting a new line into a TextEdit
Inserting hyperlinks into TextLabel captions
Inserting images into Image fields
Invoking an event OnClose of browser window
Iterating through BandIndexes
Modifying the transparent property of images
Morfik 07 - Creating a Blog Application
Morfik 07 - Creating and Using WebMethods
Morfik 07 - Working with Forms
Morfik Pascal Data Types and Variables
Morfik Pascal Object Oriented Programming
Morfik Pascal Overview
Morfik Pascal Subroutines and Scope
Morfik_Languages_Guide
Parsing browser-side XML
Parsing strings

Page 871
Parsing XML from a WebMethod parameter
Patterns for Using Web Services in Morfik
Retrieving IP addresses
Retrieving the control that triggers an event
Retrieving the filename entered in the FileUploader
Retrieving WebMethod exception messages
Returning the value of any class member field as a string
Saving a Report_programmatically
Searching a Table
Sending emails with attachments
Sorting and Filtering Data at Runtime using SQLServer Stored
Procedures
Sorting and Filtering Records in Continuous Forms
Tips and tutorials
Understanding the Morfik Framework
Using associative arrays and hashmaps
Using custom servers
Using dates in Queries
Using External Code
Using Google APIs in XApps
Using Scriptor - basic example
Validating an input field
Working with External Databases
Working with external Firebird databases

Database

These tips all relate to database issues when working with Morfik
AppsBuilder.

A Blog Application
AutoSubmit a Form
Connecting to an external database on localhost
Creating an image map
Creating and Calling Firebird Stored Procedures
Defining composite primary keys
Detecting if a Form is dirty
Duplicating a line of a Table
Dynamically specifying database connection details
Editing a RecordSet
Exporting a Table to a CSV file
Fetching data programmatically from Tables
Implementing a login to an external Firebird database

Page 872
Implementing transaction support
Morfik Database Guide - Appendix A
Morfik Database Guide - Database Modeling in Morfik
Morfik Database Guide - Introduction to Morfik Database Programming
Morfik Database Guide - Main Firebird SQL Statements
Morfik Database Guide - Visual Database Programming
Morfik Database Guide - Working with Database Connections
Morfik_Database_Guide_-_Editing_and_Searching_Data#The_EditSections_Form

Morfik_Database_Guide_-_Editing_and_Searching_Data
Morfik_Database_Guide_-_Using_Stored_Procedures_in_Morfik

Morfik_Database_Guide_-_Working_with_Database_Connections#The_UserSignI
n_Form
Parsing browser-side XML
Parsing XML from a WebMethod parameter
Searching a Table
Sorting and Filtering Data at Runtime using SQLServer Stored Procedures
Sorting and Filtering Records in Continuous Forms
Specifying column names in the Query Builder
Tips and tutorials
Updating MySQL Tables based on nested Queries
Using dates in Queries
Using NOW in a Query
Validating an input field
Working with external Firebird databases

Deployment

These tips all relate to deployment issues when working with Morfik
AppsBuilder.

Browser Not Refreshing


Deploying_an_XApp
Firewall Compatibility
Optimizing initial loading times of
XApps
Tips and tutorials

Page 873

Potrebbero piacerti anche