DamnDirtyApe has asked for the wisdom of the Perl Monks concerning the following question:

After recently reading some nodes here that talked about CGI::Application, I decided to go play with it and see how it worked. On the whole, I'm quite pleased; I can certainly see myself using it in future projects. There is, however, something about its behaviour that I don't quite understand.

Here's the stripped-down code I'm playing with:

CGIApp.pl
#! /usr/bin/perl use lib '.' ; use CGIApp ; my $cgiapp = CGIApp->new() ; $cgiapp->run() ;

CGIApp.pm
package CGIApp; use base 'CGI::Application'; use strict; sub setup { my $self = shift ; $self->start_mode('mode1') ; $self->mode_param( 'runmode' ) ; $self->run_modes( 'mode1' => 'foo', 'mode2' => 'bar', 'mode3' => 'zoot' ); } sub foo { my $self = shift ; my $q = $self->query() ; my $output = '' ; $output .= $q->start_html( "Foo" ) ; $output .= $q->h2( 'I\'m webapp run mode number one.' ) ; $output .= $q->h2( 'I like to frolick in the sun.' ) ; $output .= $q->start_form ; $output .= $q->h3( 'Gimme a number!' ) ; $output .= $q->textfield( -name => 'first_number' ); $output .= $q->hidden(-name => 'runmode', -value => 'mode2' ); $output .= $q->submit(); $output .= $q->end_form(); $output .= $q->end_html(); return $output; } sub bar { my $self = shift ; my $q = $self->query() ; my $output = '' ; my $first_number = $q->param( 'first_number' ) ; $output .= $q->start_html( "Bar" ) ; $output .= $q->h2( 'I\'m webapp run mode number two.' ) ; $output .= $q->h2( 'You click me and I\'ll click you!' ) ; $output .= $q->start_form ; $output .= $q->h3( 'Gimme another number!' ) ; $output .= $q->textfield( -name => 'second_number' ); $output .= $q->hidden( -name => 'first_number', -value => $first_number ); $output .= $q->hidden( -name => 'runmode', -value => 'mode3' ); $output .= $q->submit(); $output .= $q->end_form(); $output .= $q->end_html(); return $output; } sub zoot { my $self = shift ; my $q = $self->query() ; my $output = '' ; my $first_number = $q->param( 'first_number' ) ; my $second_number = $q->param( 'second_number' ) ; $output .= $q->start_html( "Zoot" ) ; $output .= $q->h2( 'I\'m webapp run mode number three.' ) ; $output .= $q->h2( 'Adding\'s why you called on me!' ) ; $output .= $q->pre( $first_number . ' + ' . $second_number . ' = ' . $first_number + $second_number ) ; return $output; } 1 ;

What I had hoped to see was the program prompt for a number, prompt for a second number, then display the sum. Instead, when the second number is submitted, runmode 2 (bar) is reloaded.

I think there is something I'm not getting about how this module works, or how it's intended to work. Could someone kindly fill me in?

Much thanks,

_______________
D a m n D i r t y A p e
Home Node | Email

Replies are listed 'Best First'.
Re: CGI::Application Run Modes
by rob_au (Abbot) on Jun 27, 2002 at 07:46 UTC
    The problem you are facing is not the result of the behaviour of CGI::Application, but rather that of the "sticky" behaviour of CGI.pm when used for hidden form field generation.

    From the CGI.pm POD ...

    Note, that just like all the other form elements, the value of a hidden field is "sticky". If you want to replace a hidden field with some other values after the script has been called once you'll have to do it manually: $query->param('hidden_name','new','values','here');

    As such, you will need to force the change in the runmode hidden form field value via something like $q->param('runmode', 'mode3'), for example ...

    sub bar { my $self = shift ; my $q = $self->query() ; my $output = '' ; my $first_number = $q->param( 'first_number' ) ; $q->param( 'runmode', 'mode3' ); $output .= $q->start_html( "Bar" ) ; $output .= $q->h2( 'I\'m webapp run mode number two.' ) ; $output .= $q->h2( 'You click me and I\'ll click you!' ) ; $output .= $q->start_form ; $output .= $q->h3( 'Gimme another number!' ) ; $output .= $q->textfield( -name => 'second_number' ); $output .= $q->hidden( -name => 'first_number', -value => $first_number ); $output .= $q->hidden( -name => 'runmode', -value => 'mode3' ); $output .= $q->submit(); $output .= $q->end_form(); $output .= $q->end_html(); return $output; }

    Alternatively, you could make use of the templating features offered by HTML::Template which is integrated with this framework - I would advocate this approach as the combination of the framework provided by CGI::Application and the flexibility offered by page template allows for great ease in rapid prototyping. If your preferred templating system is not HTML::Template however, you can make use of an alternate framework such as Template Toolkit in a fashion very similar to that I have described here.

     

    Update - Added code example to demonstrate the inclusion of $q->param('runmode', 'mode3') in the bar subroutine.

     

      rob_au, I tried the first approach and added "q->param('runmode', 'mode3');" to the "bar" sub right before "return" statement. It did not help. Where I'm wrong?

      --dda

      Thank you! I placed it in a wrong order... :)

      --dda