Helper for Custom Forms, inside controller

10 views
Skip to first unread message

Iceberg

unread,
Jan 2, 2009, 2:37:31 PM1/2/09
to web2py Web Framework
Hi there,

I noticed there are discussions about "Helper for Custom Forms", such
as:
http://groups.google.com/group/web2py/browse_thread/thread/2d8cc57352d158bd?hl=en


However, I am trying to do the same thing in a different approach. Not
sure whether my approach is better, so I post the idea here, request
for comments and/or criticise.

It all starts when I feel writing html in view file is more trivial
and labour-intensive, than writing handy "HTTP Building Objects" in
controller. Compare these examples:

A view, partially borrowed from http://groups.google.com/group/web2py/msg/303b8d25eb74ed91?hl=en
<form action="" enctype="multipart/form-data" method="post">
<!-- I can't remember the above line, so I have to copy&paste it
every time -->
{{=form.hidden_fields()}} <!-- Sometimes I forgot to write this stuff
-->
<fieldset>
<legend>Generic</legend>
<ol>
<li><label for="color_name">Name:</label>
{{=form.element(_name="name")}}</li>


I like to write it in a more compact and (hopefully) more intuitive
way:

In controller.py:
def insert():
form=FORM( # A FORM() or SQLFORM() automatically setup hidden
fields for you
FIELDSET(
TAG.LEGEND('Generic'),
OL(LI(LABEL('Name:',_for='color_name'),
field2html(proof.color.name), # I will explain this later
)),
...
))
if form.accepts(...): do_something()
return dict(content=form)

This way, the controller.py will be somewhat fat, but usually I don't
need any specific view file at all. Hope you get the idea.
By the way, my approach bring another convenience although not very
significant: let's say suddenly you need to handle one more form in
your insert action, and you plan to name them "color_form" and
"match_form" respectively, so at first you need to rename all "form"
into "color_form" inside your current view file (if any), otherwise an
error ticket will show up. But if you don't use a view file at all,
then you can just freely write something like this inside your
controller.py:
def foo():
...
return dict(content=DIV(color_form, match_form))


The downside of my approach. The page layout is defined inside
controller. It violates the MVC convention. But it seems not that bad.
What do you think?


PS: The field2html(proof.color.name) inside my example is the real
helper function I defined inside the model.py. It can automatically
generate proper html code for a SQLField. This is part of it.

def field2html(field,value=None,**kwargs):
requires=field.requires.other if isinstance
(field.requires,IS_NULL_OR) else field.requires
if isinstance(requires,IS_IN_SET):
options=[OPTION('',_value='')] # A default empty value
options+=[OPTION(l,_value=v) for v,l in requires.options()]
return SELECT(_name=field.name,value=value,
requires=field.requires,
*options,**kwargs)
if isinstance(requires,IS_DATE):
return INPUT(_class='date',_type='text',

_name=field.name,_id=field.name,_value=value,requires=field.requires,**kwargs)
if field.type=='double':
return INPUT(_class='double',_type='text',

_name=field.name,_id=field.name,_value=value,requires=field.requires,**kwargs)

Sincerely,
Iceberg, 2009-Jan-03, 02:12(AM), Sat


Reply all
Reply to author
Forward
0 new messages