Cool "formstyle" trick w/Python lambda

563 views
Skip to first unread message

Joe Barnhart

unread,
Aug 8, 2013, 2:15:06 PM8/8/13
to
So I'm a control-freak.  I mean that in a good way.  I discovered the beauty of "placeholders" in forms and just thought "man, I really want that!"  But where to hold the placeholder data?  And how do I get it to the SQLFORM during form creation?

At first I thought about adding YAV (yet another variable) to the Field class.  But it's getting pretty crowded in there already, and mucking with it means changes to the base, and the devs might object to a special-purpose hack inserted into Field just to satisfy my whims.  So I thought I'd just create my own formstyle function and use that.  But wait!  The formstyle function has a defined signature now, and there is no place to insert anything like a dictionary of placeholders indexed by field name.  Or is there?

I created my own formstyle function, but added a keyword parameter to the end for the placeholders dict.  The signature looke like this:


def my_fieldstyle(form, fields, placeholders=None):
    ...blah...


Now, the code in SQLFORM still has no idea that these placeholders exist.  But I can "wrap" this function with either a "partial function" or a simple lambda to provide my own dictionary just before the customized formstyle function is handed off to SQLFORM for it's main job.  It looks like this:


my_placeholder_dict = {'field1': 'place1', 'field2', 'place2'...}
...
styler = lambda form, fields: my_fieldstyle(form, fields, placeholders=my_placeholder_dict)
...
form = SQLFORM(... formstyle=styler ...)
 

That's all there is to it!  Now I can pass abundant information into the SQLFORM creation, info that the base form creation has no idea exists.  My own custom formstyle class can interpret the extra information and add all kinds of special features.  Just a few ideas:

1.  Provide "placehloders" for phone and date fields to show proper format

2.  Provide dictionary of "field sets" with "legends" and create a structured form organized the way I want

3.  ... and many many more!

Best of all, it only needs stupid Python tricks and doesn't muck with the underlying structure of web2py at all!  No nasty stares from the devs!  (Just kidding...)

-- Joe

Richard Vézina

unread,
Aug 8, 2013, 2:23:03 PM8/8/13
to web2py-users
Nice Joe! Thanks for the recipe...

Until now I was creating custom widget for that, but this seems simpler, because I was getting in trouble sometimes with custom widget when I was requiring to alter a widget or set a differents widget, since I was getting placeholder from a dabase dictionnary that I create for every fields in every table. So, if I had to set a widget in the code I have to customize a new placeholder attribute or pass placeholder as kargs... 

Thanks

Richard


On Thu, Aug 8, 2013 at 2:11 PM, Joe Barnhart <joe.ba...@gmail.com> wrote:
So I'm a control-freak.  I mean that in a good way.  I discovered the beauty of "placeholders" in forms and just thought "man, I really want that!"  But where to hold the placeholder data?  And how do I get it to the SQLFORM during form creation?

At first I thought about adding YAV (yet another variable) to the Field class.  But it's getting pretty crowded in there already, and mucking with it means changes to the base, and the devs might object to a special-purpose hack inserted into Field just to satisfy my whims.  So I thought I'd just create my own formstyle function and use that.  But wait!  The formstyle function has a defined signature now, and there is no place to insert anything like a dictionary of placeholders indeded by field name.  Or is there...

I created my own formstyle function, but added a keyword parameter to the end for the placeholders dict.  The signature looke like this:


def my_fieldstyle(form, fields, placeholders=None):
    ...blah...


Now, the code in SQLFORM still has no idea that these placeholders exist.  But I can "wrap" this function with either a "partial function" or a simple lambda to provide my own dictionary just before the customized formstyle function is handed off to SQLFORM for it's main job.  It looks like this:


my_placeholder_dict = {'field1': 'place1', 'field2', 'place2'...}
...
styler = lambda form, fields: my_fieldstyle(form, fields, placeholders=my_placeholder_dict)
...
form = SQLFORM(... formstyle=styler ...)
 

That's all there is to it!  Now I can pass abundant information into the SQLFORM created, info that the base form creation has no idea exists.  My own custom formstyle class can interpret the extra information and add all kinds of special features.  Just a few ideas:

1.  Provide "placehloders" for phone and date fields to show proper format

2.  Provide dictionary of "field sets" with "legends" and create a structured form organized the way I want

3.  ... and many many more!

Best of all, it only needs stupid Python tricks and doesn't much with the underlying structure of web2py at all!  No nasty stares from the devs!  (Just kidding...)

-- Joe

--
 
---
You received this message because you are subscribed to the Google Groups "web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web2py+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Vinicius Assef

unread,
Aug 8, 2013, 2:50:07 PM8/8/13
to web2py
Excellent approach. :-)

António Ramos

unread,
Aug 8, 2013, 3:36:34 PM8/8/13
to web...@googlegroups.com
Nice, post it in web2pyslices!!!


2013/8/8 Vinicius Assef <vinic...@gmail.com>

Anthony

unread,
Aug 8, 2013, 4:04:18 PM8/8/13
to web...@googlegroups.com
Nice. I think we should add an argument to Field() that takes a dictionary of args to pass to the field's widget (or maybe just add **kwargs to Field() and pass kwargs to the widget). For now, though, if that's all you want to do, you can do something like this:

def widget(**kwargs):
   
return lambda field, value, kwargs=kwargs: SQLFORM.widgets[field.type].widget(field, value, **kwargs)

db
.define_table('mytable',
   
Field('myfield', widget=widget(_placeholder='my placeholder', _readonly=True)))

That should work for most fields -- would need some additional logic to accommodate fields that involve special widgets (e.g., fields with an IS_IN_DB validator that automatically get an options widget).

Anthony

On Thursday, August 8, 2013 2:11:44 PM UTC-4, Joe Barnhart wrote:
So I'm a control-freak.  I mean that in a good way.  I discovered the beauty of "placeholders" in forms and just thought "man, I really want that!"  But where to hold the placeholder data?  And how do I get it to the SQLFORM during form creation?

At first I thought about adding YAV (yet another variable) to the Field class.  But it's getting pretty crowded in there already, and mucking with it means changes to the base, and the devs might object to a special-purpose hack inserted into Field just to satisfy my whims.  So I thought I'd just create my own formstyle function and use that.  But wait!  The formstyle function has a defined signature now, and there is no place to insert anything like a dictionary of placeholders indexed by field name.  Or is there?

I created my own formstyle function, but added a keyword parameter to the end for the placeholders dict.  The signature looke like this:


def my_fieldstyle(form, fields, placeholders=None):
    ...blah...


Now, the code in SQLFORM still has no idea that these placeholders exist.  But I can "wrap" this function with either a "partial function" or a simple lambda to provide my own dictionary just before the customized formstyle function is handed off to SQLFORM for it's main job.  It looks like this:


my_placeholder_dict = {'field1': 'place1', 'field2', 'place2'...}
...
styler = lambda form, fields: my_fieldstyle(form, fields, placeholders=my_placeholder_dict)
...
form = SQLFORM(... formstyle=styler ...)
 

That's all there is to it!  Now I can pass abundant information into the SQLFORM creation, info that the base form creation has no idea exists.  My own custom formstyle class can interpret the extra information and add all kinds of special features.  Just a few ideas:

1.  Provide "placehloders" for phone and date fields to show proper format

2.  Provide dictionary of "field sets" with "legends" and create a structured form organized the way I want

3.  ... and many many more!

Best of all, it only needs stupid Python tricks and doesn't muck with the underlying structure of web2py at all!  No nasty stares from the devs!  (Just kidding...)

-- Joe

Richard Vézina

unread,
Aug 9, 2013, 1:57:54 PM8/9/13
to web2py-users
You are my man Anthony!


--

Andrew Rogers

unread,
Mar 19, 2020, 9:03:52 AM3/19/20
to web2py-users
Thanks. That helped me too!  But i have no idea how it did it. Need to read up on widgets.

All i wanted to do was add the "readonly" attribute to a form field.  I thought the following would have worked (from the book). Is it intended to add attributes?

If you need to add custom attributes to fields, you can simply do this:

db.table.field.extra = {}



Reply all
Reply to author
Forward
0 new messages