George Jempty wrote:
> 
> >From the time I first started tinkering with CGI, just
> 3 years ago, I always thought that submit buttons were
>  greatly under-utilized in maintaining state.  Between
> this, and the recent discussion on this group about
> 'finite state machines', I thought I could use submit
> buttons to that end, within the framework of
> CGI::Application.
> >
> >       <form>
> >       <input type="hidden" name="rm" value="create">
> >       <input type="button" value="Create a new Whatever">
> >       </form>
> 
> Unfortunately this could never work for the system I
> am envisioning, because, even if you are in the middle
> of a 'create' of a new record, the back button is a
> 'read' of the previous page's data.
> 

George,

If you search the archives of this list, you'll find some more
discussion of using submit buttons with run modes. As you noticed they
often don't work directly. Jesse had a simple solution for this, which I
have adopted. If the submit buttons can't set the run mode directly, and
a direct hidden field doesn't work, some simple JavaScript can be used
to fill the gap. Because the JavaScript is very basic, it's easy to
implement and widely compatible. Here's a real-world example:

    function item_edit () {
        document.item_form.rm.value="item_edit";
    }
    function item_suggest_add () {
        document.item_form.rm.value="item_suggest_add";
    }
    function item_delete () {
                if (confirm('Really Delete?')) {
           document.item_form.rm.value="item_delete";
          return true;
                } else {
                return false;
                }
    }

This can help for a few reasons
* The form can submit to multiple run modes from a single form
* The run modes aren't tied to the language on the button, allowing the "design"
of the run mode name to changed without affecting the code. This would
be a
significant feature if someone wanted to translate your app into another
language. 

To make the above work, the remaining details are: 

* Have the form named "item_form", or otherwise match your JavaScript
* include an empty "rm" hidden field:
        <input type="hidden" name="rm" value="">
* Call the function through a method such as "onClick":
<INPUT TYPE="submit" NAME="action" VALUE="delete" onClick="item_delete()">

Sometimes I skip using the functions and just include the JavaScript
directly in the button, like this: 
<input type="submit" name="submit" value="Add" 
onClick="document.item_form.rm.value='item_suggest_add';">

I use this scheme and really like it. Just for fun, below is my setup
routine from Cascade. 
It's fairly basic except that I use the start_mode in a slightly unusual
way as mechanism to direct people to register if they need to. I also
make use of a few (gasp!) global variables and my &err rotuine isn't a
CGI::App method when maybe it should be. 

  -mark

#############

sub setup {
   my $self = shift;
   $DBH ||= connect_db() or die "Could not connect to database. Check
connection parameters";

   # Put param variables into a global hash
   $q = $self->query;
   %FORM = (%FORM, $q->Vars);

   # set $FORM{rm} (run mode)
   $FORM{rm} ||= 'front_page';
   $self->get_mode_param;

   %SES = validate_session();

   my $start_mode = $SES{valid_idle} ? $FORM{rm} : 'login';
   $self->start_mode($start_mode);

   $self->run_modes(
      'front_page' => 'front_page',
      # other run modes here 
      AUTOLOAD         =>
        sub { return err(title=>'Page not found',msg=>"(the run mode tried
was: $FORM{rm})") }
     );

}

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to