Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Form generation

by matthewb (Deacon)
on Apr 22, 2005 at 12:56 UTC ( #450396=perlquestion: print w/ replies, xml ) Need Help??
matthewb has asked for the wisdom of the Perl Monks concerning the following question:

Monks and mongers,

Time and again, I find myself bored silly producing XHTML forms to perform some piece of business logic which is, to some extent, coupled to a database. Indeed, so common is this requirement that I'm pushed to think of a project I've been involved in that didn't involve such an interface at some point.

Laziness, impatience, hubris...”, we echo but how to be lazy, here? I'm getting impatient.

Solutions exist that purport to solve this problem through the auto-generation of semi-intelligent forms. They appear feasible because it's a problem that sounds like it should be solvable.

I've previously noded my frustrations with Class::DBI::AsForm; I've worked with and tried to like FormBuilder but find myself feeling that something is not right. I'd feel comfortable knowing that information pertaining to the database (model) is closely coupled to it but at what point do we feel that form generation becomes display logic?

And anyone who has done web development beyond the one-man pet project will know that it inevitably involves a graphic designer whose principal skill seems to be devising convoluted means to defy your generated forms. A similar frustration is that requirements are so often more complex than simple CRUD.

I'm looking for a generic and reusable solution that, critically, is not more work or less flexible that making a library of Template Toolkit forms and being done with it.

Naturally, I was interested in merlyn's remarks the other day concerning the storage of column meta-data in a config file accessible through your Class::DBI-derived classes. Seems like a good idea and I hacked around with it that evening on a test machine. I've seen similar solutions using a database table to store meta-data before. But what meta-data to store? XHTML tag for representation? XHTML attributes? Default value? Order to appear in? User permissions? Would it be a good idea, taking the example from Class::DBI::AsForm, to somehow return HTML::Element objects for easy manipulation within templates?

And then, of course, it hits you: you've gone and defined a mini-language that does the same thing as XHTML just without being as easy to edit in emacs.

I'm interested in a general discussion on best practice and other people's experiences in this area; what are the gurus among us doing that I'm somehow missing?

Update: <readmore>s requested by tlm. I marked this OT originally because the problem is not specific to Perl. Thanks for all the replies. MB.


MB

Comment on Form generation
Download Code
Re: Form generation
by mpeters (Chaplain) on Apr 22, 2005 at 13:48 UTC
    And then, of course, it hits you: you've gone and defined a mini-language that does the same thing as XHTML just without being as easy to edit in emacs.

    I think you've hit the nail on the head with this one. Any project that is going to involve a separate graphics person/department is not going to to want to be tied down to some subset of (X)HTML that you have chosen to represent in your mini language. Whether this mini-language is meta-data or objects themselves, you will have to recreate the full complexity of (X)HTML.

    Although sometimes more tedious, having a set of templates that look just like HTML with a few extra tags, or expressions is the best way to go to keep designers happy and to make it easier to maintain in the long run.

    IMHO
Re: Form generation
by tzz (Monk) on Apr 22, 2005 at 13:56 UTC

      But Xforms is already a W3C recommendation and has already got (albeit beta) support in Firefox and Mozilla and even has a plugin for IE, why wait for something else?

      /J\

        I'm waiting for the O'Reilly book on it! Seriously, it is in beta everywhere, so I wouldn't run a business with it. I have certainly read and understood the current standard, and I'm ready to start using it.

        When XForms/WebForms is in its final form (what I referenced was the almost-final draft) I will feel more comfortable developing with it. The idea of specifying abstract UI, of course, is not new, but I really like the way that WebForms does it, because I can see that working in a Java Swing or Perl/Tk environment as well with some small modifications.

        Ted

Re: Form generation
by Hero Zzyzzx (Curate) on Apr 22, 2005 at 14:03 UTC

    This isn't OT. I suspect a lot of us spend a lot of time just gluing HTML forms together. I feel your pain. As to what I'm doing:

    I've been using Alzabo to model my database and store "column meta-data" that I then pass to CGI::FormBuilder to create forms. All the stuff that doesn't come directly off of alzabo I store in the "comment" that you can associate with each column, then I eval this comment and pass to CGI::FormBuilder::field.

    Alzabo provides a HTML::Mason-based GUI, I'm getting to the point that I can just add columns via the browser and the Alzabo GUI, define the column meta-data in the alzabo comment and the new field with just render in the form, with server-side and javascript validation. So far, I'm gluing it all together with CGI::Application and HTML::Template, but given that everything in the stack supports multiple templatting options, you don't have to go that way.

    I've also got some rough code doing a similar thing running via Mason, and the Mason version can render 1 to 1 or n to 1 cardinal relationships, too. I'm trying to figure out the best way to do n to n cardinality.

    I plan on writing this up once I clear my schedule in a while, I'm REALLY digging this methodology.

    -Any sufficiently advanced technology is
    indistinguishable from doubletalk.

    My Biz

Re: Form generation
by merlyn (Sage) on Apr 22, 2005 at 14:54 UTC
    The trick with Config::Scoped has been invaluable in my current $client project. I define in once place all the meta information about a form field, and then I can query it from both Perl and TT. The project rules forbid changing the existing database (I'm replacing a live app with new code), so I've had to be "creative" in some parts of my code. Using Class::DBI, CGI::Prototype, Template-Toolkit, and Config::Scoped, I'm nearly done with the replacement (with enhancements!) in about 1/4th the number of lines of code.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      Is there some nice full fledged example documentation for using the modules you mention? I went through the docs for CGI::Prototype but couldn't gather much.

Re: Form generation
by DaWolf (Curate) on Apr 22, 2005 at 15:28 UTC
    Speaking about the theory of this I was thinking about making a script that does something like:

    Foreach field of the table fetch the field name, data type and length. Then generate the html tag according to this information.

    I think this is quite easy to do.

    The whole thing begins to get messy when you have to deal with styles and/or javascript handlers (onClick, onBlur, etc, etc...).

      Speaking about the theory of this I was thinking about making a script that does something like:

      Foreach field of the table fetch the field name, data type and length. Then generate the html tag according to this information.

      I think this is quite easy to do.

      As I say, it does sound like a solvable problem, this is the central premise behind Class::DBI::AsForm.

      But this supposition breaks down quite quickly when developing applications for the typical (read:awkward) client. How can portability be maintained across DB servers? What about business-specific requirements for form fields such as something as simple as them wanting a <select> where a text input is implied by the schema.

      Often you'll have a couple of TEXT fields, one of which they want to be really large for some reason. In a drunker moment I once set about hacking AsForm to read existing entries in TEXT fields and try to assign appropriate rows and cols attributes based on existing entries (!).

      Look at how Maypole gets on going down this route: for all the hype about not having to type out your column names even the simplest application will require you to type them out three times to get anything resembling professionalism (to define the headings the user sees, the untaint rules, the relationships etc.)

      The consensus seems to be what I feared but have always ended up with in the past - it's still less work and more maintainable just to make the things yourself and get on with something else ;)


      MB
        Well, I can't say that you are wrong.

        Althrough it's extremely boring (as you've already posted), doing all "by hand" seems to be the only way to get the final result to be exactly as expected. (excuse my english, I'm a foreigner)

        I've forgot to mention that this "marvelous script" that I was thinking about is meant to make things a little easier, but *never* to fully automate the whole job - yes, it sounds like a doable thing, but I have serious doubts about it...

        Anyway, my whole point is quite the same as the center of your post: the concern about having to type everything, but feeling/fearing that this is the only way.

        Regards,
Re: Form generation
by cbrandtbuffalo (Deacon) on Apr 22, 2005 at 15:42 UTC
    I don't think you're missing anything. It seems to me a nice MVC design that allows you to separate concerns cleanly is the way things are going right now. There are several excellent Perl modules that have come out in the last year or two that are all hitting this key area. Some have been mentioned above. We use CGI::Prototyped.

    Yes, the HTML part is tedious, but I think it's still necessary for a few reasons:

    • Different people working on different parts. As already mentioned, in many places different people work on the HTML and the business code. Better to let the HTML people work in something close to a standard language.
    • Prototyping is much easier when the designers can mock things up in HTML and easily convert that to a working app using most of the prototype. If you have a meta language in there, less of the prototype can be used as-is.
    • Custom requests still happen all the time, at least in my shop. You may come up with a CRUD design that you can just crank out, but we still end up with special requests for changes to the look and behavior. This is easier to accommodate and maintain in a separate HTML-based view.
    • Maintenance is easier with a standardized system. You can pass things off to others and they can figure it out because the view is based on some standard module like Template. The business code is in straight Perl. The DBI code might be in Class::DBI. Tricky automation systems can be very cool, but they can also be fragile.

    Given the limitations of the web as a medium for allowing people to do work, I know I have felt that using these MVC Perl modules is light years ahead of where we were. With the INCLUDES, WRAPPERS, and MACROS in Template::Toolkit and the OO inheritance provided by CGI::Prototype, we can re-use just about as much common stuff as possible. Yet we can still be responsive to custom requests at the HTML/CSS layer.

Re: Form generation
by magog (Beadle) on Apr 22, 2005 at 19:19 UTC

    I definitely agree that designers should be allowed to work in HTML whenever possible. Not only does it make their lives easier, but they already have tools to generate all those tedious form tags and make them look purty.

    I'm thinking: why don't we make a solution based on HTML::FillInForm? If you're using CGI::Application::Plugin::ValidateRM, then you're allready using HTML::FillInForm to maintain form state between submissions, so why not use it for the initial state as well?

    HTML::FillInForm won't help you generate lists of things for select menus, radio buttons and lists of checkboxes. For that, you still need a template loop. But HTM::FillInForm does select the correct item in a list, and that's a good chunk of the work.

    Here's a little script that illustrates how it could work. It includes two mock CDBI classes, and a little CDBI-to-HTML::FillInForm bridge.

    The form is all HTML, and creates multiple views of the same data. For instance, the last name is displayed with both a regular text input tag and also a textarea tag. The profession is represented by both a list of radio buttons and a select menu.

    In an application, the bridge would be run after the template has been filled out but before the text is returned to the browser.

    I'll play around with this some more and try to turn it into a proper module.

    Michael

    edit: fixed a brain-o where I mixed up textareas and checkboxes
    edit: fixed a typo

Re: Form generation
by siracusa (Friar) on Apr 27, 2005 at 18:21 UTC
    Would it be a good idea, taking the example from Class::DBI::AsForm, to somehow return HTML::Element objects for easy manipulation within templates?
    If you're looking for a convenient, malleable storage medium for HTML forms, you might want to take a look at my module, Rose::HTML::Objects. As for metadata storage, I can find everything I need in the perl database objects themselves. I'm currently working on some code that auto-generates an appropriate form based solely on the metadata that can be extracted from the db object, but it's for a specific project and probably not for CPAN. (I'm also not using Class::DBI.)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://450396]
Approved by b10m
Front-paged by tlm
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2014-11-27 20:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (187 votes), past polls