views:

59

answers:

2

I am trying to assign different actions to same html form according to different submit buttons.

Can I do something like this ?

        <FORM>
        ------
        <INPUT type="submit" value="DoSomething" action="DoSomething.pl" method="POST">
        <INPUT type="submit" value="DoSomethingElse" action="DoSomethingElse.pl" method="POST">
        <FORM/> 
+8  A: 

No. A form has only one action (action being a property of the form, not the submit button).

The target of the action can do different things on the bases of the values in the form. So, you might want to start naming your submit buttons.

Learn HTML before you even think about writing and deploying a CGI script.

<form method="POST" action="/cgi-bin/script">
<input type="submit" name="action" value="DoSomething">
<input type="submit" name="action" value="DoSomethingElse">
</form>

Note also that choosing an action based on the value of the submit button is a losing strategy if you wish to internationalize the application because the value of a submit button is what the UA displays to humans.

Therefore, script should decide what to do on the basis of some other input element's value.

For example, CGI::Application looks at a run_mode parameter.

Alternatively, you can use different names for your submit buttons as Alec suggests. In that case, you need to check which submit button was pressed by going through the names of the parameters passed to your script which, IMHO, makes the dispatch slightly more cumbersome. It also means it is possible for someone to pass values for all submit buttons to your script (not via the user interface, but via curl or wget or similar programs.

For example, given the HTML

<form method="POST" action="/cgi-bin/script">
<input type="submit" name="submit_left" value="Go Left">
<input type="submit" name="submit_right" value="Go Right">
</form>

here is how your script may handle form submission:

#!/usr/bin/perl

use strict; use warnings;

use CGI::Simple;

my $cgi = CGI::Simple->new;

my %dispatch = (
    left  => \&handle_left,
    right => \&handle_right,
);

my @actions = grep s/^action_(right|left)\z/$1/, $cgi->param;

my $handler = \&handle_invalid_action;

if ( @actions == 1) {
    my ($action) = @actions;
    if ( exists $dispatch{ $action } ) {
        $handler = $dispatch{ $action };
    }
}
else {
    $handler = \&handle_too_many_actions;
}

$handler->($cgi);

sub handle_left { }
sub handle_right { }
sub handle_invalid_action { }

# because it may indicate someone trying to abuse your script
sub handle_too_many_actions { }
Sinan Ünür
In the example code above, two submit buttons are redundant.Both of them will be performing same action.Correct ?
alertjean
@alertjean, that depends on the script. The submit buttons have different values, so the script can tell which one was clicked, and do something different based on that.
cjm
It's usually easier to use the `name` attribute to differentiate between the different actions. E.g. `<input type="submit" name="action_left" value="Go left!" />` and `<input type="submit" name="action_right" value="Go right!" />`. That way you can match simplified action names instead of actual texts. It's also the only way when you're working with multilingual sites, since the value will never be the same.
Alec
A: 

The form tag can have only one action attribute, however you could write a script in say PHP that would do more then one thing with the submitted data.

Blake