#---- 8< ----- myproj/myproj/forms/base.py ----- """ Base classes for forms """ from formencode.schema import Schema class FilteringSchema(Schema): """ Schema that gets around the of toscawidgets in tg1 having self passed as a field. """ # TODO: Get rid of this when we upgrade to tg2 filter_extra_fields = True allow_extra_fields = True #----- 8< ------- myproj/myproj/forms/site.py """ Tosca widgets form for a CMS Site """ from toscawidgets.api import WidgetsList, CSSSource, JSSource from toscawidgets.widgets.forms import TableForm, TextField, HiddenField from toscawidgets.widgets.forms.validators import UnicodeString, Int from toscawidgets.js import js_function from cms.forms.base import FilteringSchema # Lil' chunk o' CSS for tasty eye-candy ;) # External css files can be wrapped with CSSLink css = CSSSource(""" label.required, .fielderror { font-weight: bold; color: red; }; """) # We define the source for some JS functions we're going to interface # External js files can be wrapped with JSLink functions = JSSource(""" var focus_element = function (elem) { var elem = document.getElementById(elem); elem.focus(); elem.select(); }; """, ) alert = js_function('alert') focus_element = js_function('focus_element') class SiteForm(TableForm): class fields(WidgetsList): clientId = HiddenField(validator=Int()) siteId = HiddenField(validator=Int()) newSite = HiddenField() url = TextField(validator=UnicodeString(not_empty=True)) title = TextField(validator=UnicodeString(not_empty=True)) notes = TextField(validator=UnicodeString()) validator = FilteringSchema() # allow adding js calls dynamically for a request include_dynamic_js_calls = True css = [css] javascript = [functions] def update_params(self, d): super(SiteForm, self).update_params(d) # Focus and select the 'title' field on the form # The adapter we just wrote lets us pass formfields as parameters and # the right thing will be done. if not d.error: self.add_call(focus_element(d.c.title)) else: self.add_call( alert('The form contains invalid data\n%s'% unicode(d.error))) #--------- 8< -------- Somewhere in your controllers from cms.forms.site import SiteForm class SuperController(controllers.Controller): siteForm = SiteForm(); @expose(template="cms.templates.editSite") @require(in_group("manager")) def editSite(self, clientId=None, siteId=None, url=None, title=None, notes=None, newSite=None, tg_errors=None, tg_exceptions=None, tg_source=None): """ Shows a form for editing the info of a site """ # We are just showing the edit form if not siteId: return { 'newSite': True, 'client': Client.query.get(clientId), 'form': self.siteForm, } else: return { 'newSite': False, 'site': Site.query.get_by(id=siteId), 'form': self.siteForm, } @error_handler(editSite) @validate(siteForm) @expose() def saveSite(self, siteId=None, url=None, title=None, notes=None, newSite=None, clientId=None): """ Where the site form posts to """ if newSite: # Make a new site client = Client.query.get(clientId) site = Site(client=client, url=url, title=title, notes=notes) else: # Editing an existing site site = Site.query.get(siteId) if clientId != site.client.id: site.client = Client.query.get(clientId) site.url = url site.title = title site.notes = notes site.save() session.commit() return self.showSite(site=site) ---------8< ------- in the template (I'm using genshi)
${form.display( action="saveSite", value=dict( newSite=newSite, siteId=site.id, siteTitle=site.title, siteURL=site.url, siteNotes=site.notes, ), )}
${form.display( action="saveSite", value=dict( newSite=newSite, clientId=client.id, ), )}