Pass a var to jQuery

43 views
Skip to first unread message

Tito Garrido

unread,
May 8, 2008, 10:45:15 AM5/8/08
to web...@googlegroups.com
Hi,

I'm a noob in java script... I'm trying to make a autocomplete field works with jquery in web2py.
I'm following this example: http://docs.jquery.com/Plugins/Autocomplete

My doubt is: How can I pass a web2py var to a jquery var? Like a sql query to fill the field...

Any help is appreciated,

Tito

--
Linux User #387870
____
_/_õ|__|
º[ .-.___.-._| . . . .
_(o).__(o).:_____

Massimo Di Pierro

unread,
May 8, 2008, 10:50:57 AM5/8/08
to web...@googlegroups.com
The example on the page says

$("#states").autocomplete(url, {
   extraParams: {
       country: function() { $("#country").val(); }
   }
}); 

you have do pass the URL of the controller that will will handle the request. The cotroller has to read request.vars.contry, generate the output and return it.
Does it make sense?

There is an example with scirptaculous+web2py posted on /applicances

Massimo

Tito Garrido

unread,
May 8, 2008, 10:54:56 AM5/8/08
to web...@googlegroups.com
I'll check the example... I was wondering if I couldn't pass a python var like {{states}}

in a controller -> states = [ a, b, c ]

Massimo Di Pierro

unread,
May 8, 2008, 10:57:31 AM5/8/08
to web...@googlegroups.com
yes, you can put things like {{=states}} in the JS if you want. This is OK if the text has to be generated before user input.

DenesL

unread,
May 8, 2008, 6:32:46 PM5/8/08
to web2py Web Framework
There are several jQuery autocomplete plugins.
I am using the one from:
www.pengoworks.com/workshop/jquery/autocomplete.htm
because it offers more customization options.

Your form needs a field such as:
<INPUT id="cusname" name="cusnam" class="ac_input" type="text"
style="..."/>

The autocomplete would look something like this:
$("#cusname").autocomplete("/app/handlers/cusnameAC",{ maxItemsToShow:
10 } ) ;

You can also have cascaded fields by adding:
...maxItemsToShow: 10, onItemSelect: function(itm) { ... the code to
modify the cascaded fields here ...} } ) ;

I defined the autocompletes and their handlers in the controller,
passing them in the response dict along with a function that will
create the JS code in myajax.html view:

in ctl: return dict{ ACs=ACs, ACfunc=ACfunc, ...}
in myajax view (loaded by mylayout.html):
{{try
ACs
except NameError:
pass
else:}}
{{=XML(ACfunc(ACs,request))}}
{{pass}}

The ACfunc() returns a string with all the jQuery code for each
autocomplete:
$("#field_id").autocomplete(...) ;

But you can just place the JS code directly there using:
$("#{{=field_id}}").autocomplete(...) ;

Don't forget to include your <link ...> and <script..> statements in
your ajax view and place the .js and .css in your static folder.

Your handler has to return a line per each option to be displayed in
the dropdown. To be useful you probably need the record id too. This
can be accomplished by adding the id to each line separating it with a
vertical bar:

r=''
for row in rows:
r='%s%s|%i\n'%(r,row.option,row.id)
return r

and the ids will not be displayed in the dropdown but they will be
available in JS as itm.extra .

It seems like a long answer but there is a lot of things involved that
need explaining. Once you get them right it works beautifully.

mdipierro

unread,
May 9, 2008, 1:05:05 AM5/9/08
to web2py Web Framework
Nice example!

Tito Garrido

unread,
May 9, 2008, 8:11:24 AM5/9/08
to web...@googlegroups.com
I got confused... I couldn't get it :(
But I'm trying...

I've put the <script> and css statements in web2py_ajax.html and there is something like this:
  $(document).ready(function(){
    var data = {{=locals}};
$("#example").autocomplete(data);
  });
  </script>

In my view:

{{=form_autocomplete}}

In my controler:

I'm trying to make a list with a select()... There is some method to get a list from a select()?
I'm using one "for" to get the names and append to the list "locals"

    select_locals=db().select(db.locals.name)
    locals =[]
    for local in select_locals:
        locals.append(local)

    form_autocomplete=INPUT(_type='text',_name='example',_id='example')

but "local" is SQLStorage

Tito Garrido

unread,
May 9, 2008, 8:12:11 AM5/9/08
to web...@googlegroups.com
I forgot the question... How can I convert or get a string from a select()?

Tito Garrido

unread,
May 9, 2008, 8:51:41 AM5/9/08
to web...@googlegroups.com
Hmm It's working now...
    select_locals=db().select(db.locals.name)
    locals =[]
    for local in select_locals:
        locals.append(local.name)

My doubt now is how I'll select the string and return the id...
And how can I make a form like "SQLFORM" with "FORM" statement

Regards,

Tito

DenesL

unread,
May 9, 2008, 9:42:42 AM5/9/08
to web2py Web Framework
The autocomplete uses an INPUT field to obtain a piece of info, which
is sent to a handler to obtain the options for a dropdown list (which
is similar to a SELECT).

You don't pass the list of options to the autocomplete, the list is
created and returned by the handler in an ajax call. Here is how it
happens:

1) When you type something into the INPUT field that triggers the
autocomplete (after a configurable delay with no keyboard activity).

2) The autocomplete creates an ajax call to the supplied handler
function (1st parameter with the plugin in my example) sending it
whatever was typed in a parameter named q (again, this is for the
plugin in my example, you would have to read the documentation if you
are using a different plugin). If you are using Firefox then download
Firebug to see how the info is being sent and returned.

3) Your handler ("/app/handlers/cusnameAC" in my example) has to get
the value of q from request.vars.q and do something with it to create
and return the options that will be shown in the dropdown.

4) When the ajax call returns (the plugin is doing all the work for
you behind the scenes) the dropdown is shown and you can select one of
the options which becomes the value for your INPUT field.

If this is not what you are trying to do and you just want a simple
SELECT with the info from your locals, then you can build it using the
SELECT and OPTION helpers in web2py and return it in your response
dict {theselect=theselect,...} to be displayed in the view using
{{=theselect}}.


> I forgot the question... How can I convert or get a string from a select()?

Either way when the form is submitted, all the named input type fields
(INPUTs, SELECTs, TEXTAREAs, etc. with a name="xxx" attribute) are
returned and their values can be retrieved from web2py's request in
your controller.

Tito Garrido

unread,
May 9, 2008, 10:00:32 AM5/9/08
to web...@googlegroups.com
Thanks DenesL,
I've understood the process...
What I'm trying to do is to change a select with a lot of data for a autocomplete field. In a select I can set a string to be shown and a id to go to the database...
In my example my handler is a populated list :(

How can I make a handler? You have any example?

Regards,

Tito

DenesL

unread,
May 9, 2008, 11:22:20 AM5/9/08
to web2py Web Framework
OK, so we have a JS statement:

$("#example").autocomplete("/app/handlers/exampleAC")

That means there is a controller "handlers" with a function
"exampleAC" in you app:

def exampleAC():
q=""
if request.vars: # check if you are getting the expected argument
q=request.vars.q
if not q:
return q # equivalent to no response
rows= db(db.locals.name.like("%s%
%"%q)).select(db.locals.name,db.locals.id)
r=""
for row in rows:
r='%s%s|%i\n'%(r,row.option,row.id)
return r

Now the problem on how to get the id.
I think you could use the findValue() function with the pengoworks
plugin but I decided to use:
onItemSelect: function(itm) { ... code to modify cascaded fields
here ...} } ) ;

which in your case would look like:
$("#example").autocomplete("/app/handlers/exampleAC",{onItemSelect:
function(itm) { ... code to modify a hidden field here ...} } ) ;

The hidden field would be something like this:
<INPUT type="hidden" id="exampleid" name="exampleid"/>

And the JS code to modify it:
$("#exampleid").attr({defaultValue:itm.extra});

The id would be available under request.vars.exampleid to the
controller after form submission.

If you don't want a dynamic ajax call to get the options you could use
autocompleteArray() an pass a JS array of generated options but you
would have to read up on it.

Sorry if it sounded condescending. Hope this helps.

RyeBread

unread,
May 9, 2008, 7:06:30 PM5/9/08
to web2py Web Framework
I submitted a couple of replies to the "SELECT" thread a couple of
days ago. I was having a similar problem and had derived a new class
which I called VSELECT which was an extension of the functionality of
SELECT.

The extension was that is one submitted a list of 2-tuples as the
*args to this VSELECT() class, it would split the values in each tuple
and assign element[0] to the Option value and element[1] to the Option
text. If a simple list of elements is used then it works the same as
the SELECT() class. You can mix the two types in the *args, even (but
why?). The code is in that other thread called 'SELECT' (I did not
start that thread...I just stole it!)

Massimo missed my point (bad description I guess) and interpreted that
I should be using a IS_IN_DB() call instead. He pretty much blew the
whole thing off, I was going to drop it until I figured out that it
did what I wanted better than anything else I could easily discover.
(My use of it was to create dependent menu selections...the contents
of menu-two would be loaded based on a selection from menu-one (by way
of an ajax call -- Massimo's ajax() function works just fine for it),
then the results of menu-two would load an INPUT element with a third
value pulled from the database and incremented.

[This is part of a front-end entry form for an automated software
build system that I am trying to translate into Python and
Web2.0 (hopefully will succeed using web2py sometime in the near
future) from Perl CGI which I wrote several years ago]

Anyway you can use this VSELECT class to create almost any select
element where the value is different from the description. It is bad
that I have a one-off class-name because that does not follow the HTML
pattern but it still has all the current functionality of the SELECT()
helper so it could be a replacement (Massimo doesn't what it though),
and also I hacked it into gluon.html, (my bad!). I have since taken
it out of the gluon library and put it into my application's modules
and just import it (I also have imported it across applications and it
still works there to).

Tito Garrido

unread,
May 9, 2008, 7:46:34 PM5/9/08
to web...@googlegroups.com
Thanks for your patience and attention DenesL,

I never used ajax before, so I'll try to implement what you have described and see the results. :)

RyeBread: I didn't understood, your VSELECT have a autocomplete feature?

Regards,

Tito Garrido

DenesL

unread,
May 9, 2008, 10:34:38 PM5/9/08
to web2py Web Framework
Rye, we all have to write code when the need arises, thanks for
sharing yours.
What I described above is just a small part of what I have been thru.
I also had to create another module to handle SELECT triggered
cascaded fields (similar to your case) but I took a different approach
which I might share in the future. Your code may come in handy later,
if not to me to somebody else, they might not have encountered the
need for it yet. Keep sharing if you think it is useful.

DenesL

unread,
May 9, 2008, 10:40:09 PM5/9/08
to web2py Web Framework
Tito, you are welcome.

Note: there is a mistake in def exampleAC(), where it says:
for row in rows:
r='%s%s|%i\n'%(r,row.option,row.id)

it should say:
for row in rows:
r='%s%s|%i\n'%(r,row.name,row.id)

That's the problem with using the "copy, paste & forget" method.

Happy web2py ajaxing.
Reply all
Reply to author
Forward
0 new messages