Re: Stuck on an idea..
by jZed (Prior) on Dec 23, 2003 at 19:31 UTC
|
Assuming you want "id" as the actual link and "name" as the label for the link:
my $sql = "SELECT id, name FROM names_table";
my $aryref = $dbh->selectall_arrayref($sql);
my @values = map { $_->[0] } @$aryref;
my %labels = map { $_->[0] => $_->[1] } @$aryref;
use CGI;
my $q = new CGI();
print $q->popup_menu(
-name=>'foo',
-values=>\@values,
-labels=>\%labels
);
| [reply] [d/l] |
|
|
I have a database with a million zillion names (well not that many, but let's pretend)
I am not really familiar with selectall_arrayref but suspect that all data is loaded into an array (please do correct me if I'm wrong). With a "million zillion" names, this might be a little hard on memory resources. If this is the case, I'd rather go for something like (untested):
my $dbh = DBI->connect($data_source, $user, $password);
my $sth = $dbh->prepare("SELECT id, name FROM names_table");
$sth->execute;
print "<form method=\"post\" action=\"path/to/script.cgi\">\n";
print "<select name=\"name\">\n";
while(my($id, $name) = $sth->fetchrow_array) {
print "<option value=\"$id\">$name</option>\n";
}
print "</select>\n";
print "<input type=\"submit\">\n";
print "</form>\n";
$dbh->disconnect;
| [reply] [d/l] |
|
|
I catch your point. But if there are so many names that a simple arrayref of names and ids hogs memory, then I doubt the OP will be able to print them out on a downloadable web page regardless of what methods they use. A million, zillion? Thanks, I'd prefer my dropdown menus to be less than 20 items at maximum and the ones that are close to 200 (e.g. country lists) are unweildy. Imagining a select list with 1,000+ names gives me a headache. If there really are that many or more, they would need to be broken into separate pages e.g. alaphabetically with a LIMIT clause or some such. And each of the borken down lists would be easily handled with an arrayref.
| [reply] |
|
|
A lot of people think that by using the prepare/execute/fetch cycle they will be able
to fetch only one row at a time. This is not always true. You may have to
specify a bit more in order to achieve that ... but, even if you did only fetch
one row at a time, this would hog up the CPU from other processes and you still have to send
at least twice the amount of data to the browser (data wrapped in HTML). It is not always
to the best thing to do, but it is good when you know you will be dealing with millions and
millions of records. I recommend running a packet sniffer on the database port to see if all
rows are being returned at once, or one row at a time.
Now, time for a rant. You are printing one line of HTML at a time. This is Perl, not Java! ;)
use strict;
use warnings;
use DBI;
use CGI::Pretty qw(:standard);
my $dbh = DBI->connect(
qw(DBI:driver:database:host user pass),
{RaiseError=>1},
);
my $sth = $dbh->prepare('select id,name from director order by name');
$sth->execute;
my $users = $sth->fetchall_arrayref({});
print header,
start_form('select_user'),
popup_menu('user',
[ map $_->{id}, @$users ],
undef,
{ map {$_->{id} => $_->{name}} @$users },
),
p(submit),
end_form,
;
For the record, even if i used HTML::Template for this, i would still use CGI.pm's
popup_menu(). Once you get the hang of it, it doesn't seem as daunting as it really is. ;)
| [reply] [d/l] |
Re: Stuck on an idea..
by jasonk (Parson) on Dec 23, 2003 at 19:04 UTC
|
Web Browser window? Tk window? Windows Window? Stained Glass Window?
As a CGI script, it's fairly easy...
#!/usr/bin/perl -w
use strict;
use CGI;
my %data = (
'Aaron Anderson' => 'The webmaster, blah blah',
'Someone Else' => 'Don\'t know',
'Fred' => 'Flintstone!',
);
my $cgi = new CGI;
print $cgi->header;
if($cgi->param('name')) {
print $data{$cgi->param('name')};
} else {
print <<"END";
<form method=post action="$ENV{SCRIPT_NAME}" target="_new">
Name: <input type=text name=name><br>
<input type=submit>
</form>
END
}
| We're not surrounded, we're in a target-rich environment! |
|---|
| [reply] [d/l] |
|
|
I meant a browser window!
I just installed your snippet a few minutes ago and am confused as to what it is you think it's doing. Maybe I messed something up, but when I installed that it made a text field and a button. What is it expecting me to write in there? The page redirects exactly to itself, so when I add something in there it opens a new window with a blank form.
I'm trying to post the names as links that open up displaying "The webmaster, blah blah" and such.
Thanks!
"Age is nothing more than an inaccurate number bestowed upon us at birth as just another means for others to judge and classify us"
sulfericacid
| [reply] |
Re: Stuck on an idea..
by injunjoel (Priest) on Dec 23, 2003 at 21:16 UTC
|
Greetings all,
I would suggest writing two scripts. One for the list of names the second for the display of more information (this one should take an id or something from the first to pull the correct record). Once this is set up then set the first list as links that open a JavaScript window to display the second script and pass in the unique id as a url_param.
below is a JavaScript window opener/reuser I use all the time... it takes an Url, width(of the new window), height(of the new window) as arguments.
<script language="JavaScript">
function newWin(arg,w,h){
if (!(!winup || winup.closed)){
winup.focus();
}
var winup=window.open(arg,'img_data','toolbar=no,resizable=yes,scr
+ollbars=no,width='+w+',height='+h);
winup.focus();
}
</script>
And here is how you call it from your HTML
<a href="javascript:newWin('your_page.pl?your_unique_id=your_unique_id
+_value',your_width, your_height)">Link Text</a>
Explaination:
your_page.pl => the second page you should write for the more information display
your_unique_id=your_unique_id_value => the name of your id parameter and the value you will pass by this name. From the first list of names (and ids)
your_(width|height) => how wide and tall the new window will be.
Of course the other parameters for the JavaScript call (toolbar=no,resizable=yes,scrollbars=no) are editable as well. But that should be a good start... I hope.
Hope that helps
| [reply] [d/l] [select] |
Re: Stuck on an idea..
by CountZero (Bishop) on Dec 23, 2003 at 23:03 UTC
|
use strict;
use CGI;
#Based upon the info found at: http://search.cpan.org/~lds/CGI.pm-3.01
+/CGI.pm#CREATING_A_SCROLLING_LIST
my %database = ('Aaron Anderson' => 'The webmaster, blah blah', 'Someo
+ne Else' => 'Don\'t know', 'Fred' => 'Flintstone!', 'Wilma' => 'Fred\
+'s wife', 'me' => 'A name I call myself');
my @list = keys %database;
my $query = new CGI;
if ($query->param('mylist')) {
print $query->header,
$query->start_html,
$query->param('mylist'),' : ',
$database{$query->param('mylist')},
$query->start_form,
$query->submit('Try again'),
$query->endform,
$query->end_html;
}
else {
print $query->header,
$query->start_html,
$query->start_form,
$query->scrolling_list('mylist', \@list,['me'],2),
$query->submit,
$query->endform,
$query->end_html;
}
CountZero "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law
| [reply] [d/l] |
Re: Stuck on an idea..
by InfiniteSilence (Curate) on Dec 24, 2003 at 17:51 UTC
|
Well, the million, zillion problem can be solved by simply changing your form generator script to show only X# of options at a time with a link to go and get more of them. For a contact list this is fairly common. I didn't bother resizing the popup form because I suspect that you really want to include more information about this user than a small window could provide. See your friendly JavaScript reference for details on open() function parameters.
#!/usr/bin/perl -w
use strict;
use CGI qw/:standard :debug/;
CGI::initialize_globals();
my $script = q(function open_popup(page) { window.open(page);return fa
+lse;});
my @names = qw/NAMES JOHN SALLY PETER SUE ANDRE/;
print header, start_html(-title=>'See a Name',
-script=>$script) ,
start_form(-name=>qq(NAMEFORM) -action=>'');
if (!param()) {
print '<select name="NAMELIST" onChange="open_popup(\'http://localho
+st/cgi-bin/bouncer.cgi?name=\' + this[this.selectedIndex].text)">' ,
( map {option($_) }@names) ,
'</select>';
}
else {
print h1("NAME RESPONSE"),
h3(fake_address(param('name')));
}
print &end_form, &end_html;
sub fake_address {
my $name = shift;
# Rewrite this to look up this information in a database or something
return($name . 'lives @ 1818 W. Refectory, New York, NY 22212');
}
1;
Celebrate Intellectual Diversity
| [reply] [d/l] |
Re: Stuck on an idea..
by dirthurts (Hermit) on Dec 27, 2003 at 10:40 UTC
|
| [reply] |