Tips_todo   >   Internet   >   Web Client

Web Client

I started into my first Omnis Web Client job as a web server dummy. My knowledge of how the internet, browsers, and web servers worked was (and still is) pretty sparse. I had not written a single line of JavaScript and always depended on Adobe GoLive for doing all my website/HTML work.

Getting into all of this was intimidating because of my lack of knowledge and the thought of having to slow down and battle my way through yet another learning curve.

Well, hats off to OMST! The learning curve was pretty short and before I knew it my first Omnis Web Client page was up and running. Not bug free, but hey, it worked.

Two more days of digging around and I had a thin-client HTML search page communicating with a remote task in my application through the Omnis Web Server. I was impressed! (My wife's eyes glazed over when I communicated my excitement to her.)

So, if I can get the Omnis Web Server/Web Client/Thin-client stuff working, so can you!

This section doesn't try to replace the Developing Web Applications in OMST manual. Like other sections in StudioTips, this section is intended to expand on places where you might get stuck, things to watch out for, and examples and code you can that can help you when developing your own web client application.

Hope it helps!

DKVS

$showmessage

Messages like OK, Yes/No, No/Yes, Prompt for input can not be used in any code that is executed by or for your web client or ultra-thin client. The reason is that the message prompt will show up on your server and until someone at the web server machine clicks the button on the prompt dialog the method execution will stop. (Not very handy).

$showmessage displays a message dialog window in the client's web browser without halting method execution.

Do $cinst.$showmessage('Message','Title')

Warning

The behavior of $showmessage is different depending on whether the method is executing on the client or on the server.

If $showmessage is in a method set to Execute on Client the message window will be modal. Method execution will halt until the user clicks the Okay button at which time method execution will continue.

If $showmessage is in a method which executes on the server the message window will be modeless. The methods will first finish and then the message window will be opened. When the user clicks the Okay button it merely closes the message window.

If you try to open multiple message windows from method(s) executing on the server only the last $showmessage window will be opened on the client browser.

Click the Run Demo button in the StudioTips Browser to test variations of the $showmessage method.

HTML Javascript

The following example uses Javascript for adding the correct web client plugin.

Variables are declared and set in the <head> section of the page and then used in the Javascript that sets the web client plugin. Using variables saves having to change the OmnisServer, OmnisLibrary, OmnisClass,... in multiple locations on the page.

Feel free to copy, paste, and modify this HTML/Javascript for use in your own Omnis Web Client pages.

<!-- Do not include this opening comment line in the actual page

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
        
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script language="Javascript">

// Declare and set the variables to be used in the Javascript.
var PageTitle = "Omnis Web Client Javascript Using Variables"
var ObjWidth = "755";
var ObjHeight = "585";
var OmnisServer = "5912";
var OmnisLibrary = "swWebTests";
var OmnisClass = "rfTest";
var WebServerURL = "http://localhost";
var WebServerScript = "/cgi-bin/nph-omniscgi";

</script>

<script language="Javascript">
document.writeln("<title>"+PageTitle+"</title>");
</script>
</head>

<body>

<script language="Javascript">

// Add the applicable Omnis Web Client plugin based on the browser.

if(navigator.appName == "Microsoft Internet Explorer" && navigator.platform == "Win32") {

// Web browser is Internet Explorer on Win32 platform. Use ActiveX plugin.
document.writeln("<center>");
document.writeln("<object classid='clsid:13510606-30FA-11D2-B383-444553540000' ");
document.writeln("width='"+ObjWidth+"' ");
document.writeln("height='"+ObjHeight+"' ");
document.writeln(">");

document.write("<param name='_Version' value='65536'>");
document.write("<param name='_ExtentX' value='7161'>");
document.write("<param name='_ExtentY' value='7373'>");
document.write("<param name='_StockProps' value='0'>");
document.write("<param name='OmnisServer' value='"+OmnisServer+"'>");
document.write("<param name='OmnisLibrary' value='"+OmnisLibrary+"'>");
document.write("<param name='OmnisClass' value='"+OmnisClass+"'>");
document.write("<param name='WebServerURL' value='"+WebServerURL+"'>");
document.write("<param name='WebServerScript' value='"+WebServerScript+"'>");

document.writeln("</object><center>");

} else {

// Web browser is not Internet Explorer on Win32. Use Netscape plugin.
document.writeln("<center><embed type='application/OMNIS-RCC-plugin' name='rcc1' ");

document.writeln("width='"+ObjWidth+"' ");
document.writeln("height='"+ObjHeight+"' ");
document.writeln("OmnisServer='"+OmnisServer+"' ");
document.writeln("OmnisLibrary='"+OmnisLibrary+"' ");
document.writeln("OmnisClass='"+OmnisClass+"' ");
document.writelin("WebServerUrl='"+WebServerURL+"' ");
document.writelin("WebServerScript='"+WebServerScript+"'");

document.writelin("></center>");

}

</script>

</body>
</html>

Do not include this closing comment line in the actual page -->

Paged Pane

I ran into an interesting problem problem when trying to reference objects on a paged pane.

In window classes the notation path to an object in a paged pane is as follows:

$cinst.$objs.PagedPane.$objs.ObjectName

But in a remote form the notation to the same object inside the PagedPane would simply be:

$cinst.$objs.ObjectName

The notation path to an object inside a paged pane on a remote form does not include the paged pane. Even thought you can visually group objects in containers on a remote form in design mode, at runtime they are flat. All the objects in a remote form are at the same level when it is instantiated.

Printing Reports

The web client plugin has a great component that allow web client to preview Omnis reports in their browser window and print then print them locally. (I believe you can print directly without print preview.)

Click the Run Demo button to test printing a report to the web client.

@BUG: The "Page Count" external component doesn't work with the web client printing control component. (Omnis v3.2)
@BUG: I have had any luck printing from the print component using Mac OS X.

Subform Communication

You can pass messages from subforms to the parent form and from the parent form to the subform.

The trick is each of the methods involved must be set to Execute on Client.

From the subform to the parent remote form: Do $cwind.$ParentMethodName

From the parent remote form to the subform: 'Do $cinst.$obj.SubformFieldName.$SubformMethodName'

To communicate from one subform to another subform you pass the message through the parent remote form.

Click the Run Demo button to see an example of subform/parent remote form communication.

Subform Communication Treelist

SUBFORM COMMUNICATION - TREELIST

When I built my first web tree component subform I had a terrible time trying to get the evWTreeNodeClick events in the subform passed on to the parent remote from and on to other subforms.

I finally decided to stop fighting with it in my real application and build a test demo of it from scratch in StudioTips. As often happens, things worked when I tried it step by step from scratch.

Click the Run Demo button to see an example of subform treelist/parent remote form communication.

Task Call Back

You may have a situation where you want a remote task instance to be able to send messages to a remote form which has instantiated the task.

Click the Run Demo button to see an example of how you can register a remote form with a remote task.

Task Communication

Communicating from the form to the task can be tricky if you start from a method which is set to Execute on Client.

Click the Run Demo button to see an example of remote form to task communication.

Thin Client

Thin client means communicating with the Omnis Web Server without using the Web Client plugin.

The Omnis Web Server is sitting on the server listening on port 5912 (or whatever port you set it to) It can receive messages from html pages specifying the web client plug-in, or it can recieve messages from html pages NOT using the Web Client.

Using the Web Client you can quickly create very "rich" browser windows. That is, browser window which are similar to the window classes which you are used to creating in Omnis Studio.

However, in my opinon, the Omnis Web Client is not that great for the general public.

1. It requires users to download and install the Web Client plugin.

2. Every time you use a new component, the plugin asks the user if it is okay to download the component.

3. Licensing can get expensive because each simultaneous Web Client connection requires a separate runtime license. (Note: The licensing cost is quite reasonable.)

Where you have a web page that is targeted to the general public, it is quite easy to create an HTML form that can submit data to a remote task in your Omnis web application, and then from the remote task respond to the web page.

If you want to see an example of an html page which uses the thin-client, click the 'Go to Thin-Client' button below.
Enter the letter 'Z' and press the search button. The html results page is dynamically generated by an Omnis Studio application.

Web Client Gotchas

When you move in the Web Client world, there are some gotchas you need to be aware of. This list of gotchas is being added to as I run into them.

Do method $cinst vs. Do $cinst

In the remote form when you want to execute a remote task method or a remote form method you need to use "Do method $cinst", rather than "Do $cinst". If you are operating inside the same class, you should use "Do method" without the "$cinst." prefix.

Do $cinst.$MethodDoesNotExist()

In the Web Client world you can't get away with a line of code in your method that tries to call a method that does not exist. I had a line of code in table class that called a method which I had deleted. The code had been running for months without a problem, but when that same table class method was called during Web Client execution it generated a runtime error! You can't get away with sloppy notation when using the web client.

No OK Messages, No Breakpoints, No Modal Prompts.

Hitting any of these things when working with the web client halts execution on the client. The client is powerless to do anything since they can't see the OK message on your server nor hit the OK or Cancel button in the dialog window on your server.

Use an oMessages object class for all your prompts. Make the oMessages object sensitive to whether or not it is running as under a web server license or a development license and use the appropriate prompt so as to not halt the web server/client method execution.

Notation Path to Objects Inside Containers on Remote Forms

When you use notation to an object inside a container, ignore the container. If you include the container in the notation path, the code will fail if you are operating the method as "Execute on Web Client". There is no form objects hierarchy on the client. This was removed to save space in the client. All objects live at the root, "$cinst.$obj", irrelevant of the container they are in.

Don't get too Fancy

In Omnis Studio thick client you can get quite fancy with objects and item references, and fancy notation like $sendall. Out on the web client you have to keep it simple. If your code isn't working, simplify it, start from the basics and layer it up till you find out where it fails.

No $construct for Remote Form Objects

You can add a $construct method to a remote form object but it doesn't do anything. Only the class method $constuct is called when a remote form is instantiated.

Set $event for the Events You Want to Trap

Remember to set the event you want to trap in the F6 Property Manager for each event you want to trap in each field. It is easy to forget to do this and then wonder why your pushbtton $event method isn't picking up evClick events.

Remote Task $construct

Don't end out of the remote task $construct with Quit method kTrue or kFalse. Doing so will cause the web client browser to be receive a kTrue or kFalse message and will empty the browser page.

Web Client Programming

Since the Web Client uses remote forms which "lose their connection" with your Omnis Studio application you must pass the data to the remote form and cannot get real object-oriented fancy between the remote form and your application.

Web Client Testing

One of the first things to do before you start programming for the web client, is to make sure your the web client is installed and working for your browser.

The easiest way to do this is to go to the web gallery at www.omnis.net and make sure your browser works with the demos provided by Omnis. If it doesn't work there, try downloading and reinstalling the web client plug-in.

If your browser won't work on the mother ship's examples, then it isn't going to work for anything you write either. Get it working there first!

Click the 'Go to Web Gallery' button below to test your web browser web client plugin.

Web Server Serialize

While testing the Omnis server you can use your single user web developer license serial number. Once you are ready to go live, you will need to purchase sufficient web client run-time licenses.

After you receive the new serial number you will need to reserialize the Omnis server software. The simplest way to do this is to delete the 'omnis.cfg' file located in the 'studio' folder of your Omnis application.

You will be prompted to enter the new serial number when you reopen Omnis Studio.

Web Server Setup - Linux

I ran into some problems installing and setting up the Omnis Server on the Linux box which I use for serving the Vencor web site. The problems were inflicted because I downloaded the RPM from omnis.net rather than installing from the CD supplied by Omnis Studio. The downloaded RPM didn't automatically copy the '.so' files from the rainingdata folder to /usr/lib.

Here are the steps I followed for installing the Omnis Web Server onto my Linux box.

1. Using a Linux web browser download the omnisserver.rpm file from Omnis Softwre.

2. Save the rpm file to the home directory.

3. Go to terminal mode.

4. Go to the home directory.

5. Switch to super user. Enter: su

5. Install the packger. Enter: rpm-i omnisserver.rpm This creates the necessary directories and puts the files in /usr/local/rainingdata/os321web. (321represents the Omnis version. This will vary depending on the version you are using.)

6. Copy the nhp-omniscgi to the cgi-bin directory.
6a. Go to the cgi-bin directory to make sure it exists. Enter: cd /var/www/cgi-bin
6b. Make sure the nhp file exists. Enter: ls /usr/local/rainingdata/os321web/webserver
6c. Copy the file to the cgi-bin directory.
Enter: cp /usr/local/rainingdata/os321web/webserver/nhp-omniscgi nhp-omniscgi

7. Copy the '.so' files to the /usr/lib directory
7a. Go to the os321web directory. Enter: cd /usr/local/rainingdata/os321web
7b. List the .so files. Enter: ls *.so
7c. Copy the .so files to usr/lib. Enter: cp *.so /usr/lib

All going well you should be able to startup the Omnis Studio server as follows:
Enter: /user/local/rainingdata/o321web/omnis &
The '&' ampersand spawns the task in the background.
The first time you run Omnis Studio you will need to serialize it.
In the Omnis Studio File menu > select Server Configuration... and set Server Port to 5912 (or whatever port you choose to have the Omnis Server listen on.

AUTO RESTART OMNIS SERVER AND OPEN OMNIS LIBRARIES.

You will likely want Omnis Studio to automatically startup and open your web server
application so that if the web server computer is restarted, the Omnis server and your libraries will automatically be reopened.

One of the option for doing this is to add this to the 'rc.local' file. Steps are as follows:
1. Go to the rc.d directory. Enter: cd /etc/rc.d
2. Edit the rc.local file. Enter: pico rc.local
3. Go to the end of the file and add the following text:
/usr/local/rainingdata/os321web/omnis &
4. Exit the file and save changes. Enter: Ctrl+X
After Linux reboots, the rc.local file will now automatically restart Omnis Studio.
In order to get your Omnis web application libraries automatically opened, you simply need to store the libraries in the /os321/startup folder.

Web Server Setup - Mac OS X

Setting up personal web serving on Mac OS X is really easy to do.

The steps are as folllows:

1. Select System Preferences > click Sharing.

2. Services tab > check Personal Web Sharing. Your computer is now a web server. (Easy eh!?) The URL address for your computer's web sites are specified below the Services tab checklist.
(Click the 'See Screenshots' button to view actual screenshots of these settings.)

3. Finder > Applications > Omnis Studio application folder > webclient folder > server folder.

4. Option+Drag the 'nph-omniscgi' file to the desktop. (Creates a copy on the desktop.)

5. Finder > Library > WebServer > CGI-Executables folder.

6. Drag the 'nph-omniscgi' file from the desktop into the CGI-Executables folder.

That's it, your Mac OS X computer is ready for full testing as a web server/Omnis server for both the web client and thin-client.

The next step is to take an html page which is created by Studio when you Ctrl/Cmd+T on a remote form that you develop. Studio puts the html file which it creates in the Omnis Studio 'html' folder. You need to modify the following parameters in the html file.

"WebServerURL" value="http://localhost"
"WebServerScript" value="/cgi-bin/nph-omniscgi"

Note: Do NOT add a trailing "/" to the WebServerURL! I am assuming that the OmnisServer port, OmnisLibrary, and OmnisClass values are correct.

Remember to modify BOTH the Internet Explorer ActiveX "param name =" parameters AND the Netscape parameters. On the Mac platform the Netscape plugin is used for BOTH Netscape AND Internet Explorer, so it is critical that you modify BOTH sets of parameters. (See HTML Embed for more information)

Drag the modified html file into the WebServer\Documents folder or a subfolder of Documents.

Make sure the OmnisLibrary specified in the html parameters is currently open. (You can use your running it with your development copy of Omnis Studio as long as it is a "web edition" developer version.

Using your browser enter the URL of the html file. e.g. http://localhost/rfFormName.html

All going well the web client plugin will be loaded, a message will be sent from the html page and received by your Omnis application. The remote form should be displayed in the html browser.

Hope it worked for you!

If you find any errors in these instruction, be sure to send me an email.

Web Tree Component

I like using the web tree component for letting the user navigating menus and opening windows. (See Cemetery demo) There are a couple of gotchas that I ran into with the web tree component.

1. $expandcollapse iconid is set to 613. If you don't load the MultiState2 icons with the remote form page, clicking on the icon nodes misbehaves. Be sure to load icon 613 with the remote form which contains the web tree component, or set the $expandcollapse iconid to 0 zero.

2. If you want to open the treelist with any root nodes already open you need to set the 'expandcollapse' state column for the specified node to 2. The sample code below sets the 'Books' node to expanded when the web tree component list is built.

Web Tree with Tags

WEB TREE COMPONENT WITH TAGS

The F6 Properties > Custom tab, has a $datamode property which can be set to kTreeDataFlatListWithTags. I had to contact Tech Support to find out how to use it.

You can add a character column up to 255 characters to your flat list and include whatever information you like. During event handling "pTagID" will return the value of your tag column for the current node.

Very handy!