kellner,
Here are the routines you asked for +.
Code:
sub build_select_field_from_aux {
# --------------------------------------------------------
# Builds a select field from an auxilary database (text file).
my $aux = shift;
my $value = shift;
my $name = shift; #
added this line so the correct db field is used. my $aux_file = $aux; # e.g. "default.dates"
my @select_values;
open (AUX, "<$aux_file") || &cgierr("Can't open $aux_file: $!");
while (my $line = <AUX>) {
chomp($line);
push (@select_values, $line);
}
close (AUX);
my $out = qq|<select name="$name">|; #
changed this as well. foreach my $select_value (@select_values) {
if ($select_value eq $value) { $out .= qq|<option selected>$select_value|;}
else { $out .= qq|<option>$select_value|;}
}
$out .= qq|</select>|;
return ($out);
}
Code:
sub validate_record {
# --------------------------------------------------------
# Verifies that the information passed through the form and stored
# in %in matches a valid record. It checks first to see that if
# we are adding, that a duplicate ID key does not exist. It then
# checks to see that fields specified as not null are indeed not null,
# finally it checks against the reg expression given in the database
# definition.
my ($col, @input_err, $errstr, $err, $line, @lines, @data);
# Start add to aux DB here.
if ($in{'aux'}){
my $db = $in{'aux'};
my $value = $in{$db};
open (FILE, "<$db") || &cgierr("can't open $db in validate_record: $!");
while (my $line = <FILE>) {
chomp($line);
if ($line eq $value) {
push (@input_err, "ERROR: $value already exists in $db"); last}
}
close (FILE);
}
if ($in{'add_record'}) { # don't need to worry about duplicate key if modifying
open (DB, "<$db_file_name") or &cgierr("error in validate_records. unable to open db file: $db_file_name.\nReason: $!");
if ($db_use_flock) { flock(DB, 1); }
LINE: while (<DB>) {
(/^#/) and next LINE;
(/^\s*$/) and next LINE;
$line = $_; chomp ($line);
@data = &split_decode($line);
if ($data[$db_key_pos] eq $in{$db_key}) {
return "duplicate key error";
}
}
close DB;
}
foreach $col (@db_cols) {
if ($in{$col} =~ /^\s*$/) { # entry is null or only whitespace
($db_not_null{$col}) and # entry is not allowed to be null.
push(@input_err, "$col (Can not be left blank)"); # so let's add it as an error
}
else { # else entry is not null.
($db_valid_types{$col} && !($in{$col} =~ /$db_valid_types{$col}/)) and
push(@input_err, "$col (Invalid format)"); # but has failed validation.
(length($in{$col}) > $db_lengths{$col}) and
push (@input_err, "$col (Too long. Max length: $db_lengths{$col})");
if ($db_sort{$col} eq "date") {
push (@input_err, "$col (Invalid date format)") unless &date_to_unix($in{$col});
}
}
}
if ($#input_err+1 > 0) { # since there are errors, let's build
foreach $err (@input_err) { # a string listing the errors
$errstr .= "<li>$err"; # and return it.
}
return "<ul>$errstr</ul>";
}
else {
return "ok"; # no errors, return ok.
}
}
Code:
sub add_record {
# --------------------------------------------------------
# Adds a record to the database. First, validate_record is called
# to make sure the record is ok to add. If it is, then the record is
# encoded and added to the database and the user is sent to
# html_add_success, otherwise the user is sent to html_add_failure with
# an error message explaining why. The counter file is also updated to the
# next number.
my ($output, $status, $counter);
# Set the userid to the logged in user.
($auth_user_field >= 0) and ($in{$db_cols[$auth_user_field]} = $db_userid);
# First we validate the record to make sure the addition is ok.
$status = &validate_record;
# We keep checking for the next available key, or until we've tried 50 times
# after which we give up.
while ($status eq "duplicate key error" and $db_key_track) {
return "duplicate key error" if ($counter++ > 50);
$in{$db_key}++;
$status = &validate_record;
}
if ($status eq "ok") {
if ($in{'aux'}) {
my $db = $in{'aux'}; # or maybe: "in{'aux'}" . ".db" - depends on file extension
my $value = $in{$db};
open (FILE, ">>$db") || &cgierr("can't write to $db in add_record: $!");
print FILE "$value\n";
close (FILE);
}
# possibly an "else {" here? open (DB, ">>$db_file_name") or &cgierr("error in add_record. unable to open database: $db_file_name.\nReason: $!");
if ($db_use_flock) {
flock(DB, 2) or &cgierr("unable to get exclusive lock on $db_file_name.\nReason: $!");
}
print DB &join_encode(%in);
close DB; # automatically removes file lock
if ($db_key_track) {
open (ID, ">$db_id_file_name") or &cgierr("error in get_defaults. unable to open id file: $db_id_file_name.\nReason: $!");
if ($db_use_flock) {
flock(ID, 2) or &cgierr("unable to get exclusive lock on $db_id_file_name.\nReason: $!");
}
print ID $in{$db_key}; # update counter.
close ID; # automatically removes file lock
}
&auth_logging("added record: $in{$db_key}") if ($auth_logging);
if ($in{'aux'}) {
delete ($in{'aux'}); # otherwise the auxiliary db add fields will show up again
&html_add_form;
}
else {
&html_add_success;
}
}
else {
&html_add_failure($status);
}
}
Code:
sub html_record_form {
# --------------------------------------------------------
# The form fields that will be displayed each time a record is
# edited (including searching). You don't want to put the
# <FORM> and </FORM tags, merely the <INPUT> tags for each field.
# The values to be displayed are in %rec and should be incorporated
# into your form. You can use &build_select_field, &build_checkbox_field
# and &build_radio_field to generate the respective input boxes. Text and
# Textarea inputs can be inserted as is. If you turn on form auto
# generation, the program will build the forms for you (all though they may
# not be as nice). See the README for more info.
my (%rec) = @_;
($db_auto_generate and print &build_html_record_form(%rec) and return);
my $font = 'Font face="Verdana, Arial, Helvetica" Size=2 Color=#003399';
print qq|
<TABLE WIDTH="450" CELLPADDING=0 CELLSPACING=0 BORDER=1 BGCOLOR="#FFFFCC">
<TR><TD ALIGN="Right" VALIGN="TOP" WIDTH="150"><$font>ID:</FONT></TD>
<TD VALIGN="TOP" WIDTH="475"> <INPUT TYPE="TEXT" NAME="ID" VALUE="$rec{'ID'}" SIZE="3" MAXLENGTH="3"></TD></TR>
<TR><TD ALIGN="Right" VALIGN="TOP"><$font>Item Name:</FONT></TD>
<TD VALIGN="TOP"> <INPUT TYPE="TEXT" NAME="Item_Name" VALUE="$rec{'Item_Name'}" SIZE="40" MAXLENGTH="255"></TD></TR>
<TR><TD ALIGN="Right" VALIGN="TOP"><$font>Category: </FONT></TD>
<TD VALIGN="TOP"> <INPUT TYPE="TEXT" NAME="Category" VALUE="$rec{'Category'}" SIZE="40" MAXLENGTH="255"></TD></TR>
<TR><TD ALIGN="Right" VALIGN="TOP"><$font>Date 1:</FONT></TD>
<TD VALIGN="TOP"> |; print &build_select_field_from_aux("test.dates", "$rec{'Date1'}"
, Date1); print qq|<a href="$db_script_url?db=$db_setup&uid=$db_uid&add_form=1&aux=test.dates">Add value to list</a></TD></TR>
<TR><TD ALIGN="Right" VALIGN="TOP"><$font>Date 2:</FONT></TD>
<TD VALIGN="TOP"> |; print &build_select_field_from_aux("test.dates", "$rec{'Date2'}"
, Date2); print qq|</TD></TR>
# *** See Note At End *** <TR><TD ALIGN="Right" VALIGN="TOP"><$font>Price (\$):</FONT></TD>
<TD VALIGN="TOP"> <INPUT TYPE="TEXT" NAME="Price_USD" VALUE="$rec{'Price_USD'}" SIZE="12" MAXLENGTH="12" onChange="auto_fill()"></TD></TR>
<TR><TD ALIGN="Right" VALIGN="TOP"><$font>Price (¥):</FONT></TD>
<TD VALIGN="TOP"> <INPUT TYPE="TEXT" NAME="Price_YEN" VALUE="$rec{'Price_YEN'}" SIZE="12" MAXLENGTH="12" onChange="auto_fill()"></TD></TR>
<TR><TD ALIGN="Right" VALIGN="TOP"><$font>Weight (Oz):</FONT></TD>
<TD VALIGN="TOP"> <INPUT TYPE="TEXT" NAME="Weight_Oz" VALUE="$rec{'Weight_Oz'}" SIZE="12" MAXLENGTH="12" onChange="auto_fill()"></TD></TR>
<TR><TD ALIGN="Right" VALIGN="TOP"><$font>Weight (Kg):</FONT></TD>
<TD VALIGN="TOP"> <INPUT TYPE="TEXT" NAME="Weight_Kg" VALUE="$rec{'Weight_Kg'}" SIZE="12" MAXLENGTH="12" onChange="auto_fill()"></TD></TR>
</TABLE>
|;
}
Code:
sub html_add_form {
# --------------------------------------------------------
# The add form page where the user fills out all the details
# on the new record he would like to add. You should use
# &html_record_form to print out the form as it makes
# updating much easier. Feel free to edit &get_defaults
# to change the default values.
&html_print_headers;
print qq|
<html>
<head>
<title>$html_title: Add a New Record.</title>
<script language="javascript">
function auto_fill(){
if (document.title == "$html_title: Add a New Record." \|\| document.title == "$html_title: Modify a Record."){
if (document.test.Price_USD.value > 0){
document.test.Price_YEN.value = document.test.Price_USD.value * 125;
}
if (document.test.Weight_Oz.value > 0){
document.test.Weight_Kg.value = document.test.Weight_Oz.value * .02841;
}
}
}
</script>
</head>
<body bgcolor="#DDDDDD">
<form action="$db_script_url" method="POST" name="test">
<input type=hidden name="db" value="$db_setup">
# I was thinking that this could be the problem? <input type=hidden name="uid" value="$db_uid">|;
if ($in{'aux'}) {
my $db = $in{'aux'};
print qq|Add a new value to the list "$db"<br>
<input type="text" name="$db" size="30" maxlength="100">
<input type="hidden" name="aux" value="$db"><br>
<INPUT TYPE="SUBMIT" NAME="add_record" VALUE="Add Record">
<INPUT TYPE="RESET" VALUE="Reset Form">
|;}
else {
print qq|
<center>
<table border=1 bgcolor="#FFFFFF" cellpadding=5 cellspacing=3 width=500 align=center valign=top>
<tr><td colspan=2 bgcolor="navy">
<FONT FACE="MS Sans Serif, arial,helvetica" size=1 COLOR="#FFFFFF">
<b>$html_title: Add a New Record</b>
</td></tr>
<tr><td>
<p><center><$font_title><b>
Add a New Record
</b></font></center><br>
<$font>
|; &html_record_form (&get_defaults); print qq|
</font></p>
<p><center> <INPUT TYPE="SUBMIT" NAME="add_record" VALUE="Add Record"> <INPUT TYPE="RESET" VALUE="Reset Form"></center></p>
|; &html_footer; print qq|
</td></tr>
</table>
</center>
|;
}
print qq|
</form>
</body>
</html>
|;
}
Code:
sub html_add_success {
# --------------------------------------------------------
# The page that is returned upon a successful addition to
# the database. You should use &get_record and &html_record
# to verify that the record was inserted properly and to make
# updating easier.
&html_print_headers;
print qq|
<html>
<head>
<title>$html_title: Record Added.</title>
</head>
<body bgcolor="#DDDDDD">
<center>
<table border=1 bgcolor="#FFFFFF" cellpadding=5 cellspacing=3 width=500 align=center valign=top>
<tr><td colspan=2 bgcolor="navy">
<FONT FACE="MS Sans Serif, arial,helvetica" size=1 COLOR="#FFFFFF">
<b>$html_title: Record Added</b>
</td></tr>
<tr><td>
<p><center><$font_title><b>
Record Added
</b></font></center><br>
<$font>
<P><Font face="Verdana, Arial, Helvetica" Size=2>The following record was successfully added to the database:</FONT>
|; &html_record(&get_record($in{$db_key})); print qq|
</font></p>
|; &html_footer; print qq|
</td></tr>
</table>
</center>
</body>
</html>
|;
}
I did make a few modifications to the html_add_form as I didn't want to redo general layout.
In html_record_form you'll see a third value entered in the build_select... call
(Date1 and Date2) this is where $name in the sub build_select... gets its variable.
As said before, Everything works, just not quite perfect yet.
This DB is just a testing area before the real thing gets underway.
The actual DB will have about 50 fields (10 date fields) so you can probably understand why I've setup a testing area. Fewer possibly problems in debugging!
For visual reference:
Beetleman's Test DB user/pass
kellner/kellner
Feel free to add, modify, delete, etc... To get the full picture.
No real data listed.
Thanks,
beetleman Marcus L. Griswold