[3] | 1 | """ |
---|
| 2 | Form Options Helpers |
---|
| 3 | """ |
---|
| 4 | # Last synced with Rails copy at Revision 4331 on Aug 19th, 2006. |
---|
| 5 | # Purposely left out a few redundant options_for_collection stuff. |
---|
| 6 | |
---|
| 7 | |
---|
| 8 | from webhelpers.util import html_escape |
---|
| 9 | |
---|
| 10 | def options_for_select(container, selected = None): |
---|
| 11 | """ |
---|
| 12 | Creates select options from a container (list, tuple, dict) |
---|
| 13 | |
---|
| 14 | Accepts a container (list, tuple, dict) and returns a string of option tags. Given a container where the |
---|
| 15 | elements respond to first and last (such as a two-element array), the "lasts" serve as option values and |
---|
| 16 | the "firsts" as option text. Dicts are turned into this form automatically, so the keys become "firsts" and values |
---|
| 17 | become lasts. If ``selected`` is specified, the matching "last" or element will get the selected option-tag. |
---|
| 18 | ``Selected`` may also be an array of values to be selected when using a multiple select. |
---|
| 19 | |
---|
| 20 | Examples (call, result):: |
---|
| 21 | |
---|
| 22 | >>> options_for_select([["Dollar", "$"], ["Kroner", "DKK"]]) |
---|
| 23 | <option value="$">Dollar</option>\\n<option value="DKK">Kroner</option> |
---|
| 24 | >>> options_for_select([ "VISA", "MasterCard" ], "MasterCard") |
---|
| 25 | <option value="VISA">VISA</option>\\n<option value="MasterCard" selected="selected">MasterCard</option> |
---|
| 26 | >>> options_for_select(dict(Basic="$20", Plus="$40"), "$40") |
---|
| 27 | <option value="$20">Basic</option>\\n<option value="$40" selected="selected">Plus</option> |
---|
| 28 | >>> options_for_select([ "VISA", "MasterCard", "Discover" ], ["VISA", "Discover"]) |
---|
| 29 | <option value="VISA" selected="selected">VISA</option>\\n<option value="MasterCard">MasterCard</option>\\n |
---|
| 30 | <option value="Discover" selected="selected">Discover</option> |
---|
| 31 | |
---|
| 32 | Note: Only the option tags are returned, you have to wrap this call in a regular HTML select tag. |
---|
| 33 | """ |
---|
| 34 | if hasattr(container, 'values'): |
---|
| 35 | container = container.items() |
---|
| 36 | |
---|
| 37 | if not isinstance(selected, (list,tuple)): |
---|
| 38 | selected = (selected,) |
---|
| 39 | |
---|
| 40 | options = [] |
---|
| 41 | |
---|
| 42 | for elem in container: |
---|
| 43 | if isinstance(elem, (list, tuple)): |
---|
| 44 | name, value = elem |
---|
| 45 | n = html_escape(name) |
---|
| 46 | v = html_escape(value) |
---|
| 47 | else : |
---|
| 48 | name = value = elem |
---|
| 49 | n = v = html_escape(elem) |
---|
| 50 | |
---|
| 51 | #TODO: run timeit for this against content_tag('option', n, value=v, selected=value in selected) |
---|
| 52 | if value in selected: |
---|
| 53 | options.append('<option value="%s" selected="selected">%s</option>' % (v, n)) |
---|
| 54 | else : |
---|
| 55 | options.append('<option value="%s">%s</option>' % (v, n)) |
---|
| 56 | return "\n".join(options) |
---|
| 57 | |
---|
| 58 | def options_for_select_from_objects(container, name_attr, value_attr = None, selected = None): |
---|
| 59 | """ |
---|
| 60 | Create select options from objects in a container |
---|
| 61 | |
---|
| 62 | Returns a string of option tags that have been compiled by iterating over the ``container`` and assigning the |
---|
| 63 | the result of a call to the ``value_attr`` as the option value and the ``name_attr`` as the option text. |
---|
| 64 | If ``selected`` is specified, the element returning a match on ``value_attr`` will get the selected option tag. |
---|
| 65 | |
---|
| 66 | NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag. |
---|
| 67 | """ |
---|
| 68 | if value_attr: |
---|
| 69 | def make_elem(elem): |
---|
| 70 | return getattr(elem, name_attr), getattr(elem, value_attr) |
---|
| 71 | else : |
---|
| 72 | def make_elem(elem): |
---|
| 73 | return getattr(elem, name_attr) |
---|
| 74 | |
---|
| 75 | return options_for_select([make_elem(x) for x in container], selected) |
---|
| 76 | |
---|
| 77 | def options_for_select_from_dicts(container, name_key, value_key = None, selected = None): |
---|
| 78 | """ |
---|
| 79 | Create select options from dicts in a container |
---|
| 80 | |
---|
| 81 | Returns a string of option tags that have been compiled by iterating over the ``container`` and assigning the |
---|
| 82 | the result of a call to the ``value_key`` as the option value and the ``name_attr`` as the option text. |
---|
| 83 | If ``selected`` is specified, the element returning a match on ``value_key`` will get the selected option tag. |
---|
| 84 | |
---|
| 85 | NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag. |
---|
| 86 | """ |
---|
| 87 | if value_key: |
---|
| 88 | def make_elem(elem): |
---|
| 89 | return elem[name_key], elem[value_key] |
---|
| 90 | else : |
---|
| 91 | def make_elem(elem): |
---|
| 92 | return elem[name_key] |
---|
| 93 | |
---|
| 94 | return options_for_select([make_elem(x) for x in container], selected) |
---|
| 95 | |
---|
| 96 | __all__ = ['options_for_select', 'options_for_select_from_objects', 'options_for_select_from_dicts'] |
---|