Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

Here you go. It's minimal/simplistic but it's functional and self-contained. You should be able to walk through it and see how things are working. I doubt this thread will expand so I'm going to forgo the readmore tags.

use strict; use warnings; use CGI qw(:standard); use Template; use JSON::XS; # Don't use CGI::Carp in production, it's here to make your life # easier while you experiment with this. use CGI::Carp qw(fatalsToBrowser); my $default = "splash"; my %actions = ( $default => \&show_form, ajax_lookup => \&ajax_lookup, ); my $action = param("x") || $default; my $executable = $actions{$action} || \&no_such_action; $executable->(); # Subroutines #--------------------------------------------------------------------- sub show_form { print header(); my $tt2 = Template->new(); $tt2->process(\*DATA, { self_uri => CGI::url(), usernames => [ map { $_->{username} } @{_du +mmy_db()} ], }) or die $tt2->error; } sub ajax_lookup { my $data = _dummy_db(); my $query = param("username"); my $result = {}; for my $row ( @{$data} ) { $result = $row if lc($query) eq lc($row->{username}); } print header("application/json"), encode_json($result); } sub no_such_action { print header(), h1("Nopers! Don't know how to do that!"); } sub _dummy_db { return [ { username => "paco", fish => "Sunfish", }, { username => "YourUncle", fish => "Coelacanth", }, { username => "hiragana", fish => "Monkfish", }, { username => "MosaicNL", fish => "Sixgill Shark", }, ]; } __DATA__ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US"> <head> <title>OH, HAI! I CAN HAS AJAKS?</title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.js"></s +cript> <script type="text/javascript">//<![CDATA[ $(function() { $("input[name='username']").bind("keyup", function(){ var myField = $(this); var myData = { username: myFiel +d.val() ,x: "ajax_lookup" }; $.ajax({ type: "GET" ,dataType: "json" ,url: "[% self_uri %]" ,data: myData ,success: function(json){ if ( json.username ) { $("input[name='fish'] +").val(json.fish); } else { $("input[name='fish'] +").val(""); } } }); }); }); //]]> </script> </head> <body> <form action="[% self_uri %]" method="post"> <fieldset> <legend>Simplistic Ajax Example</legend> <p> <label for="username">Username</label> <input id="username" type=" +text" name="username"/> <label for="fish">Fish</label> <input id="fish" type="text" name=" +fish"/> </p> <p style="clear:both; font-size:9px"> Usernames you can search for: <i>[% usernames.join(", ") %]</i> +. </p> </fieldset> </form> </body> </html>

There are some Perl idioms in there to make the thing terse enough for a small sample. So, just to explain: the __DATA__ section is a Template Toolkit template. Check the docs if it doesn't make sense.

The CGI proper does exactly three things; all different. If called without args, or with x=show_form, it prints the template which has a form in it. It sends two pieces of data to the template: self_uri (its own URI for the Ajax call to use) and usernames (an array ref from our "DB" of users to help prompt the person testing the form).

Instead of names and addresses, I've given each username a fish. When the page loads, the jQuery installs a keyup listener on the username field: $("input[name='username']").bind("keyup", function()...). You can read up on how jQuery selectors work. It's easy and intuitive. It's just CSS for the most part.

The next part is the Ajax. Ajax traditionally used XML, hence the "X." But I find JSON as a data layer superior in almost all cases. JSON::XS is perhaps the fastest data serializing available from Perl. So, read some of this page, jQuery/Ajax, to see what's going on. It should be pretty obvious.

Our Ajax call will GET data of the type json from the same URL the CGI displays the form with the arguments x=ajax_lookup (which sub to run in the CGI) and username=[whatever the value of the username field is on the last keyup].

The CGI then uses the username to look in the "DB" and returns a JSON data object like { username: "found user", fish: "Fish type" } if a username matches or {} if none does. The results get sent to the success: function(json){...} which is installed into our Ajax call. If the JSON data has a username, then its "fish" is put into the other form field. If not, the field is emptied. Ta!

The third handler, no_such_action, is just there for code "completeness." Arbitrary user input should never be able to break an application.

If this were a real application I'd install an "intent" layer in the keyup binding. You probably don't want to lookup the users on every keystroke. Just the one which is followed by a brief pause, probably, meaning the user is done typing (similar to hover intent stuff for mouseovers on menus so they don't flicker on and off but allow for friendlier UI). There are jQuery plugins for this -- I used one a year ago and can't remember its name.

As you can see, it's quite easy, just confusing until you know how it all hangs together. Something like Catalyst underneath it makes it easy to extend it all over the place. Hope that helps get you (and anyone else) going. :)


In reply to CGI/Ajax example: lookup a value when a field is filled in by Your Mother
in thread CGI how to lookup a value when a Field is filled in by javahead

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (3)
As of 2024-04-25 06:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found