Skip to main content

Summary of Callbacks and Event Handlers

This chapter summarizes all the event handlers and callbacks that apply to a Zen Mojo page. To define the behavior of the page, you must implement some or all of these items. This chapter discusses the following topics:

The ongetdata and ongetlayout Callback Attributes

The two most basic callback attributes of a documentView are ongetdata and ongetlayout, which were introduced in earlier parts of this book.

When These Callbacks Are Used

When a Zen Mojo page is displayed or when the method updateLayout() is executed, Zen Mojo examines both ongetdata and ongetlayout, and executes the code specified in these callbacks. ongetdata is executed first, followed by ongetlayout (but see the following notes).

Typically, these callbacks invoke the page method getContent().

Within both callbacks, the variables key and value are available. The variable key equals the key of the selected layout object, if any, and the variable value equals the value of the selected layout object, if any.

Furthermore, within ongetlayout, it is possible to access the data object returned by ongetdata (but see the following notes).

Notes:

  • The ongetdata callback is not invoked if the ongetlayout returns a layout graph that contains the sourceData object.

  • The ongetdata callback is not invoked if the cache contains data for the given key.

    Zen Mojo caches both data objects and layout graphs. You can invalidate the cache for a given documentView. To do so, you use the invalidate() method of the documentView. For example:

    var mainView = zen('mainView');
    mainView.invalidate();
    
  • It is also possible to invoke only the ongetdata callback. To do this, you use the getSourceData() method of the documentView. For example:

    var mainView = zen('mainView');
    var data = mainView.getSourceData();
    

    The getSourceData() method returns the source data for the documentView instance. This may come from the layout graph (if it defines a sourceData property), the data cache for the current level, or from the ongetdata callback.

Specifying ongetdata or ongetlayout

To define either of these callback attributes, use the following general procedure:

  • Specify a value for the attribute within the definition of a documentView.

    In most cases, the value is a JavaScript expression that invokes the getContent() method of the page, as in the following example:

    <mojo:documentView id="mainView"
    ongetlayout = "return zenPage.getContent('layout',key,criteria);"
    ongetdata = "return zenPage.getContent('data',key,criteria);">
    ...
    </mojo:documentView>
    
    
  • Implement the onGetContent() and %OnGetJSONContent() methods in the associated template class. The following sections describe these methods formally.

    For an overview of onGetContent() and %OnGetJSONContent(), see “The Template System,” earlier in this book.

Details for getContent()

The ongetdata and ongetlayout callback attributes typically call the getContent() method of the page. This section provides detailed information on this method.

(Note that it can also be useful to call this method in other scenarios. For example, see the onselect() method in the sample ZMdemo.LoadAsync.baseTemplateOpens in a new tab.)

The getContent() method returns a content object (a data object or a layout graph). This method has the following arguments:

getContent(providerName, key, criteria, force, notify)

Where:

  • providerName specifies the name of the content object to get (see “Content Objects” in the chapter “Zen Mojo Templates”). Each documentView can have its own content objects.

  • key is a short, unique name that indicates the specific version of the content. .

  • criteria contains any additional information to pass to the content template. This can be a search string entered by the user or other criteria used internally in your code.

  • force specifies whether to reload content from the server.

  • notify is either null or a function. If this argument is a function, the page sends the data asynchronously to the server (rather than synchronously). Then, when the data has been sent, the page executes the function named by this argument.

    For an example, see the onselect() method in the sample ZMdemo.LoadAsync.baseTemplateOpens in a new tab.

The getContent() method does the following:

  1. It invokes the onGetContent() method of the associated template class. If that method returns content, the system returns that content.

    To find the initial template class, Zen Mojo examines the TEMPLATECLASS parameter of the page class.

  2. If onGetContent() returns null, the system checks to see whether the page cache contains any content. If so, the system returns that content.

  3. If there is no cached content, the system invokes the %OnGetJSONContent() method of the associated template class, uses the result to create the content, and then returns that content.

For a diagram of this activity, see “The Template System,” earlier in this book.

Defining onGetContent()

Each Zen Mojo template class should define the onGetContent() method. This method is a dispatcher that returns a content object. This method has the following signature:

ClientMethod onGetContent(providerName, key, criteria) [ Language = javascript ]

Where:

  • providerName specifies the content object to return.

  • key specifies the key to use when retrieving the content object.

  • criteria is any additional criteria to use when retrieving the content object.

In this method, the standard technique is to use an outer branching construct that uses the providerName argument.

  • If providerName corresponds to a layout graph, onGetContent() should call a suitable layout method. See the chapter “Defining Layout Methods.”

    Also, onGetContent() should pass the key and criteria arguments to that method.

  • If providerName corresponds to a data object, onGetContent() should return null.

    In this case, Zen Mojo gets the object by calling %OnGetJSONContent() in this class (see the next subsection, “Defining %OnGetJSONContent()”).

The following shows an example. In this scenario, mainViewLayout and leftViewLayout are the keys for layout graphs. Notice that the switch construct contains branches only for these layout graphs. The method thus returns null when it is invoked with the key for a data object.

ClientMethod onGetContent(providerName, key, criteria) [ Language = javascript ]
{
    var content = null;

    // dispatch to convenient methods
    // if content is null, then the %OnGetJSONContent method will be called

    switch(providerName) {
    case 'mainViewLayout':
        content = this.myGetMainViewLayout(key,criteria);
        break;
    case 'leftViewLayout':
        content = this.myGetLeftViewLayout(key,criteria);
        break;
    }
    return content;
}

Defining %OnGetJSONContent()

In most cases, each Zen Mojo template class should define the %OnGetJSONContent() method. This method should return the requested data object as an output parameter. This method has the following signature:

ClassMethod %OnGetJSONContent(pProviderName As %String, 
                              pKey As %String, 
                              ByRef pParms, 
                              Output pObject As %RegisteredObject, 
                              pCriteria As %RegisteredObject, 
                              pLoad As %Boolean = 0) As %Status

Where:

  • pProviderName specifies the data object to return.

  • pKey specifies the key to use when retrieving the data object.

  • pParms is currently unused.

  • pObject is the instance of %ZEN.ProxyObject that contains the data to return to the client.

    The class %ZEN.ProxyObject does not have any predefined properties but instead is a special-purpose container object. For an introduction, see “Zen Proxy Objects” in Developing Zen Applications.

  • pCriteria is any additional criteria sent from the client.

  • pLoad specifies whether to load the data. This argument is true when the page is first served.

In this method, the standard technique is to use an outer branching construct that uses the pProviderName argument.

Then, within any given pProviderName branch, use an inner branching construct that examines the pKey argument and that creates a different version of pObject depending on that argument. The following shows an example where pProviderName has only one possible value, but pKey has multiple possible values:

ClassMethod %OnGetJSONContent(pProviderName As %String, pKey As %String, ByRef pParms, 
                              Output pObject As %RegisteredObject, pCriteria As %RegisteredObject, 
                              pLoad As %Boolean = 0) As %Status
{

    if (pProviderName = "mainViewData") {

        //nothing to return for MyButton1 so there is no branch for that
        if (pKey = "MyButton2") {
            //create proxy object that the Zen Mojo will convert to a JSON string
            //and send to the client
            set pObject = ##class(%ZEN.proxyObject).%New()
            set random=$R(100)+1
            set tPerson = ##class(Sample.Person).%OpenId(random)
            set pObject.personName=tPerson.Name
            set pObject.personDOB=$zdate(tPerson.DOB,3)
        }
        elseif (pKey = "MyButton3") {
            //create proxy object that the Zen Mojo will convert to a JSON string
            //and send to the client
            set pObject = ##class(%ZEN.proxyObject).%New()
            set tList = ##class(%Library.ListOfObjects).%New()
            set pObject.children = tList
            For i=1:1:5 {
                // we could retrieve the same company more than once this way
                // but this is a demo so that doesn't matter
                set tNumber=$RANDOM(20)+1
                set tCompany = ##class(Sample.Company).%OpenId(tNumber)
                set tCompanyData = ##class(%ZEN.proxyObject).%New()
                set tCompanyData.companyName = tCompany.Name
                set tCompanyData.companyMission = tCompany.Mission
                set tCompanyData.companyRevenue = tCompany.Revenue
                Do tList.Insert(tCompanyData)
            }
            set pObject.rowCount = tList.Count()
        }

    } ; additional pProviderName branches would go here
    quit $$$OK
}

Other Callback Attributes

Zen Mojo provides several additional callback attributes for a documentView:

  • onload

    Used to perform any setup logic. For example, you could set the initial document and layout keys based on localStorage. This callback is invoked only before the first time the documentView is rendered.

  • onrender

    Provides notification that the documentView is being rendered.

  • onresolvemethod

    Enables you to define methods that you can use in layout graphs (see “Invoking Template Methods in a Layout Graph” in the chapter “Defining Layout Methods”).

  • onresolvepluginconflicts

    Provides information about plugin conflicts if any conflicts have occurred during plugin registration. For details, see “Detecting and Resolving Plugin Conflicts” in the book Using Zen Mojo Plugins.

To use these callback attributes, specify a value for the attribute for a documentView used on the page. In most cases, the value is an expression that invokes a method you have implemented in the template class. For example:

  onresolvemethod="return zenPage.getTemplate().resolve(context,which);"

where getTemplate() is a method of basePage that returns a reference to the instance of the current template associated with the page.

Alternately, you could invoke it indirectly by calling a simple wrapper method of the same name in the page class. If necessary, you can implement the callback method itself in the page class, but best practice is to put all application logic in the template class.

Event Handlers

When an event occurs on the page, Zen Mojo automatically invokes an event handler in the associated template class. The Zen Mojo event handlers are the onselect(), onchange(), and onevent() methods, which have no behavior by default. You define these methods in your template class, in order to make your page interactive.

Where Events Are Supported

In each plugin, events are supported (by default) in the layout objects that are typically used for user interaction. This means that layout objects that represent buttons, menus, sliders, and other controls support events; that is, the plugin inserts event handling for those objects. Layout objects that represent static elements do not support events.

You can suppress the insertion of event handling for a given layout object. To do so, specify one or more of the following attributes of that layout object, as needed:

  • $ignoreSelect — if you specify this attribute as true, the layout object does not have an associated onselect handler (onselect() is ignored). The default is false.

  • $ignoreChange — If you specify this attribute as true, the layout object does not have an associated onchange handler (onchange() is ignored). The default is false, and any layout object that represents a control has an associated onchange handler.

  • $ignoreEvent — If you specify this attribute as true, the layout object does not have an associated generic event handler (onevent() is ignored). The default is false.

Implementing Event Handlers

Define some or all of the following event handler methods in your template class. In a typical implementation, these methods cause changes to the page or documentView instance, depending on your needs.

onselect()
ClientMethod onselect(key, value, docViewId) [ Language = javascript ]

Defines how the page behaves when a user selects a layout object in a documentView. The arguments are as follows:

  • key — key of the selected layout object.

  • value — value of that layout object, if any.

  • docViewId — id of the documentView.

onchange()
ClientMethod onchange(key, value, final, docViewId) [ Language = javascript ]

Defines how the page behaves when a user changes the value of a layout object in a documentView. The arguments are as follows:

  • key — key of the changed layout object.

  • value — new value of the layout object.

  • final — indicates whether the value passed is the final value.

  • docViewId — id of the documentView.

onevent()
ClientMethod onevent(eventType, key, value, docViewId) [ Language = javascript ]

Defines how the page behaves when another type of event occurs within a documentView (an event other than select or change). The arguments are as follows:

  • evtType — type of the event. For information on event types, see “zenEvent” in Developing Zen Applications.

  • key — key of the layout object that triggered the event.

  • value — value of that object, if any.

  • docViewId — id of the documentView.

FeedbackOpens in a new tab