Event Handling
Listening to the events
To attach the event handler to an event use the event binding syntax:
(eventName)="statement"
For example:
class EventHandling extends BaseComponent
{
 public int $count = 0;
}
<button (click)="$count = $count + 1">Add 1</button>
<span>Count: <b>$count</b></span>
The result:
Count: 0You can find the list of all available events at Event reference.
Component's method as an event handler
You can use component's method as an event handler:
class EventHandling extends BaseComponent
{
 public string $greetingMessage = '';

 function greet()
 {
 $this->greetingMessage = 'Hello Viewi!';
 }
}
<button (click)="greet">Greet</button>
<b>$greetingMessage</b>
The result:
Passing arguments
You can also pass arguments into the method:
class EventHandling extends BaseComponent
{
 public string $greetingMessage = '';

 function greetByName($name)
 {
 $this->greetingMessage = "Hello $name!";
 }
<button (click)="greetByName('Viewi')">Greet Viewi</button>
<button (click)="greetByName('Diana')">Greet Diana</button>
<b>$greetingMessage</b>
The result:
Event object
Sometimes you also need to access the original DOM event in your statement. For that purpose use $event variable or argument.
<form (submit)="handleSubmit($event)">
 <button>Send</button>
</form>
Or
<form (submit)="handleSubmit">
 <button>Send</button>
</form>
And now you can access it in your handleSubmit method:
use Viewi\Components\DOM\DomEvent;

class EventHandling extends BaseComponent
{
 public function handleSubmit(DOMEvent $event)
 {
 $event->preventDefault();
 }
}
Please note: if you already have in your component property $event, then you will have to use {$_component->event} in order to use the template. $event is a magic variable that contains reference to the DOM event.
Keyboard events
DomEvent has the standard keyboard fields:
key- the key the user pressed:'Enter','Escape','ArrowDown',' 'for the space bar.code- the physical key on the keyboard:'KeyA','Digit1','Space'. It does not change with the keyboard layout.ctrlKey,shiftKey,altKey,metaKey-truewhile that key is held down.repeat-truewhen the event comes from a key being held down.
keyCode is still there, but browsers have deprecated it. Use key instead.
use Viewi\Components\DOM\DomEvent;

class KeyEventExample extends BaseComponent
{
 public string $pressed = '';

 function onKey(DomEvent $event)
 {
 $combo = '';
 if ($event->ctrlKey) {
 $combo .= 'Ctrl + ';
 }
 if ($event->altKey) {
 $combo .= 'Alt + ';
 }
 if ($event->shiftKey) {
 $combo .= 'Shift + ';
 }
 if ($event->metaKey) {
 $combo .= 'Meta + ';
 }
 $key = $event->key === ' ' ? 'Space' : $event->key;
 $this->pressed = $combo . $key . ' (' . $event->code . ')';
 }
}
<input (keydown)="onKey" placeholder="Press any key" />
<div>Pressed: <b>$pressed</b></div>
The result:
For drag and drop events, $event->dataTransfer gives you the
DataTransfer object.
Firefox does not start a drag unless dragstart calls setData() on it.
Event modifiers
Add modifiers to the event name, separated by dots, to filter events or change how they are handled.
<input (keyup.enter)="add" (keyup.esc)="$draft = ''" />
<form (submit.prevent)="save">...</form>
<textarea (keydown.ctrl.enter)="send"></textarea>
Here is a list you can add items to. Press Enter to add an item, or Escape to clear the input:
class EventModifiersExample extends BaseComponent
{
 public string $draft = '';
 public array $items = [];

 function add()
 {
 $text = trim($this->draft);
 if ($text === '') {
 return;
 }
 $this->items = [...$this->items, $text];
 $this->draft = '';
 }
}
<input model="$draft" (keyup.enter)="add" (keyup.esc)="$draft = ''" placeholder="Type, then press Enter" />
<ul>
 <li foreach="$items as $item">$item</li>
</ul>
The result:
Key modifiers
The handler runs only for the listed key. It matches on event.key.
| Modifier | Key |
|---|---|
enter |
Enter |
esc, escape |
Escape |
space |
Space bar |
tab |
Tab |
up, down, left, right |
Arrow keys |
arrowup, arrowdown, arrowleft, arrowright |
Arrow keys |
home, end, pageup, pagedown |
Home, End, Page Up, Page Down |
delete |
Delete or Backspace |
backspace |
Backspace |
If you list two keys, either one triggers the handler: (keydown.up.down) runs for both arrows.
System modifiers
ctrl, shift, alt and meta make the handler run only while that key is held down. (keydown.ctrl.enter) runs for Ctrl + Enter.
Add exact to reject any other held keys: (keydown.ctrl.enter.exact) does not run for Ctrl + Shift + Enter.
Behaviour modifiers
| Modifier | Effect |
|---|---|
prevent |
Calls $event->preventDefault() before the handler |
stop |
Calls $event->stopPropagation() before the handler |
self |
Runs the handler only when the event started on this element, not on a child |
exact |
See system modifiers above |
prevent and stop apply only when the event passes the key and system checks. (keydown.enter.prevent) blocks Enter and lets every other key through.
Listener options
once, passive and capture are passed to addEventListener as
listener options.
<div (scroll.passive)="onScroll">...</div>
<button (click.once)="start">Start</button>
Modifier names are case-insensitive. An unknown modifier fails the build with the list of valid ones, so a typo like (keyup.entr) is caught when you build, not left as a handler that never runs.
Dynamic event
Well, if you really do not know what event it will be, you can use a dynamic syntax:
$myEventName="expression"
Where $myEventName should contain a valid event attribute name, like this:
public string $myEventName = '(click)';
Whenever you decide to change event name, the application will reattach events accordingly. You are allowed to change it to regular attribute name, that is also ok and application will remove the event and set attribute accordingly.