(You are Anonymous)

Ajax Info

CGI-App and Ajax, perfect together

Warning

The suggestion below - use Perl to generate Javascript - doesn't make much sense these days, since to do anything sophisticated you're going to be using a JS library like YUI (V 2) anyway, in which case you're vastly better off using the AJAX features of that library.

A module which uses a number of features of YUI V2, incuding AJAX, is App::Office::Contacts.

Modules

Note that although CAP::HTMLPrototype or CGI::Ajax might be useful to get you started with AJAX, you don't need to use them (see "Without Modules" below) to use AJAX in your CGI-App.

CGI::Ajax Example

  • an example that processes changed fields without submitting and re-drawing the form

Without CAP::HTMLPrototype or CGI::Ajax Modules

Since you have to write a fair amount of Javascript anyway (to redraw/reconfigure the page after getting JSON or XML or HTML back from your CA app), it may be easier to write the Javascript yourself, especially with the help of a Javascript library like jQuery or Prototype, which take care of a lot of the heavy lifting with AJAX and page updates.

Also, since the AJAX Perl modules auto-generate much of the Javascript, using these modules results in Javascript being returned to the browser on every page load – the javascript is not in a separate file. So, your browser needs to parse the same Javascript on each page load (hence your page is larger than is should be). If you use a standalone Javascript framework (e.g, jQuery, Prototype, Dojo, etc.) instead, the Javascript is in an external file, and the browser would only load it and parse it on the first request. For all subsequent requests, a cached copy is used. Bandwidth is reduced, and page loading is faster.

Discussions

jQuery Example

When the CGI-Application script below (my_ajax.cgi) executes, method default_runmode() returns an HTML document with two divs and two buttons. jQuery is used to attach click event handlers to the two buttons. When you click on a button, an AJAX call is made back to the server (via the jQuery load function), specifying the appropriate run mode. The "ajax" run mode returns some data/HTML (not the whole page!), and only the contents of one of the divs is updated (again by the jQuery load function). If you want to try the script on your web server, note that it expects to find the jQuery javascript library at URL /js/jquery-1.3.2.min.js.

#!/usr/bin/perl -w -T
use strict;
use CGI::Carp qw(fatalsToBrowser);

MyApp->new()->run;
# ----------------------------------------------------------
package MyApp;
use base 'CGI::Application';
use CGI::Application::Plugin::AutoRunmode;

sub default_runmode : StartRunmode {
  my $self = shift;
  my $q = $self->query;
  my $output = _page_header()
      . $q->div({-id=>'box1'},'This is div1')
      . $q->div({-id=>'box2'},'Another div, div2')
      . $q->button(-id=>'b1', -value=>'Alter div1')
      . $q->button(-id=>'b2', -value=>'Alter div2')
}
sub ajax_alter_div1 : Runmode {
  my $self = shift;
  scalar localtime . $self->query->p('Look Ma, no page reload!');;
}
sub ajax_alter_div2 : Runmode {
  my $self = shift;
  reverse $self->query->param('some_text');
}

sub _page_header {
  return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
  <title>CGI-Application and jQuery</title>
  <meta http-equiv="Content-type" content="text/html; charset=iso-8859-1" />
  <meta http-equiv="Content-Language" content="en-us" />
  <style type="text/css">
      body { background-color: #eee }
      #box1, #box2 { border: 1px solid gray; width: 200px; height: 50px; padding: 4px; margin: 10px; }
      #box2        { border: 1px solid blue; }
  </style>
  <script type="text/javascript" src="/js/jquery-1.3.2.min.js"></script>
  <script type="text/javascript">
    $(function(){
      $("#b1").click(function() {
          $("#box1").load(
              "my_ajax.cgi",
              { rm: "ajax_alter_div1" }
              )
      });
      $("#b2").click(function() {
          $("#box2").load(
              "my_ajax.cgi",
              { rm: "ajax_alter_div2", some_text: $("#box2").text() }
              )
      });
    });
    </script>
</head>
';
}

Normally, you'll have an instance script for the first few lines, a separate MyApp.pm module for the runmodes, and your jQuery code (above, this is the code that starts with $(function(){) should be in a separate *.js file, so that it can be cached by the browser.