optgroup support

178 views
Skip to first unread message

hamdy.a.farag

unread,
Feb 15, 2010, 4:19:18 AM2/15/10
to web2py-users
Hi

I read this post
http://groups.google.com/group/web2py/browse_thread/thread/f9967ef7151c5ae8/d0c47ff7a40e0dfc?lnk=gst&q=OPTGROUP#d0c47ff7a40e0dfc

and I didn't find optgroup in html.py either

so why not adding it since from time to time people may need it?

mdipierro

unread,
Feb 15, 2010, 9:48:49 AM2/15/10
to web2py-users
Please let' snot proliferate these.

Use TAG.optgroup

On Feb 15, 3:19 am, "hamdy.a.farag" <hamdy.a.fa...@inbox.com> wrote:
> Hi
>
> I read this post

>  http://groups.google.com/group/web2py/browse_thread/thread/f9967ef715...

DenesL

unread,
Feb 17, 2010, 11:06:49 AM2/17/10
to web2py-users

Problem is that you can not use TAG.optgroup because it does not work
with the SELECT helper.

Here is a little example:

def index():
OG=TAG.OPTGROUP
g1=[ OPTION( r.name, _value=r.id ) for r in
db(db.person.age<=30).select() ]
g2=[ OPTION( r.name, _value=r.id ) for r in
db(db.person.age>30).select() ]
ogs=[OG(_label='30 and under',*g1),OG(_label='over 30',*g2)]
sel=SELECT(_name='person',*ogs )
f=FORM( sel )
print ogs[0] # OK
print ogs[1] # OK
print sel # not OK
return dict(f=f)

The SELECT is completely messed up inside since it only checks for
OPTION instances.

Denes.


On 15 feb, 09:48, mdipierro <mdipie...@cs.depaul.edu> wrote:
> Please let' snot proliferate these.
>
> Use TAG.optgroup
>
> On Feb 15, 3:19 am, "hamdy.a.farag" <hamdy.a.fa...@inbox.com> wrote:
>
> > Hi
>
> > I read this post
> >  http://groups.google.com/group/web2py/browse_thread/thread/f9967ef715...
>

> > and I didn't findoptgroupin html.py either

mdipierro

unread,
Feb 17, 2010, 11:10:05 AM2/17/10
to web2py-users
true. Use TAG.select

DenesL

unread,
Feb 17, 2010, 11:48:13 AM2/17/10
to web2py-users

So for future reference:

you can create OPTGROUPs with TAG.OPTGROUP
but do NOT use it with the SELECT helper,
you must use TAG.SELECT as in the following example:

def index():
OG=TAG.OPTGROUP
g1=[ OPTION( r.name, _value=r.id ) for r in
db(db.person.age<=30).select() ]
g2=[ OPTION( r.name, _value=r.id ) for r in
db(db.person.age>30).select() ]
ogs=[OG(_label='30 and under',*g1),OG(_label='over 30',*g2)]

sel = TAG.SELECT(_name='person', *ogs)
# DO NOT USE sel=SELECT(_name='person',*ogs )
f=FORM( sel )
return dict(f=f)

Denes.

Iceberg

unread,
Apr 17, 2010, 2:08:43 PM4/17/10
to web2py-users
Hi Denes and/or Massimo,

I just pick up this old post from http://groups.google.com/group/web2py/browse_frm/thread/971433920541935a

I used the code suggested by Denes, e.g. using TAG.SELECT and
TAG.OPTGROUP.

The code shows proper drop-down box but, after form.accepts(...) the
form.vars.my_field seems always None.

def test_code():
OG=TAG.OPTGROUP
g1=[ OPTION( r, _value=r ) for r in [23, 24, 25] ]
g2=[ OPTION( r, _value=r ) for r in [32, 33, 34] ]
ogs=[OG(_label='30 and under',*g1),OG(_label='over 30',*g2)]
sel = TAG.SELECT(_name='person', *ogs) # DO NOT USE
sel=SELECT(...)
form=FORM( sel, INPUT(_type='submit') )
if form.accepts(request.vars,keepvalues=True):
response.flash = 'got %s' % form.vars.person # Why always got
none?
return dict(form=form)

Question: What need I change to make form.vars.my_field work when
using TAG.SELECT()?

By the way, in case some people might ask why bother, why not just use
request.vars.my_field instead, well, it is just my personal best-
practice because form.vars.my_field usually contains data qualified by
validators, therefore more precisely than request.vars.my_field. Think
about this:
define_table('my_table',Field('my_field', requires=IS_UPPER()))
form = SQLFORM(db.mytable)
and input "hello world", then
request.vars.my_field=="hello world"
but
form.vars.my_field=="HELLO WORLD"
usually form.vars.my_field contains what I really need.

Regards,
Iceberg

mdipierro

unread,
Apr 17, 2010, 3:04:28 PM4/17/10
to web2py-users
you must user SELECT and not TAG.SELECT. The former is derived from
INPUT an knows how to process options, tha latter is simply derived
from a DIV and does not.

On Apr 17, 1:08 pm, Iceberg <iceb...@21cn.com> wrote:
> Hi Denes and/or Massimo,
>
> I just pick up this old post fromhttp://groups.google.com/group/web2py/browse_frm/thread/971433920541935a

Iceberg

unread,
Apr 20, 2010, 11:41:31 PM4/20/10
to web2py-users, dene...@yahoo.ca
Massimo's answer makes sense but does not entirely solve the problem.

Using SELECT(...) instead of TAG.SELECT(...) in my previous sample
code, does not render proper html output. There are two unnecessary
blank option with wrong value.

I guess SELECT(...) need to be fixed to support TAG.OPTGROUP(...),
perhaps a native OPTGROUP(...).

Regards,
Iceberg

On Apr18, 3:04am, mdipierro <mdipie...@cs.depaul.edu> wrote:
> you must use SELECT and not TAG.SELECT. The former is derived from

mdipierro

unread,
Apr 20, 2010, 11:59:59 PM4/20/10
to web2py-users
Now I see the problem:

do this

class MYSELECT(SELECT):
def _fixup(self): pass

and use MYSELECT

Iceberg

unread,
Apr 21, 2010, 3:57:19 AM4/21/10
to web2py-users
That is better, but still not good enough because form.accepts(...,
keepvalues=True) has no effect.

Anyway, Massimo gave enough hint for the correct direction. Here comes
my patch to html.py

__all__.append('OPTGROUOP') # Finally we have native OPTGROUP support!
class OPTGROUP(DIV):
tag = 'optgroup'

class SELECT(INPUT):
tag = 'select'

def _fixup(self):
components = []
for c in self.components:
if isinstance(c, str): # my patch
components.append(OPTION(c, _value=str(c)))
else: # my patch
components.append(c)
self.components = components

def _postprocessing(self):
import itertools
options = itertools.chain( *[ # my patch
( c.components if isinstance(c, OPTGROUP) else [c] )
for c in self.components ] )
if self['value'] != None:
if not self['_multiple']:
for c in options: # my patch
if self['value'] and str(c['_value'])\
== str(self['value']):
c['_selected'] = 'selected'
else:
c['_selected'] = None
else:
values = re.compile('[\w\-:]
+').findall(str(self['value']))
for c in options: # my patch
if self['value'] and str(c['_value']) in values:
c['_selected'] = 'selected'
else:
c['_selected'] = None

Regards,
iceberg


On Apr21, 11:59am, mdipierro <mdipie...@cs.depaul.edu> wrote:
> Now I see the problem:
>
> do this
>
> class MYSELECT(SELECT):
>     def _fixup(self): pass
>
> and use MYSELECT
>

Iceberg

unread,
Apr 24, 2010, 2:17:06 PM4/24/10
to web2py-users
Hi Massimo,

May I have your opinion about following patch?

If you don't like it but just because you really hate to add a
OPTGROUP helper, please tell me, I think I can adjust my patch to work
without a native OPTGROUP helper. It is up to you.

Regards,
Iceberg

mdipierro

unread,
Apr 24, 2010, 2:32:14 PM4/24/10
to web2py-users
I will include OPTGROUP in trunk and some version of your patch.

Massimo

quesad...@gmail.com

unread,
Sep 19, 2016, 9:44:24 AM9/19/16
to web2py-users
Hola, aquí la solución. Es fácil. 

selectnombre = SELECT(OPTGROUP(*opcions, _label="grupo"), _name="selNombre", _id="selNombre",
_multiple="multiple")

Saludos!!
Reply all
Reply to author
Forward
0 new messages