Custom forms again

22 views
Skip to first unread message

Peter

unread,
Jan 18, 2009, 3:54:10 PM1/18/09
to web2py Web Framework
Hi Massimo et al,

First of all, the onvalidation callback that is now in SQLFORM (in
trunk) is a real winner, thanks! The validation rules in my app are
largely context-sensitive, and that was a big problem -- until now.

I am still struggling to find the best way to customize SQLFORM views,
though. The "new" form.element() function only allows me to modify the
attributes existing xml nodes -- is that correct?

For instance, I needed previous/next buttons in a multi-page form, and
I really hate having to handcode entire forms in the html (or in the
controller, for that matter). This is what I came up with:

# controller
form=SQLFORM(db.t2_person,myperson,deletable=False,showid=False)

l = len(form.components[0]) # =number of rows in form

# add input element to second td in submit row
form.components[0][l-1][1].append( INPUT(_type="buttonx") )

# redefine both "submit" and "buttonx"
form.element(_type="submit").update(_type="button",
_value="<<Previous",_onclick="location='"+URL
(r=request,f='step1')+"';")
form.element(_type="buttonx").update(_type="submit",
_value="Next>>")

Basically, I add a new 'dummy' input element and then redefine both
inputs using form.element(). This works, but the direct use of the
internal form/div structure to insert a new xml node is an eyesore. Is
there a better way to do this?

Ideally, I'd be looking for a sort of formalized API that I could use
to manipulate the entire xml tree of the form, eg, similar to the
DOM.

Cheers,
-Peter

mdipierro

unread,
Jan 18, 2009, 9:34:22 PM1/18/09
to web2py Web Framework
At this time using [i], .element, .append and .insert are the only
methods to manipulate the form. Can you provide an example of the API
you would like to have?

Massimo

Peter

unread,
Jan 19, 2009, 2:39:05 AM1/19/09
to web2py Web Framework
> Can you provide an example of the API you would like to have?

A small subset of the formal DOM API (http://www.w3.org/TR/DOM-Level-2-
HTML/html.html) would do wonders:

* Top of the list would be "structural manipulation" functions that
would allow insertion or removal of elements at specific places in the
tree: appendChild(node), insertBefore(node), removeChild(node) .

* Second would be "structural navigation", parentNode, .childNodes
(see http://krook.org/jsdom/Node.html)

* Search functions (a bit of a luxury given that we have form.element
()?): getElementByID(string elementId) and getElementsByTagName(string
tagname) (http://krook.org/jsdom/Document.html)

* And manipulation of "html nodes": getAttribute(), setAttribute(),
removeAttribute() (http://krook.org/jsdom/Element.html)

Of course, if I were half a man I would build it myself and send you a
patch for html.py, but I'm afraid I am lacking both in experience and
in time... ;-)

Cheers,
-Peter

mdipierro

unread,
Jan 19, 2009, 5:02:36 AM1/19/09
to web2py Web Framework
I think what is provided is not much different than what you asking
> a=DIV()
> a.append(H1())
> a.append(H2())
> a[0].append('hello')
> a[1].append('world')
> a.insert(1,SPAN(' '))
> print a

<div><h1>hello</h1><span> </span><h2>world</h2></div>

> a[1]['_id']='myid'
> a.element(_id='myid').update(_class='myclass')
> print a

<div><h1>hello</h1><span class="myclass" id="myid"> </span><h2>world</
h2></div>

> del a[0]
> print a

<div><span class="myclass" id="myid"> </span><h2>world</h2></div>

Really the only missing thing is the ability to query for the parent
of a node, and that would be easy to add.

Massimo

On Jan 19, 1:39 am, Peter <peter.kleyn...@gmail.com> wrote:
> >  Can you provide an example of the API you would like to have?
>
> A small subset of the formal DOM API (http://www.w3.org/TR/DOM-Level-2-
> HTML/html.html) would do wonders:
>
> * Top of the list would be "structural manipulation" functions that
> would allow insertion or removal of elements at specific places in the
> tree: appendChild(node), insertBefore(node), removeChild(node) .
>
> * Second would be "structural navigation", parentNode, .childNodes
> (seehttp://krook.org/jsdom/Node.html)

Peter

unread,
Jan 19, 2009, 10:21:18 AM1/19/09
to web2py Web Framework
Okay Massimo, that's exactly the clarity I'm looking for! I couldn't
really find it in the docs, but if I can use this as a more or less
official API, I'm happy. For one thing, I had overlooked the obvious
del()... ;-) A parent() function would be nice --especially since I
can't delete an element found with form.element()-- but that is really
just icing on the cake.

It means that I can now answer my own question "is there a better way
to do this":
form=SQLFORM(db.t2_person,myperson,deletable=False,showid=False)

submit_tr = form.element(_id='submit_record__row')
# get rid of the submit button and append two new INPUTs in its
place
del(submit_tr[1][0])
submit_tr[1].append( INPUT( _type='button', _value=T
('<<Previous'), _onclick="location='"+URL(r=request,f='step1')+"';") )
submit_tr[1].append( INPUT( _type='submit', _value=T('Next>>') ) )

Looks a lot better, doesn't it? :-) This way, I can really "go to
town" on the html as generated by SQLFORM.
Thanks again!
-Peter

Peter

unread,
Jan 19, 2009, 10:32:19 AM1/19/09
to web2py Web Framework
Bahh, I'm asleep at the wheel here... it should of course be:
form=SQLFORM
(db.t2_person,myperson,deletable=False,showid=False,submit_button="Next>>")

submit_tr = form.element(_id='submit_record__row')
submit_tr[1].insert( 0, INPUT( _type='button', _value=T('<<Back'),
_onclick="location='"+URL(r=request,f='step1')+"';") )

Sorry for that, folks.
-P
Reply all
Reply to author
Forward
0 new messages