wiki:AutoCompleteField
Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Version 1 (modified by bjourne@…, 9 years ago) (diff)

an howto about AutoCompleteField

Check out  Google Suggest to see input completion in action. The AutoCompleteField widgets allows you to very easily create a similar effect in TurboGears. See also the AutoCompleteField and the AutoCompleteDesc classes source code.

How to use AutoCompleteField

  1. Create a new probject (tg-admin quickstart) and name it autocomplete, or reuse an old one. We will mount the code required for the AutoCompleteField one level below your RootController.
  2. If you created a new project, remove the methods login and logout from your controllers.py file. We won't use them for this tutorial.
  3. Import the AutoCompleteField widget to controllers.py with
    from turbogears.widgets import AutoCompleteField
    
  4. Create a controller-class with an index-method that shows an empty page (for now):
    class TestInputCompletion(controllers.Controller):
        @turbogears.expose(template="autocomplete.templates.complete")
        def index(self):
            return dict()
    
  5. Mount an instance of your new controller:
    class Root(controllers.RootController):
        testcompletion = TestInputCompletion()
    
    Create the complete.kid file necessary to display the empty page by copying welcome.kid to complete.kid and clearing out everything inside the body. The file should look like this:
    <!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" xmlns:py="http://purl.org/kid/ns#"
        py:extends="'master.kid'">
    
    <head>
        <meta content="text/html; charset=UTF-8" http-equiv="content-type" py:replace="''"/>
        <title>Testing the AutoCompleteField widget!</title>
    </head>
    
    <body>
    </body>
    </html>
    
  6. You can check if everything works OK so far by going to localhost:8080/testcompletion. You should see a blank page.
  7. Add an __init__ method to TestInputCompletion where you instantiate the AutoCompleteField widget:
    def __init__(self):
        self.acfield = AutoCompleteField() 
    
  8. Modify complete.kid and add ${acfield.display()} inside the <body> tag. That code automagically inserts all the HTML and Javascript code necessary to display the AutoCompleteField if we pass it an instance. Then change the index method so that the template gets passed our widget:
    @turbogears.expose(template="autocomplete.templates.complete")
    def index(self):
        return dict(acfield = self.acfield)
    
  9. You should now be able to see a lonely input-box if you go to  http://localhost:8080/testcompletion. However, it doesn't complete any input yet.
  10. The next step is to give the AutoCompleteField some data with which it can complete input. In a real program the data probably comes from a database, but here we just add the strings to the TestInputCompletion? class that we wan't completed:
    class TestInputCompletion(controllers.Controller):
        countries = ["Abkhazia", "Afghanistan", "Akrotiri", "Åland", "Albania", "Algeria",
                     "American Samoa", "Andorra", "Angola", "Anguilla", "Antigua and Barbuda",
                     "Argentina", "Armenia", "Aruba", "Ascension Island", "Austria", "Azerbaijan"]
    
  11. Add a search method to TestInputCompletion?:
    @turbogears.expose(format = "json")
    def search(self, input):
        input = input.lower()
        matches = [country for country in self.countries \
                   if country.lower().startswith(input)]
        return dict(matches = matches)
    
    This method takes as it's input a search string and returns a page in JSON format with all the countries it thinks matches the search string. You can test it out by going to:  http://localhost:8080/testcompletion/search?input=a.
  12. Change how the AutoCompleteField is constructed so that it can interact witht the search method:
    def __init__(self):
        self.acfield = AutoCompleteField(search_controller = "search",
                                         search_param = "input",
                                         result_name = "matches")
    

That's it! You should now have an awesome AutoCompleteField that completes on countrynames. If not, state your problem here and the tutorial will be updated.

Possible additions

  • It would be cool if the AutoCompleteField updated a FastDataGrid? in realtime. Only those rows that matches the input in the AutoCompleteField should be shown.
  • Instead of hardcoding which strings that should be completed, the strings should come from a database.