Friday, December 14, 2012

WebSDK: Deferring User Commands

One of the things that trips up new and experienced web app developers on a regular basis is the concept of what commands can be sent to the browser at what time during the initial setup of a web control. The general idea is this:

When the Open() event fires, the control has not been delivered to the page yet. Sending commands to manipulate the control will likely result in javascript errors.

When the Shown() event fires, the control has been delivered to the page, has been set up, and is ready to receive javascript commands.

It seems fairly straightforward, and yet we still get a lot of questions about why users can't do this or that in their applications in the Open event.

If you're creating custom web controls for distribution, there is a way to help users avoid this issue, but it takes careful thought on your part because it's easy to get things out of order if you don't plan ahead.

One solution is to defer calls to ExecuteJavascript in the Open event and send them at the beginning of the Shown event:

  1. Create two private properties on your control:
    Private deferredCommands() as String
    Private inOpenEvent as Boolean = False
  2. Override the ExecuteJavascript method:
    Sub ExecuteJavaScript(Script As String)
      if ControlAvailableInBrowser() or not InOpenEvent then
        deferredCommands.Append script
      end if
    End Sub
  3. Create an event definition for Shown()
  4. Implement the Shown() event:
    if Ubound(deferredCommands)>-1 then
    End If
    RaiseEvent Shown()
  5. Create an event definition for Open()
  6. Implement the Open() event:
    InOpenEvent = True
    RaiseEvent Open()
    InOpenEvent = False
Using this method, you can be sure that user code will not be sent to the browser before your control and its code reaches the browser.

BE CAREFUL! If you only defer some commands, you could cause user code to execute out of order. For example, if you defer property assignments but not function calls, a function may get called before the user property assignments have been set.

No comments: