Tech News Back Issues Issue: 111606

New Features of Remote Forms

By David Swain
Polymath Business Systems

It has been quite a while since Remote Forms were last addressed within the Omnis Tech News. There have been some significant improvements to them in that time. In this article we will examine some of the new features added since Omnis Studio version 4.0 was released. This is only a survey of those new features that do not require lengthy explanations, either because they are straightforward or because they work essentially the same as Window features we have already covered extensively. We will return to this topic in future articles to look at individual new features that require more individual attention.

New Features of Old Components

A number of basic Remote Form field types have been given additional properties and other facilities in Omnis Studio 4.x. These enhancements have been developed to give our browser-based applications more of the look and feel of our desktop applications. It appears that, whenever possible, efforts have been made to unify the programming techniques we use between Window Classes and Remote Forms.

For example, Studio 4.2 provides tooltip functionality to most basic Remote Form field types. Edit fields (both single and multiline), pushbuttons (but not button areas), checkboxes, radio groups, list, heading list and picture fields all now contain a $tooltip property. A couple of new field types have this ability as well, but we will get to them later in this article. The $tooltip property takes a string value. Unlike Window object tooltips, though, Remote Form tooltips do not support square bracket notation. So only static text can be displayed as a tooltip. However, if we need tooltips to report the current state of some variable or other application element, we can always update the necessary tooltip properties with a calculation whenever that value changes. Just be sure that the code used to make this change modifies the value of the $tooltip property for an item in the current instance and not in the current class. This will not be practical for constantly changing information, such as the current time, but is easily done with values changed as part of an action under our control.

Remote Form with Tooltip

The observant reader will notice that the illustration above was captured on a Windows machine rather than on Mac OS X as is my usual habit. This is because I have so far failed to get the Remote Form tooltip feature to work in Safari on Mac OS X. I am not yet ready to call this a bug, but I cannot think of any more options to twiddle that should have any effect on this. On Windows XP with Internet Explorer, this feature worked flawlessly on the first attempt.

Also notice the futile attempt to use square bracket notation, which is simply carried as part of the text and not evaluated. Even using instance variables will not help as the resources for evaluating square bracket notation are not available on the client.

A feature that has long been on the wish list for Remote Forms is the ability to detect the use of modifier keys during event processing. These are the Shift, Command/Control and Option/Alt keys. Since Omnis Studio 4.1, we can use #SHIFT, #COMMAND, #CONTROL, #OPTION and #ALT in our event handling methods in Remote Forms. They are properly populated for both server- and client-side methods during the event cycle. If part of the event is processed on the server, the necessary event-related variables are passed to the server. I do not know whether these are thread-safe on the server, however. This will require more testing (or asking) than I was able to do before publication here. Certainly these variables are specific to the Remote Form instance when accessed on the client side.

In addition, Edit fields (single and multiline) have a $isshift() method that reports kTrue if the Shift key is held down when it is invoked. This method was given to us in Omnis Studio 4.0. I must emphasize that this is a method of the field and not a property. It differs from the message variables listed above in another important way as well. The value returned by $isshift() is an instantaneous value at the time of execution. #SHIFT is part of an event message, so it reports the state of the Shift key at the time the current event occurred - even though that key may no longer actually be depressed. This distinction is subtle, but it may be important to understand at some point.

One of the more exciting new abilities we have been given in Omnis Studio 4.2 is drag-and-drop functionality among Remote Form fields. This is a great enhancement of the user experience with browser-based applications! As with many other Remote Form operations, a little more preparation is required than with the same operation on Window Classes, but the basic programming is the same.

Many Remote Form field types now offer us the choice of selecting evDrop, evDrag, evCanDrop, evWillDrop and evDragFinished events for detection. As with other event types, this must be specified or the event will not be generated. These fields must also be set to allow either dragging or dropping (or both) by setting their $dragmode and $dropmode properties to the appropriate value. This is simpler than it is for window fields because there are fewer choices. In fact, it is literally an "all or nothing" proposition. $dragmode only lets us choose between kNoDragging and kDragData and $dropmode only offers a choice between kAcceptAll and kAcceptNone. At least that part of the operation is simpler! (We can also specify a $dragiconid if we wish.)

An interesting side note is that many more Remote Form field types contain $dragmode and $dropmode properties than offer drag-and-drop events for selection. Perhaps this is a sign of future expansion?

Once we have set these properties for our source and/or target fields, we must then build the method segments that are to handle the drag-and-drop operations. These must be handled on the client side, so the $event methods of the fields involved must be set to "Execute on client". This is true even for a field used only for basic dragging where we do not need any event handling. Of course, I didn't have to tell you this because the first time you test your handiwork Omnis Studio itself (actually, the webclient plugin) will tell you if your $event method for either the source or target field is not properly designated. Otherwise, the programming is exactly the same as for drag-and-drop among Window Class fields.

Here is what the result looks like in operation. Notice that the dragged value follows the mouse pointer and that the target field highlights to indicate that dropping is allowed. Also, the default mouse pointer icon when dropping is not allowed is the international "circle-slash" symbol.

Drag and Drop on Remote Form

Improved Components

There are other components beyond the basic ones that have received improvements in Omnis Studio 4.x. One which was barely mentioned in any of the documentation, but which I know about because of requests I made, is the QuickTime or MoviePlayer component. This component now properly supports streaming video and audio as well as downloaded files. To clarify what the manual says: This component plays streaming video that is set to stream from its server. The component downloads QuickTime movies that are not specifically set up for streaming, but will begin playing them before the download is complete if the movie is properly configured. All media type supported by QuickTime 6 are supported.

The player component also supports additional QuickTime plugins, such as the Flip4Mac extension that allows Windows Media files (.wmv) to be played using the QuickTime Player. If it's set up in your QuickTime installation (and doesn't require features added in QuickTime 7), the QuickTime component can take advantage of it!

The FormFile component has a new $splitpathname() method that was introduced in Omnis Studio 4.2. This allows us to parse pathnames out on the client (in client-side methods) whenever the need arises. This method uses exactly the same parameters and operates in exactly the same way as the $splitpathname() method of the FileOps extension. But to use FileOps, we have to come back to the server for processing.

This is not so much of a problem, though, and there is another new feature that was given to us in Studio 4.1 that makes this more viable. A number of external components, FileOps among them, were rewritten to make them multi-threaded when used with the Omnis Web Server. This helps the server function more efficiently and keeps one user's operations from stepping on those of another.

Another efficiency enhancement is one given to the FormPri component in Omnis Studio 4.1. This component was rebuilt to offer print compression so that large reports can be sent more quickly to the client. This process takes advantage of the compress() and uncompress() functions of Omnis Studio to reduce the size of the binary report data for transport to the client browser. Here is a brief description of the process:

First the report, which is generated on the server, is written to a binary variable by setting the report destination to the Memory device. This was always the way we would generate a report for a Remote Form. But now we can also compress that binary value before transmitting it back to the client. this is done using the compress() function, which takes the binary variable containing our report as its one parameter. Since the Printing Control field on our Remote Form must use the uncompress() function (which it does internally as needed, so we don't have to worry about it), we need to gather some other information before we compress the report value, though. The uncompress() method requires two parameters: the name of the variable that contains the compressed binary value and the original binary length of the uncompressed report. These two pieces of information are transmitted in the $reportdata and $reportdatalen properties of the Printing Control field (which exists on both the server and the client instances of the form), but we have to populate those properties first. We can do so like this:

; print report into binary variable reportBinary
Calculate $cinst.$objs.printField.$reportdatalen as binlength(reportBinary)
Calculate $cinst.$objs.printField.$reportdata as compress(reportBinary)
Calculate $cinst.$objs.printField.$action as kFPriSendToScreen
; complete process and let Omnis Studio send changed values back to client

As long as we are not putting the compressed version of the report data back into our binary variable, it doesn't matter in which order we deal with the report binary data. We just want to be sure that we supply the uncompressed binary length so that the Printing Control object has the necessary information to uncompress the report.

Compressing the report data gives us increasing benefits the larger our reports become. If we happen to not compress the report data, no problem! The Printing Control component can deal with that situation seamlessly.

New Components

Omnis Studio 4.x has seen the advent of two new Remote Form field types: the Masked Edit field and the Hyperlink component. These both work in essentially the same way as their Window Class counterparts - with the usual additional limitations imposed by the Remote Form environment.

Masked Edit fields work basically like Masked Entry fields. This is a great new field type - and one I've requested for quite some time. We can now gather and present formatted data elements without having to store the formatting using either Window or Remote Form classes. In Omnis Studio 4.2, this field type was also given the $tooltip property as were the other edit fields. It was also given the $dragmode, $dragiconid and $dropmode properties, although it was not given any of the drag-and-drop event types for us to select in its $events property. Nevertheless, drag and drop operations work with it just fine as long as all other preparations are made. This is an intriguing exception to the rule that events must always be specified for a field to be able to use them!

The Hyperlink component was added to Window Classes in Omnis Studio 4.0 . In Omnis Studio 4.1, this component was also added for use on Remote Forms. In fact, many developers have expressed to me that they felt a Remote Form is a more appropriate place for the use of such a control, since it mimics the kinds of link controls we use on web pages. I slightly disagree, feeling that this interface element is a very familiar one since so many people have become accustomed to using a web browser. Its use on a thick client window should not be a shock or surprise to such a user. But opinions are just that...

An interesting note is that the Remote Form version of this component retained its $tooltipcolumn property in Studio 4.1, which could be viewed as a precursor to the tooltips feature we now have for other Remote Form field types. To use this property, the list variable named in the $dataname property value must have a column to hold the "link tips". So each link can have its own separate tooltip value in addition to its text label. Here is an example of what that tooltip might look like:

Hyperlink Tooltip on Remote Form

New Operations

A couple of operational items have become easier to deal with - and simply less confusing to some - as we move through the generations of Studio 4.x. In Studio 4.1, we were given the $enablesenddata property for a Remote Task. The default value for this property for new Remote Tasks is kFalse, although existing Remote Tasks created before this property existed will have a value of kTrue to maintain their original operating style. The purpose of this property is to switch off the execution of (and, generally, the need for) the $senddata() method of Remote Form instances opened within the Remote Task. Omnis Studio is now able to determine for itself which variables on the server require synchronization to the client. We used to have to either manage this ourselves or accept that Omnis Studio would update all instance variables on the client from the server with each trip back from a server method. And there were rules we could follow to keep the variables in the return collection from accumulating. But the rules for using $senddata() were difficult for many developers to understand, so this new "automatic mode" should be a welcome change.

The value of $enablesenddata must be set in design mode. It cannot be modified at runtime. Simply setting it to kFalse will disable any existing $senddata() methods in our code, so it is not necessary to traverse the code and strip out or comment out those lines containing that method. Once this is done, Omnis Studio will pass back to the client only those variable values that have changed as the result of actions on the server. If a developer feels the need to continue managing this process using $senddata(), that developer must set $enablesenddata to kTrue for each new Remote Task that is created.

The $startfield property for a Remote Form is becoming more viable in Omnis Studio 4.2. There still appear to be issues with its use on the Mac Os X platform, but it now properly sets the field that will originally receive the focus when a form is opened. We give the $startfield property the $order value of that field. The field so specified must be enterable and enabled for this to work properly. This is how it works given a positive numeric value. if we give it a negative value and then use the form within a subform field, the absolute value of the $startfield value is the number of the field within the subform that will initially receive the focus when the subform receives the focus. Of course, if a zero value is given for this property, the focus will go to the first enterable field in $order order that can accept it.

New Operating Environment

Finally, we have a new way of using Remote Forms. Omnis Studio 4.1 first allowed us to open a Remote Form within a window directly within the thick client for the first time. This is an historic event, but time will tell how frequently this feature gets used. Possible uses might be to maintain a consistent interface on both thick and thin client uses of a form to reduce library size and to minimize end user training problems. Perhaps you will begin to develop some ideas as we briefly review how this new environment works.

We cause a Remote Form to open in a window on either a development or runtime copy of Omnis Studio by first setting the $openinwindow property of the Remote Form class to kTrue. We have not been given any new 4GL commands for opening a form and the Open window instance command will not accept the name of a Remote Form on execution, but we can use the $open() method of the class. This launches a window instance containing our Remote Form instance. So far, so good - but there are some limitations of which we must remain mindful.

First, we no longer can use features and methods that relate to being deployed in a browser. This means that methods like $showurl() will not function in this environment because there is nowhere to direct the display of the url - and no browser software to which to pass the url in the first place.

But we can invoke items that are specific to Remote Tasks, because the appropriate Remote Task is also instantiated along with the Remote Form! Some methods that we might think would be included in the limitation mentioned in the previous paragraph have been reworked to sense within which environment the instance resides. So the $showmessage() method for either the Remote Form or the Remote Task will display an Omnis Studio dialog rather than the dialog of a browser. Since we have both a Remote Form instance and a Window instance co-existing (well, the window is a shell for the form), we also have a Remote Task and a "normal" Task instance co-existing as well! This leads to some interesting results.

Even such methods as $openform() and $changeform() of a Remote Task can be used effectively in this environment. If we issue $ctask.$changeform() and specify a different Remote Form (and one which also has its $openinwindow property set to kTrue), Omnis Studio will swap the forms within the shell of the same window instance, just as if that window were a web browser. If the new form is a different size than the original, Omnis Studio will even resize the window instance to accommodate the new form. If we use the $ctask.$openform() method to open another form, the window retains its original size (although it can be manually resized), but both forms now reside within the same window instance!

So this window shell acts as a substitute browser, maintaining an interface that is as consistent as possible between our thick and thin client deployments. The only things it can't do are those reserved for a real browser. It has no frames, so we cannot direct output to a different frame. And it cannot open a new browser window or display HTML content from web sites on the internet.

And we have been given all the tools we need to find our way around within this environment. Remote Form instances now have a $windowinst() method that returns a reference to the containing window instance - or a null if the form is deployed within a browser. And window instances have been given a $rforminst() method, which returns a reference to the Remote Form instance it contains - or a null if this is a "normal" window instance. We can use these methods to reach out and influence this new environment if we need that kind of control.

Just imagine the possibilities!

Another Time

There are many more new features of Omnis Studio Remote Forms and Remote Tasks, but most of the rest require more extensive explanations than we can deal with this month - not to mention that we also have a complete new suite of Web Services tools available! But all of this will have to wait for another time. I hope you have found this brief tour useful - or, at least, intriguing!

© 2006 Copyright of the text and images herein remains with the respective author. No part of this newsletter may be reproduced, transmitted, stored in a retrieval system or translated into any language in any form by any means without the written permission of the author or Raining Data.
Omnis® and Omnis Studio® are registered trademarks, and Omnis 7™ is a trademark of Raining Data UK Ltd. Other products mentioned are trademarks or registered trademarks of their corporations. All rights reserved.