سؤال

I am going through the basic example for CGI::Application but when I try to add a 3rd mode, it seems the query object is refusing to use my supplied value.

webapp.cgi:

#!/usr/bin/perl 
  use webapp;
  my $webapp = WebApp->new();
  $webapp->run();

webapp.pm:

package WebApp;
use base 'CGI::Application';

sub setup {
    my $self = shift;
    $self->start_mode('mode1');
    $self->mode_param('rm');
    $self->run_modes(
        'mode1' => 'do_stuff',
        'mode2' => 'do_more_stuff',
        'mode3' => 'do_something_else'
        );
}


sub do_stuff {
    my $self = shift;
    my $q = $self->query();

    my $output = '';
    $output .= $q->start_html(-title => 'Widget Search Form');
    $output .= $q->start_form();
    $output .= $q->textfield(-name => 'widgetcode');
    $output .= $q->hidden(-name => 'rm', -value => 'mode2');
    $output .= $q->submit();
    $output .= $q->end_form();
    $output .= $q->end_html();

    return $output;
}

sub do_more_stuff {
        my $self = shift;
        my $q = $self->query();
        my $widgetcode = $q->param("widgetcode");
        my $output = '';
        $output .= $q->start_html(-title => 'List of Matching Widgets');    
        $output .= $q->start_form();
        $output .= $q->textfield(-name => 'widgetcode');
        $output .= $q->hidden(-name => 'rm', -value => 'mode3'); 
                                                     # ^^^^^^ 
                                                     # this value is being ignored
        $output .= $q->submit();
        $output .= $q->end_form();      
        $output .= $q->end_html();

        return $output;
}

sub do_something_else {
        my $self = shift;
        my $q = $self->query();
        my $widgetcode = $q->param("widgetcode");
        my $output = '';
        $output .= $q->start_html(-title => 'Widgets details');  
        $output .= $q->start_form();
        $output .= $q->textfield(-name => 'widgetcode');
        $output .= $q->hidden(-name => 'rm', -value => 'mode4');
        $output .= $q->submit();
        $output .= $q->end_form();
        $output .= $q->end_html();
        return $output;
}

1;

So it works fine to load the first page (mode1), it gives me the form, and I can submit it and reach the second page (mode2), but I cannot reach mode3, because the rm param is being set to "mode2", despite the fact that, as you can read above, I am setting it to "mode3". That means I am sent back to mode2 again. I can change the rm to be rm2 or something else and then the right value gets picked up, but obviously that's not helpful, since the rm variable is what is used to set the mode.

I don't have experience with CGI.pm (which supplies the query object) and as you can tell, I am only just starting to learn CGI::Application, so I don't know what is going on or how to solve this.

هل كانت مفيدة؟

المحلول

It seems the perlmonks had the wisdom: Hidden fields using CGI

You can use the -override parameter to force it to use the default value.

Which in my case would be used as follows:

$output .= $q->hidden(-name => 'rm', -value => 'mode3' , -override => 1);

Hope that helps whoever finds this question through a search, since this isn't obvious at all.

نصائح أخرى

Yes, it appears that the hidden method will use the current form value if one exists instead of what you specify as the default. This could be observed with the following code when accessing a view with ?rm=mode2:

$output .= $q->hidden(-name => 'rm', -value => 'mode3'); # Prints mode2
$q->param('rm' => 'mode3');
$output .= $q->hidden(-name => 'rm'); # Print mode3

As you found, the best solution is to use the override flag as documented in CGI #Form Elements

$output .= $q->hidden(-name => 'rm', -value => 'mode3', -override => 1); # Print mode3
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top