SQLFORM.factory or a better way for custom forms

195 views
Skip to first unread message

K.R.Arun

unread,
Jan 2, 2010, 2:15:53 PM1/2/10
to web2py-users
hi,
I'm new to web2py and my first experience with it is fun.
It's true that I can develop fast but for now customization is pain in
some places.
For example, I like css over tables. And I have to add some fieldsets
to my form.
Form is generated from a table and using SQLForm(because many tasks
are done by it, like automatic insertion, validation etc.,)

You can see my site on-line at http://exodus-fest.appspot.com/
(It uses css3, best viewed on a latest chrome/firefox or any other
css3 supported browser)


at the end of the post I'm posting code for view and controller.
Now tell me is there any better way to do the same; like using
SQLFORM.factory (I tried, but hopelessly failed.) so that view get
shortened.

Now, what follows is my code...

controller
~~~~~~~

def register():
msg = ''
fieldLabels={'name':'Full Name:', 'course':'Enrolled Course:',
'college':'College/University:', 'mobile':'Mobile Number:',
'email':'Email Address:'}
form = SQLFORM(db.register, submit_button='Register',
labels=fieldLabels)
if form.accepts(request.vars, session):
form = None
a = q = c = d = ''
import smtplib
toaddr = request.vars.email
q = 'Yes' if request.vars.quiz else 'No'
a = 'Yes' if request.vars.animation else 'No'
c = 'Yes' if request.vars.coding else 'No'
d = 'Yes' if request.vars.dance else 'No'
body = ('Dear ' + request.vars.name +',\n\n' +
'It is a pleasure for me to let you know that you had successfully
registered for the Exodus-10 (Cultural and IT fest) ' +
'conducted by Computer Science Dept. of St. Thomas College, Thrissur
\n\n'+
'You are registered to:\n'+
' Quiz : ' + q + '\n' +
'Animation : ' + a + '\n' +
' Coding : ' + c + '\n' +
' Dance : ' + d + '\n\n'+
'Please note that program commence on 14th Jan, 2010, 9:30am'+
'\n\n\nThank You,\nShibu \n(Student Co-ordinator)\nMobile :
+919496349988' + '\n Website: http://exodus-fest.appspot.com/')

mail.send(to = toaddr, subject='Exodus: Event registration',
message= body)
msg += "You are Successfully registered. Please Check your email."
elif form.errors:
if form.errors.name: form.errors.name='Your name seems too short'
if form.errors.college: form.errors.college='It is a too short name'
if form.errors.mobile: form.errors.mobile='Enter a valied Mobile
Number'
if form.errors.email: form.errors.email='Enter a valied Email
Address'
return dict(form=form, msg=msg)


--------------------------------------------------------------------------------------------------------------------------------------------
now view
~~~~~~~

{{extend 'tmpl.html'}}

{{if form:}}
{{lbl=form.custom.label}}
{{wdgt=form.custom.widget}}

<form action="" enctype="multipart/form-data" method="post">
<h1>Exodus: Event Registration Form</h1>
<fieldset>
<legend>Your Details</legend>
<ul>
<li>
<label for="register_name" id="register_name__label">{{=lbl.name}}
</label>
{{=wdgt.name}}
</li>
<li>
<label for="register_course" id="register_course__label">
{{=lbl.course}}</label>
{{=wdgt.course}}
</li>
<li>
<label for="register_college" id="register_college__label">
{{=lbl.college}}</label>
{{=wdgt.college}}
</li>
</ul>
</fieldset>
<fieldset>
<legend>Contact Information</legend>
<ul>
<li>
<label for="register_mobile" id="register_mobile__label">
{{=lbl.mobile}}</label>
{{=wdgt.mobile}}
</li>
<li>
<label for="register_email" id="register_email__label">
{{=lbl.email}}</label>
{{=wdgt.email}}
</li>
</ul>
</fieldset>
<fieldset>
<legend>Participating Events</legend>
<div class="events">
<ul>
<div><li>
<label for="register_quiz" id="register_quiz__label">{{=lbl.quiz}}
</label>
{{=wdgt.quiz}}
</li>
<li>
<label for="register_animation" id="register_animation__label">
{{=lbl.animation}}</label>
{{=wdgt.animation}}
</li></div>
<div><li>
<label for="register_coding" id="register_coding__label">
{{=lbl.coding}}</label>
{{=wdgt.coding}}
</li>
<li>
<label for="register_dance" id="register_dance__label">
{{=lbl.dance}}</label>
{{=wdgt.dance}}
</li></div>
</ul>
</div>
</fieldset>
<input type="reset" value="Reset" />
<input type="submit" value="Register" />
<div class="hidden">
{{=form.hidden_fields()}}
</div>
</form>

{{pass}}

{{=msg}}

mdipierro

unread,
Jan 2, 2010, 2:30:45 PM1/2/10
to web2py-users
I cannot think of a better way. Nice site by the way. I would only
replace

<div class="hidden">
{{=form.hidden_fields()}}
</div>
</form>

with

{{=form.custom.end}}

On Jan 2, 1:15 pm, "K.R.Arun" <the1.a...@gmail.com> wrote:
> hi,
> I'm new to web2py and my first experience with it is fun.
> It's true that I can develop fast but for now customization is pain in
> some places.
> For example, I like css over tables. And I have to add some fieldsets
> to my form.
> Form is generated from a table and using SQLForm(because many tasks
> are done by it, like automatic insertion, validation etc.,)
>

> You can see my site on-line athttp://exodus-fest.appspot.com/

K.R.Arun

unread,
Jan 2, 2010, 2:48:36 PM1/2/10
to web2py-users
Thank you, and really really appreciate the response time for the post
(hardly 15min).
I thought it may be constructed using SQLFORM.factory (I tried
but...).
If this is the better way, I'm happy.
I have another problem with AJAX.
( You can see that menu Items loads asynchronously using ajax(u,s,t)
function of web2py_ajax.html.
For example following is code for 'home' menu item. (here also, Is
there any better way to do this; like read out a html file and send,
or jason/xml)
-------------------------------------------------------------------------------------------------------------------------------------------------
def home():
return DIV(
H1('EXODUS'),
P('The Computer Science Department of St. Thomas’ college has been
conducting, Inter-Collegiate Techno-Cultural Fest named ‘Exodus-Saga
Of Campus‘ every year since 2005. Nearly 20 – 25 colleges participate
in this program with a total strength of about 1000 students.'),
P('It includes technical events such as'),
OL(
LI('Iron Out – Debugging'),
LI('Enlivenance – Flash Animation'),
LI('Enigma – Quiz'),
),
P('and a cultural program'),
OL(
LI('Enlivenance – Flash Animation'),
),
).xml()
----------------------------------------------------------------------------------------------------

But how can I do the same with registration form?
Now it's done using a separate view.

Thanks for the quick reply.
Have a nice day.

Arun

mdipierro

unread,
Jan 2, 2010, 3:25:03 PM1/2/10
to web2py-users
well, you can do it with FROM (not SQLFORM.factory) but You would not
gain anything in your case.

About AJAX.

You could make something like

def ajax_user(): return auth() # instead of dict(form=auth())

and then in a page

{{=LOAD('default','ajax_user/register',ajax_trap=True)}}

you do not need to use LOAD, you can use ajax('...').

Alex Fanjul

unread,
Jan 3, 2010, 11:58:15 AM1/3/10
to web...@googlegroups.com, mdipierro
Hi Massimo,
In relation to this, there is one previous but important big thread
talking about tableless forms that I would add to web2py roadmap
somehow. http://www.mail-archive.com/web...@googlegroups.com/msg27116.html
I think it's a recurrent subject in this forum, and there was some
attempts to solved it like the one done by Thadeus. I know there are
some priorities like the new DAL but anyway...
Once ago I read something like "the best web you will ever has done,
it's the web done by your users", so maybe you could gauge the "future
feature requests" using a free tool like this:
http://www.polleverywhere.com to poll the roadmap, what do you think?

regards,
Alex F

El 02/01/2010 20:30, mdipierro escribi�:

> --
>
> You received this message because you are subscribed to the Google Groups "web2py-users" group.
> To post to this group, send email to web...@googlegroups.com.
> To unsubscribe from this group, send email to web2py+un...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/web2py?hl=en.
>
>
>
>

--
Alejandro Fanjul Fdez.
alex....@gmail.com
www.mhproject.org

K.R.Arun

unread,
Jan 3, 2010, 1:01:28 PM1/3/10
to web2py-users

On Jan 3, 1:25 am, mdipierro <mdipie...@cs.depaul.edu> wrote:
> well, you can do it with FROM (not SQLFORM.factory) but You would not
> gain anything in your case.
>
> About AJAX.
>
> You could make something like
>
> def ajax_user(): return auth() # instead of dict(form=auth())
>
> and then in a page
>
> {{=LOAD('default','ajax_user/register',ajax_trap=True)}}
>
> you do not need to use LOAD, you can use ajax('...').

Sorry, I can't able to understand it.
I read it somewhere that LOAD can be used to AJAX load components into
the page.
BTW, in {{=LOAD('default','ajax_user/register',ajax_trap=True)}} ,
what this parameters mean except 'default'?
ajax_user is our function defined above, then what's register(Is it
argumet??)?
what is meant by return auth() (Is auth() is a function that returns a
form object?)

I'm from C++ and Java background, new to Python, hope wordings are apt
to python also.

Arun

mdipierro

unread,
Jan 3, 2010, 1:28:57 PM1/3/10
to web2py-users
{{=LOAD(a,b,args=args,vars=vars,ajax=ajax,ajax_trap=ajax_trap)}}

a,b,args,vars are used to build the URL
URL(request.application,c=a,f=b,args=args,vars=vars)

if ajax=False the URL is called BEFORE the page is served
if ajax=True the URL LOAD just generate JS code to request tha page
via AJAX
if ajax_trap=True all forms in the content are captured and submitted
via AJAX.
ajax=True implied ajax_trap=True.
ajax=False implies args andvars are ignored and request.args ad
request.vars are used.

K.R.Arun

unread,
Jan 4, 2010, 1:15:13 AM1/4/10
to web2py-users
hi,
Is that mean I can use LOAD function in the register button's href
attribute.
You can see from my code that, my form needs some customization,
that's why I used separate view.
Now how can I load the form via ajax.
can I load separate view within another view?
what's the target for the AJAX loaded content?

mdipierro

unread,
Jan 4, 2010, 3:36:01 AM1/4/10
to web2py-users
LOAD itself cannot go in the href/onclick of a button because it is a
server-side function that generates JS you can try use it (with
ajax=True), look at the generated JS and put that into the BUTTON
onclick.

You can do

<BUTTON onclick="web2py_ajax_page('POST','{{=URL
(r=request,f='callback')}}',"a=b&c=d",'target')">click me</button>
<div id="target"></div>

and when you click the button is calls /yourapp/default/callback,
places the result in the target div and every form loaded in the div
will stay in the div even if submitted.

The ""a=b&c=d" argument can be any a urlencoded set of parameters.

K.R.Arun

unread,
Jan 5, 2010, 2:16:49 AM1/5/10
to web2py-users
You can see from my first post that my form gets custom rendered on
another view.
This LOAD thing will render my form as default, right?
How can I get all those custom modification in the view?

Arun

mdipierro

unread,
Jan 5, 2010, 9:34:14 AM1/5/10
to web2py-users
In my example

<BUTTON onclick="web2py_ajax_page('POST','{{=URL
(r=request,f='callback')}}',"a=b&c=d",'target')">click me</button>
<div id="target"></div>

you are calling via ajax the action URL(r=request,f='callback'). If
the action has a view it will be used. Actually unless the action
itself returns a string, it must have a view, since the generic.html
view should not be used in this context. This is because if you load a
part of a page via ajax you do not want that part of the page to
{{extend 'layout.html'}}.

K.R.Arun

unread,
Jan 5, 2010, 10:32:13 AM1/5/10
to web2py-users
I tried <a onclick="web2py_ajax_page('POST','{{=URL
(r=request,f='register')}}','','data')"> <button
type="button">Register</button></a>
but nothing happened when I clicked the button.
Then I tried again by adding {{=LOAD
('default','register',ajax=True,ajax_trap=True)}} to the view I get
following result.

<script><!--
web2py_component("/register","796460028363")
//--></script><div id="796460028363">loading...</div>

but if ajax=False then the register's view get displayed within main
view.
But how can I do the same with Register button's click.
I tried many ways but failed.
Any suggestions are welcomed.

Arun

K.R.Arun

unread,
Jan 5, 2010, 10:42:49 AM1/5/10
to web2py-users
hi,

Sorry for my own foolishness.

I done all those things in my previous post (that's still waiting for
moderation) but I missed one info from your previous post, "This is


because if you load a part of a page via ajax you do not want that
part of the page to {{extend 'layout.html'}}. "

And exactly that was the problem with me.
I just removed {{extend 'tmpl.html'}} with <a href="{{=URL(r=request,
f='register')}}" onclick="web2py_ajax_page('POST','{{=URL
(r=request,f='register')}}',' ','data'); return false;"> <button


type="button">Register</button></a>

Hurray, everything is fine now, totally RIA enabled page, no
redirection.

This satisfied me a lot, since this is my project after working on GWT
based project.

Thank you very much for every bit of advise these far.

(NB: Actually I already customised web2py_ajax.html and removed last 3
functions including web2py_ajax_page(), so I have to add them
again ;-) )

Web2Py wins for sure,
Arun

Reply all
Reply to author
Forward
0 new messages