0001"""FormBuild - Helpful tools to generate HTML forms, designed to complement FormEncode
0002
0003(C) James Gardner 2005 MIT Licence see FormBuild.__copyright__"""
0004
0005__docformat__ = "restructuredtext"
0006from formbuild.form import Form
0007__copyright__ = """
0008Copyright (c) 2005 James Gardner <python@jimmyg.org>
0009
0010All rights reserved.
0011
0012Redistribution and use in source and binary forms, with or without
0013modification, are permitted provided that the following conditions
0014are met:
00151. Redistributions of source code must retain the above copyright
0016   notice, this list of conditions and the following disclaimer.
00172. Redistributions in binary form must reproduce the above copyright
0018   notice, this list of conditions and the following disclaimer in the
0019   documentation and/or other materials provided with the distribution.
00203. The name of the author or contributors may not be used to endorse or
0021   promote products derived from this software without specific prior
0022   written permission.
0023
0024THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
0025ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0026IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0027ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
0028FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0029DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
0030OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0031HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
0032LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
0033OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0034SUCH DAMAGE.
0035"""
0036
0037def handle(schema, template, form=None, data=None, params=None, context=None, render_response=None, fragment=False):
0038    if data == None:
0039        data = {}
0040    else:
0041        if not isinstance(data, dict):
0042            raise TypeError('Expected data to be a dictionary')
0043            #~ values = {}
0044            #~ for k in data.c.keys():
0045                #~ values[k] = getattr(data, k)
0046            #~ data = values
0047    import formencode
0048    if params == None:
0049        from pylons import request
0050        params = {}
0051        for k in request.params.keys():
0052            v = request.params.getall(k)
0053            if len(v) == 1:
0054                params[k] = v[0]
0055            else:
0056                params[k] = v
0057    if context == None:
0058        from pylons import c as context
0059    if not form:
0060        form = Form
0061    if not render_response:
0062        from pylons.templating import render_response
0063    c = context
0064    errors = {}
0065    data.update(params)
0066    results=data
0067    if len(params):
0068        try:
0069            results = schema.to_python(results, state=c)
0070        except formencode.Invalid, e:
0071            errors = e.error_dict or {}
0072    c.form = form(results, errors)
0073    if not len(params) or errors:
0074        return results, errors, render_response(template, fragment=fragment)
0075    return results, errors, ''
0076
0077"""
0078
0079    # Some new thoughts for a better handle()
0080
0081    import formbuild
0082    import formencode
0083
0084    # in a controller
0085       
0086        
0087        def email_form(self):
0088
0089
0090            if len(request.params):
0091                try:
0092                    results = schema.to_python(results, state=c)
0093                except formencode.Invalid, e:
0094                    errors = e.error_dict or {}
0095                    results = e.values
0096                    c.form = form(dict(request.params), errors)
0097                    return submitted, results, errors, render_response(template, fragment=fragment)
0098                else:
0099                    c.form = form(results, {})
0100                    return results, {}, None
0101            else:
0102                return {}, {}, render_response(template, fragment=fragment)
0103
0104
0105
0106 
0107        class ProcessedForm:
0108            def __init__(self, defaults={}, submitted={}, results={}, response={}, errors={}):
0109                self.submitted=submitted
0110                self.defaults=defaults
0111                self.results = results
0112                self.response = response
0113                self.errors = errors
0114                self.valid = False
0115                if not self.response:
0116                    self.valid = True
0117        
0118        def pylons_render_form(template, form, **options):
0119            fragment = options.get('fragment', False)
0120            from pylons.templating import render_response
0121            from pylons import c
0122            c.form = form
0123            return render_response(template, fragment=fragment)
0124            
0125            
0126        def handle(schema, template, form=None, defaults={}, submitted={}, render_from=pylons_render_form, render_options={}):
0127            defaults.update(submitted)
0128"""