Widget Events"
(22 intermediate revisions by 3 users not shown) | |||
Line 8: | Line 8: | ||
In addition, ZK Client Engine intercepts most DOM events and encapsulate them into widgets events, such that it is easier and more efficient for component developers to handle events at widget-level (rather than DOM-level, <javadoc directory="jsdoc">jq.Event</javadoc>). | In addition, ZK Client Engine intercepts most DOM events and encapsulate them into widgets events, such that it is easier and more efficient for component developers to handle events at widget-level (rather than DOM-level, <javadoc directory="jsdoc">jq.Event</javadoc>). | ||
+ | |||
+ | = Lifecycle-related Widget Events = | ||
+ | ZK fires some lifecycle-related events when creating and destroying widgets. Please check [https://github.com/zkoss/zkbooks/blob/master/clientreference/src/main/webapp/notification/client-side-lifecycle.zul client-side-lifecycle.zul] to know the basic concept. | ||
+ | |||
=Event Listening for Component Developers= | =Event Listening for Component Developers= | ||
− | ZK Client Engine intercepts most DOM events that are targeting the DOM elements | + | ZK Client Engine intercepts most DOM events that are targeting the DOM elements belong to widgets. It then encapsulates them into widget events, and then invokes the corresponding method of <javadoc directory="jsdoc">zk.Widget</javadoc>. For example, when the user moves the mouse over a DOM element of a widget, <javadoc method="doMouseOver_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> will be called. Similarly, when the user clicks a DOM element of a widget, <javadoc method="doClick_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> will be called. |
+ | |||
+ | == Events and Corresponding Methods == | ||
+ | |||
+ | {|class='wikitable' | ||
+ | |+ Events that can be handled by overriding a method | ||
+ | |- | ||
+ | ! DOM Event Name | ||
+ | ! ZK Widget Event Name | ||
+ | ! Method to Override | ||
+ | |- | ||
+ | | blur | ||
+ | | onBlur | ||
+ | | <javadoc method="doBlur_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> | ||
+ | |||
+ | Note: unlike others, you have to register a listener with <javadoc method="domListen_(_global_.DOMElement, _global_.String, zk.Object)" directory="jsdoc">zk.Widget</javadoc> as follows. Otherwise, doBlur_ won't be called. | ||
+ | <source lang="javascript"> | ||
+ | this.domListen_(n, "onBlur"); | ||
+ | </source> | ||
+ | |- | ||
+ | | click | ||
+ | | onClick | ||
+ | | <javadoc method="doClick_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> | ||
+ | |- | ||
+ | | dblclick | ||
+ | | onDoubleClick | ||
+ | | <javadoc method="doDoubleClick_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> | ||
+ | |- | ||
+ | | contextmenu (aka., the right click) | ||
+ | | onRightClick | ||
+ | | <javadoc method="doRightClick_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> | ||
+ | |- | ||
+ | | focus | ||
+ | | onFocus | ||
+ | | <javadoc method="doFocus_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> | ||
+ | |||
+ | Note: unlike others, you have to register a listener with <javadoc method="domListen_(_global_.DOMElement, _global_.String, zk.Object)" directory="jsdoc">zk.Widget</javadoc> as follows. Otherwise, doFocus_ won't be called. | ||
+ | <source lang="javascript"> | ||
+ | this.domListen_(n, "onFocus"); | ||
+ | </source> | ||
+ | |- | ||
+ | | mouseover | ||
+ | | onMouseOver | ||
+ | | <javadoc method="doMouseOver_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> | ||
+ | |- | ||
+ | | mouseout | ||
+ | | onMouseOut | ||
+ | | <javadoc method="doMouseOut_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> | ||
+ | |- | ||
+ | | mousedown | ||
+ | | onMouseDown | ||
+ | | <javadoc method="doMouseDown_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> | ||
+ | |- | ||
+ | | mouseup | ||
+ | | onMouseUp | ||
+ | | <javadoc method="doMouseUp_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> | ||
+ | |- | ||
+ | | mousemove | ||
+ | | onMouseMove | ||
+ | | <javadoc method="doMouseMove_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> | ||
+ | |- | ||
+ | | keydown | ||
+ | | onKeyDown | ||
+ | | <javadoc method="doKeyDown_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> | ||
+ | |- | ||
+ | | keyup | ||
+ | | onKeyUp | ||
+ | | <javadoc method="doKeyUp_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> | ||
+ | |- | ||
+ | | keypress | ||
+ | | onKeyPress | ||
+ | | <javadoc method="doKeyPress_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> | ||
+ | |- | ||
+ | | x | ||
+ | | onBind | ||
+ | | handle it by registering a listener according to [https://www.zkoss.org/wiki/ZK_Client-side_Reference/General_Control/Event_Listening Event Listening] | ||
+ | ZK fires it in afterMount, starting from the inner-most child then its parent, and so on. | ||
+ | |- | ||
+ | | x | ||
+ | | onSize | ||
+ | | handle it by registering a listener according to [https://www.zkoss.org/wiki/ZK_Client-side_Reference/General_Control/Event_Listening Event Listening] | ||
+ | ZK fires it when you resize a widget and propagates this event to its children. | ||
+ | |- | ||
+ | | x | ||
+ | | onAfterSize | ||
+ | | handle it by registering a listener according to [https://www.zkoss.org/wiki/ZK_Client-side_Reference/General_Control/Event_Listening Event Listening] | ||
+ | ZK fires it when each time ZK completes rendering/re-rendering a widget and propagates this event to its children. | ||
+ | |- | ||
+ | | x | ||
+ | | onUnbind | ||
+ | | handle it by registering a listener according to [https://www.zkoss.org/wiki/ZK_Client-side_Reference/General_Control/Event_Listening Event Listening] | ||
+ | ZK fires it when ZK removes a widget from a page. | ||
+ | |} | ||
+ | |||
+ | Please read [[ZK_Client-side_Reference/General_Control/Event_Listening]] for listening to widget events. | ||
==Listen by Overriding a Method== | ==Listen by Overriding a Method== | ||
− | Thus, the simplest way to listen a DOM event is to override the corresponding method. For example | + | Thus, the simplest way to listen a DOM event is to override the corresponding method. For example, |
<source lang="javascript"> | <source lang="javascript"> | ||
Line 24: | Line 122: | ||
</source> | </source> | ||
− | where <code>evt</code> is an instance of <javadoc directory="jsdoc">zk.Event</javadoc>. The original DOM event can be retrieved by use of <javadoc method="domEvent" directory="jsdoc">zk.Event</javadoc>, and the original DOM element can be found by use of <javadoc method="domTarget" directory="jsdoc">zk.Event</javadoc> (or <code>evt.domEvent.target</code>). | + | where <code>evt</code> is an instance of <javadoc directory="jsdoc">zk.Event</javadoc>. The original DOM event can be retrieved by the use of <javadoc method="domEvent" directory="jsdoc">zk.Event</javadoc>, and the original DOM element can be found by the use of <javadoc method="domTarget" directory="jsdoc">zk.Event</javadoc> (or <code>evt.domEvent.target</code>). |
If you want to listen and disable the default behavior, just not to call the super class: | If you want to listen and disable the default behavior, just not to call the super class: | ||
Line 38: | Line 136: | ||
==Event Propgation == | ==Event Propgation == | ||
− | The default implementation of the event methods (doXxxx_ in <javadoc directory="jsdoc">zk.Widget</javadoc>) propagates the event from the target widget to its parent, grandparent and so on. To stop the propagation, you can either invoke <javadoc method="stop(_global_.Map)">zk.Event</javadoc>, or not calling back the superclass's event method (the effect is the same). In other words, if the propagation is stopped, the parent's event method won't be called. | + | The default implementation of the event methods (doXxxx_ in <javadoc directory="jsdoc">zk.Widget</javadoc>) propagates the event from the target widget to its parent, grandparent and so on. To stop the propagation, you can either invoke <javadoc method="stop(_global_.Map)" directory="jsdoc">zk.Event</javadoc>, or not calling back the superclass's event method (the effect is the same). In other words, if the propagation is stopped, the parent's event method won't be called. |
If a widget event is not stopped and required by the server, it will be sent to the server, and converted to an instance of <javadoc type="interface">org.zkoss.zk.au.AuRequest</javadoc> at the server<ref>For more information, please refer to the [[ZK Client-side Reference/Communication/AU Requests|AU Requests]] section.</ref>. | If a widget event is not stopped and required by the server, it will be sent to the server, and converted to an instance of <javadoc type="interface">org.zkoss.zk.au.AuRequest</javadoc> at the server<ref>For more information, please refer to the [[ZK Client-side Reference/Communication/AU Requests|AU Requests]] section.</ref>. | ||
− | In | + | In addition to the event propagation, the default implementation will invoke <javadoc method="fireX(zk.Event, int)" directory="jsdoc">zk.Widget</javadoc> to inoke the application-level listeners, if any (registered with <javadoc method="listen(_global_.Map, int)" directory="jsdoc">zk.Widget</javadoc>. |
Notice that there are two kinds of propagation: widget-level and DOM-level. If you stop only the widget-level propagation (by calling <code>evt.stop({propagation:true})</code>), the DOM event will go through all DOM-level event listeners and then trigger the browser default behavior. | Notice that there are two kinds of propagation: widget-level and DOM-level. If you stop only the widget-level propagation (by calling <code>evt.stop({propagation:true})</code>), the DOM event will go through all DOM-level event listeners and then trigger the browser default behavior. | ||
Line 53: | Line 151: | ||
== Capture the Mouse Event == | == Capture the Mouse Event == | ||
− | Sometime you want the following <javadoc method="doMouseOver_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> and <javadoc method="doMouseUp_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> are called against the same widget, no matter where the mouse-up event happens. | + | Sometime you want the following <javadoc method="doMouseOver_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> and <javadoc method="doMouseUp_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> are called against the same widget, no matter where the mouse-up event happens. This is also known as capturing. It can be done by setting <javadoc method="mouseCapture" directory="jsdoc">_global_.zk</javadoc> as follows. |
<source lang="javascript"> | <source lang="javascript"> | ||
Line 66: | Line 164: | ||
== Capture the Input Event == | == Capture the Input Event == | ||
− | Sometime you want the following <javadoc method="onKeyPress_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> and <javadoc method="onKeyUp_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> | + | Sometime you want the following <javadoc method="onKeyPress_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> and <javadoc method="onKeyUp_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> to be called against the same widget, no matter where the key-up event happens. It is also known as capturing. It can be done by setting <javadoc method="keyCapture" directory="jsdoc">_global_.zk</javadoc> as follows. |
<source lang="javascript"> | <source lang="javascript"> | ||
Line 76: | Line 174: | ||
Notice that the key capture is reset automatically after <javadoc method="onKeyUp_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> is called. | Notice that the key capture is reset automatically after <javadoc method="onKeyUp_(zk.Event)" directory="jsdoc">zk.Widget</javadoc> is called. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
=Event Listening for Application Developers= | =Event Listening for Application Developers= | ||
− | To listen a widget event, you could invoke <javadoc method="listen(_global_.Map, int)" directory="jsdoc">zk.Widget</javadoc> to listen | + | To listen a widget event, you could invoke <javadoc method="listen(_global_.Map, int)" directory="jsdoc">zk.Widget</javadoc> to listen any widget event you want. However, <javadoc method="listen(_global_.Map, int)" directory="jsdoc">zk.Widget</javadoc> is designed for applications to listen events at the client. Thus, it is also called the application-level event listener. |
For component development, the method overriding is suggested as described in the previous subsections. | For component development, the method overriding is suggested as described in the previous subsections. | ||
Line 153: | Line 193: | ||
Then, the listeners registered with <javadoc method="listen(_global_.Map, int)" directory="jsdoc">zk.Widget</javadoc> will be invoked one-by-one. Then, it will be sent to the server, if an event listener has been registered at the server or it is an import event<ref>For more information, please refer to the [[ZK Client-side Reference/Communication/AU Requests|AU Requests]] section.</ref>. | Then, the listeners registered with <javadoc method="listen(_global_.Map, int)" directory="jsdoc">zk.Widget</javadoc> will be invoked one-by-one. Then, it will be sent to the server, if an event listener has been registered at the server or it is an import event<ref>For more information, please refer to the [[ZK Client-side Reference/Communication/AU Requests|AU Requests]] section.</ref>. | ||
− | A client-side event listener could stop | + | A client-side event listener could stop sending a widget event to the server by invoking <javadoc method="stop(_global_.Map)" directory="jsdoc">zk.Event</javadoc> with <code>{au:true}</code>, such as |
<source lang="javascript"> | <source lang="javascript"> | ||
Line 164: | Line 204: | ||
</blockquote> | </blockquote> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{{ZKClient-sideReferencePageFooter}} | {{ZKClient-sideReferencePageFooter}} |
Latest revision as of 07:12, 14 July 2023
A widget event is the widget-level event (Event).
Like Event at the server side, the widget event can be anything, and can be triggered by a widget or an application to notify a widget-level or application-level event, such as that a window has been moved.
In addition, ZK Client Engine intercepts most DOM events and encapsulate them into widgets events, such that it is easier and more efficient for component developers to handle events at widget-level (rather than DOM-level, Event).
ZK fires some lifecycle-related events when creating and destroying widgets. Please check client-side-lifecycle.zul to know the basic concept.
Event Listening for Component Developers
ZK Client Engine intercepts most DOM events that are targeting the DOM elements belong to widgets. It then encapsulates them into widget events, and then invokes the corresponding method of Widget. For example, when the user moves the mouse over a DOM element of a widget, Widget.doMouseOver_(Event) will be called. Similarly, when the user clicks a DOM element of a widget, Widget.doClick_(Event) will be called.
Events and Corresponding Methods
DOM Event Name | ZK Widget Event Name | Method to Override |
---|---|---|
blur | onBlur | Widget.doBlur_(Event)
Note: unlike others, you have to register a listener with Widget.domListen_(DOMElement, String, Object) as follows. Otherwise, doBlur_ won't be called. this.domListen_(n, "onBlur");
|
click | onClick | Widget.doClick_(Event) |
dblclick | onDoubleClick | Widget.doDoubleClick_(Event) |
contextmenu (aka., the right click) | onRightClick | Widget.doRightClick_(Event) |
focus | onFocus | Widget.doFocus_(Event)
Note: unlike others, you have to register a listener with Widget.domListen_(DOMElement, String, Object) as follows. Otherwise, doFocus_ won't be called. this.domListen_(n, "onFocus");
|
mouseover | onMouseOver | Widget.doMouseOver_(Event) |
mouseout | onMouseOut | Widget.doMouseOut_(Event) |
mousedown | onMouseDown | Widget.doMouseDown_(Event) |
mouseup | onMouseUp | Widget.doMouseUp_(Event) |
mousemove | onMouseMove | Widget.doMouseMove_(Event) |
keydown | onKeyDown | Widget.doKeyDown_(Event) |
keyup | onKeyUp | Widget.doKeyUp_(Event) |
keypress | onKeyPress | Widget.doKeyPress_(Event) |
x | onBind | handle it by registering a listener according to Event Listening
ZK fires it in afterMount, starting from the inner-most child then its parent, and so on. |
x | onSize | handle it by registering a listener according to Event Listening
ZK fires it when you resize a widget and propagates this event to its children. |
x | onAfterSize | handle it by registering a listener according to Event Listening
ZK fires it when each time ZK completes rendering/re-rendering a widget and propagates this event to its children. |
x | onUnbind | handle it by registering a listener according to Event Listening
ZK fires it when ZK removes a widget from a page. |
Please read ZK_Client-side_Reference/General_Control/Event_Listening for listening to widget events.
Listen by Overriding a Method
Thus, the simplest way to listen a DOM event is to override the corresponding method. For example,
doMouseDown_: function (evt) {
//do whatever you want
this.$supers('doMouseDown_', arguments); //invoke parent.fireX() and so on
}
where evt
is an instance of Event. The original DOM event can be retrieved by the use of Event.domEvent, and the original DOM element can be found by the use of Event.domTarget (or evt.domEvent.target
).
If you want to listen and disable the default behavior, just not to call the super class:
doClick_: function (evt) {
this.fireX(evt);
//don't call this.$supers to avoid the event propagation
},
Note that this approach is suggested for better performance since no real DOM-level event registration is required (as described in the next section).
Event Propgation
The default implementation of the event methods (doXxxx_ in Widget) propagates the event from the target widget to its parent, grandparent and so on. To stop the propagation, you can either invoke Event.stop(Map), or not calling back the superclass's event method (the effect is the same). In other words, if the propagation is stopped, the parent's event method won't be called.
If a widget event is not stopped and required by the server, it will be sent to the server, and converted to an instance of AuRequest at the server[1].
In addition to the event propagation, the default implementation will invoke Widget.fireX(Event, int) to inoke the application-level listeners, if any (registered with Widget.listen(Map, int).
Notice that there are two kinds of propagation: widget-level and DOM-level. If you stop only the widget-level propagation (by calling evt.stop({propagation:true})
), the DOM event will go through all DOM-level event listeners and then trigger the browser default behavior.
- ↑ For more information, please refer to the AU Requests section.
Capture the Mouse Event
Sometime you want the following Widget.doMouseOver_(Event) and Widget.doMouseUp_(Event) are called against the same widget, no matter where the mouse-up event happens. This is also known as capturing. It can be done by setting zk.mouseCapture as follows.
doMouseDown_: function () {
zk.mouseCapture = this;
this.$supers('doMouseDown_', arguments);
}
Notice that the mouse capture is reset automatically after Widget.doMouseUp_(Event) is called.
Capture the Input Event
Sometime you want the following Widget.onKeyPress_(Event) and Widget.onKeyUp_(Event) to be called against the same widget, no matter where the key-up event happens. It is also known as capturing. It can be done by setting zk.keyCapture as follows.
doKeyDown_: function () {
zk.keyCapture = this;
this.$supers('doKeyDown_', arguments);
}
Notice that the key capture is reset automatically after Widget.onKeyUp_(Event) is called.
Event Listening for Application Developers
To listen a widget event, you could invoke Widget.listen(Map, int) to listen any widget event you want. However, Widget.listen(Map, int) is designed for applications to listen events at the client. Thus, it is also called the application-level event listener.
For component development, the method overriding is suggested as described in the previous subsections.
The signature of an event listener is as follows.
function (event) { //an instance of zk.Event
}
Event Firing
To fire a widget event, you could invoke Widget.fire(String, Object, Map, int) or Widget.fireX(Event, int).
Then, the listeners registered with Widget.listen(Map, int) will be invoked one-by-one. Then, it will be sent to the server, if an event listener has been registered at the server or it is an import event[1].
A client-side event listener could stop sending a widget event to the server by invoking Event.stop(Map) with {au:true}
, such as
evt.stop({au: true});
- ↑ For more information, please refer to the AU Requests section.