Alberto Valverde wrote:
> On Sep 7, 2006, at 8:00 PM, [EMAIL PROTECTED] wrote:
>
> >
> > Hello,
> > I've been trying to come up with a small widget which takes another
> > widget and uses it as a template for a javascript to clone when a user
> > clicks a link. The practical effect is to allow a form to have a group
> > of fields for which the user can create as many values as he wishes.
> > Unfortunatly I haven't been able to cook up the correct group of code,
> > js, template and validator to implement it. Right now i'm stumped with
> > no way to tell the RepeatingFormField superclass of the widget how
> > many
> > repetitions already exist, so for now I just 'imagine' 1. But when we
> > try and validate the form, FormEncode throws up  the following error:
>
> You can tell it the number of repetitions to render the same way you
> pass any other widget parameter listed at "params". The Widget's
> docstring explains it better.
My problem with the repetitions number was because that number is the
number of values already submitted for the form. So should I create a
callable to pass into the widget which snoops into the request , finds
the values, and changes the repetitions?

>
> >
> >   File
> > "c:\python24\lib\site-packages\FormEncode-0.5.1-py2.4.egg\formencode
> > \schema.py",
> > line 116, in _to_python
> >     for name, value in value_dict.items():
> > AttributeError: 'list' object has no attribute 'items'
> >
> > The widget is a subclass of RepeatingFormField, and the code is :
> >
> > class AjaxRepeating(RepeatingFormField):
> >     member_widgets = ["widget"]
> >     params = ["id","linklabel" ]
> >
> >     template = "ajaxrepeating.templates.ajaxrepeating"
> >     counter = itertools.count()
> >     repetitions = 0
> >
> >     def __init__(self, widget, id="ajaxcompound", *args, **kw):
> >         # Call super cooperatively so our params
> >         # get bound to the widget instance
> >         kw.setdefault('linklabel',"new")
> >         super(AjaxRepeating, self).__init__(*args, **kw)
> >         self.id = "%s_%d" % (id, self.counter.next())
> >         self.widget = widget
> >         self.fields = [widget]
> >         self.repetitions = 1
> >         self.javascript = [
> >              JSLink("ajaxrepeating","ajaxrepeating.js"),
> >              JSSource("""
> >                            %(id)s_AjaxRepeating = new
> > AjaxRepeating('%(id)s');
> >                            """ % dict(id = self.id),
> >                            location = js_location.bodytop),
> >              CSSSource(""".invisible { display: none; }""")]
> >
> > The template is inspired on the one used to demo the repeatingfields,
> > and is the following:
> >
> > <div xmlns:py="http://purl.org/kid/ns#";>
> >   <div>
> >     <a href="#" onclick="javascript:${id}_AjaxRepeating.addNew();
> > return false;">
> >       ${linklabel}
> >     </a>
> >   </div>
> >   <div class="invisible" id="${id}_AjaxRepeating_template">
> >     ${widget.display(' ')}
> >   </div>
> >   <div py:for="repetition in repetitions"
> >        id="${id}_AjaxRepeating_rep_${repetition}">
> >     <label class="fieldlabel" for="${widget.field_id}"
> >           py:content="widget.label" />
> >     <span py:content="widget.display(value_for(widget),
> > **params_for(widget))" />
> >     <span py:if="error_for(widget)" class="fielderror"
> >           py:content="error_for(widget)" />
> >     <span py:if="widget.help_text" class="fieldhelp"
> >           py:content="widget.help_text" />
> >   </div>
> >
> >   <div id="${id}_AjaxRepeating_container">
> >   </div>
> > </div>
> >
> > The javascript picks up the whole div with the template, clones it,
> > changes the id and slips the new element on the container div.
> > Can anyone with more knowledge of widgets help me out here? Perhaps
> > I'm
> > overlooking something on the RepeatingFormField...
>
> I can't really tell right now from looking at that code....
>
> the traceback says that a schema is complaining because it finds a
> list where it expects a dict so probably your validator is broken or
> it's not being processed properly by the metaclass.
I believe it's the second.

>
> Maybe if you post your validator code we can help you better.
I've reduced the form to this:

class AjaxRepeaterForm:
    class Fields(widgets.WidgetsList):
        customFieldsRepeater = AjaxRepeating(label = "",
                                             widget =
widgets.TextField('customFields'),
                                             linklabel=_('add new
custom field'))


    class Schema(validators.Schema):
        class customFieldsRepeater(validators.Schema):
            customFields =
validators.All(validators.ForEach(validators.UnicodeString(strip =
True))
                                          )
        customFieldsRepeater = customFieldsRepeater()

    form = widgets.TableForm(fields = Fields(),
                             name = 'ajax_repeater_form',
                             form_attrs = {'class':'form'},
                             table_attrs = {'id':'ajax-repeater-form'},
                             validator = Schema())

I think the problem is that the RepeatingForm displays a widget, and
then repeats that widget client side.
Can you give a few pointers as to where should I search for the root of
the problem?
Many thanks!

Bruno

> 
> Alberto


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"TurboGears" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/turbogears
-~----------~----~----~----~------~----~------~--~---

Reply via email to