Here is a simple implementation of a form created with CGI::Appication, Template-Toolkit, and CGI::Ajax that will process changed fields without submitting and re-drawing the form.

Thanks to all for your help.

Cheers,

Bruce

############ webapp pl ##########

#!/usr/bin/perl

use WebApp;
my $webapp = WebApp->new();
$webapp->run();


############ WebApp pm ##########

package WebApp;
use base 'CGI::Application';
use CGI::Application::Plugin::TT;
use strict;

# initialize application, template

sub cgiapp_init {
    my $self = shift;
    my $ttconfig = {
       INCLUDE_PATH => ["tmpl"],
    };
    $self->tt_config( TEMPLATE_OPTIONS => $ttconfig );
}

sub setup {
    my $self = shift;
    $self->start_mode('test');
    $self->mode_param('rm');
    $self->run_modes(
        test             => 'display_test_form',
        process_formdata => 'process_formdata',
    );
}


#run mode to build page with TTK
sub display_test_form {
    my $self   = shift;

# create Javascript ;
# make an association between a javascript function
# that we'll write on the page we're constructing,
# and the url of the app we'll use to process the form data
# which happens to be this app; the javascript func will
# decide what variables to send for processing
    use CGI::Ajax;
    my $url = "webapp.pl";
    my $pjx = new CGI::Ajax( 'submit_formdata' => $url );
    my $ajax_js = $pjx->show_javascript();

# send the javascript constructed by CGI::Ajax to TTK
    $self->tt_params(ajax_js=>$ajax_js);
    my $output = $self->tt_process('test_form.tt2');
    return $output;
}

# run mode for stuff we get back from Javascript func
sub process_formdata {
    my $self  = shift;
    my $cgi   = $self->query;
    my %vars  = $cgi->Vars;

    # get rid of CGI::Ajax items we don't need for this app
    delete $vars{$_} for qw / rm args fname / ;

    # send back some HTML that will appear in a predetermined spot
    # on the form page
    my $ret;
    while ((my $key, my $value) = each %vars) {
       $ret .= qq{ Script "process_formdata" can handle
                   value "$value" in field "$key"<br>} ;
    }
    return $ret;
}

1;

############ tmpl/test_form.tt2 (Template) ##########

[% USE cgi = CGI %]

[% page_js = BLOCK %]
    [% ajax_js # this is code built by CGI::Ajax.pm
               # and inserted by perl app runmode;
               # it includes enclosing "<script>" tags
    %]

    <script language="JavaScript" type="text/javascript">

    <!--
    // "hash" in which to list fields that have changed
    var changed_fields = new Object;

    // onChange handler for input fields
    function note_change(myObj){
        var myID = myObj.id;
        if (myID){
           changed_fields[myID] = 1;
        }
    }

    // onClick handler for submit button
    // "submit" only changed fields, not the whole form
    function doSubmit(){
    // CGI::Ajax wants an array to send to the server
    // include run mode contained in hidden field "rm"
    var myList = ["rm"];

    // add the other fields
        for ( var myField in changed_fields ){
            myList.push(myField);
            delete changed_fields[myField];
        }
        if ( myList.length == 1 ){ // nothing but the runmode
           alert ("No changes to process");
           return false;
        }
        submit_formdata( myList, ['resultdiv'] );
        // "resultdiv" is where we're going to write the html
        //  the perl app we're sending this to sends back
        return false;
    }

    // -->
    </script>

[% END #page_js block %]


[% # write the page HTML %]
<html>
<head>
    [% page_js %]
    <title>Test Page</title>
</head>
<body >
    <div id="page">
        <h4>Test</h4>
        [% cgi.start_form(name=>"testform") %]
            <div id="form_inputs">

                <!-- Note that each of the form elems must have an "id",
                     the name doesn't matter.
                     CGI::Ajax uses getElementByID -->

                [% cgi.hidden( id=>"rm", name=>"Some name",
                   value=>"process_formdata",override=>1)
                   #run mode for cgiapp %]

                Field "Bert"&nbsp;&nbsp;
                [% cgi.textfield( onChange=>"note_change(this)",
           id=>"Bert",name=>"Some other name") %]<br /><br />

                Field "Ernie"&nbsp;
                [% cgi.textfield( onChange=>"note_change(this)",
                   id=>"Ernie", name=>"No name") %]<br /><br />

                [% cgi.submit( onClick=>"return doSubmit()" )  %]
            </div>
             <div id="resultdiv">
             <!-- ajax stuff should appear here -->
             </div>
        [% cgi.end_form.join("") %]
    </div>
</body>
</html>

############ works for me ;-) ##########







---------------------------------------------------------------------
Web Archive:  http://www.mail-archive.com/cgiapp@lists.erlbaum.net/
             http://marc.theaimsgroup.com/?l=cgiapp&r=1&w=2
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to