BoxLang 🚀 A New JVM Dynamic Language Learn More...
Make your native CFML app extendable by defining custom events, listening for those events, and running a closure when the event occurs. cfEvents is similar to the interceptors provided in Coldbox, only with less configuration required and fewer features. :)
box install cfevents
Then include cfevents
in some global scope.
request.cfEvents = new cfevents.models.cfEvents();
Pass an event name and a closure in to the listen()
method to listen for an event. The closure will get executed any time that cfevents.run()
is called with that event name.
request.cfEvents.listen("htmlHead", function() {
// stick this file in the head
writeOutput('<invalidTag src="/dist/app.js"></script>');
});
This closure will now get executed when .run("htmlHead")
is called. (See "Running Events".)
request.cfEvents.run("htmlHead");
A more organized way of using cfEvents might be to call an object method when that event triggers. To do this, pass the object as the third argument to listen()
.
var paypal = new paypal.paypal();
// "chargePaypal" function in paypal object will take the form parameters and send a payment charge.
request.cfEvents.listen( "formSubmit", "chargePaypal", paypal );
Here, formSubmit
is the event name to listen for, and chargePaypal
is the name of the function in the paypal
object to execute when the event is triggered. This event can be triggered like any other event: using the run()
function:
request.cfEvents.run( "formSubmit", form);
Notice in this example we're passing the form scope to the event listener for easy form processing.
You can run an event by calling cfEvents.run('eventName')
. This will execute every closure associated with that event in order of creation.
request.cfEvents.run("htmlHead");
You can pass arguments to the executing closure by providing them as a struct. The arguments can be accessed from the arguments
scope, just like any CFML function.
var data = { "mailer": mailerObj, "data": form };
request.cfEvents.run("formSubmit", data);
If multiple listeners are defined for a given event name, the listeners will be executed by priority order - lowest numerical priority first, highest numerical priority last.
By default, event listeners are created with a priority of 10
.
request.cfEvents.listen("formSubmit", myClosure);
Forcing a higher or lower priority will alter the listener execution order. We recommend staying in the 1-100 range.
request.cfEvents.listen(name = "formSubmit", func = myClosure, priority = 5);
This would be useful for making sure that redirects happen before any buffer output via cfcontent or cfheader, for example.
First, remember that a closure will inherit the local scope of the defining block (e.g. local
and variables
scope outside the closure definition are available inside the closure).
Secondly, this
inside an event closure will refer to the cfEvents
class. So instead of calling component methods via this.myFunc()
, use variables.myFunc()
or just myFunc()
if you don't care about scoping your vars. (I recommend scoping!)
Sorry - this is currently Lucee only, due to the use of parallel ArrayEach().
For all have sinned, and come short of the glory of God (Romans 3:23)
But God commendeth his love toward us, in that, while we were yet sinners, Christ died for us. (Romans 5:8)
That if thou shalt confess with thy mouth the Lord Jesus, and shalt believe in thine heart that God hath raised him from the dead, thou shalt be saved. (Romans 10:9)
Copyright 2019 (and on) - Michael Born
$
box install cfevents