Forum Moderators: coopster & phranque

Message Too Old, No Replies

Parsing Form with cgi-lib.pl

Output of Form Fields not in same order as Input

         

Bazzaboy

10:41 pm on Feb 20, 2007 (gmt 0)

10+ Year Member



I have used cgi-lib.pl to parse data from an online form. This form has fields in the following order:

Salutation
Name
Surname
Email

However, when I get the result the order of the fields gets distorted. I get it in the following order:

Surname
Email
Name
Salutation

How can I get cgi-lib.pl to give me the results in the same order as the HTML form?

The code I use is as follows:

#!/usr/bin/perl
require "cgi-lib.pl";
&ReadParse;

print "Content-type: text/html\n\n";

print <<"PrintTag";
<HTML>
<HEAD>
<TITLE>Testing Form Input</TITLE>
</HEAD>
<BODY>
<TABLE>
PrintTag

foreach $key (keys(%in))
{
print <<"PrintTag";
<TR>
<TD>$key</TD>
<TD>$in{$key}</TD>
</TR>
PrintTag
}

print <<"PrintTag";
</TABLE>
</BODY>
</HTML>
PrintTag

Yes, I am from the old school and still use cgi-lib.pl. So please excuse me.

perl_diver

12:14 am on Feb 21, 2007 (gmt 0)

10+ Year Member



hashes do not maintain order, but since you know your form field names you can do this:

foreach my $key qw(Salutation Name Surname Email) {
{
print <<"PrintTag";
<TR>
<TD>$key</TD>
<TD>$in{$key}</TD>
</TR>
PrintTag
}

Bazzaboy

12:34 am on Feb 21, 2007 (gmt 0)

10+ Year Member



Thanks for that. This method would be OK if I only had a handful of incoming fields. I just gave an example. The form that I am actually going to use is 3 pages long and has close to 40 fields.

So we need to do it in some other more generic way.

If you can help me further with this, please do. I'll appreciate it.

perl_diver

1:24 am on Feb 21, 2007 (gmt 0)

10+ Year Member



one possibility:

#!/usr/bin/perl
require "cgi-lib.pl";
&ReadParse;
s/=[^=]*$// for @in;

print "Content-type: text/html\n\n";

print <<"PrintTag";
<HTML>
<HEAD>
<TITLE>Testing Form Input</TITLE>
</HEAD>
<BODY>
<TABLE>
PrintTag

foreach $key (@in)
{
print <<"PrintTag";
<TR>
<TD>$key</TD>
<TD>$in{$key}</TD>
</TR>
PrintTag
}

print <<"PrintTag";
</TABLE>
</BODY>
</HTML>
PrintTag

cgi-lib is so old you should not be using it. It is written for perl 4 and there is no gaurantee it will continue to work with more modern perl versions.

Bazzaboy

1:41 am on Feb 21, 2007 (gmt 0)

10+ Year Member



Thanks Kevin,

I'll try it out later and keep you posted in this forum. Wont be for a few hours yet.

Meanwhile, can you please tell me what this extra line

s/=[^=]*$// for @in;

does? What does it mean in plain English?

I am in the process of migrating to CGI.pm, but finding it rather difficult. All books using CGI.pm use strict CGI. And that is very unforgiving. So I have stuck to cgi-lib.pl.

Any suggestions as to the best websites to visit or the books to read for such migration? I write very elementary scripts as I do web design only as a hobby and not as a day job.

perl_diver

6:28 am on Feb 21, 2007 (gmt 0)

10+ Year Member



I am going on memory here as far as cgi-lib.pm goes so don't hold me to the fire too much.

When you call the ReadParse() function, the cgi-lib.pm module creates an array @in and a hash %in. @in is simply the name value pairs in one string:

name=value
name=value
etc
etc

and the hash is key/value pairs:

keys values
------------
name value
name value
etc
etc

the array has the form fields in the same order as the form, which is what you wanted. Now this bit of code:

s/=[^=]*$// for @in;

which is the short form of:

for (@in) {
s/=[^=]*$//;
}

removes the "=value" part from the "name=value" strings in the array leaving you with just the names of the form fields. The names are the same as the keys in %in. So you can use that to print out the form fields in original order.

Bazzaboy

7:49 am on Feb 21, 2007 (gmt 0)

10+ Year Member



Thank you very much Kevin,

I will have to read your explanation a few times to properly understand it.

In the meanwhile, I have tried out your code and it works like a charm.

Best Regards and have a nice day.

perl_diver

9:30 am on Feb 21, 2007 (gmt 0)

10+ Year Member



You're welcome.

rocknbil

8:30 pm on Feb 21, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Quite often the order in the form must differ than the order you want to output. Sometimes you want to "skip" some keys, for example, one response to the company and a shorter one to the customer. So what you do is apply the same method but use your own arrays, built of the form keys.

phranque

12:34 am on Feb 22, 2007 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



you can also use a hidden variable within the form to set the order.
for example:
<INPUT TYPE="Hidden" NAME="variable_order" value="Salutation,Name,Surname,Email"

in your script, retrieve and split the variable_order value and process in that order:
foreach $key (split /,/, $in{variable_order}){...}