This is a simple jquery + ajax + views based pop-up alarm based on the results of a view consulted by a timed process.
Step 1 – create the view
Create a view having a filter which determines whether or not there are any nodes of the type you are interested in (say, Todo) with a date field "less than or equal to" "now".
This view (say, "late_todos") will return nothing if there are no Todo items with a date/time prior to now, or else a list of all Todo’s which are "late", that is, which have a certain date field earlier than "now".
Step 2 – determine what we need
We are going to create a module which sets up a url (via hook_menu) that can be called by a jQuery ajax command (say, $.get()), and which, through a callback function set up in the module, will return the results obtained from the view late_todos.
The jQuery javascript can be invoked in all pages during certain common operations (view, edit) through hook_nodeapi, for example.
So, when I view any page, the jQuery code will be installed and a timer set, so that each minute the view will be consulted. If there are "late_todos", a pop up window will appear, giving the choice of dismissing the alarm with cancel, or renewing it for 5 minutes (snooze ).
(A more sophisticated option could include the option to view or edit the TODO directly, but for the purposes of this howto, a simple alarm will suffice).
Step 3 – Implementation
So, first of all, the implementation of hook_menu to add the ajax url:
/** * Implementation of hook_menu(). */ function todoalarm_menu($may_cache) { $items = array(); $items[] = array( 'path' => 'todos/get_status', 'title' => 'todos', 'type' => MENU_CALLBACK, 'callback' => '_todoalarm_ajax_get_status', 'access' => user_access('access content'), ); return $items; }
Now the invocation of the jQuery code itself on most pages:
/** * Implementation of hook_nodeapi */ function todoalarm_nodeapi(& $node, $op, $a3 = NULL, $a4 = NULL) { switch ($op) { case 'view' : case 'prepare' : // for adds and edits case 'search result' : // general universal timer code _todoalarm_set_timer(); break; } }
and the timer setter itself:
function _todoalarm_set_timer() { drupal_add_js( 'function doit() { $.get(base_url + "/todos/get_status", function(status){ if (status == "false") { var result = confirm("Hay pendientes, hacer click en OK para repetir alarma en cinco minutos"); if (result) { setTimeout(doit, 300000); // five more minutes snooze } } }); } $(document).ready(function(){ setTimeout(doit, 60000); // check after one minute });', 'inline' ); global $base_url; // nice way to pass parameters from drupal to jQuery! drupal_add_js("var base_url = "" . $base_url . "";", 'inline'); }
And finally, the ajax invoked function itself which executes the view (notice how it passes its info to jQuery):
function _todoalarm_ajax_get_status() { $view = views_get_view('late_todos'); $todoalarms = views_build_view('items', $view); print drupal_to_js(($todoalarms['items'])?false:true); exit; }
cool!
Anyway, this is just a proof-of-concept, let me know if it was useful at all.