I read this post a few times.
At 03:44 PM 5/24/01 -0400, David Harris wrote:
>[[ This is a resend.. did some cutting and pasting of code into telnet
>windows that messed it up through shell expansion. My bad. ]]
>
>I have a couple modules that might be the start of what you are calling a
>Widget system. I'm not sure if my modules are in line with the thoughts
>expressed on this list. Pardon me if this is something different: I've been
>loosely following this discussion..
>
>Using my library, whenever I want a form I specify in one list all of the
>elements along with the type of data and any validation routines. Some
>information about how the form should look is also included. My code then
>automatically generates the form (it looks like a dialogue box) from this
>information. The same informational hash is used to parse the form and
>validate the data. If the data is not validated correctly, the form is shown
>again with the validation errors and the data remaining sticky. If the data
>is validated then it is returned in a hash.
I think this is reasonable and correct direction and its good that you've
functionally broken the pieces down.
But the syntax feels like you are wrapping up too many things at once.
We don't really want to define any HTML for the individual widgets. Nor
should the widgets know how to validate themselves. Nor should the widgets
know how to draw stuff around themselves like tables.
>Here is a simplified example of the widget definitions for a form that
>allows a customer to charge money on their credit card into their balance:
>
>[
> amount => { width => "20", same_line => 1,
> label => "Amount to charge (in dollars)", _label => "Amount to
>charge",
> _looks_like => "number", _required => 1, },
>
> [{ addl_require => [{
> type => "sub",
> fields => [qw(amount)],
> sub => sub {
> my ($require, $values, $labels) = @_;
> return "You may not initiate a charge for less than \$5.00."
> if ( $values->[0] < 5 );
> return "You may not initiate a charge for more than \$900.00. If
>you really do want to
> charge this much, then you need to call us and we can do it
>for you."
> if ( $values->[0] > 900 );
> return undef;
> },
> }], }],
>]
"Simplified". :)
Well, while I think this is interesting, it is too much for a widget
library. I think this is fairly clear from the examples.
Let's focus a bit.
All I (just my opinion) really want is a widget library for is to get and
set data in a widget and have the widget subclass know how to display
itself. In addition, there should be some mechanism for specifying how the
widget sets up it's internal state based on CGI.pm, Apache::Request,
Session data or what have you.
1. Data Validation logic. No, this does not belong there. This is a
separate library. I already have a rich Data handling library in my toolkit
that I intend to plug widgets into. All I need is to be able to get widget
data from the data handling/validation library.
2. External display stuff. No, I just want the widget to know how to draw
itself and only itself. It's up to a template language plugin like TT or
some other template language to provide the wrappings. Or it can be a
toolkit like your drawing forms library -- but the widget itself shouldn't
have to know about external decoration around it. Just how to draw itself.
>This above code is showing the strains of evolution of my system. :-) Notice
I don't think it is a strain on the evolution, just that you attempt to
combine many different concepts together. I think it's too much. You can
abstract away some of these things as noted above.
>This really calls for the widgets to be embedded directly in the HTML
>template which contains the formatting a la <widget name=card_name> that
>Gunther proposed.
Yes, but the widgets I propose could also go into a form builder functions
like the ones you laid out as well. The widgets are supposed to be flexible
to suit any template needs not just TT.
>This above code actually sits in a subroutine that returns a list of the
>definitional information. This list is then simply included other places so
>I can write stuff like this:
>
>[
> [qq[
> Enter your billing information and credit card.<p>
> ]],
>
> [qq[ <b>Billing information</b><p> ]],
>
> [{ default_by_name => CUST::DbAccess::Cust::default_by_name("custs") }],
>
> CUST::InterfaceUtil::opensrs_contact_fields($country_select_box, "bill",
>"Billing"),
> undef,
>
> [qq[ <b>Credit card information</b><p> ]],
>
> [{ default_by_name => CUST::DbAccess::Ccard::default_by_name("ccards") }],
>
> CUST::InterfaceUtil::credit_card_fields(),
> undef,
>]
>
>It's great for reuse.
>
>The default_by_name does something interesting: it imports all the defaults
>for the fields (_looks_like and _required and _size) information from the
>database table. If I change the size of a text field in a table all the
>forms which use that text field are automatically updated. (However, I
>should change the default_by_name system so that it doesn't need to be
>specified when I'm including default confirmation. Like I said, this system
>is straining under the evolution.)
This may be interesting, but I still see this as being too much. It looks
more like you have a mini-templating system which is really a language for
drawing GUIs but you are also adding extra stuff like the data validation
on top of it in the same config.
But I think that config can be broken out so that it would make your GUI
drawing library much easier to see.
>I can contribute this library if it would help. I'll warn you that there's
>not too much documentation. I can also contribute some examples of my code
>that use the library.
It's possible, but I am not quite sure because the primary complexity seems
to be the data handling (which I have already in a separate abstraction)
and the UI generation which I have already in Template Toolkit. So all I
really want is an object abstract called a Widget along with a
WidgetCollection to allow grouping widgets together that belong on a given
HTML page.
So on a personal level, I would say this library is not compelling for what
I would like the end-product to be. But others may feel differently.