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'] |
---|