AutocompleteWidget: experimental, magic, RFC

51 views
Skip to first unread message

mdipierro

unread,
Feb 6, 2010, 3:30:53 PM2/6/10
to web2py-users
People say there is some magic in web2py.
Here is some real magic now in trunk that I am sure you have never
seen.

Caveats:
0) requires latest trunk (bzr 1603, hg 175:e42b559254f6)
1) this is an experiment, not sure it is a good idea
2) this is the first function in web2py that REQUIRES jQuery
3) works but I am not yet convinced it should stay there
4) even if it stays, I am sure the API should stay

Example:

### assume this model
db.define_table('target',Field('name'))
if not db(db.target.id>0).count():
db.target.insert(name="Klingon")
db.target.insert(name="Romulans")
db.target.insert(name="Borg")
db.target.insert(name="Borg2")
db.define_table('photon_torpedo',Field('target',db.target))

### assume this action in controller default.py
def launch():
db.photon_torpedo.target.represent=lambda target: target.name
return dict(new_torpedo=crud.create(db.photon_torpedo),
launched_torpedos=db().select(db.photon_torpedo.ALL))

So far nothing new.

Now append to the model or insert at top of controller the following:

from gluon.sqlhtml import AutocompleteWidget
db.photon_torpedo.target.widget=AutocompleteWidget(request,db.target.name,db.target.id)

No need to define any callback action (there is no callback action!)
No plugin required (perhaps some optional css to style).
No js coding required.
Applies to existing apps, including those that use custom forms.

Let's see who can figure out how it works!

Massimo

Jason Brower

unread,
Feb 7, 2010, 12:40:51 AM2/7/10
to web...@googlegroups.com
I have my current autocomplete but it doesn't do öäå in a search. Does
this handle that?
Best Regards,
Jason

mdipierro

unread,
Feb 7, 2010, 2:02:50 AM2/7/10
to web2py-users
I do not know that. I am still playing with it...

mdipierro

unread,
Feb 7, 2010, 3:09:19 PM2/7/10
to web2py-users
I fixed some problem with validators. Can somebody give this a try? I
could use a second opinion.

Massimo

mdipierro

unread,
Feb 7, 2010, 3:11:35 PM2/7/10
to web2py-users
How about we change IS_IN_DB so that, if the number of referenced
records exceeds a maximum the auto complete widget is on by default?

Massimo

On Feb 7, 1:02 am, mdipierro <mdipie...@cs.depaul.edu> wrote:

mr.freeze

unread,
Feb 7, 2010, 4:12:29 PM2/7/10
to web2py-users
Nice! I like this but I think it needs a few more tweaks. Can you
modify it to allow the arrow keys to select an item? Also, when you
clear the input after typing something, all of the options show.

I personally think that javascript should be used more in the
framework (with proper attention paid so that things degrade
gracefully when it's off).

mdipierro

unread,
Feb 7, 2010, 5:26:32 PM2/7/10
to web2py-users

On Feb 7, 3:12 pm, "mr.freeze" <nat...@freezable.com> wrote:
> Nice! I like this but I think it needs a few more tweaks. Can you
> modify it to allow the arrow keys to select an item? Also, when you
> clear the input after typing something, all of the options show.

Yes it can be done. It is on my to do list.

>
> I personally think that javascript should be used more in the
> framework (with proper attention paid so that things degrade
> gracefully when it's off).

Something like auto-completion is just going to break if jQuery is not
present. I am not sure if it is possible to make degrade gracefully.

mdipierro

unread,
Feb 7, 2010, 9:34:31 PM2/7/10
to web2py-users
Now it is very customizable and works well, including right, up, down
arrows. It requires at least two chars to start the ajax calls.

just do

db.table.field.widget=AutocompleteWidget(request,db.othertable.name,db.othertable.id)

it looks up in field "name" for the value of "id".

On Feb 7, 3:12 pm, "mr.freeze" <nat...@freezable.com> wrote:

mr.freeze

unread,
Feb 7, 2010, 9:52:44 PM2/7/10
to web2py-users
Looking good but now I can't select an unselected option by clicking.
I can only select the currently selected option with a mouse click.

mdipierro

unread,
Feb 7, 2010, 11:34:00 PM2/7/10
to web2py-users
Please give it a try. It seems some time requires double click instead
of single click but cannot figure out why.

mr.freeze

unread,
Feb 8, 2010, 12:22:43 AM2/8/10
to web2py-users
It is doing two callbacks, one to get autocomplete options and one
when you click an item. It seems like it shouldn't do the second one.
Also, it probably shouldn't submit the form if you hit the enter key
while selecting an option. You might try breaking that huge js code on
attr['_onkeyup'] into smaller more digestible pieces to see what's
going on :)

There should really be a widget script resource section in
web2py_ajax.html so that widget makers can include global functions
and styles that multiple instances of a widget can use. Kind of like
response.files but raw code instead of file includes. Maybe just a
blank jQuery(document).ready function at the end of web2py_ajax.html
that renders a list called response.ready. Putting it at the end will
keep user code from breaking necessary framework code. Thoughts?

villas

unread,
Feb 8, 2010, 6:53:29 AM2/8/10
to web2py-users
I just spent ages playing around with Pengoworks, but it's even better
if this can be built into Web2py without any dependencies.

> How about we change IS_IN_DB so that, if the number of referenced
> records exceeds a maximum the auto complete widget is on by default?

Yes, that's even better. I suppose in that case, the feature will
automatically have to be disabled if JS not available? IS_IN_DB will
have to function every time!

Problem: After making selection (FireFox 3.5), the dropdown list
doesn't close up. Only way of closing seems to be pressing return
which then submits the form.

--David

villas

unread,
Feb 8, 2010, 7:40:23 AM2/8/10
to web2py-users
Problem2: Multi-select appears to be turned on. I mean, press ctrl key
and you can click several options.

mdipierro

unread,
Feb 8, 2010, 11:29:07 AM2/8/10
to web2py-users
Can you give it one more try?

Jason Brower

unread,
Feb 8, 2010, 11:29:26 AM2/8/10
to web...@googlegroups.com
I will try it when it's in a release, I want to test the ÖÄÅ features as
I can't get it to work in my setup.
Best Regards,
Jason

villas

unread,
Feb 8, 2010, 1:48:22 PM2/8/10
to web2py-users
> Can you give it one more try?

Here are my results with latest sqlhtml.py

Firefox 3.5.7: Works better, but not 100%.
The drop-down appears. OK
Single click selection. NO
Double click selection. OK
Drop-down closes after selection. OK
Note: You can still select more than one option with control click,
which leads to a ticket.

IE8: Unusable.
The drop-down appears, but then immediately fades away again. It
appears just long enough to be able to click on your selection but the
item selected is not transferred into input box.
Single click selection. NO
Double click selection. NO

Thadeus Burgess

unread,
Feb 8, 2010, 2:21:54 PM2/8/10
to web...@googlegroups.com
can we get an uncompressed version of the javascripts?

-Thadeus

> --
> You received this message because you are subscribed to the Google Groups "web2py-users" group.
> To post to this group, send email to web...@googlegroups.com.
> To unsubscribe from this group, send email to web2py+un...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/web2py?hl=en.
>
>

mdipierro

unread,
Feb 8, 2010, 2:28:32 PM2/8/10
to web2py-users
Instead of clicking can you use the up, down, right arrows? DO they
work?

mdipierro

unread,
Feb 8, 2010, 2:38:52 PM2/8/10
to web2py-users
I posted a modified version. Can you check it it makes any difference?

On Feb 8, 12:48 pm, villas <villa...@gmail.com> wrote:

villas

unread,
Feb 8, 2010, 3:04:28 PM2/8/10
to web2py-users
Running my manual test-suite :)

Firefox 3.5.7 (Win):
Single Click OK.
Multi-select fixed.
Up and Down arrow keys also work.
Suggestion: when dropped-down, it would be nice if <ENTER> key
completed the selection and closed the drop-down, instead of
submitting form.
Good to go!

IE8 (Win):
No good.
The drop-down opens and closes even faster than before. Selection
not poss. Arrow keys and clicking does not work.

mdipierro

unread,
Feb 8, 2010, 7:39:53 PM2/8/10
to web2py-users
please try once more.

villas

unread,
Feb 8, 2010, 9:22:10 PM2/8/10
to web2py-users
Firefox 3.5.7 (Win):
Appear to be unchanged since my last report.
Conclusion: Good.

IE8 (Win):
The drop-down opens, but then closes after a second.
However, there is now just enough time to click-select an option.
The selected option is transferred correctly to the input field.
Arrow keys do not appear to work.
Conclusion: Better, at least now functions to a degree. But the drop-
down does not stay down properly to allow selection.

mdipierro

unread,
Feb 8, 2010, 10:35:17 PM2/8/10
to web2py-users
In gluon/sqlhtml.py in two places, there is a delay(1000). Does it
help if you increase that number to 2000 or 3000 or 5000?

villas

unread,
Feb 9, 2010, 5:27:59 AM2/9/10
to web2py-users
IE (Win):
Adjusting the delay to 3000 does help to give enough time to make a
choice.
Setting it above 3000 doesn't seem to make any further difference
though.
On dropdown, the input loses focus so you cannot keep typing to
narrow down the selection.
Arrow keys do not work.

Wes James

unread,
Feb 9, 2010, 4:29:59 PM2/9/10
to web...@googlegroups.com
When text is typed that is not in the list and submitted there is this error:

Traceback (most recent call last):
File "/opt/00/gluon/restricted.py", line 173, in restricted
exec ccode in environment
File "/opt/00/applications/0/controllers/default.py", line 60, in <module>
File "/opt/00/gluon/globals.py", line 96, in <lambda>
self._caller = lambda f: f()
File "/opt/00/applications/0/controllers/default.py", line 12, in launch
return dict(new_torpedo=crud.create(db.photon_torpedo),
File "/opt/00/gluon/tools.py", line 2324, in create
deletable=False,
File "/opt/00/gluon/tools.py", line 2271, in update
keepvalues=self.settings.keepvalues):
File "/opt/00/gluon/sqlhtml.py", line 944, in accepts
fields[fieldname] = int(fields[fieldname])
ValueError: invalid literal for int() with base 10: ''

Is this supposed to have built in validation?

-wes

On Sat, Feb 6, 2010 at 1:30 PM, mdipierro <mdip...@cs.depaul.edu> wrote:
> People say there is some magic in web2py.
> Here is some real magic now in trunk that I am sure you have never
> seen.
>
> Caveats:
> 0) requires latest trunk (bzr 1603, hg 175:e42b559254f6)
> 1) this is an experiment, not sure it is a good idea
> 2) this is the first function in web2py that REQUIRES jQuery
> 3) works but I am not yet convinced it should stay there
> 4) even if it stays, I am sure the API should stay
>

<snip>

mdipierro

unread,
Feb 9, 2010, 11:12:27 PM2/9/10
to web2py-users
No you still needs to setup a validator

On Feb 9, 3:29 pm, Wes James <compte...@gmail.com> wrote:
> When text is typed that is not in the list and submitted there is this error:
>
> Traceback (most recent call last):
>   File "/opt/00/gluon/restricted.py", line 173, in restricted
>     exec ccode in environment
>   File "/opt/00/applications/0/controllers/default.py", line 60, in <module>
>   File "/opt/00/gluon/globals.py", line 96, in <lambda>
>     self._caller = lambda f: f()
>   File "/opt/00/applications/0/controllers/default.py", line 12, in launch
>     return dict(new_torpedo=crud.create(db.photon_torpedo),
>   File "/opt/00/gluon/tools.py", line 2324, in create
>     deletable=False,
>   File "/opt/00/gluon/tools.py", line 2271, in update
>     keepvalues=self.settings.keepvalues):
>   File "/opt/00/gluon/sqlhtml.py", line 944, in accepts
>     fields[fieldname] = int(fields[fieldname])
> ValueError: invalid literal for int() with base 10: ''
>
> Is this supposed to have built in validation?
>
> -wes
>

ecall

unread,
Feb 17, 2010, 4:58:10 PM2/17/10
to web2py-users
Thanks for this nice feature.

How can I make it run with ./dev_appserver.py (development for gae)?

So far, I have this:
File "......../workspace/google_appengine/src/google/appengine/api/
datastore.py", line 2172, in _GetCompleteKeyOrError
raise datastore_errors.BadKeyError('Key %r is not complete.' %
key)
BadKeyError: Key datastore_types.Key.from_path(u'target', 0L,
_app_id_namespace=u'web2py') is not complete.

Regards,
Edouard


On 6 fév, 21:30, mdipierro <mdipie...@cs.depaul.edu> wrote:
> People say there is some magic in web2py.
> Here is some real magic now in trunk that I am sure you have never
> seen.
>
> Caveats:
> 0) requires latest trunk (bzr 1603, hg 175:e42b559254f6)
> 1) this is an experiment, not sure it is a good idea
> 2) this is the first function in web2py that REQUIRES jQuery
> 3) works but I am not yet convinced it should stay there
> 4) even if it stays, I am sure the API should stay
>

mdipierro

unread,
Feb 17, 2010, 6:26:39 PM2/17/10
to web2py-users
I have never seen this error. Can you show the relavant code and the
complete traceback?

ecall

unread,
Feb 18, 2010, 3:19:15 AM2/18/10
to web2py-users
I use your photon_torpedo/target sample in "welcome" application.

The request is http://127.0.0.1:8080/welcome/default/launch (GAE
1.3.1)

ERROR 2010-02-18 09:04:36,200 restricted.py:53] In FILE: C:
\Python25\eclipse\workspace\web2py_1.75.3\applications\welcome/
controllers/default.py

Traceback (most recent call last):

File "C:\Python25\eclipse\workspace\web2py_1.75.3\gluon
\restricted.py", line 173, in restricted
exec ccode in environment
File "C:\Python25\eclipse\workspace\web2py_1.75.3\applications
\welcome/controllers/default.py:launch", line 62, in <module>
File "C:\Python25\eclipse\workspace\web2py_1.75.3\gluon\globals.py",


line 96, in <lambda>
self._caller = lambda f: f()

File "C:\Python25\eclipse\workspace\web2py_1.75.3\applications
\welcome/controllers/default.py:launch", line 59, in launch
File "C:\Python25\eclipse\workspace\web2py_1.75.3\gluon\tools.py",
line 2395, in create
deletable=False,
File "C:\Python25\eclipse\workspace\web2py_1.75.3\gluon\tools.py",
line 2333, in update
upload=self.settings.download_url,
File "C:\Python25\eclipse\workspace\web2py_1.75.3\gluon\sqlhtml.py",
line 675, in __init__
inp = field.widget(field, default)
File "C:\Python25\eclipse\workspace\web2py_1.75.3\gluon\sqlhtml.py",
line 434, in __call__
record =
self.db(self.fields[1]==value).select(self.fields[0]).first()
File "C:\Python25\eclipse\workspace\web2py_1.75.3\gluon\contrib
\gql.py", line 673, in select
(items, tablename, fields) = self._select(*fields, **attributes)
File "C:\Python25\eclipse\workspace\web2py_1.75.3\gluon\contrib
\gql.py", line 636, in _select
item = self._db[tablename]._tableobj.get_by_id(filter.right)
File "C:\Python25\eclipse\workspace\google_appengine_1.3.1\google
\appengine\ext\db\__init__.py", line 1010, in get_by_id
return get(keys[0], rpc=rpc)
File "C:\Python25\eclipse\workspace\google_appengine_1.3.1\google
\appengine\ext\db\__init__.py", line 1203, in get
keys, multiple = datastore.NormalizeAndTypeCheckKeys(keys)
File "C:\Python25\eclipse\workspace\google_appengine_1.3.1\google
\appengine\api\datastore.py", line 141, in NormalizeAndTypeCheckKeys
keys = [_GetCompleteKeyOrError(key) for key in keys]
File "C:\Python25\eclipse\workspace\google_appengine_1.3.1\google
\appengine\api\datastore.py", line 2354, in _GetCompleteKeyOrError


raise datastore_errors.BadKeyError('Key %r is not complete.' %
key)
BadKeyError: Key datastore_types.Key.from_path(u'target', 0L,

_app=u'web2py') is not complete.


INFO 2010-02-18 09:04:36,200 gaehandler.py:55] **** Request:
109.00ms/109.00ms (real time/cpu time)
INFO 2010-02-18 09:04:36,246 dev_appserver.py:3246] "GET /welcome/
default/launch HTTP/1.1" 200 -

Says 200, but the browser send this:
Status: 500 INTERNAL SERVER ERROR
Content-Type: text/html; charset=UTF-8
web2py_error: ticket welcome/
127.0.0.1.2010-02-18.08-16-43.e1b0f638-417c-4108-a75b-f809cb1de3ec
Content-Length: 841

Thx

mdipierro

unread,
Feb 18, 2010, 9:29:28 AM2/18/10
to web2py-users
Can you post your code? Are you doing autocomplete for a reference
field? If so, do you have the validator?

ecall

unread,
Feb 18, 2010, 9:40:14 AM2/18/10
to web2py-users
The trace come from a fresh (web2py 1.75.3) install. I just add the
magic.

welcome/controllers/default.py :
------------------------------


### assume this action in controller default.py
def launch():
db.photon_torpedo.target.represent=lambda target: target.name
return dict(new_torpedo=crud.create(db.photon_torpedo),
launched_torpedos=db().select(db.photon_torpedo.ALL))

welcome/models/db.py :
--------------------


### assume this model
db.define_table('target',Field('name'))
if not db(db.target.id>0).count():
db.target.insert(name="Klingon")
db.target.insert(name="Romulans")
db.target.insert(name="Borg")
db.target.insert(name="Borg2")
db.define_table('photon_torpedo',Field('target',db.target))

from gluon.sqlhtml import AutocompleteWidget
db.photon_torpedo.target.widget=AutocompleteWidget(request,db.target.name,db.target.id)

Tito Garrido

unread,
Mar 16, 2010, 6:59:46 PM3/16/10
to web...@googlegroups.com
Is there a way to close the autocomplete field when the option get clicked?

--
You received this message because you are subscribed to the Google Groups "web2py-users" group.
To post to this group, send email to web...@googlegroups.com.
To unsubscribe from this group, send email to web2py+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/web2py?hl=en.




--

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

jep

unread,
Mar 27, 2010, 11:16:58 AM3/27/10
to web2py-users
Tito,

I had the same problem, but after i copied the latest jquery.js file
to the static/ folder of my application, it automatically closes
(after 2 or 3 seconds).
Closing should/should be a little faster to give it a more responsive
feeling. (i am on linux / firefox
3.5.8)

jep

unread,
Mar 27, 2010, 11:26:25 AM3/27/10
to web2py-users
Cool feature,

Is it possible to use the value in input A as a limiting select for
input B.

eg. If your targets can belong to different groups and Borg2 is only
in Group2, not Group1.

If i select Group2 in my first input field in a form, then in field 2
of the form the autocomplete should only select values that belong to
Group2.

1. reading the entered value from the first input field.
2. using that value for the autocomplete of the next input field.

Is / how would this be possible.

Reply all
Reply to author
Forward
0 new messages