Formulator nice-to-have features

Josef Meile <[email protected]> Fri, 24 Nov 2006 15:44:07 +0100
Newsgroups gmane.comp.web.zope.formulator.devel
Message-ID <[email protected]>
Hi,

After having worked with Formulator, I needed some features that it
doesn't have that perhaps would be nice to include in the official
release.

1) i18n_domain for each field: Sometimes instead of using the default
form domain, it would be nice to use a different domain for a specific
field or perhaps a group. Let's say that you have a form to setup
different products. So, it could be that you use the same English word
in different contexts, but its translation into another language throws
two different translations.

2) group property for each field: this will avoid having to scan all
groups to figure out to which group a field belongs to.

3) Dynamically setting properties while rendering a form. I'm working in
a series of multi-language Products. In some of them I need a list of
countries in different languages. So, a way of coping with this problem
would be to allow to override the 'items' attribute without changing the
form like this:

<div tal:replace="structure 
python:country.render_from_request(request,items=Countries.COUNTRY_ITEMS[currentLang])"/>

Countries is a dictionary containing items like this:

{'en': [(u"Colombia", u"CO"),
         (u"Switzerland", u"CH"),
         (u"United States", u"US")],

  'de': [(u"Kolumbien", u"CO"),
         (u"Schweiz", u"CH"),
         (u"Vereinigte Staaten", u"US")
        ],
  'es': [(u"Colombia", u"CO"),
         (u"Estados Unidos", u"US"),
         (u"Suiza", u"CH")]
}

And this is how I solved it with a MonkeyPatch:
#ListWidget class
def renderListWidget(self, field, key, value, REQUEST, **kw):
     rendered_items = self.render_items(field, key, value, REQUEST, **kw)
     css_class = kw.get('css_class',field.get_value('css_class'))
     size = kw.get('size',field.get_value('size'))
     extra = kw.get('extra',field.get_value('extra'))

     return render_element('select',
                           name=key,
                           css_class=css_class,
                           size=size,
                           contents=string.join(rendered_items, "\n"),
                           extra=extra)
ListWidget.render = renderListWidget

There you can not only override the 'items' property, but also the other
attributes without changing the original form (ie: it can be that you
want to render a hidden field if certain condition is true, so, you may
pass 'hidden=0'). I did this for the whole formulator Fields and it
works nice.

***RELATED WISH***: Perhaps it would be also nice to allow the user to
specify a dictionary in the 'items' field of a ListField, like the one
in the example, to support multilanguage ListFields (Perhaps adding a
new Field type would be also OK).

* Allow to specify the width of a text input and a textarea in pixels.
(ie: 'pixels:20). Then, when rendering the field, use inline style-sheets:
   <input type="text" style="width:20px">

If the user enters just a number ie: '20' or 'chars:20', then it will be
rendered as the usual width attribute.

The problem with the normal "width" attribute is that it will be
different between browsers and operative systems. I know you could also
work directly with the "css_class" or "extra" field of formulator, but
for the normal user, with no idea of html, it would be nicer that
Formulator did this automatically for her/him.

* Allow to specify a default value for ListFields. Now you can only
specify an index, but what if you want to specify a value from the
list? I need this cause I'm dinamically generating a country list
according to the current locale. So, a country won't be exactly in the
same place between diferent languages, but it will have the same code
indeed.

Let's say that if you just introduced a number in 'Default', then it 
will be taken as now: as an index from the list. On the contrary, if he
enters: 'value:CO', then the entry corresponding to "CO" (Colombia in
'en' and 'es' and Kolumbien in 'de') will be marked as "selected".
Alternatively, you could introduce the same concept for indexes, ie:
'index:3' will select the fourth value of the ListField.


Best regards
Josef