# get existed categories
categories = list(ScheduleCategory.select())
options = []
for category in categories:
options.append((category.id, "%s - %s" % (category.name,
category.description)))
class AddEntryFields(widgets.WidgetsDeclaration):
# option won't update automatically if i add new record to
ScheduleCategory.
category = widgets.SingleSelectField(label="Category:",
options=options)
add_entry_form = widgets.TableForm(fields=AddEntryFields(),
submit_text=" Save Entry ")
You can use a callable to prepare options:
def prepare_options():
categories = list(ScheduleCategory.select())
return [(category.id, "%s - %s" % (category.name,
category.description)) for category in categories]
then:
category = widgets.SingleSelectField(label="Category:",
options=prepare_options)
Not tested but I think it should work.
Ciao
Michele
What about changing the options at "display-time"? That should work too,
right?
--
Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/
.------------------------------------------------------------------------,
\ GPG: 5F5A8D05 // F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05 /
'--------------------------------------------------------------------'
SEÑOR BIELSA: CON TODO RESPETO ¿USTED LO VE JUGAR A RIQUELME?
-- Crónica TV
Allberto
Pass an option parameter to the display method of your form, if you
have a field named "type" that's a SelectionField (like
SingleSelectField, MultipleSelectField, RadioButtonList and
CheckBoxList) you can for example pass a dict like this from the
controller:
new_options = dict(type=[(1, "Java"), (2, "Ruby")])
and then:
form.display(options=new_options)
By the way even using a callable changes the options at display time
since that's when it's called.
For further reference take a look at our tests:
http://trac.turbogears.org/turbogears/browser/trunk/turbogears/widgets/tests/test_widgets.py#L229
Ciao
Michele
You can set the default value only at instantation time.
But you can pass the value to be displayed on the first form display by
using the same method as for options, for example if you have a form
like this:
class PageFormFields(WidgetsDeclaration):
page = TextField()
languages = MultipleSelectField(options=[(1, "Python"), (2,
"C"), (3, "Java")])
form = TableForm(fields=PageFormFields())
you should use:
form_values = dict(page="pagename", languages=[1,2])
The you display your for form in this way:
form(value=form_values, options=...)
Ciao
Michele
I've been trying to do that for forms. How would you pass just new options
for some widgets inside, for example, a TableForm?
Example:
================================================================================
def unidades():
unidades = [[unidade.id, unidade.simbolo]
for unidade in model.Unidade.select(
orderBy = model.Unidade.q.simbolo,
)]
return unidades
formulario_conversao_unidades_de_medida = widgets.TableForm(
[
widgets.SingleSelectField(name = 'origem',
label = lazy_gettext('Unidade de Origem'),
css_classes = ['required'],
validator = validators.Int(not_empty = True),
options = unidades(),
),
widgets.SingleSelectField(name = 'destino',
label = lazy_gettext('Unidade de Destino'),
css_classes = ['required'],
validator = validators.Int(not_empty = True),
options = unidades(),
),
widgets.TextField(attrs = {'size':16, 'maxlength':15},
name = 'multiplicador',
label = lazy_gettext('Fator Multiplicador'),
css_classes = ['required'],
validator = validators.Number(not_empty = True),
),
widgets.HiddenField(name = 'conversao_unidade_id',
validator = validators.Int(if_empty = None),
),
],
)
================================================================================
Having it like this, if some new unit ('unidade') is added or removed the
value is either absent or present, depending on the case, what is
undesirable. The user never sees what is on tha database at the exact moment
he "opens" the page.
I've tried this in my controller:
================================================================================
for field in formulario_conversao_unidades_de_medida.widgets['fields']:
if field.name in ['origem', 'destino']:
field.options = unidades()
================================================================================
But then I get an exception:
================================================================================
Traceback (most recent call last):
File "/usr/lib/python2.4/site-packages/CherryPy-2.2.0beta-py2.4.egg/cherrypy/_cphttptools.py", line 99, in _run
self.main()
File "/usr/lib/python2.4/site-packages/CherryPy-2.2.0beta-py2.4.egg/cherrypy/_cphttptools.py", line 247, in main
body = page_handler(*virtual_path, **self.params)
File "<string>", line 3, in index
File "/home/godoy/desenvolvimento/python/TurboGears/trunk/turbogears/controllers.py", line 212, in expose
tg_format, html, fragment, *args, **kw)
File "/home/godoy/desenvolvimento/python/TurboGears/trunk/turbogears/database.py", line 218, in run_with_transaction
retval = func(*args, **kw)
File "/home/godoy/desenvolvimento/python/TurboGears/trunk/turbogears/controllers.py", line 230, in _execute_func
output = errorhandling.try_call(func, *args, **kw)
File "/home/godoy/desenvolvimento/python/TurboGears/trunk/turbogears/errorhandling.py", line 62, in try_call
output = func(self, *args, **kw)
File "/home/godoy/empresa/clientes/latam/Site-Amostras/siteamostras/conversoes_unidades.py", line 48, in index
return self.conversoesunidades(conversao_unidade_id)
File "<string>", line 3, in conversoesunidades
File "/home/godoy/desenvolvimento/python/TurboGears/trunk/turbogears/controllers.py", line 207, in expose
output = _execute_func(func, tg_format, html, fragment,
File "/home/godoy/desenvolvimento/python/TurboGears/trunk/turbogears/controllers.py", line 230, in _execute_func
output = errorhandling.try_call(func, *args, **kw)
File "/home/godoy/desenvolvimento/python/TurboGears/trunk/turbogears/errorhandling.py", line 62, in try_call
output = func(self, *args, **kw)
File "<string>", line 3, in conversoesunidades
File "/home/godoy/desenvolvimento/python/TurboGears/trunk/turbogears/identity/conditions.py", line 232, in require
return fn(self, *args, **kwargs)
File "/home/godoy/empresa/clientes/latam/Site-Amostras/siteamostras/conversoes_unidades.py", line 62, in conversoesunidades
field.options = unidades()
File "/home/godoy/desenvolvimento/python/TurboGears/trunk/turbogears/widgets/base.py", line 281, in __setattr__
raise ValueError, \
ValueError: It is not threadsafe to modify widgets in a request
================================================================================
I've also tried this in my controller:
================================================================================
data = dict(options = dict(origem = unidades(), destino = unidades()))
================================================================================
while having
================================================================================
<span py:replace="formulario.display(data, action='%s/update/' % root_link, method = 'post')" />
================================================================================
in my template... But it didn't work either.
What is the correct way, in this case, to update my data so that it is
threadsafe and dynamic?
TIA,
--
Jorge Godoy <jgo...@gmail.com>
> I've tried this in my controller:
>
> ================================================================================
> for field in formulario_conversao_unidades_de_medida.widgets['fields']:
> if field.name in ['origem', 'destino']:
> field.options = unidades()
> ================================================================================
Using
================================================================================
formulario_conversao_unidades_de_medida.field_for('origem').options = unidades()
================================================================================
gives me the same exception on thread (un)safety.
--
Jorge Godoy <jgo...@gmail.com>
Oops! My bad here.
I have to pass it like 'unidades' instead of 'unidades()' for the options
value. If I pass the callable it works as expected.
Sorry to bother ;-)
--
Jorge Godoy <jgo...@gmail.com>
Hi Jorge,
can you try to change unidades() to be unidades, we want a callable not
what the function returns, that function will then be called every time
at display to update options dynamically.
Ciao
Michele
Great, just replied with the same correction.
> Sorry to bother ;-)
>
No problem at all! :-)
CIao
Michele