*sigh* Things have been very disruptive for me outside of work for the past few days. I have a feature to cleanup and two more devcasts to do that will make some of these things clearer. I'll see what I can clarify below and we'll see if the direction I was heading works for you.
On 12/16/05, Dan Jacob <[EMAIL PROTECTED]> wrote: > > I've been following the discussions about form handling and widgets > lately and I think it would be fantastic if we get this aspect of > TurboGears working right. At present it is very awkward to handle forms > and widgets are difficult to use and extend. I also think if we get > this aspect of TG right we will be well on the way to a Rails-and > -Django beating framework (feature for feature). I agree that this is a very critical feature, and I think that the framework that's there is a good part of the way to where it needs to be... not 100%. (more to follow) > Here's my Christmas list: > > 1. An error_handler argument to @turbogears.expose. This would simplify > code like this: > > @turbogears.expose(html="templates.form") > def add(self): > return dict(form=article_form()) > > @turbogears.expose(inputform=article_form()) > def create(self, title, maintext, categoryID, **kw): > if cherrypy.request.form_errors:return self.add > # rest of function:add an article and redirect > > to this: > > @turbogears.expose(html="templates.form") > def add(self): > return dict(form=article_form()) > > @turbogears.expose(inputform=article_form(), error_handler=add) > # go straight to adding an article and redirect, no need to check > for errors I opened a ticket that does this slightly differently. We could revise the ticket to match what you're saying here, and I think all will be well. http://trac.turbogears.org/turbogears/ticket/219 My suggestion was this: @turbogears.expose(validators=[...]) def mymethod(self, **kw): handle the good case def mymethod_error(self, errors, **kw): handle the bad case with an optional error_handler argument: def tackle_errors(self, errors, **kw): handle the bad case @turbogears.expose(validators=[...], error_handler=self.tackle_errors) def mymethod(self, **kw): handle the good case If we get rid of the "errors" parameter, this will look much like your suggestion. I added the errors parameter to make it more convenient to get at the errors if you want. The problem that some error handling situations will have is the "edit" case: @expose... def edit(self, myinstance): ...do things... @expose... def save_edits(self, myinstance, var1, var2, var3): ...do things... save_edits and edit don't have the same method signature so you can't arbitrarily call edit again as an "error_handler". The *nice* thing about just looking at cherrypy.request.form_errors is that it's very simple, you've got access to all of the parameters and you can do whatever you need to do. @expose... def save_edits(self, myinstance, var1, var2, var3): if cherrypy.request.form_errors: return self.edit(myinstance) > 2. Functions to access cherrypy.request.form_errors and input_values to > save on typing, for example: > > errors = turbogears.get_errors() > turbogears.set_defaults(article.toDict()) I made a minor change to form handling a few days back that fixes input_values usage. TableForm now works like other widgets: you pass it a value at insert time. That value can be an instance or a dictionary. So, if you're adding a new record you just pass in None and the form's defaults take hold. If you're editing, you just pass in an appropriate instance or dictionary. > 3. An "attributes" argument for widgets, for example: > > TextField("name", default="Ok", attrs={'size':50, 'maxlength'100'}) > -> also for compound widgets if needed: > > f = TableForm(attrs={'enctype':'multipart/form-data'}, > widget_attrs={'name', {'size':50}}) I'm sold on this. > 4. A "schema" argument for Form widgets, so you can pass in a > FormEncode schema Are you envisioning that you'd define a schema and then the widgets are chosen based on that? Or are you thinking you'd hand in a schema just for validation? What would be the advantage to using a schema for validation rather than having a validator on each widget as it works now? > 5. Multiple submit buttons for Forms This should be easy. Assuming you can set the form's "official" submit button to None, you can hand the form as many submit button widgets as you want. The submit button values will get passed through (which is what you'd want if you have multiple). > 6. Select and radio/checkbox group widgets which select/check values > automatically Yep. That's a necessity. > 7. Select and radio/checkbox group widgets populated automatically by > passing in a SQLObject SelectResult Interesting. What would these widgets do with the selectresult? > 8. Extended SQLObject class which populates results from form request > values. When you define a subclass you provide a __public__ list like > so: > > class Article(TG_SQLObject): > __public__=["title", "maintext", "categoryID"] > title = StringCol(length=200) > ....other fields > In your controller: > > @turbogears.expose(..) > def create(self, **kw): > Article.autoCreate(author=identity.user) > > @turbogears.expose(..) > def update(self, id, **kw): > a = Article.get(id) > a.autoUpdate(updated=datetime.now()) > > In both cases, the attributes "title", "maintext" and "categoryID" are > automatically set if found in the cherrypy.request.paramMap, and > additional fields are then passed in as arguments. This is **sort of** > like Add/UpdateManipulators in Django. While working on the partially finished CRUD stuff, I found this to be quite easy to do without adding anything to the model. I'd better try to get that together so I can show what I mean. > 9. A PSP and world peace :-) World peace, sadly, isn't going to make it into TurboGears 1.0. We'll keep trying for 2.0 :) You'll have to check with Santa on the PSP. Kevin -- Kevin Dangoor Author of the Zesty News RSS newsreader email: [EMAIL PROTECTED] company: http://www.BlazingThings.com blog: http://www.BlueSkyOnMars.com

