Mose
Mose

Reputation: 563

JQuery Autocomplete from Perl

I'm struggling to pin point where this is failing. I can get this plugin to work using php/jquery on my local PC, but trying to duplicate it with Perl on my production box (Where php is not an option for reasons I'll not go into).

index.cgi - This is perl code that generates the html page that contains the text box.

#!/usr/bin/perl -w 

use DBI;
use CGI;
use warnings;
use strict;

$cgi = new CGI;
$cgi->autoEscape(undef);
print $cgi->header;
print $cgi->start_html(-title=>'test',
                        -dtd=>'//W3C//DTD HTML 4.01 Transitional//EN',
                        -style=>'/themes/ui-lightness/jquery.ui.all.css',
                        -script=>[
                                {-type=>'javascript', -src=>'/js/jquery-1.5.2.min.js'},
                                {-type=>'javascript', -src=>'/js/test.js'},
                                {-type=>'javascript', -src=>'/ui/jquery-ui-1.8.11.custom.js'},
                                {-type=>'javascript', -src=>'/ui/jquery.ui.core.js'},
                                {-type=>'javascript', -src=>'/ui/jquery.ui.widget.js'},
                                {-type=>'javascript', -src=>'/ui/jquery.ui.position.js'},
                                {-type=>'javascript', -src=>'/ui/jquery.ui.autocomplete.js'}
                        ]
        );

print $cgi->start_div({-class=>'ui-widget'});
print $cgi->textfield(-id=>'customer',-size=>25),$cgi->br;
print $cgi->end_div(),$cgi->br;
print $cgi->div({-class=>'ui-widget-content',-id=>'log'});
print $cgi->end_html;

test.pl - This is the code that runs in the background to feed the JSON to the autocomplete:

#!/usr/bin/perl 
use warnings;
use strict;
use CGI;
use DBI;
use JSON;

my $cgi = CGI->new;
print $cgi->header(-type => "application/json", -charset => "utf-8");
my $dbh = DBI->connect('dbi:mysql:hostname=test;database=test',"test","test");
my $term = $cgi->param('term');
my $sth = $dbh->prepare(qq{SELECT customer.name, customer.id FROM test WHERE customer.name ?;}) or die $dbh->errstr;
$sth->execute($term.'%') or die $sth->errstr;
my $json = {};
while(my @customer = $sth->fetchrow_array()) {
   $json->{$customer[0]} = $customer[1];
}
print JSON::to_json($json);

test.js - This is the actual JQuery that is being used:

$(function() {
        function log( message ) {
                $( "<div/>" ).text( message ).prependTo( "#log" );
                $( "#log" ).attr( "scrollTop", 0 );
        }

        $( "#customer" ).autocomplete({
                source: "test.pl?term=",
                minLength: 2,
                select: function( event, ui ) {
                      log( ui.item ?
                              "Value: " + ui.item.value + " Key " + ui.item.id :
                              "Nothing selected, input was " + this.value );
                }
        });
});

I've been around google, but haven't found anything solid where someone has an example of Perl with JQuery. The test.js and index.cgi files duplicate the code from the jquery-ui example files for jquery autocomplete almost exactly except index.cgi is written in Perl using CGI.pm.

Any help would be appreciated, again I am somewhat limited in languages here due to the nature of the server and the applications that are on it.

Upvotes: 1

Views: 3632

Answers (2)

jk.
jk.

Reputation: 14435

You do not have the value or label field assigned in the returned json string. You are dumping name and id. The autocomplete does not know which one you want to appear in the autocomplete results. Assign the customer name to the value field.

$json->{"value"} = $customer[0];
$json->{"id"} = $customer[1];

The jQuery autocomplete needs a "value" or "label" field returned with the json result. If you do not include it, the jquery autocomplete will not work:

The basic functionality of the autocomplete works with the results of the query assigned to the ‘label’ and ‘value’ fields. Explanation on the ‘label’ and ‘value’ fields from the jQuery UI site:

“The local data can be a simple Array of Strings, or it contains Objects for each item in the array, with either a label or value property or both. The label property is displayed in the suggestion menu. The value will be inserted into the input element after the user selected something from the menu. If just one property is specified, it will be used for both, eg. if you provide only value-properties, the value will also be used as the label.”

Link to full example: http://www.jensbits.com/2011/05/09/jquery-ui-autocomplete-widget-with-perl-and-mysql/

Upvotes: 0

Axeman
Axeman

Reputation: 29854

Perl and jQuery are mostly isolated. If the Perl sends the correct HTML your browser should execute the right jQuery code. And if in test.pl you send the right JSON--provided that you've set up jQuery to handle it correctly--it ought to process correctly.

However, as mentioned in my comment it has to compile first. You're missing a semi-colon at the end of your $dbh assignment. That means that Perl thinks you're not done and is expecting that you are trying in some way to tie the $sth assignment in with the $dbh assignment.

Once I made that change, your code compiled. To check compilation: perl -c test.pl. But it failed because I don't have access to the DBs you're trying to check, so assuming that the connection string is correct, I can't see why this wouldn't work.

And always, always--in development at least--start your scripts off with:

use strict;
use warnings;
...

To give yourself a fighting chance to catch coding errors. Of course in production, they'll give you better error messages as well, if there is a segment of the code that you failed to test in pre-production testing.

Upvotes: 3

Related Questions