How to create a pop-up alarm in Drupal based on the results of a view

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 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 Cool ).

(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.