-
Notifications
You must be signed in to change notification settings - Fork 14
Sending Custom Events across DomNodes
In Aardvark.Media, we don't have explicit notation of DOM Elements, or their IDs, and use the DomNode abstraction instead. We specify Event Listeners as attributes for a speficic DomNodes. For Example:
div (AttributeMap.ofListCond [
onlyWhen (condition) (onMouseMove moveHandler)
]) [
text "Hello"
]
This attribute adds a listener to the DOM element's onmousemove
event which triggers the server function moveHandler
only when the value in condition
is true
, and removes it when its false
. The JavaScript function which triggers server functions is called aardvark.processEvent
.
How would we trigger events on a different DomNode though? To communicate between DomNodes, we simply use custom events.
We can trigger custom events using aardvark.processEvent
like this:
aardvark.processEvent('__ID__', 'mycustomevent', { content:'testcontent' });
This code calls aardvark.processEvent
and emits and event called 'mycustomevent'
, sending a (JSON-stringified) anonymous object with one field to the server. The special string '__ID__'
(two underscores and the letters I D, follwed by another two underscores) gets replaced by the id
of the DOM Element that triggered the event. On the server side, all DomNodes can listen to the event using the appropriate attribute, in this example:
onEvent "mycustomevent" [] (List.head >> Pickler.json.UnPickleOfString >> f)
This code unpickles an object from the JSON content inside the message and applies f
on it.
In the initial example, we can listen to the window
's mouse move event instead of the div
's (which works everywhere on the screen instead of just on the div) like this:
onBoot ("window.onmousemove = function(ev){ aardvark.processEvent('__ID__', 'onglobalmousemove', { X: event.clientX, Y: event.clientY }) };") (
div (AttributeMap.ofListCond [
onlyWhen (condition) (onEvent "onglobalmousemove" [] (List.head >> Pickler.json.UnPickleOfString >> moveHandler)
]) [
text "Hello"
]
)
Note that the function moveHandler
takes a V2i
, which has a constructor taking two arguments. This means that FsPickler can automatically unpickle a JavaScript objects with the two fields X and Y into a V2i
without any additional boilerplate code.
As another example, call a JavaScript function opening a file open dialog, and return the selected file, like this:
button [
onEvent "onchoose" [] (fun files -> printfn "%A" files; LoadFiles files)
clientEvent "onclick" ("aardvark.processEvent('__ID__', 'onchoose', aardvark.dialog.showOpenDialog({properties: ['openFile', 'openDirectory', 'multiSelections']}));")
] [text "open directory"]