Let's first have a look at what the application looks like:
tasklist.py
from the code directory of this chapter. http://localhost:8080
.You should be able to add a new task by entering a date and a description in the input boxes and pressing the add button. Entering a date is facilitated by jQuery UI's datepicker widget that will pop up once you click the input field for the date, as shown in the following screenshot:
Once you have added one or more tasks, you can now either delete those tasks by clicking the button with the little trash can icon or mark it as done by clicking the button with the check icon. Tasks marked as done have a slightly different background color depending on the chosen theme. If you mark a task as done, its completion date will be today. You can select a different date by clicking on the completion date of a task (displayed as None for an unfinished task). It will present you with yet another datepicker, after which the selected date will be stored as the completion date once the done button is clicked. The following screenshot gives an impression of a task list with numerous items:
There is some hidden magic that might not be immediately obvious. First of all, all the tasks are sorted according to their Due date. This is done on the client-side with the help of some JavaScript and a jQuery plugin, as we will see in the section on JavaScript. Also accomplished with some JavaScript are the tooltips. Both hovering tooltips on every button and the inline help text inside the<input>
elements are added with the same script. We will examine this in depth.
tasklist.py
is rather straightforward as it delegates most work to two modules: the logon
module that we encountered in the previous sections and a task
module that deals with displaying and manipulating task lists.
The highlighted line in the following code shows the core of the application. It starts up CherryPy with a suitable configuration. Note that we enabled the sessions tool, so that we can actually use the logon
module. Also, we construct the path to jQuery UI's theme stylesheet in such a way that it depends on the theme
variable to make changing the application's theme simple (second highlight).
The instance of the Root
class that we pass to quickstart()
creates a simple tree:
/ /logon /logon/logon /logon/logoff /task /task/add /task/mark
The top level URL /
returns the same content as /login
by calling the index()
method of the Logon
instance. We could have used an InternalRedirect
exception, but this is just as simple. The paths starting with /task
are all handled by an instance of the Task
class:
Chapter3/tasklist.py
import cherrypy import os.path import logon import task current_dir = os.path.dirname(os.path.abspath(__file__)) theme = "smoothness" class Root(object): task = task.Task(logoffpath="/logon/logoff") logon = logon.Logon(path="/logon", authenticated="/task", not_authenticated="/") @cherrypy.expose def index(self): return Root.logon.index() if __name__ == "__main__": cherrypy.quickstart(Root(),config={ '/': { 'log.access_file':os.path.join(current_dir,"access.log"), 'log.screen': False, 'tools.sessions.on': True }, '/static': { 'tools.staticdir.on':True, 'tools.staticdir.dir':os.path.join(current_dir,"static") }, '/jquery.js': { 'tools.staticfile.on':True, 'tools.staticfile.filename':os.path.join(current_dir, "static","jquery","jquery-1.4.2.js") }, '/jquery-ui.js': { 'tools.staticfile.on':True, 'tools.staticfile.filename':os.path.join(current_dir, "static","jquery","jquery-ui-1.8.1.custom.min.js") }, '/jquerytheme.css': { 'tools.staticfile.on':True, 'tools.staticfile.filename':os.path.join(current_dir, "static","jquery","css",theme,"jquery-ui-1.8.4.custom.css") }, '/images': { 'tools.staticdir.on':True, 'tools.staticdir.dir':os.path.join(current_dir, "static","jquery","css",theme,"images") } })
3.21.93.20