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

Web Client Testing

One of the first things to do before you start programming for the web client, is to make sure 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 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 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. You may find that more recent versions of Omnis Studio have solved some of these gotchas, so be sure to test them yourself.


  • 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 server and 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.

    You might want to use an oPrompts object class for all your prompts. Make the oPrompts 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, regardless 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.

    JavaScript for Setting Web Client Plug-in

    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 not had any luck printing from the print component using Mac OS X.

    Show Message

    Omnis commands 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 on the server.

    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.

    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

    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.

    Web Tree Component

    I like using the web tree component for letting the user navigating menus and opening windows. 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.

    ; Define the treelist flatlist.
    Do iTreelist.$define()
    Do iTreelist.$cols.$add('root',kCharacter,kSimplechar,100)
    Do iTreelist.$cols.$add('child',kCharacter,kSimplechar,100)
    Do iTreelist.$cols.$add('iconid',kInteger,kLongint)
    Do iTreelist.$cols.$add('ident',kInteger,kLongint)
    Do iTreelist.$cols.$add('reserved',kInteger,kLongint)
    Do iTreelist.$cols.$add('expandcollapse',kInteger,kLongint)
    Do iTreelist.$cols.$add('textcolor',kInteger,kLongint)

    ; Add node items to the treelist.
    Do iTreelist.$add('Files',,614+k16x16,100,0,1,0)
    Do iTreelist.$add('Classes','Class 1',1700+k16x16,101,0,0,0)
    Do iTreelist.$add('Classes','Class 2',1701+k16x16,102,0,0,0)

    ; Set the 'Books' node to expanded. (expandcollapse=2)
    Do iTreelist.$add('Books',,615+k16x16,200,0,2,0)
    Do iTreelist.$add('Books','Book1',1705+k16x16,201,0,0,0)
    Do iTreelist.$add('Books','Book2',1706+k16x16,202,0,0,0)

    Web Tree with Tags

    The F6 Property Manager > Custom tab, has a $datamode property which can be set to kTreeDataFlatListWithTags.

    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!