Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

CGI question: elegant way to have three form image buttons doing different things?

by meonkeys (Chaplain)
on Sep 13, 2001 at 07:23 UTC ( [id://112094]=perlquestion: print w/replies, xml ) Need Help??

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

I'm attempting to make an HTML form with three different images that do three different actions. The buttons must be images, and all three buttons must be in the same form.

I made this simple script to test. Does anyone know a more elegant way to do this? I can't do three separate forms, because I need the data in the text box. Note that this is purely academic, as I am doing nothing exciting with the form data, I just thought it was an interesting problem.
#!/usr/bin/perl -Tw use CGI; use CGI::Carp qw( fatalsToBrowser ); use strict; my $cgi = CGI->new(); my $mode = $cgi->param('mode'); my $action = get_action( $cgi ); my $date = scalar localtime(); print $cgi->header(); print <<EndHTML; <html> <head><title>Test Three: ( $action : $mode )</title></head> <body> <form method="get" action="test_three.cgi"> <input type="text" name="date" value="$date"><br> <input type="image" name="invite" alt="Invite" src="invite.gif"> <br> <input type="image" name="view" alt="View Results" src="view.gif"> <br> <input type="image" name="leave" alt="Leave" src="exit.gif"> <br> <input type="hidden" name="mode" value="1"> </form> </body> </html> EndHTML sub get_action { my $cgi = shift; my $action; my @actions = qw( view invite leave ); TRY: for my $try ( @actions ) { if ( $cgi->param("$try.x") || $cgi->param("$try.y") ) { $action = $try; last TRY; } } $action; }
  • Comment on CGI question: elegant way to have three form image buttons doing different things?
  • Download Code

Replies are listed 'Best First'.
Re: CGI question: elegant way to have three form image buttons doing different things?
by Chady (Priest) on Sep 13, 2001 at 10:25 UTC

    Have your image submits with the same name and place a value:

    <input type="image" name="action" value="invite" alt="Invite" src="inv +ite.gif"> <br> <input type="image" name="action" value="view" alt="View Results" src= +"view.gif"> <br> <input type="image" name="action" value="leave" alt="Leave" src="exit. +gif">

    then you test that value in your script:

    my $action = $cgi->param('action'); if ($action eq 'invite') { # invite code } elsif ($action eq 'view') { # view ... ..

    He who asks will be a fool for five minutes, but he who doesn't ask will remain a fool for life.

    Chady | http://chady.net/

      Nice. Giving the images the same name, and associating a value is probably the most "elegant" way.

      As an alternative to a series of if...elsif...else statements, you could also use a hash of acceptable action names, paired with a sub, e.g.:

      my %actions = ( invite => sub { ... }, view => sub { ... }, leave => sub { ... }, ); my $action = $cgi->param('action'); $actions{$action}->() if exists $actions{$action};

      Update:

      ...except that from an HTML perspective, I don't think that using the same name for the input/image elements will work. According to the the HTML 4 standard,

      When a pointing device is used to click on the image, the form is submitted and the click coordinates passed to the server. The x value is measured in pixels from the left of the image, and the y value in pixels from the top of the image. The submitted data includes name.x=x-value and name.y=y-value where "name" is the value of the name attribute, and x-value and y-value are the x and y coordinate values, respectively.

      So, it looks like in the CGI script, you'd have to get the coordinates; you can't assign a value to that input/image element, since it acts like a submit button. So, we're probably again reduced to haveing to use separate names, and detecting the different names, or alternatively, knowing the coordinates that will be returned and detecting those.

      Or, like I mentioned before (and like wildooUK mentions below), use JavaScript. :-)

Re: CGI question: elegant way to have three form image buttons doing different things?
by willdooUK (Beadle) on Sep 13, 2001 at 14:30 UTC
    If you didn't mind using Javascript, you could get the form to submit to different cgi scripts. You just need to set the 'action' property of the form and call the 'submit' method:
    <html> <head> <script language="javascript"> function doSubmit(_action) { document.login.action = _action; document.login.submit(); } </script> </head> <body> <form name="login"> <table cellspacing="0" cellpadding="0" border="0"> <tr> <td align="right">User:</td> <td align="left"><input type="text" name="user" size="15"></td> </tr> <tr> <td align="right">Pass:</td> <td><input type="password" name="pass" size="15"></td> </tr> <tr> <td colspan="2"> <a href="javascript:doSubmit('delete.cgi');"><img alt="Delete" src +="delete.gif" border="0"></a> <a href="javascript:doSubmit('add.cgi');"><img alt="Add" src="add. +gif" border="0"></a> <a href="javascript:doSubmit('edit.cgi');"><img alt="Edit" src="ed +it.gif" border="0"></a> </td> </tr> </table> </form> </body> </html>

    willdooUK
    --------------
    "Home is a castle you built in my mind; I'm home anywhere, anytime."
    Donny Hathaway
Re: CGI question: elegant way to have three form image buttons doing different things?
by Ryszard (Priest) on Sep 13, 2001 at 09:57 UTC
    for a start, if youre using CGI, then you shouldnt be printing all that nasty HTML. Even tho' you've done well with the start of your script print $cgi->header() you should really continue the tradition.  print $cgi->start_html would be a start :-).

    the method i use for doing something similar (but using html buttons) is by having a form for each button.

    HTH
    .R

    updated to start_html (from begin_html) after coltsfoot's comment

      I think you mean $cgi->start_html();
Re: CGI question: elegant way to have three form image buttons doing different things?
by andye (Curate) on Sep 13, 2001 at 21:02 UTC
    Looks OK to me as it is - it's pretty clear what's going on - but you could simplify it slightly like this:
    my %act = ( 'view.x' => \&view , 'invite.x' => \&invite ); foreach ($query->param()) { $act{$_}->() if defined $act{$_}; } #danger, will robinson: I don't think $query->param() exists in old ve +rsions of cgi.pm
    I'm not sure this is really any better than what you've got, though. Still, hth.

    Andy.

Re: CGI question: elegant way to have three form image buttons doing different things?
by hatter (Pilgrim) on Sep 14, 2001 at 13:17 UTC
    I thought I had a similar problem a few weeks ago. Turns out it was a different problem, but I only figured that after I'd found a solution. Instead of using <input type=image> which I found various problems with presentation on different browsers, you can use the HTML4-friendly (that is, if you're a NS4 fan, it won't work) you can use
    <button type=submit name=foo value=bar src=image1.gif alt=whatever>
    Then check for the buttons name and value in whichever way your script likes.

    the hatter

Re: CGI question: elegant way to have three form image buttons doing different things?
by khippy (Scribe) on Sep 14, 2001 at 12:05 UTC

    Please don't listen to the folks who recommend using java script!
    If you concentrate on perl (and this is a 'about perl'
    site) you can use the server sided script even with
    lynx or GUI oriented Browsers without java script
    being enabled.
    Keep using the smallest common type of functions if
    possible.

    --
    there are no silly questions
    killerhippy
      also re: Please don't listen to the folks who recommend using java script!

      I'm not convinced.

      While you're right that its good to keep to the least complicated solution possible, in this case I think JS is a good choice.

      Since Lynx is a text-only browser, the original HTML wouldn't work - meonkeys wanted "an HTML form with three different images that do three different actions". He wanted three images to submit the form in three different ways.

      Also, since we're talking about forms with text input, its already prejudiced against GUI browsers (like a touch-screen info station, presumably). You could code for non-keyboard devices, but I'd only do it if I really had to.

      Surely it makes sense to utilise the best technologies at our disposal? I use Perl because it lets me make dynamic server side code with the least fuss. I use Javascript because it lets me make the client side dynamic with the least fuss.

      willdooUK
      --------------
      "Home is a castle you built in my mind; I'm home anywhere, anytime."
      Donny Hathaway
      re: Please don't listen to the folks who recommend using java script!

      Although this site is about Perl, we all have to realize that it's not always the 'best' solution to a particular problem. We have to use what is best suited for a particular task.

      I really don't like when someone say's not to listen to someone simply because they disagree. Let's keep our minds open and take advice from all, even those who we don't necessarily agree with.

      Personally, I would have gone for the javascript solution only because I know that the clients we support here are javascript enabled. However, if I am pointed to a better solution, I keep an open mind am likely to use it if I deem it appropriate.

      Mick
      Ok, here I am replying to myself, because mrmick and willdooUK
      are right in their sight and, of course, meonkeys approach.
      Let's say I was small-minded, when writing this. I was trapped
      by the imagination of an application of my own, instead of
      having read everything *before* answering (which was to be use-
      able by lynx, but later on, it couldn't work that way, but I
      am still aiming to that).
      Furthermore the experience of new websites, mixing their
      html-code with java-script e.g. to make a download-button, which
      disables copying the download-target, and other "modern" stuff,
      which might be functional but break my habbit of using things
      caused me to be angry about that.
      I was transporting this problem to the question of meonkeys,
      which was not ok, ok!
      Maybe I am answering better next time :)

      --
      there are no silly questions
      killerhippy
A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://112094]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (2)
As of 2024-04-20 11:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found