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

Hello, I'm using CGI::Application to drive my web site project. I'm very happy using it along with HTML::Template and CGI::Application::ValidateRM

My Problem? I am creating a list such that at the end of each row I intended to have a submit button. Depressing this button should send the user into a different run mode (rm) of my CGI App.

CGI App "knows" which rm to enter by either a hidden field, regular field, or query string that looks like: rm=foo. Submit buttons are part of the query string, so if you have a button named "rm" with a value of "foo" then CGI app will jump to the "foo" run mode. Unfortunately, if I set the label attribute of the button to "Click here nice user" then CGI app takes that as the run mode to use, ignoring the value attribute. This seems like a bug.

Anyone know a way to have a set of buttons with arbitrary labels that fire off to specific run modes?

Cheers

-------------------------------------
Nothing is too wonderful to be true
-- Michael Faraday

Replies are listed 'Best First'.
Re: CGI::Application usage question
by diotalevi (Canon) on Aug 28, 2003 at 21:36 UTC

    This is an HTML/browser question more than it is a perl/CGI::Application question but I'll bite anyway. Each row would be its own form, have a hidden field specifying the runmode and the button is useful only to get the browser to submit the entry to the server.

    <p><form method="POST" action="..."><input type="hidden" name="rm" val +ue="foo"><input type="submit" value="Click here nice user"></form></p +> <p><form method="POST" action="..."><input type="hidden" name="rm" val +ue="bar"><input type="submit" value="No, click *here* nice user"></fo +rm></p>
Re: CGI::Application usage question
by bart (Canon) on Aug 28, 2003 at 22:05 UTC
    In the same realm as diotalevi's response, I'd like to stress that if you submit a form in any way without pressing the submit button, for example by pressing "enter", the name=value pair for the submit button will not be included in the query string. In other words: stay away of the submit button to pass along a value for the run mode, if it is essential. Use a hidden input value instead.
      The name/value pair is included in the query string if you submit the form by pressing enter if you have tabbed to the submit button, which would have to be the case in this application (that, or clicking on the button). Actually, Mozilla always sends the submit button name/value pair - it's IE that doesn't unless the button is clicked or highlighted.

      As for a workaround, you have to choose among hacks. There's the multiple forms/hidden fields hack as already suggested, or you can do a javascript onClick for each submit button that changes a hidden field. The problem with the former is if there are other, shared form elements you have to do further hacks (probably javascript) to distribute the information to each form. The latter hack is better, but relies on javascript, which I like to avoid.

      What I like to do is name the submit buttons differently, and use the names as values. For example, if you have
      <input type='submit' name='add1' value='Add'> <input type='submit' name='add2' value='Add'>
      and the user clicks on the first "Add" button, you'll get a add1/Add key value pair - you use the name/key as the submit button value and you're set (just make sure your naming scheme won't clobber any of your other form element names).

        -------------------------------------
        ++ to your comments. You've reiterated and confirmed my impression that what I want to do requires some not-so-elegant code. In particular, I considered using a bit of JS to accomplish this, but I am working toward a 100% server side solution.

        You wrote:

        What I like to do is name the submit buttons differently, and use the names as values. For example, if you have

        <input type='submit' name='add1' value='Add'> <input type='submit' name='add2' value='Add'>
        and the user clicks on the first "Add" button, you'll get a add1/Add key value pair - you use the name/key as the submit button value and you're set (just make sure your naming scheme won't clobber any of your other form element names).

        Previously, I was using "rm" as the name, and the value as the name of the rm (and implicitly the label). I can see now that I can set a hidden var defining the run mode, then read the name/value pair from the submit button to branch to the appropriate actions.


        Nothing is too wonderful to be true
        -- Michael Faraday
Re: CGI::Application usage question
by PodMaster (Abbot) on Aug 29, 2003 at 07:09 UTC
    I suggest you study the CGI::Application documentation a bit more (3.1 is the latest version which is what you should have). CGI::Application (like the docs say) uses $self->query() to retrieve an object (a CGI.pm object by default), which has a param() method that behaves like that of CGI.pm (that's all the object has to do). Now, CGI.pm has a method called "url_param", read about it in the "MIXING POST AND URL PARAMETERS" section of the CGI.pm manual. You can also read there how the param method behaves in different contexts (it is context sensitive). I leave you with a crucial snippet from CGI::Application
    sub run { my $self = shift; my $q = $self->query(); my $rm_param = $self->mode_param() || croak("No rm_param() specifi +ed"); my $rm; # Support call-back instead of CGI mode param if (ref($rm_param) eq 'CODE') { # Get run-mode from subref $rm = $rm_param->($self); } else { # Get run-mode from CGI param $rm = $q->param($rm_param); # PodMaster: FYI - this is scala +r context } # If $rm undefined, use default (start) mode my $def_rm = $self->start_mode() || ''; $rm = $def_rm unless (defined($rm) && length($rm)); #...
    You may also wanna read up on "mode_param()" in the CGI::Application docs. I hope this helps you see what's going on and solve your problem.

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

      Thanks for your socratic reply. I think I get the gist of it.

      The CGI::Application documentation has a nice example of a very similar problem to mine. In that case, instead of using submit buttons, the example uses links. These links contain the run mode and another name/value pair indicating other information in the query parameters. That would certainly be one way to solve this problem, but I don't want to use links, I prefer buttons.

      You also refer me to mode_param method which would allow me to choose a run mode based upon things other than something in the query string. I'm not sure how this helps my current problem.

      -------------------------------------
      Nothing is too wonderful to be true
      -- Michael Faraday

Re: CGI::Application usage question
by aquarium (Curate) on Aug 29, 2003 at 13:07 UTC
    if you can get away with it, you could also use cookies. You could use one of the more elaborate session modules. or you could write your own quick and dirty (which hides rm altogether from users) of storing rm and instance info to little files on the server in a temp directory.