[Perl-widget-developer] XSP PerForm taglib (fwd)
Status: Alpha
Brought to you by:
spadkins
|
From: Matt S. <ma...@se...> - 2001-06-08 21:49:23
|
Thought this might interest some of you widget geeks :-)
--
<Matt/>
/|| ** Founder and CTO ** ** http://axkit.com/ **
//|| ** AxKit.com Ltd ** ** XML Application Serving **
// || ** http://axkit.org ** ** XSLT, XPathScript, XSP **
// \\| // ** mod_perl news and resources: http://take23.org **
\\//
//\\
// \\
---------- Forwarded message ----------
Date: Fri, 8 Jun 2001 22:40:56 +0100 (BST)
From: Matt Sergeant <ma...@se...>
To: AxKit Users Mailing List <axk...@ax...>
Subject: XSP PerForm taglib
Taking a bunch of ideas from a number of places I've started putting
together what I call the "PerForm" taglib. This is sort of a magic form
tag library that will enable you to write web forms sucking data from
various sources more easily.
I'm looking for some sort of feedback on this, though it's pretty funky as
it stands IMHO.
Best way to describe it is with an example (this assumes passing
familiarity with XSP):
===============
<?xml version="1.0"?>
<xsp:page
xmlns:xsp="http://apache.org/xsp/core/v1"
xmlns:web="http://axkit.org/NS/xsp/webutils/v1"
xmlns:f="http://axkit.org/NS/xsp/perform/v1"
language="perl"
indent-result="yes"
>
<!-- TOP LEVEL LOGIC -->
<xsp:logic>
# Each function recieves a $ctxt object, which is a hash to
# store things in. It has one entry by default, "Form", which
# is a hash of form values
sub load_title {
my ($ctxt, $default, $current) = @_;
warn("load_title ($default, $current)\n");
return $current || $default;
}
sub load_link {
my ($ctxt, $default, $current) = @_;
warn("load_link ($default, $current)\n");
return $current || $default;
}
sub save_title {
my ($ctxt, $new_value) = @_;
warn("save_title : $new_value\n");
}
sub save_link {
my ($ctxt, $new_value) = @_;
warn("save_link : $new_value\n");
}
sub start_form_create {
my ($ctxt, $save_mode) = @_;
warn("start_form\n");
}
sub end_form_create {
my ($ctxt, $save_mode) = @_;
warn("end_form\n");
# if everything is OK, and we're in save_mode, redirect.
if ($save_mode) {
if ($ctxt->{OK}) {
# note mixing taglibs and Perl!!!
<web:redirect uri="everything_ok.xsp"/>
}
}
}
</xsp:logic>
<html>
<head>
<title>Blah blah</title>
</head>
<body>
<f:form name="create">
Title: <f:textfield type="text" name="title" width="30"
maxlength="255" />
<br />
Link: <f:textfield type="text" name="link" width="30"
maxlength="255" />
<br />
<!-- I haven't coded the submit button yet! -->
<input type="submit"/>
</f:form>
</body>
</html>
</xsp:page>
===============
OK, hopefully that hasn't confused anyone too much. Now the idea is that
these forms always get submitted back to themselves. They do their own
validation. If everything went well and the form got saved OK, they issue
a redirect to another page. It's kinda like the MVC model, only slightly
spiced the AxKit way :-)
Now when the form is first loaded, the input fields are populated by a
callback to the load_<name>() function, where <name> is the name entry of
the particular form field. So to populate the first textfield, it calls
load_title(...). It passes in parameters $ctxt, $default, and $current.
Note that $current will only be filled if this form has already been
submitted once (filled with the current value, obviously). The value you
return is what goes in the text box that the user sees.
When the form is submitted, the save_<name>() functions are called. This
time they are passed the $ctxt and the new value. There you can do
validation or whatever you like (save to a DB, etc).
Each view of the form is started by a call to start_form_<name>(), where
<name> this time is the name attribute on the form. When all the form's
callbacks have been performed, the end_form_<name>() callback is called.
The $ctxt object is a simple hashref that you can fill with whatever you
like. It's there to help you maintain state between the callbacks. It
contains one entry by default, "Form", which is a hashref to all the other
form values. This allows you to do validation where one value depends on
another.
If you *don't* want to supply callbacks for load_*, then it defaults to
using either the current value (i.e. the value last posted to the form),
or the default value specified if this is the first load of this form.
Now when all this has been done, it doesn't generate a HTML widget. It
just generates some XML decorated with all the relevant attributes. You
need to write an XSLT stylesheet (which I'll include with the package for
HTML) to render it to HTML. But it's really simple to do that with
xsl:include/xsl:import. I may even be persuaded to do an XPathScript
stylesheet for it :-)
I welcome your feedback on this. I think it will make building complex
forms really easy. One nice thing with XML is we can put all that nasty
callbacks code in another file, and use entities to load it in. Or we can
use "use OtherPackage qw(...)" to import the functions to the current
namespace. Either way will work.
I can put this in CVS if people want to play with it as it stands. But I
have only implemented the textfield widget as yet.
--
<Matt/>
/|| ** Founder and CTO ** ** http://axkit.com/ **
//|| ** AxKit.com Ltd ** ** XML Application Serving **
// || ** http://axkit.org ** ** XSLT, XPathScript, XSP **
// \\| // ** mod_perl news and resources: http://take23.org **
\\//
//\\
// \\
---------------------------------------------------------------------
To unsubscribe, e-mail: axk...@ax...
For additional commands, e-mail: axk...@ax...
|