I'm developing a form, that includes a SingleSelectField. Depending on
the value entered in that field, different supplemental questions are
asked. To do this I've created the HidingSingleSelectField widget. If
you're interested, I've created a sample app that does this
http://pajhome.org.uk/hssf.tar.gz
Can this be added to the standard widgets? I think other people would
find this useful.
Some work would be required to make it releasable. Currently it works
purely in javascript, using HTML IDs to determine which areas to hide.
This means you have to define the form long-hand in the template. If we
can find some way to express this relationship between widgets, the
default forms could be used.
So, anyone who's interested in this, please get in touch!
Paul
TG 1.0 is currently in a feature freeze so I guess the answer would
be no...
However, you could build a skeleton widget egg by running
tg-admin quickstart -twidget HidingSingleSelectField
and distrubute the widget as stand-alone component we could download
and install when needed.
The setup.py that tg-admin will generate includes metadata so the
CogBin (http://www.turbogears.org/cogbin)
can find it once you register it at PyPI.
>
> Some work would be required to make it releasable. Currently it works
> purely in javascript, using HTML IDs to determine which areas to hide.
hmmm, maybe it would be easier and more portable to find the areas
you want to hide using javascript only instead of needing to modify
the template that should render the widget.
For example:
from turbojson import jsonify
from turbogears.widgets import *
class HiddingSelectField(SingleSelectField):
#hide targets is a list (or dict) of targets that should be
hidden indexed
# by the option in the selectfield. If using jQuery you could
reference
# contactType_1 in your example easily using XPath:
#
# For your example you would pass:
# ["input[@name=company]/../../", "input
[@name=nickname]/../../"]
# so option 0 hides the tr enclosing company and 1 the one
enclosing nickname
params = ["hide_targets"]
hide_targets = []
javascript = [hssf_js]
def update_params(self, d):
super(....)
# JSON encode it to pass them as parameters to the JS
constructor
d['hide_targets'] = jsonify.encode(d['hide_targets'] )
Then customize the SSF's template to initialize a JS object that will
take care of hiding the divs:
<div xmlns:py="http://purl.org/kid/ns#">
<select
name="${name}"
class="${field_class}"
id="${field_id}"
py:attrs="attrs"
>
<optgroup py:for="group, options in grouped_options"
label="${group}"
py:strip="not group"
>
<option py:for="value, desc, attrs in options"
value="${value}"
py:attrs="attrs"
py:content="desc"
/>
</optgroup>
</select>
<script type="text/javascript">
InitializeHSSF("${field_id}", ${hide_targets})
</script>
</div>
InitializeHSSF should take care of connecting an event handler to the
select's 'change' event (referenced by it's id) that checks what
option was selected, use it as a key to look up the target in the
targets array/hash, reference it and show/hide/toggle it (could be a
3 liners in jQuery ;)
BTW, in ToscaWidgets you could build that <script></script> as a
JSSource inside __init__ (because the effective DOM id can be known
at this time) and put it in the widget's javascript list so you don't
need to modify the template...
What's particulary attractive of this soultion is that once the
select field is debugged and packed, it can be included in any form
and can reference any element we want by just passing it parameters
from python (the js-python impedance-mismatch soother)
> This means you have to define the form long-hand in the template.
> If we
> can find some way to express this relationship between widgets, the
> default forms could be used.
Hmm, I'm not sure you want to relate other widget's but DOM element's
instead.... else you'll have to make a widget out of a <tr> which
would be overkill IMO...
HTH,
Alberto