This is followed by the footer_javascript_section and footer_javascript_page blocks. This means that if we don't want the plugin ,which is the last inclusion, to be downloaded for each page, we could put it in overridden section and page blocks. This would render as including the plugin after jQuery.

How to make pages more responsive

We would also note that the setup, with three JavaScript downloads, is appropriate for development purposes but not for deployment. In terms of YSlow client-side performance optimization, the recommended best practice is to have one HTML/XHTML hit, one CSS hit at the top, and one JavaScript hit at the bottom. One of the basic principles of client-side optimization, discussed by Steve Souders (see http://developer.yahoo.com/yslow/) is,since HTTP requests slow the page down, the recommended best practice is to have one (preferably minifed) CSS inclusion at the top of the page, and then one (preferably minifed) JavaScript inclusion at the bottom of each page. Each HTTP request beyond this makes things slower, so combining CSS and/or JavaScript requests into a single concatenated file is low-hanging fruit to improve how quick and responsive your web pages appear to users.

For deployment, we should minify and combine the JavaScript. As we are developing, we also have JavaScript included in templates and rendered into the delivered XHTML; this may be appropriate for development purposes. For deployment though, as much shared functionality as possible should be factored out into an included JavaScript fle. For content that can be delivered statically, such as CSS, JavaScript, and even non-dynamic images, setting far-future Expires/Cache-Control headers is desirable. (One practice is to never change the content of a published URL for the kind of content that has a far-future expiration set, and then if it needs updating, instead of changing the content at the same location, leave the content where it is, publish at a new location possibly including a version number, and reference the new location.)

A template handling the client-side requirements

Here's the template. Its view will render it with an entity and other information. At present it extends the base directly; it is desirable in many cases to have the templates that are rendered extend section templates, which in turn extend the base. In our simple application, we have two templates which are directly rendered to web pages. One is the page that handles both search and search results—and the other, the page that handles a profile, from the following template:

{% extends "base.html" %}

We include honorifics before the name, and post-nominals after. At this point we do not do anything to make it editable.

{% extends "base.html" %}Following earlier discussion, we include honorifcs before the name, and post-nominals after. At this point we do not do anything to make it editable.{% block head_title %}{{ entity.honorifics }} {{ entity.name }} {{ entity.post_nominals }}{% endblock head_title %}{% block body_main %}

There is one important point about Django and the title block. The Django developers do not fnd it acceptable to write a templating engine that produces errors in production if someone attempts to access an undefned value (by typos, for instance). As a result of this design decision, if you attempt to access an undefned value, the templating engine will silently insert an empty string and move on. This means that it is safe to include a value that may or may not exist, although there are ways to test if a value exists and is nonempty, and display another default value in that case. We will see how to do this soon. Let's move on to the main block, defned by the last line of code.

Once we are in the main block, we have an h1 which is almost identical to the title block, but this time it is marked up to support editing in place. Let us look at the honorifics span; the name and post_nominals spans work the same way:

The class edit is used to give all $(".edit") items some basic special treatment with Jeditable; there is nothing magical about the class name, which could have been replaced by user-may-change-this or something else. edit merely happens to be a good name choice, like almost any good variable/function/object name.

We create a naming convention in the span's HTML ID which will enable the server side to know which—of a long and possibly open-ended number of things we could intend to change—is the one we want. In a nutshell, the convention is modelname_feldname_instanceID. The frst token is the model name, and is everything up to the first underscore. (Even if we were only interested in one model now, it is more future proof to design so that we can accommodate changes that introduce more models.)

The last token is the instance ID, an integer. The middle token, which may contain underscores (for example post_nominals in the following code), is the feld name. There is no specifc requirement to follow a naming convention, but it allows us to specify an HTML ID that the server-side view can parse for information about which feld on which instance of which model is being edited.

We also provide a default value, in this case Click to edit, intended not only to serve as a placeholder, but to give users a sense on how this information can be updated.

We might also observe that here and in the following code, we do not presently have checks against race conditions in place. So nothing here or in the following code will stop users from overwriting each others' changes. This may be taken as a challenge to refne and extend the solution to either prevent race conditions or mitigate their damage.

Taken together, the three statements form the heading in this screenshot:

If we click on the name (for instance) it becomes:

The image is presently a placeholder; this should be expanded to allow an image to be uploaded if the user clicks on the picture (implementing consistent-feeling behavior whether or not we do so via the same plugin). We also need the view and urlpattern on the backend:

The bulk of the profile

For small bits of text, we use the edit CSS class, which will be transformed to an input of type text on click (or double-click or mouseover, if we were using Jeditable differently). The description is an example of something that would more naturally lend itself to a textarea, so we will use the edit_textarea CSS class, which will be confgured to use a textarea.

The Department, as well as Reports to feld, are not arbitrary text in our implementation; they are another entity (if one is specifed). This could appropriately enough be implemented as a dropdown menu, but even a carefully pruned dropdown menu could be long and unwieldy for a large company.

One additional note on usability: When displaying "label: value" information on pages, particularly heavily used pages, the most basic option is not to use any emphasis:

Name: J. Smith

To help people's eyes fnd what they want, one obvious solution is to emphasize the label, as in:

Name: J. Smith

This works well the frst time. However, if people are looking at the same set of felds, in the same order, on a web page they visit repeatedly, it is no longer best to emphasize the labels. Regular visitors already know what the labels are, and the motive for even looking at the labels is to see the value. Therefore, for our directory, we will be using bold for the value rather than the label:

If a homepage is defned, we give the URL, wrapped in a link and a strong that makes the link editable by right clicking. If the link were just editable by a regular click, Jeditable would short-circuit the usual and expected behavior of clicking on a link taking you to the corresponding page or opening the corresponding e-mail. To allow editing while also allowing normal use of links on a profle page, we assign the right click rather than click event to be the way to allow editing. From a UI consistency perspective, it might be desirable to additionally always allow a right click to trigger any (possible) editing. However, we will leave that on our wishlist for now. We will defne JavaScript later on in this chapter that will add desired behavior.

Whitespace and delivery

The formatting used above is preferable for development; for actual delivery, we may wish to strip out all whitespace that can be stripped out, for this page:

Some browsers now are better about this, but it has happened in the past that if you have whitespace such as a line break between the intended text of a link and the tag, you could get unwanted trailing whitespace with a visible underline on the rendered link. In addition, pages load faster if minifed. For development purposes, though, we will add whitespace for clarity. In the next code, we will have a spurious space before rendered commas because we are not stripping out unnecessary whitespace:

For the Location field, we are deferring an intelligent way to let people choose an existing location, or create a new one, until the next chapter. For now we simply display a location's identifer, which is meant as a human-readable identifer rather than a machine-readable primary key or other identifer:

The following felds are presently only displayed. The Reports to feld should be autocomplete based. The Start date feld might well enough be left alone as a feld that should not need to be updated, or for demonstration purposes it could be set to a jQuery UI datepicker, which would presumably need to have Ajax saving functionality added.

In views.py proper, we defne a profle view, with the regular @login_required decorator. (We use @ajax_login_required for views that return JSON or other data for Ajax requests, and @login_required for views that return a full web page.)

We log what we have done, and for a view servicing Jeditable Ajax requests, return the HTML that is to be displayed. In this case we return a new link, and re-run the script that applies in-place edit functionality to all appropriate classes, as dynamically added content will not have this happen automatically. Our motive is that people will sometimes hit Save and then realize they made a mistake they want to correct, and we need to handle this as gracefully as the case where the in-place edit is perfect on the frst try. We escape for display:

Then it looks up the selected model (under the directory module, rather than anywhere), fnds the instance having this ID, sets the instance's field value, and saves the instance. The solution is generic, and does the usual job that would be done by code like entity.name = new_name.

Summary

We have now gone from a basic foundation to continuing practical application. We have seen how to divide the labor between the client side and server side. We used this to make a profle page in an employee directory where clicking on text that can be edited enables in-place editing, and we have started to look at usability concerns.

More specifcally, we have covered how to use a jQuery plugin, in our case Jeditable, in a solution for Ajax in-place editing. We saw how to use Jeditable in slightly different ways to more appropriately accommodate editable plain text and editable e-mail/URL links. We discussed the server-side responsibilities, including both a generic solution for when a naming convention is required. We looked at an example of customizing behavior when we want something more closely tailored to specifc cases (which often is part of solving usability problems well), and also how a detailed profle page can be put together.

Alerts & Offers

Series & Level

We understand your time is important. Uniquely amongst the major publishers, we seek to develop and publish the broadest range of learning and information products on each technology. Every Packt product delivers a specific learning pathway, broadly defined by the Series type. This structured approach enables you to select the pathway which best suits your knowledge level, learning style and task objectives.

Learning

As a new user, these step-by-step tutorial guides will give you all the practical skills necessary to become competent and efficient.

Beginner's Guide

Friendly, informal tutorials that provide a practical introduction using examples, activities, and challenges.

Essentials

Fast paced, concentrated introductions showing the quickest way to put the tool to work in the real world.

Cookbook

A collection of practical self-contained recipes that all users of the technology will find useful for building more powerful and reliable systems.

Blueprints

Guides you through the most common types of project you'll encounter, giving you end-to-end guidance on how to build your specific solution quickly and reliably.

Mastering

Take your skills to the next level with advanced tutorials that will give you confidence to master the tool's most powerful features.

Starting

Accessible to readers adopting the topic, these titles get you into the tool or technology so that you can become an effective user.

Progressing

Building on core skills you already have, these titles share solutions and expertise so you become a highly productive power user.