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

Hello, I have a send page that have two sets of five fields each, with basically the same input names that are represented by the following variables arranged by row:

$recipname1   $recipemail1 #row1
$recipname2   $recipemail2 #row2
$recipname3   $recipemail3 #row3
$recipname4   $recipemail4 #row4
$recipname5   $recipemail5 #row5

I also allow users to set the number of fields for them to fill up. Like if they set $recipnumber to 2 (through a select menu), only two input fields ($recipname1 & 2 and $recipemail1 & 2) appear in the page. I have also gotten it to work so that, say $recipname1 had already been inputed with "Andrew" and $recipemail1 with "andrew@andrew.com", no matter how many times I set $recipnumber to different numbers from 1-5 the data still remains where they're supposed to be. However, my problem enters when say, there are currently 5 rows available, and $recipname5 and $recipemail5 are filled with values "Joseph" and "joseph@joseph.com" respectively (all other fields empty), when I set $recipnumber to 1 for example, of course only one row will appear, however, the 5th row values dissappear accordingly with the 5th row, which I am expecting anyway. I would like it to work so that the script can detect that the other fields are empty, and any row with readable values will fill in the higher fields, so that "Joseph" and "joseph@joseph.com" will appear in row 1 (since it is empty) instead of disappearing. If the 4th row was filled up, then its values will appear in the 1st row, but the fifth row values will be discarded. I hope you understand what I'm saying. I appreciate your help... Thanks!

Replies are listed 'Best First'.
Re: Filling up empty values
by mirod (Canon) on Dec 05, 2002 at 10:44 UTC

    You did not post your code, so I don't know what kind of data structure you are using, but i would think that's where the problem comes from: you should store your values in an array (actually an array of hashes would be the most appropriate data structure), one item per "line". When you fill the array you can check whether an input line is empty, and just not store the line. This way you only store useful data.

    Here is a little script to show what I mean (code speaks louder than words? ;--) The important parts are the first 3 subs (process_param which fills the data structure, row_ok which does a very rudimentary error checking, and nb_filled_fields which gives you the number of... filled fields in a line. The rest of the script is the main loop that calls process_param for different test cases and some smoke and mirror that allows me to simulate CGI's param function by reading the data from the DATA section (now that I think about it it is quite stupid, I could have just used CGI and saved myself some time... but hey, this makes it easier to create additional tests). I assumed you are writing a CGI script BTW.

    #!/usr/bin/perl -w use strict; my $NB_ROWS= 5; my @FIELDS= qw( name email); sub process_params { my @data; # stores all the data retrieved as an array of hashes foreach my $nb (1..$NB_ROWS) { my $row; # stores the data for a single row: field_name => val +ue # load the data foreach my $type ( @FIELDS) { $row->{$type}= param( "recip$type$nb"); } # error check, here just check that all fields are filled or e +mpty row_ok( $nb, $row) or return; # this is the important part: store row only if values are fil +led push @data, $row if( nb_filled_fields( $row)); } return @data; } sub row_ok { my( $nb, $row)= @_; my $nb_fields= nb_filled_fields( $row); if( !$nb_fields or $nb_fields == @FIELDS) { return 1; } else { warn "bad data in row $nb"; return 0; } } # count the number of fields that have true values # you would need to use defined $_ in the grep # if 0 is a valid value for one of the parameters sub nb_filled_fields { my( $row)= @_; my @filled_fields= grep { $_ } values %$row; my $nb_filled_fields= @filled_fields; return $nb_filled_fields; } # main test and smoke and mirror subs my $test_nb=1; while( read_params()) { print "test $test_nb:\n"; my @data=process_params(); display_data( @data); $test_nb++; } sub display_data { my @data= @_; foreach my $i (0..$#data) { print "data[$i]: "; foreach my $field (@FIELDS) { print " $field => $data[$i]->{$field}"; } print "\n"; } print "\n"; } { my $params; # just a hack to simulate CGI's param method sub read_params { $params={}; # reset params local $/="\n\n"; my $data=<DATA>; return undef unless $data; $data=~ s{[ \t]*\#.*\n}{}g; # remove comments my @rows= split /\n/, $data; foreach my $row (@rows) { my( $nb, $name, $email)= split /\s*:\s*/, $row; $params->{$nb}= { name => $name, email => $email }; } return 1; } sub param { my( $param_name)= @_; if( $param_name=~ m{^recip(name|email)(\d+)$}) { my( $type, $nb)= ($1, $2); return $params->{$nb}->{$type}; } else { die "wrong param called: $param_name"; } } } __DATA__ # test 1 1 : Andrew : andrew@andrew.com 2 : Joseph : joseph@joseph.com 3 4 5 # test 2 - line 4 should appear as line 2 1 : Andrew :andrew@andrew.com 2 3 4 : Joseph : joseph@joseph.com 5 # test 3 - line 4 should appear as line 1 1 2 3 4 : Joseph : joseph@joseph.com 5 # test 4 - should output warning 1 2 3 : : dummy@dummy.com 4 : Joseph : 5
Re: Filling up empty values
by ibanix (Hermit) on Dec 05, 2002 at 09:49 UTC
    > I hope you understand what I'm saying.

    No, sorry. Can you post some code, and some sample data that causes your problem?

    $ echo '$0 & $0 &' > foo; chmod a+x foo; foo;
      I probably wouldn't be able to help you anyway because I am a real newbie, but I am going to make a suggestion. Maybe you should consider changing the structure of your writeup and using bullet points or something. It is very difficult to even follow what you are trying to achieve, much less what the problem is, as it stands. I think people will be more likely to help if they don't think they are going to have to decipher the post before they can even volunteer advice. If you go to the Information links to the right, that should help you.
Re: Filling up empty values
by drewboy (Sexton) on Dec 05, 2002 at 19:13 UTC
    Thank mirod, for the code. I will study it as soon as possible. but please check out this page i made to make my question more understandable:

    Example