
Events
=======

What are Events
----------------
In a web application there are two kinds of events: client-side
and server-side events. Client-side events are events that happen
in the browser. Server-side events are events that are sent
to the application during a transition, which is done from a 
client-side event handler. The server-side events are usually sent
to a certain webox of the target page, which handles it. When we
refer to "events" we usually mean the server-side events, which are
more important in the framework.


Client-side Events
-------------------
Client-side events are events that happen in the browser. Such events
are: clicking a link, pressing a button, expiration of a timer, 
selection of a radio button, getting or loosing the focus, etc.
Some of these events are handled by JS code which may do some input 
validation, error checking etc. Some examples of client-side event 
handling are these:

    <a href="javascript: on_click()"> Link </a>
    <input type="button1" onClick="on_button1()">
    <form name="form1" onSubmit="on_form1Submit(); return false;">
    <input type="text" name="text1" onBlur="on_text1Blur()">

The functions: on_click(), on_button1(), on_form1Submit(),
on_text1Blur(), are the event handlers for the events of clicking
a link, clicking a button, submitting a form, and loosing focus of
a text input.


Server-side Events
-------------------
During the handling of a client-side event, a handler may also 
decide to make a transition (by calling the predefined function 
GoTo(), for more details read 'transitions.txt'). Usually, during
a transition, a server-side event is sent as well to the next page.
This event is handled by the PHP code of the application, which
may do some input validation, save data to database or get data
from database, change the state of the application, etc.
In this case the function GoTo() is called like this:

    GoTo('targetPage?event=targetBox.eventName(arg1=val1;arg2=val2)')

where 'targetPage' is the template that will be processed by the
framework, 'targetBox' is the ID of the box to which the event 
is sent, 'eventName' is the name of the event, and inside the
paranthesis there are the arguments of the event, separated by 
semicolumn (;).


Sending an Event to the Current Page
-------------------------------------
The 'targetPage' is an HTML template (e.g. 'page1.html').
If it is missing, like this:
    GoTo('?event=targetBox.eventName(args)')
or targetPage="thisPage", like this:
    GoTo('thisPage?event=targetBox.eventName(args)')
then it is assumed by the framework that the target page is 
the same as the 'sourcePage' (the current page), which is known
by the framework. 

In this case the transition is used just to send an event to the 
application, not to change the page that is being displayed; it is 
a transition to the same page. This kind of transition is usually
used by common weboxes (weboxes that are used by more than one page
or more than one application). Such a webox cannot know beforehand
in which page it will be included, so it sends an event to itself
and lets the framework construct again the same page that it 
constructed last time (the framework remembers it itself).


How is Handled an Event
------------------------
When the framework gets the variable 'event', it builds a global 
variable '$event', which is an object of class Event. The framework 
forwards this event only to the webbox specified by the 'targetBox', 
and the other boxes cannot handle it even if they want to. 

If targetBox="any", then the framework forwards it to all the
WebBox-es of the page, and any of them can handle it, if it
wants. If targetBox="none", then this means that this event is not 
sent to any webbox; in this case it is called an indipendent (or
free, or application) event, and it is handled in a special way by
the application.

The framework forwards the event to the webbox by calling the 
function "targetBox_eventHandler($event)", if it is defined by the
webox. The parameter $event that is passed to this function, is the 
global variable '$event'. This object has the attributes $name, $args,
$target, etc. Inside the event handler, the programer usually does a
switch on $event->name (which contains the name of the event).
$event->target contains the ID of the webox to which the event 
is sent. $event->args is an associated array that contains the 
arguments of the event.


Getting the Arguments of an Event
----------------------------------
The arguments of the event can be obtained in the following ways,
(whichever is more handy for the programer):

1 - Getting them directly from the array $event->args, like this:
        $argument1 = $event->args["arg1"];
    
2 - Using the function Event::getArgs():
        list($arg1, $arg2) = $event->getArgs();
    Is important that the order of the args in the list() 
    be the same as the order of the args in GoTo().

3 - Using the PHP function extract:
        extract($event->args);
    This declares the variables $arg1, $arg2, etc. in the current 
    scope.


Predefined (Framework) Events
------------------------------
Predefined events are events that are triggered by the framework 
itself in certain cases. They are not related with a certain webox
or with a certain page. The files that contain the event handlers
should be placed in the EVENTHANDLER_PATH and they must be named
"on.eventName.php" and must contain a function named 
"on_eventName()", which is called by the framework.
If an event handler for a predefined event is not defined, then
nothing happens (no error is generated).

For the time being there are only three predefined events:

1 - firstTime ( on.firstTime.php, on_firstTime() )
    Triggered when the application is opened for the first time, i.e
    when the user enters the application for the first time. This is
    used to initialize the application, e.g. it tells the framework
    which is the first page that will be displayed.  
    
2 - beforePage (on.beforePage.php on_beforePage() )
    Triggered before any page i constructed.
    
3 - afterPage ( on.afterPage.php on_afterPage() )
    Triggered after any page is constructed.


Handeling Free (Application) Events
------------------------------------
If targetBox of the event is "none", then this means that this event 
is not sent to any webbox, but rather is sent to the application
in general. So, it cannot be handled by a webox, as usually, but is
handled in a special way. The event handler for this event is the
function "on_eventName($event)", which is not associated with any 
webox, and is found in the file "on.eventName.php". 

The file "on.eventName.php" is found in the following way:
- First the folder of the targetPage is searched for it
- If it is not found, then the folder of the sourcePage is
    searched for it.
- If it is not found, then the folder EVENTHANDLER_PATH is
    searched for it (defined in 'config/const.Paths.php').
- If it is not found, then an error message is generated.

In the case of the free events, the 'targetPage' is just
a sugestion, which can even be omitted. It doesn't necessarily
mean that this page will be constructed. Instead, the event
handler can decide to construct any page that it wants, and it
may send another event to the page that it constructs.

Free events are provided by the framework for the cases when it is
not known beforehand (at the time that the event is sent) which 
page will be displayed next, because such a thing is decided in the
event handler. E.g. suppose that there are two pages, a login page
and a main page, and the user submits his username and password. In
such a case we are not sure which page will be displayed next, the
login page or the main page, because this dipends whether the 
username and password are correct or not, so we send the event to
the application, and take care that in the event handler we decide
which page to open next. 

The usage of free events is discouraged, use them only when you
cannot do otherwise, because the framework may find later better
solutions for the problem that they solve now, and then they will
become obsolete or not supported.


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

------------------ event handling -------------------------------
* - The class of a webox can declare an event handler function,
    with the name "on_eventName". If such a function exists,
    then this function is called to handle the event, otherwise
    the function eventHandler($event) is called, as before. This
    is useful both for backward compatibility and for flexibility:
    the programer chooses how to handle the events, either with a
    separate event handler for each event, or with a common event
    handler for all the events.
-------- transmitVars() --------------------------
* - function transmitVar(var_name, var_value)
    This function sends the var_name (which has the given var_value)
    to the server side as a PHP global variable. It can also be used
    in the template as a tpl variable: {{var_name}}, since all PHP
    global variables can be used as tpl variables. It should be used
    carefully, because any tpl variable with the same name will 
    override its value.
    It must be called before GoTo().

  - function transmitVars(var_list)
    Similar to transmitVar() but can transmit more than one variable.
    The format of var_list is: var1=val1&var=val2&var3=val3.
    Must be called before GoTo().

---------------- SendEvent() ----------------------------------------
* - js function: SendEvent(obj_id, event_name, event_args)
    
    Sends an event to the server-side (PHP) code.
    obj_id  -- the object to which the event is sent
    event_name -- the name of the event
    event_args -- the arguments of the event, optional

    It is defined in 'func.GoTo.js' which is included automatically
    by the framework in each page. This function uses GoTo() to
    send an event to a webobject (or webbox). Its target is always
    'thisPage' (so, it cannot switch to another page of the application,
    like GoTo()) and it cannot send global PHP variables (like GoTo()).
    So, GoTo() is more general, but SendEvent() should be more common
    and more frequently used. 
 
--------------------------------------------------------------------
* - The GoTo() function accepts only a string of the form
    GoTo("target.html?event=obj_id.event_name(event_args)");
    Before it was possible to send some global PHP vars, by appending
    them after the event like this: &var1=val1&var2=val2 etc.
    This was deprecated and actually it is almost never used. In the
    rare cases when it is needed to send a global variable to PHP,
    the functions transmitVar() and transmitVars() can be used.
    The values of the event arguments could not contain '&' before,
    but now they can.

    They cannot contain ';', because it is used to separate event args
    from each-other, however, the JS function encode_arg_value(str),
    which is defined by the framework, can be used to replace them
    with '#semicolumn#', in cases that they need to contain ';'.
    The decoding (replacing '#semicolumn#' by ';') is done by the
    framework itself.
