If you benefit from web2py hope you feel encouraged to pay it forward by contributing back to society in whatever form you choose!

Requirements

Download the necessary files from here

Extract the jquery-autocomplete folder to your static folder

Include the necessary files in your model

response.files.append(URL(r=request,c='static/jquery-autocomplete',f='jquery.autocomplete.js'))
response.files.append(URL(r=request,c='static/jquery-autocomplete',f='jquery.autocomplete.css'))

Getting the items locally

Add the widget to your model

def autocomplete_widget(f,v):
    import uuid
    d_id = "autocomplete-" + str(uuid.uuid4())[:8]
    wrapper = DIV(_id=d_id)
    inp = SQLFORM.widgets.string.widget(f,v)
    rows = f._db(f._table['id']>0).select(f,distinct=True)
    itms = [str(t[f.name]) for t in rows]
    scr = SCRIPT('var data= "%s".split("|");jQuery("#%s input").autocomplete(data);' % \
                  ("|".join(itms),d_id))
    wrapper.append(inp)
    wrapper.append(scr)
    return wrapper

Getting the items remotely

If you want to fetch the items remotely using an ajax call then use this widget instead:

def autocomplete_widget(f,v):
    import uuid
    d_id = "autocomplete-" + str(uuid.uuid4())[:8]
    get_url = URL(r=request,c='default',f='get_items')
    wrapper = DIV(_id=d_id)
    inp = SQLFORM.widgets.string.widget(f,v)
    scr = SCRIPT('jQuery("#%s input").autocomplete("%s",{extraParams:{field:"%s",table:"%s"}});' % \
                  (d_id, get_url,f.name,f._tablename))
    wrapper.append(inp)
    wrapper.append(scr)
    return wrapper

And include this in your controller. WARNING: Alter this to take your own security needs into account. It is not secure as is.

def get_items():
    itms = []
    if request.vars.q and \
       request.vars.table and \
       request.vars.field:
        q = request.vars.q
        f = request.vars.field
        t = request.vars.table
        fld = db[t][f]
        rows = db(fld.upper().like(q.upper()+"%")).select(fld,distinct=True) 
        itms = [str(t[f]) for t in rows] 
    return '\n'.join(itms)

Assign the widget

db.things.name.widget = autocomplete_widget

image

Presto whammo! You're done.

Related slices

Comments (3)

  • Login to post



  • 0
    jv 9 years ago
    Getting the items remotely - not secure implementation , anyone can change the request.vars.table and request.vars.field and read any table , in the database ( d.auth_user for example.

  • 0
    mrfreeze 9 years ago
    Correct, the example is to display the functionality of getting items remotely, not how to use auth. I will add a note pointing that out. Thanks.

  • 0
    richard 10 years ago
    Great slice when you can get it to work. The doc is a little too terse (at this writing), so it was a little hard for an autocomplete newbie like me to figure out what was going on. But with some hand holding, I got it to work and it works great!

Hosting graciously provided by:
Python Anywhere