jQuery effects

The basic effects described here do not require any additional files; everything you need is already included in web2py_ajax.html.

HTML/XHTML objects can be identified by their type (for example a DIV), their classes, or their id. For example:

  1. <div class="one" id="a">Hello</div>
  2. <div class="two" id="b">World</div>

They belong to class “one” and “two” respectively. They have ids equal to “a” and “b” respectively.

In jQuery you can refer to the former with the following CSS-like equivalent notations

  1. jQuery('.one') // address object by class "one"
  2. jQuery('#a') // address object by id "a"
  3. jQuery('DIV.one') // address by object of type "DIV" with class "one"
  4. jQuery('DIV #a') // address by object of type "DIV" with id "a"

and to the latter with

  1. jQuery('.two')
  2. jQuery('#b')
  3. jQuery('DIV.two')
  4. jQuery('DIV #b')

or you can refer to both with

  1. jQuery('DIV')

Tag objects are associated to events, such as “onclick”. jQuery allows linking these events to effects, for example “slideToggle”:

  1. <div class="one" id="a" onclick="jQuery('.two').slideToggle()">Hello</div>
  2. <div class="two" id="b">World</div>

Now if you click on “Hello”, “World” disappears. If you click again, “World” reappears. You can make a tag hidden by default by giving it a hidden class:

  1. <div class="one" id="a" onclick="jQuery('.two').slideToggle()">Hello</div>
  2. <div class="two hidden" id="b">World</div>

You can also link actions to events outside the tag itself. The previous code can be rewritten as follows:

  1. <div class="one" id="a">Hello</div>
  2. <div class="two" id="b">World</div>
  3. <script>
  4. jQuery('.one').click(function(){jQuery('.two').slideToggle()});
  5. </script>

Effects return the calling object, so they can be chained.

When the click sets the callback function to be called on click. Similarly for change, keyup, keydown, mouseover, etc.

A common situation is the need to execute some JavaScript code only after the entire document has been loaded. This is usually done by the onload attribute of BODY but jQuery provides an alternative way that does not require editing the layout:

  1. <div class="one" id="a">Hello</div>
  2. <div class="two" id="b">World</div>
  3. <script>
  4. jQuery(document).ready(function(){
  5. jQuery('.one').click(function(){jQuery('.two').slideToggle()});
  6. });
  7. </script>

The body of the unnamed function is executed only when the document is ready, after it has been fully loaded.

Here is a list of useful event names:

Form events
  • onchange: Script to be run when the element changes
  • onsubmit: Script to be run when the form is submitted
  • onreset: Script to be run when the form is reset
  • onselect: Script to be run when the element is selected
  • onblur: Script to be run when the element loses focus
  • onfocus: Script to be run when the element gets focus
Keyboard events
  • onkeydown: Script to be run when key is pressed
  • onkeypress: Script to be run when key is pressed and released
  • onkeyup: Script to be run when key is released
Mouse events
  • onclick: Script to be run on a mouse click
  • ondblclick: Script to be run on a mouse double-click
  • onmousedown: Script to be run when mouse button is pressed
  • onmousemove: Script to be run when mouse pointer moves
  • onmouseout: Script to be run when mouse pointer moves out of an element
  • onmouseover: Script to be run when mouse pointer moves over an element
  • onmouseup: Script to be run when mouse button is released

Here is a list of useful effects defined by jQuery:

Effects
  • jQuery(...).show(): Makes the object visible
  • jQuery(...).hide(): Makes the object hidden
  • jQuery(...).slideToggle(speed, callback): Makes the object slide up or down
  • jQuery(...).slideUp(speed, callback): Makes the object slide up
  • jQuery(...).slideDown(speed, callback): Makes the object slide down
  • jQuery(...).fadeIn(speed, callback): Makes the object fade in
  • jQuery(...).fadeOut(speed, callback): Makes the object fade out

The speed argument is usually “slow”, “fast” or omitted (the default). The callback is an optional function that is called when the effect is completed.

jQuery effects can also easily be embedded in helpers, for example, in a view:

  1. {{=DIV('click me!', _onclick="jQuery(this).fadeOut()")}}

Other useful methods and attributes for handling selected elements

Methods and attributes
  • jQuery(...).prop(name): Returns the name of the attribute value
  • jQuery(...).prop(name, value): Sets the attribute name to value
  • jQuery(...).html(): Without arguments, it returns the inner html from the selected elements, it accepts a string as argument for replacing the tag content.
  • jQuery(...).text(): Without arguments, it returns the inner text of the selected element (without tags), if a string is passed as argument, it replaces the inner text with the new data.
  • jQuery(...).val(): Without arguments, it returns the current value of the first element of the selected elements, if a string is passed as argument, it replaces the value of every matched element.
  • jQuery(...).css(name, value): With one parameter, it returns the CSS value of the style attribute specified for the selected elements. With two parameters, it sets a new value for the specified CSS attribute.
  • jQuery(...).each(function): It loops trought the selected elements set and calls function with each item as argument.
  • jQuery(...).index(): Without arguments, it returns the index value for the first element selected related to its siblings. (i.e, the index of a LI element). If an element is passed as argument, it returns the element position related to the selected elements set.
  • jQuery(...).length: This attribute returns the number of elements selected.

jQuery is a very compact and concise Ajax library; therefore web2py does not need an additional abstraction layer on top of jQuery (except for the ajax function discussed below). The jQuery APIs are accessible and readily available in their native form when needed.

Consult the documentation for more information about these effects and other jQuery APIs.

The jQuery library can also be extended using plugins and User Interface Widgets. This topic is not covered here; see ref.[jquery-ui] for details.

Conditional fields in forms

A typical application of jQuery effects is a form that changes its appearance based on the value of its fields.

This is easy in web2py because the SQLFORM helper generates forms that are “CSS friendly”. The form contains a table with rows. Each row contains a label, an input field, and an optional third column. The items have ids derived strictly from the name of the table and names of the fields.

The convention is that every INPUT field has an id tablename_fieldname and is contained in a row with id tablename_fieldname__row.

As an example, create an input form that asks for a taxpayer’s name and for the name of the taxpayer’s spouse, but only if he/she is married.

Create a test application with the following model:

  1. db = DAL('sqlite://storage.sqlite')
  2. db.define_table('taxpayer',
  3. Field('spouse_name'))

the following “default.py” controller:

  1. def index():
  2. form = SQLFORM(db.taxpayer)
  3. if form.process().accepted:
  4. response.flash = 'record inserted'
  5. return dict(form=form)

and the following “default/index.html” view:

  1. {{extend 'layout.html'}}
  2. {{=form}}
  3. <script>
  4. jQuery(document).ready(function(){
  5. if(jQuery('#taxpayer_married').prop('checked'))
  6. jQuery('#taxpayer_spouse_name__row').show();
  7. else jQuery('#taxpayer_spouse_name__row').hide();
  8. jQuery('#taxpayer_married').change(function(){
  9. if(jQuery('#taxpayer_married').prop('checked'))
  10. jQuery('#taxpayer_spouse_name__row').show();
  11. else jQuery('#taxpayer_spouse_name__row').hide();});
  12. });
  13. </script>

The script in the view has the effect of hiding the row containing the spouse’s name:

image

When the taxpayer checks the “married” checkbox, the spouse’s name field reappears:

image

Here “taxpayer_married” is the checkbox associated to the “boolean” field “married” of table “taxpayer”. “taxpayer_spouse_name__row” is the row containing the input field for “spouse_name” of table “taxpayer”.

Confirmation on delete

Another useful application is requiring confirmation when checking a “delete” checkbox such as the delete checkbox that appears in edit forms.

Consider the above example and add the following controller action:

  1. def edit():
  2. row = db.taxpayer[request.args(0)]
  3. form = SQLFORM(db.taxpayer, row, deletable=True)
  4. if form.process().accepted:
  5. response.flash = 'record updated'
  6. return dict(form=form)

and the corresponding view “default/edit.html”

  1. {{extend 'layout.html'}}
  2. {{=form}}

The deletable=True argument in the SQLFORM constructor instructs web2py to display a “delete” checkbox in the edit form. It is False by default.

web2py’s “web2py.js” includes the following code:

  1. jQuery(document).ready(function(){
  2. jQuery('input.delete').prop('onclick',
  3. 'if(this.checked) if(!confirm(
  4. "{{=T('Sure you want to delete this object?')}}"))
  5. this.checked=False;');
  6. });

By convention this checkbox has a class equal to “delete”. The jQuery code above connects the onclick event of this checkbox with a confirmation dialog (standard in JavaScript) and unchecks the checkbox if the taxpayer does not confirm:

image