Minor PhoneGap Alert updates
Last night, and on my commute in to work this morning, I made some updates to my UIControls branch on Github, largely around adding callback and event support to the Alert notification code.
I’ve been working on providing more feedback into JavaScript from the commands run inside of Objective-C. So far PhoneGap has been largely one-way, you push actions into PhoneGap and maybe you get some sort of response out in some general sort of way, but most of it has involved polling mechanisms. Well the DOM and JavaScript in general has a native facility for dispatching ad-hoc events. And it’s super easy to call from Objective-C, if only a little bit verbose:
[webView stringByEvaluatingJavaScriptFromString:
@"(function(){ "
"var e = document.createEvent('Events'); "
"e.initEvent('alertClosed', 'false', 'false'); "
"e.buttonIndex = %d; "
"document.dispatchEvent(e); "
"})()",
buttonIndex];
It looks a little complicated, but it really isn’t. It’s calling some code in an anonymous function closure so this doesn’t leak any references or variables into the global scope, creates a DOM event, sets it with a custom event name, adds some arbitrary properties to it, and dispatches it against the document element.
This same pattern applies everywhere some event occurs, and something in the JavaScript side of the gap:// barrier might be interested in it. Listening to this event is as simple as doing:
document.addEventListener('alertClosed', function(e) {
debug.log("Alert box with button " + e.buttonIndex);
}, false);
Pretty simple, and super flexible. If you’re interested in an event, you bind an event listener to it. If you’re not, you simply ignore it. I’m pretty excited about this design pattern since it reduces the complexity of having to loop and wait for something that might never happen.
Update: Oh, I almost forgot. The main reason for doing all this is I added the capability to add a second button to the Alert popup. So you can do “OK / Cancel”, or whatever else you want. But doing so necessitated adding callback support so you could tell not only when the user closed the alert, but so you could tell which button they pressed.