NAME

Apache2::Ajax - mod_perl interface to CGI::Ajax

SYNOPSIS

######################################################
# in httpd.conf
PerlLoadModule Apache2::MyAjaxApp
<Location /ajax>
   SetHandler perl-script
   PerlResponseHandler Apache2::MyAjaxApp
   PJX_fn js_function_name perl_function_name
   PJX_html Show_Form_sub
   PJX_JSDEBUG 2
   PJX_DEBUG 1
</Location>
######################################################

######################################################
# module file Apache2/MyAjaxApp.pm
package Apache2::MyAjaxApp
use Apache2::Ajax;
# use whatever else

sub perl_function_name {
  my @params = @_;
  # do whatever
  return $return_value;
}

sub Show_Form_sub {
  my $html = '';
  # construct html string
  return $html;
}

sub handler {
  my $r = shift;
  # do stuff
  my $ajax = Apache2::Ajax->new($r);
  $r->print($ajax->build_html());
  return Apache2::Const::OK;
}
1;
##################################################

DESCRIPTION

This module is a mod_perl2 interface to CGI::Ajax, which provides a mechanism for using perl code asynchronously from javascript-enhanced HTML pages.

As well as mod_perl2, this package requires CGI::Ajax, as well as a CGI.pm-compatible CGI module for supplying the param() and header() methods. If available, CGI::Apache2::Wrapper will be used, which is a minimal module that uses methods of mod_perl2 and Apache2::Request to provide these methods; if this is not available, CGI (version 2.93 or greater) will be used.

Setting things up can be illustrated by the following example of CGI::Ajax, which contains a more thorough discussion, as well as a number of illustrative example scripts.

  • Define a Perl subroutine

    At least one Perl subroutine must be defined which takes input from some form element and returns a result. For example,

    sub evenodd_func {
      my $input = shift;
      # check that $input is defined and is a number
      $input % 2 == 0 ? return("EVEN") : return("ODD");
    }

    will accept an argument from a form element and return a string indicating if that number is even or odd.

    Note that, in this module, only Perl subroutines are used, whereas in CGI::Ajax, references to subroutines may also be used.

  • Generate the web page

    A subroutine is provided which generates the html for the web page. Within this is a trigger which calls the Perl subroutine, as well as the particular HTML div element to which the results are sent. For example,

    sub Show_HTML {
      my $html = <<EOT;
    <HTML>
    <HEAD><title>A Simple Example</title>
    </HEAD>
    <BODY>
      Enter a number:&nbsp;
      <input type="text" name="somename" id="val1" size="6"
         OnKeyUp="evenodd( ['val1'], ['resultdiv'] );">
      <br>
      <hr>
      <div id="resultdiv">
      </div>
    </BODY>
    </HTML>
    EOT
    
      return $html;
    }

    By means of either an Apache configuration directive or arguments passed into the constructor for the object, to be described later, the Perl subroutine evenodd_func defined earlier will be associated with a JavaScript function evenodd. This function is triggered using the OnKeyUp event handler of the input HTML element. The subroutine takes one value from the form, the input element val1, and returns the the result to an HTML div element with an id of resultdiv.

There may be circumstances under which it is desireable to generate the html page directly within a handler, rather than through a subroutine as described above. This is possible, but one is then responsible for inserting the JavaScript code directly into the page, which can be done with the show_javascript() method described later. The following is a a handler which illustrates this technique:

sub handler {
  my $r = shift;
  my $my_func = sub {
    my $arg = shift;
    return ( $arg . " with some extra" );
  };
  my $ajax = Apache2::Ajax->new($r, tester => $my_func);
  my $html = "";
  $html .= "<HTML>";
  $html .= "<HEAD>";
  
  $html .= $ajax->show_javascript;
  
  $html .= <<EOT;
  </HEAD>
  <BODY>
  <FORM name="form">
  <INPUT type="text" id="inarg"
      onkeyup="tester(['inarg'],['output_div']); return true;">
  <hr>
  <div id="output_div"></div>
  </FORM>
  <br/><div id='pjxdebugrequest'></div><br/>
  </BODY>
  </HTML>
  EOT
  
  my $cgi = $ajax->cgi;
  my $pjx = $ajax->pjx;
  $cgi->header();
  
  if ( not $cgi->param('fname') ) {
    $r->print($html);
  }
  else {
    $r->print($pjx->handle_request());
  }
  return Apache2::Const::OK;
}

mod_perl handler

The mod_perl response handler used must use Apache2::Ajax, and has the following general form:

package Apache2::MyAjaxApp
use Apache2::Ajax;
# use whatever else

sub perl_function_name {
  my @params = @_;
  # do whatever
  return $return_value;
}

sub Show_Form_sub {
  my $html = '';
  # construct html string
  return $html;
}

sub handler {
  my $r = shift;
  # do stuff
  my $ajax = Apache2::Ajax->new($r, %new_args);
  $r->print($ajax->build_html(%build_args));
  return Apache2::Const::OK;
}

Apache2::Ajax makes available the following.

Methods

my $ajax = Apache2::Ajax->new($r, %new_args);

The new() method creates an Apache2::Ajax object, and takes a mandatory argument of the Apache2::RequestRec object $r. It can also accept an optional set of arguments, in the form of a hash, specifying the mapping of Perl subroutines to the automatically-generated JavaScript functions:

my $ajax = Apache2::Ajax->new($r, 'JSFUNC' => \&PERLFUNC);

or, using a coderef:

my $ajax = Apache2::Ajax->new($r, 'JSFUNC' => $perlfunc);

This mapping can alternatively be done through the Apache configuration directive PJX_fn, to be described below.

* my $html = $ajax->build_html(%build_args);

This returns the HTML used for the web page, either the complete html for the whole page or the updated html; this corresponds to the build_html() method of CGI::Ajax. This method also accepts optional arguments, in the form of a hash, of two types:

  • header => $header

    By default, the only header Apache2::Ajax sets is the Content-Type, for which text/html is used. If additional headers are required, they may be passed as an optional argument in the form of a hash reference, as in

      my $header = {'Content-Type' => 'text/html; charset=utf-8',
    		'X-err_header_out' => 'err_headers_out',
    	       };
      my $ajax = Apache2::Ajax->new($r);
      my $html = $ajax->build_html(header => $header);
  • html => \&Show_form

    This option specifies the subroutine provided which generates the html for the web page:

    my $ajax = Apache2::Ajax->new($r);
    $r->print($ajax->build_html(html => \&Show_form));

    A coderef or a string containing the raw html can also be used. This subroutine can alternatively be specified through the PJX_html Apache configuration directive, to be described below.

* my $js = $ajax->show_javascript();

This returns the javascript needed to be inserted into the calling scripts html <head> section; this corresponds to the show_javascript() method of CGI::Ajax.

* my $pjx = $ajax->pjx;

This returns the CGI::Ajax object created with the new method.

* my $r = $ajax->r;

This returns the Apache2::RequestRec object passed into the new method.

* my $cgi = $ajax->cgi;

This returns the CGI.pm-compatible object used to supply the param(), header(), remote addr(), and url() methods needed by CGI::Ajax.

* my $html_ref = $ajax->html;

This returns a reference to the subroutine specified by the PJX_html Apache directive for constructing the html for the page.

Configuration Directives

Apache configuration directives can be used to control aspects of the operation of Apache2::Ajax, typically done within a <Location > directive:

PerlLoadModule Apache2::MyAjaxApp
<Location /ajax>
   SetHandler perl-script
   PerlResponseHandler Apache2::MyAjaxApp
   PJX_fn js_function_name perl_function_name
   PJX_html Show_Form_sub
   PJX_JSDEBUG 2
   PJX_DEBUG 1
</Location>

Note the use of PerlLoadModule to load the custom Apache handler; this must be done so as the custom Apache2::Ajax directives are understood. These directives are as follows.

  • PJX_fn js_function_name perl_function_name

    This directive is used to associate the Perl function perl_function_name defined in the handler with a JavaScript function js_function_name. This can be used as an alternative to passing in this mapping within the new method.

  • PJX_html Show_Form_sub

    This directive is used to define the Perl subroutine which returns the html string used for the page. This can be used as an alternative to passing in this mapping within the build_html method.

  • PJX_JSDEBUG 2

    This directive, which is optional, is used to control the level of JavaScript debugging used. Available levels are

    • 0 : turn javascript debugging off

    • 1 : turn javascript debugging on, some javascript compression

    • 2 : turn javascript debugging on, no javascript compression

  • PJX_DEBUG 1

    This directive, which is optional, is used to control the level of debugging information which will appear in the web server logs. Available levels are

    • 0 : turn debugging off (default)

    • 1 : turn debugging on

SEE ALSO

See CGI::Ajax for more details of how this works, as well as a number of useful examples.

If using CGI is a concern due to the memory footprint, see CGI::Apache2::Wrapper for a minimal CGI.pm-compatible module that uses methods of mod_perl2 and Apache2::Request.

Development of this package takes place at http://cpan-search.svn.sourceforge.net/viewvc/cpan-search/Apache2-Ajax/.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc Apache2::Ajax

You can also look for information at:

COPYRIGHT

This software is copyright 2007 by Randy Kobes <r.kobes@uwinnipeg.ca>. Use and redistribution are under the same terms as Perl itself; see http://www.perl.com/pub/a/language/misc/Artistic.html.

6 POD Errors

The following errors were encountered while parsing the POD:

Around line 400:

Expected text after =item, not a bullet

Around line 439:

Expected text after =item, not a bullet

Around line 446:

Expected text after =item, not a bullet

Around line 450:

Expected text after =item, not a bullet

Around line 455:

Expected text after =item, not a bullet

Around line 461:

Expected text after =item, not a bullet