[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... |