#!/usr/bin/perl -w
use strict;
use CGI;
use CGI::Ajax;
use Cache::FileCache;
use Template;

my $cache =
Cache::FileCache->new();

#############################
sub display {
#############################
my ($topic) = @_;

return $cache->get($topic),
"Retrieved $topic";
}

#############################
sub remove_me {
#############################
my ($topic) = @_;

$cache->remove($topic);
return "Deleted $topic";
}

#############################
sub update_me {
#############################
my ($topic, $text) = @_;

$cache->set($topic, $text);

my $disptext = $text;
$disptext =
substr($text, 0, 60)
. "..."
if length $text > 60;
return
"Topic '$topic' updated "
. "with '$disptext'";
}

#############################
sub show_html {
#############################
my $template =
Template->new();

my @keys =
sort $cache->get_keys();

$template->process(
"snip.tmpl",
{ topics => \@keys },
\my $result)
or die $template->error();

return $result;
}

#############################
# main
#############################
my $cgi = CGI->new();
$cgi->charset("utf-8");

my $pjx = CGI::Ajax->new(
'display' => \&display,
'update_me' => \&update_me,
'remove_me' => \&remove_me
);
print $pjx->build_html($cgi,
\&show_html);

@KT:Listado 2: snip.js
@LI:// ##########################
function topic_add(topic) {
// ##########################
var itemTable = document.getElementById("topics");
var newRow = document.createElement("TR");
var newCol1 = document.createElement("TD");
var newCol2 = document.createElement("TD");
var input = document.createElement("INPUT");

if(topic.length == 0) {
alert("No topic name specified.");
return false;
}

input.name = "r";
input.type = "radio";
input.id = topic;
input.value = topic;
input.onclick = function() {
display([topic],['tarea', 'statusdiv']);
};
input.checked = 1;
newCol1.appendChild(input);

var textnode = document.createTextNode(topic);
newCol2.appendChild(textnode);

itemTable.appendChild(newRow);
newRow.appendChild(newCol1);
newRow.appendChild(newCol2);

document.getElementById('tarea').value = "";
document.getElementById('new_topic').value = "";

return false;
}

// ##########################
function topic_update() {
// ##########################
if(!id_selected()) {
alert("Create a new topic first");
return;
}
update_me( [ id_selected(),'tarea' ],
'statusdiv');
}

// ##########################
function topic_remove() {
// ##########################
var sel = id_selected();

if(!sel) { alert("No topic available");
return;
}

remove_me([sel], 'statusdiv');

var node = document.getElementById(sel);
var row = node.parentNode.parentNode;
row.parentNode.removeChild(row);
select_first();
}

// ##########################
function select_first() {
// ##########################
var form = document.getElementById("form");
if(! form.r) { return; }
if(! form.r.length) {
form.r.checked = 1;
if(! document.getElementById(id_selected())) {
document.getElementById('tarea').value = "";
return;
}
display([id_selected()],['tarea', 'statusdiv']);
}

for(var i = 0; i < form.r.length; i++) {
form.r[i].checked = 1;
break;
}
display([id_selected()],['tarea', 'statusdiv']);
}

// ##########################
function id_selected() {
// ##########################
sel = id_selected_first_pass();

if(! document.getElementById(sel) ) {
document.getElementById('tarea').value = "";
return;
}
return sel;
}

// ##########################
function id_selected_first_pass() {
// ##########################
var form = document.getElementById("form");
if(! form.r) { return 0; }
if(! form.r.length) { return form.r.id; }

for(var i = 0; i < form.r.length; i++) {
if(form.r[i].checked) {
return form.r[i].id;
}
}
alert("Selected ID is unknown");
return 0;
}
