Question
Steve Pisani · Aug 25, 2016

ZEN Mojo onEvent() callback

Hi - Trapping onselect and onchange events that occur on layout objects seems to work fine, however, according to the documentation, I should also be able to use onevent, which is defined as follows:

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

and has the method signature:

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

I would have expected that, therefore, on events other than onselect and onchange (for example onkeydown, or onkeyup), this method should be called with the eventType, key, value and docViewId as promised.

However - (at least in my case using the bootstrap-3.3 helper plugin - does it make a difference?), this method is never called.

I couldn't find any documentation on how to get this to work as advertised.  

Sure - I can implement the onkeyupHandler(evt) on my zen page, and trap specifically, the onkeyup event for the whole page, then interrogate the element that fired the event etc, and get around things that way - but I'd rather use the onevent method in the template, which should already give me the eventType, key, and value.

Steve

1
0 316
Discussion (8)2
Log in or sign up to continue

Steve,

the onevent callback is used for events like viewport adjustments and you should call this method for your custom event handlers.

Zen Mojo does not register to all possible events on a page in order to throw them at onevent. Page performance would be horrible. If you are interested in any additional events, like onkeydown, you have to register them in addition.

HTH,

Stefan

Hi Stefan,

I guess that's not how it is described under 'Event Handling' here:  http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=...  which incorrectly implies that that Zen Mojo will call onevent for anything other than onselect or onchange.  

So: in my ZENPage, I've overridden onkeydownhandler(evt), and I intend to call the onevent() method in my template class, which will have all the logic for all the events other than onsearch and onclick.

The zenPage onkeyuphandler gives me evt, which I can use to get the HTML DOM id of the component that raised the event.  (id=evt.srcElement .id).

How do I go about finding the layout object's  key attribute, given the DOM id ?

Steve

Steve,

starting with ZM 1.1.1 the "event" object is now passed to all event-handlers (unselect/onevent/onchange) as the optional last argument. User could now make use of it in their template client methods if needed (e.x. handle propagation-related issues, etc.)

This is missing in the documentation so far but is already addressed to be added shortly.

HTH,

Bernd

Thanks Bernd.

My issue is actually managing to get the onevent() method in the template class to be fired at all.  

I'm currently trying to determine what code is required to register onKeyUp() events to be captured for specific layout objects -  that would result in the onevent() in my template class gets invoked (with the evt, key, value and docViewId arguments passed).

Have you use the onevent method callback in the template class ?

Steve

yes, with the html5 type $input layout object you have to add onkeypress:true to it in order that onevent() gets triggered.

And in onevent(eventType,key,value,docViewId,event), you can do for example :

//$input onkeypress:true
if (eventType == 'keypress') {
  var keyCode = event.keyCode || event.which;
  console.log('keyCode :' + keyCode);  
  if (keyCode == '13') {
    // Enter pressed -> Do something
    zenPage.doSomething(value);
  }
}

HTH,
Bernd

Thanks Bernd,

I see that onkeypress works- just as I expected it to firing onevent(). you're right.-

But - I was trying to capture onkeyup - which does not get fired into the onevent().

For onkeyup, and probably other events, we need to implement this manually. We would need to resolve the element id of the layout object, then, register an event listener for the event occurring on that element  - which when fired, would invoke onevent() in the template class.    (as per Steve Whitemen's next post)

thanks - 

As I mentioned before the onevent method is not directly called for most events. The onevent method is only called for viewport changes by default.

Here is an example how you can register your own events. Everything happens in the homepage class.

Step 1) Subscribe to the onPageShow callback

Most pageManagers implement the onPageShow method to let you know when a certain layout has finished rendering. This is a complete documentView example:

<mojo:documentView
 id="mainView"
ongetdata="return zenPage.getContent('data',key,criteria);"
ongetlayout="return zenPage.getContent('layout',key,criteria);"
initialDocumentKey="login"
initialLayoutKey="login"
>
<mojo:jQM-1.4.3-PageManager onPageShow="zenPage.onPageShow(layoutkey,documentkey);">
<mojo:HTML5Helper/>
<mojo:jQM-1.4.3-Helper/>
<mojo:mojoDefaultHelper/>
</mojo:jQM-1.4.3-PageManager>
</mojo:documentView>

Step 2) Implement your logic

I'll just paste the code in here, as I have documented the methods individually:

/// Gets called when a certain layout has been rendered.
/// In this case we are registering additional events and
/// forward them to the onevent callback method in the template.
ClientMethod onPageShow(
    layoutKey,
    documentKey) [ Language = javascript ]
{
    if (layoutKey=='login') {
        zenPage.registerEventHandler('txt-user','keydown');
    }
}

/// Register an event to a layout object by key.
ClientMethod registerEventHandler(
    key,
    eventType) [ Language = javascript ]
{
    var element = zen('mainView').getItemByKey(key);
    element.$findElement('').addEventListener(eventType,new Function('evt','return zenPage.myCustomEventHandler("'+eventType+'","'+key+'");'),false);
}

/// Forward an event to the onevent method in the template.
ClientMethod myCustomEventHandler(
    evtType,
    key) [ Language = javascript ]
{
    var item = zen('mainView').getItemByKey(key);
    var template = zenPage.getTemplate();
    template.onevent(evtType,key,item.$findElement('').value,'mainView');
}

Zen Mojo does not provide a lot of special methods for this task. It involves some coding.