Any XHTML document can be used as a side-bar, footer bar, toolbar or explorer bar. This makes it very easy to build bars that extend your browser, and all that we need to do is to let the browser know where to find the XHTML documents. We do this not be creating standard desktop installers, but by creating XForms that call the Soft-bar Installer API. This API provides functions to add and remove bars.
This tutorial will show how to use the API to create an installer, and to illustrate the technique we'll place the del.icio.us bookmark form created in the Introduction to XForms in a side-bar. In order to illustrate how any document can be used as a 'soft bar', we won't make any changes at all to the bookmark form, with all the work being done by the installer.
The sample and source code are available from here.
Tutorial reviewed on 2006-12-07, by MB.
TODO: Incorporate material from A del.icio.us Link Manager Written in XForms.
To create a side-bar we need two things; an XHTML document that will provide the functionality of the side-bar, and an installer that will wire the side-bar into the browser. The XHTML document we will use is the del.icio.us bookmarking form that we create in the Introduction to XForms. We'll use this partly because it's a useful form, and partly to show that any XHTML document can be used as a side-bar.
The installer will have to be created from scratch, but since it is just a normal XForm we can use the usual template as our starting-point. We'll begin by setting the document's title:
<title>Soft-bar Installer</title>
</head>
To access any external function library in XForms you need to provide a reference to a namespace that identifies the library, and you need to indicate the functions you want to access in the functions attribute on the model. So the first step is to add the following namespace to the top of the document:
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sb="urn:formsplayer.com/softbars"
>
<head>
Now add a model which will contain the data about the soft-bar we will be installing, and reference the functions that will be called to do the adding and removing:
<title>Soft-bar Installer</title>
<xf:model id="m-soft-bars" functions="sb:GenerateBar sb:RemoveBar">
...
</xf:model>
</head>
To make it easy to reuse this installer form for other bars, we'll put all information that is specific to our del.icio.us side-bar into an external XML document. Create a document called delicious-sidebar.xml that contains the following:
<bar retval="0">
<type>2</type>
<screenshot>http://static.flickr.com/142/319487219_f598c70667.jpg</screenshot>
<internalName>fpdelicioussidebar</internalName>
<name>del.icio.us Sidebar</name>
<description>
The del.icio.us Sidebar allows you to quickly add a bookmark to del.icio.us
for a document that you are viewing in the main browser window.
</description>
<uri>http://svn.x-port.net/svn/public/samples/del.icio.us/howto.html</uri>
</bar>
type, internalName, name and uri correspond to the parameters needed by sb:GenerateBar, whilst screenshot and description are used in the form, as we'll see in a moment.
To make the configuration parameters available to the form, we need to load it into an instance, so next add the following mark-up to the model:
<xf:model id="m-soft-bars" functions="sb:GenerateBar sb:RemoveBar">
<xf:instance src="delicious-sidebar.xml" />
</xf:model>
Part of the information in the configuration file is for the calls to the Soft-bar API, and some of it is just to improve the appearance of our form. Add the following controls to the body element, which will give the user some information about the soft-bar being added:
<body>
<h1><xf:output ref="name" /></h1>
<xf:output
value="concat('
<img src="',
screenshot,
'" />'
)"
/>
<div><xf:output ref="description" /></div>
</body>If you save and refresh the form, you should see a heading of the name of the soft-bar, a screenshot (if there is one), and a description of what the bar does.
The next piece we need to add is the code to install the bar. For this we have to use the sb:GenerateBar method, which is available to us because we specified the library in the functions attribute. We have to call the function from an XPath expression, and since we want the returned value (so that we know if it succeeded or not) we'll use the setvalue action. We'll put the setvalue inside an action handler that is listening for the event my-install-bar; place the following in the model element:
<xf:instance src="delicious-sidebar.xml" />
<xf:action ev:event="my-install-bar">
<xf:setvalue
ref="@retval"
value="sb:GenerateBar(
string(../type),
string(../internalName),
string(../name),
string(../uri)
)"
/>
</xf:action>
</xf:model>
Once the function returns we'll be left with either "Success" or an error message in the retval attribute. We can make use of this by following the setvalue action handler with a message:
/>
<xf:message level="modal">
'<xf:output ref="name" />'
has
<xf:output value="
if(
@retval = 'Success',
' been added. You will need to open a new browser
window to see the change.',
concat(
' failed to install. The error is "',
@retval,
'".'
)
)"
/>
</xf:message>
</xf:action>
The effect of this is to always show a message after installing, but the text of the message will depend on whether the installation was successful or not--with the if function being used to determine which.
To allow the user to install the bar, all we need do now is provide a button that will invoke the my-install-bar event. We'll put it after the other controls:
<div><xf:output ref="description" /></div>
<xf:trigger>
<xf:label>Install</xf:label>
<xf:dispatch ev:event="DOMActivate"
name="my-install-bar" target="m-soft-bars"
/>
</xf:trigger>
</body>
To complete the form we need to add an event handler and button for removing the soft-bar. The handler will use the sb:RemoveBar function and pass it the internal name of the bar. Add the following to the model:
</xf:action>
<xf:action ev:event="my-remove-bar">
<xf:setvalue
ref="@retval"
value="sb:RemoveBar(string(../internalName))"
/>
<xf:message level="modal">
'<xf:output ref="name" />'
has
<xf:output value="
if(
@retval = 'Success',
' been removed. You will need to open a new browser
window to see the change.',
concat(
' failed to be removed. The error is "',
@retval,
'".'
)
)"
/>
</xf:message>
</xf:action>
</xf:model>
To invoke the handler we need another button:
</xf:trigger>
<xf:trigger>
<xf:label>Remove</xf:label>
<xf:dispatch ev:event="DOMActivate"
name="my-remove-bar" target="m-soft-bars"
/>
</xf:trigger>
</body>