Introduction
jQuery is an industry-standard Javascript framework, used by a lot of Foswiki extensions and many foswiki developers. jQuery is the "javascript framework of choice" for use with Foswiki. That doesn't mean you can't use other frameworks (such as Dojo, YUI, or Mootools), just that we focus our efforts on supporting jQuery first.
Getting started
We're going to assume you are familiar with the following:
If you have ever hand-crafted an HTML page, styled it using CSS, and maybe written a bit of Javascript (for example to validate forms input) then you are well positioned to use jQuery. If you are new to any of these, then sorry, you have a steep learning curve ahead of you. There are a wealth of resources on the web to help you get started, though.
Before you start trying to use jQuery in Foswiki, we'd also recommend that you familiarize yourself with how Foswiki works, especially:
Useful links
JQueryPlugin
The easiest way to get started using jQuery is to install the
JQueryPlugin. Once you have done that, all you need to do is to add the appropriate
%JQREQUIRE
directive, and you will be able to use the required plugin in your HTML, as described in the plugin documentation. That really is all there is to it!
Adding more jQuery plugins
The plugins shipped with JQueryPlugin itself live in
-
pub/System/JQueryPlugin/plugins/myplugin/
This is the where all js and css code of the default plugins are located. All plugins except jQuery-ui and themes live next to this directory.
-
lib/System/JQueryPlugin/MYPLUGIN.pm
This is the perl stub that takes care of loading the library into a page as well as all of its dependencies.
Other Foswiki extensions can also add new jQuery plugins to the set managed by JQueryPlugin, and the recommended approach to adding new jQuery plugins is to package the JQuery plugin as a Foswiki extension module. The advantage of packaging as a contrib module is that you don't incur the overhead of a Foswiki plugin module, which can be significant. The process for both is very similar.
The first step is to create an extension - we'll focus on creating an contrib module called "JEditableContrib" which packages the excellent jQuery edit-in-place support from Miko Tuupola. We're going to assume you are working in a subversion checkout of the Foswiki development repository, and have done a
pseudo-install developer
as described elsewhere in the
DevelopersBible. The process for packaging in a Foswiki plugin is almost identical, with some small exceptions that we'll cover at the end.
Step 1 create the extension framework:
$ cd to the root of your subversion checkout
$ core/create_new_extension.pl JEditableContrib
This should give you:
JEditableContrib/
data/
System/
JEditableContrib.txt
lib/
Foswiki/
Contrib/
JEditableContrib.pm
JEditableContrib/
build.pl
DEPENDENCIES
MANIFEST
Step 2 Create a directory
JEditableContrib/pub/System/JEditableContrib
, and put the
source (uncompressed) javascript there (you can call it
_src.js or =.uncompressed.js
, your choice)
pub/
System/
JEditableContrib/
jquery.jeditable_src.js
Step 3 Edit
JEditable/lib/Foswiki/Contrib/JEditableContrib/MANIFEST
and add the following lines:
lib/Foswiki/Contrib/JEditableContrib/JEDITABLE.pm 0644 Plugin stub
lib/Foswiki/Contrib/JEditableContrib/Config.spec 0644 Configuration data
pub/System/JEditablePlugin/jquery.jeditable_src.js 0644 Uncompressed javascript
pub/System/JEditablePlugin/jquery.jeditable.js 0644 Compress javascript
Step 4 Edit
JEditable/lib/Foswiki/Contrib/JEditableContrib/DEPENDENCIES
and add
Foswiki::Plugins::JQueryPlugin,>4.02,perl,Required
Step 5 Edit
JEditable/lib/Foswiki/Contrib/JEditableContrib.pm
. You are best to clear this file out and start again. It's a very simple stub.
package Foswiki::Contrib::JEditableContrib;
use strict;
use warnings;
use version 0.77; our $VERSION = version->declare('v1.7.1');
our $RELEASE = '1.7.1'; # keep in synch with jquery.jeditable.js
our $SHORTDESCRIPTION = 'The JQuery "JEditable" plugin, packaged for use in Foswiki';
1;
Step 6 Edit
JEditable/lib/Foswiki/Contrib/JEditableAddO/JEDITABLE.pm
. This describes meta-data about the plugin, and is the most complicated code you will write today.
package Foswiki::Contrib::JEditableContrib::JEDITABLE;
use strict;
use warnings;
use Foswiki::Plugins::JQueryPlugin ();
our @ISA = qw( Foswiki::Plugins::JQueryPlugin::Plugin );
use Foswiki::Plugins::JQueryPlugin::Plugin ();
use Foswiki::Contrib::JEditableContrib ();
sub new {
my $class = shift;
my $session = shift || $Foswiki::Plugins::SESSION;
my $this = $class->SUPER::new(
$session,
name => 'JEditable',
version => $Foswiki::Contrib::JEditableContrib::RELEASE,
author => 'Mika Tuupola',
homepage => 'http://www.appelsiini.net/projects/jeditable',
puburl => '%PUBURLPATH%/%SYSTEMWEB%/JEditableContrib',
documentation => "$Foswiki::cfg{SystemWebName}.JEditableContrib",
summary => $Foswiki::Contrib::JEditableContrib::SHORTDESCRIPTION,
javascript => [ "jquery.jeditable.js" ]);
return $this;
}
1;
The constructor for the
Foswiki::Plugins::JQueryPlugin::Plugin
supports a number of fields:
Field |
Description |
name |
symbolic name of the module; mandatory |
version |
semi-numeric version number of the plugin; this is added to the urls loading this module |
summary |
Descriptive text |
documentation |
topic holding the plugin's documentation |
author |
creator and/or copyright holder of this plugin |
homepage |
url where the bulk of the module's documentation is located |
puburl |
url base for finding CSS and Javascript files. By default this points to the %PUBURLPATH%/%SYSTEMWEB%/JQueryPlugin/plugins/<name> but can be redirected to your own plugin, as in the example above. |
css |
Reference to a perl array of CSS filenames. These files must exist in puburl . |
javascript |
Reference to a perl array of Javascript filenames. These files must exist in puburl . |
dependencies |
names of other plugins to be loaded before this library is added to the head. Each entry can either be the symbolic name of another jquery library registered to JQueryPlugin, or any other identifier used in an ADDTOHEAD call |
tags |
list of macros this plugin implements; only used for documentation |
debug |
Set to 1 to enable debug |
Step 7 Create/edit
JEditable/lib/Foswiki/Contrib/JEditableContrib/Config.spec=
# ---+ Extensions
# ---++ JQueryPlugin
# ---+++ Extra plugins
# **STRING**
$Foswiki::cfg{JQueryPlugin}{Plugins}{JEditable}{Module} = 'Foswiki::Contrib::JEditableContrib::JEDITABLE';
# **BOOLEAN**
$Foswiki::cfg{JQueryPlugin}{Plugins}{JEditable}{Enabled} = 1;
1;
See also the example module in =EMPTY.pm
and
jquery.empty.uncompressed.js
as well as the other plugins shipped with JQueryPlugin.
Packaging in a plugin
If you want your plugin to be usable with
JQueryPlugin versions < 4.02, then you can add a "plugin stub" to make it compatible.
Step 8 Create the directory
JEditable/lib/Foswiki/Plugins/JEditableContribPlugin
.
Step 9 Create/edit
JEditable/lib/Foswiki/Plugins/JEditableContribPlugin.pm=
package Foswiki::Plugins::JEditableContribPlugin;
use strict;
use warnings;
use Foswiki::Plugins::JQueryPlugin::Plugins ();
use Foswiki::Contrib::JEditableContrib::JEDITABLE ();
sub initPlugin {
Foswiki::Plugins::JQueryPlugin::registerPlugin(
'JEditable', 'Foswiki::Contrib::JEditableContrib::JEDITABLE');
Foswiki::Plugins::JQueryPlugin::createPlugin('JEditable');
}
1;
Plugins have to be enabled via =configure
. Only then are they loadable via
%JQREQUIRE{"mynewplugin"}%
.
The plugin should be
disabled in
configure
when running with
JQueryPlugin 4.02 or later.
Debug mode
The
$Foswiki::cfg{JQueryPlugin}{Debug}
flag is used to switch on debug mode for JQueryPlugin itself as well as all of its sub-modules.
If enabled, it will load the
uncompressed
variants of a module's static file, e.g.
jquery.myplugin.uncompressed.js
instead of
jquery.myplugin.js
So make sure your source files are called
...uncompressed.js
and
...uncompressed.css
as the plugin won't work in debug mode otherwise.
Documentation
The
documentation
property of a jquery plugin points to a separate topic that holds all documentation for it, including a pointer to the third-party homepage. Use
System.JQueryPluginEmpty
as a template.
The default documentation topic is
System.JQuery + PluginName
unless otherwise specified. For example, the docu for
rubberduck
should be located in
System.JQueryRubberduck
.
Instead of specifying a
summary
on perl level, defined a named
summary
section in this topic.
Please make sure to document how your plugin is integrated into Foswiki, that is how to make use of it and which class name enables your plugin on a html element (see
#LiveQuery below).
JQuery Coding Standards
See
JQueryCodingStandards for information on:
- Good coding practice
- Using jQuery with other libraries
- Propagating perl settings to Javascript
- Avoiding Internet Explorer errors
- Using
livequery
and HTML5 data
Using jQuery and AJAX
The main jQuery documentation is located at
http://docs.jquery.com/Ajax.
Making a simple query to the server
The easiest way to make a request to the server is to get it to give you a page of results already formatted in a way that jQuery understands. The simplest approach is to use JSON. For example, let's say I want to perform a search for the string "look for this" on the server. In my Javascript I have:
$.get(viewurl+'/Myweb/JsonSearch',
{
skin: "text",
contenttype: "text/plain",
inweb: web,
string: "look for this"
},
function(results) {
// do something with the array of results
}, "json");
viewurl
is the result of calling
SCRIPTURL{view}%
, and can easily be passed to the Javascript, as described in
Propagating perl settings to javascript, above. This request makes Javascript request a topic Myweb.JsonSearch from the server.
When raw-edited, Myweb.JsonSearch contains:
[%SEARCH{"%URLPARAM{string}%" web="%URLPARAM{inweb}%" nonoise="on" format="'$topic'" separator=","}%]
The use of the
contenttype
and
skin
parameters stops Foswiki from generating any template furniture around the result, and the formatted search produces a JSON format array, which is then read by jQuery and converted to a Javascript array object
results
.
Loading part of the UI asynchronously
jQuery supports a short form of the above
$.get
method by directly injecting the HTML result of a REST handler into the DOM tree:
$("#container").load("<url>, [<params>], [<callback>]");
Optionally a jQuery selector can be specified in the URL. Doing so will filter the incoming HTML document, only injecting the elements that match the selector:
$("#mysidebar .installedplugins-list").load("%SCRIPTURLPATH{"view"}/%SYSTEMWEB%/InstalledPlugins ul:first li");
Note also, that javascript included in the HTML fragment will be executed after
load()ing
it.
Complex queries involving plugin functions
Foswiki supports plugin handlers (called REST handlers) that can be called by issuing a request to the server with a specifically crafted URL. Exactly the same approach can be used to call these handlers, except that the URL specifies the function to call. See the extensive documentation on plugin REST handlers for more information.