Querying fields before merge
Sometimes it can be really nice (read: improve the user experience) to be able to query some fields without merging the value from the form back into an object. An example is when a user changes a input select field in a form which has an attached value. In an app we have, a user has a select list of product numbers. We make the app update the product's name on the page when the product changes.
Note that we are treading on thin ice here: if the user has not entered a valid value for the field, when get_value tries to convert it to the appropriate type, it will raise an exception that will need to be dealt with. It is (generally) safe to reference values from a TextField or a SelectField though.
1 class ProductFieldsetForm(FieldsetForm):
2
3 products_menu = product_factory.all_products_menu()
4
5 def __init__(self, product):
6 self.product_id = product.product_id
7 elements = (
8 Fieldset((
9 SelectField('Product code', self.products_menu, 'product_id',
10 html_attrs={'onchange': 'javascript:product_form.submit()'}),
11 StaticField('Product', product.name),
12 )),
13 )
14 FieldsetForm.__init__(self, 'Product selection', elements)
15
16 self.load(product)
17
18 def update(self):
19 product_code_field = self.get_field('Product code')
20 if self.product_id != product_code_field.get_value():
21 self.product_id = product_code_field.get_value()
22 product = product_factory.product_with_product_id(self.product_id)
23 product_field = self.get_field('Product')
24 product_field.set_value(product.name)
The interesting part here is where we query the form for a specific field using its get_field method.
We use the little bit of Javascript to make a change to the select list force an update to the page. That means having to name the form when we render the page:
In the app itself, we use: