def error_container(name, as_text=False): return HTML.tag('span', class_='error %s hidden' % ('fa fa-arrow-circle-down as-text' if as_text else 'fa fa-exclamation-circle'), c=HTML.tag('span'), **{'data-name': name})
def form(url, method="post", multipart=False, hidden_fields=None, **attrs): """An open tag for a form that will submit to ``url``. You must close the form yourself by calling ``end_form()`` or outputting </form>. Options: ``method`` The method to use when submitting the form, usually either "GET" or "POST". If "PUT", "DELETE", or another verb is used, a hidden input with name _method is added to simulate the verb over POST. ``multipart`` If set to True, the enctype is set to "multipart/form-data". You must set it to true when uploading files, or the browser will submit the filename rather than the file. ``hidden_fields`` Additional hidden fields to add to the beginning of the form. It may be a dict or an iterable of key-value tuples. This is implemented by calling the object's ``.items()`` method if it has one, or just iterating the object. (This will successfuly get multiple values for the same key in WebOb MultiDict objects.) Because input tags must be placed in a block tag rather than directly inside the form, all hidden fields will be put in a '<div style="display:none">'. The style prevents the <div> from being displayed or affecting the layout. Changed in WebHelpers 1.0b2: add <div> and ``hidden_fields`` arg. Changed in WebHelpers 1.2: don't add an "id" attribute to hidden tags generated by this helper; they clash if there are multiple forms on the page. """ fields = [] attrs["action"] = url if multipart: attrs["enctype"] = "multipart/form-data" if method.lower() in ['post', 'get']: attrs['method'] = method else: attrs['method'] = "post" field = hidden("_method", method, id=None) fields.append(field) if hidden_fields is not None: try: it = hidden_fields.items() except AttributeError: it = hidden_fields for name, value in it: field = hidden(name, value, id=None) fields.append(field) if fields: div = HTML.tag("div", style="display:none", _nl=True, *fields) else: div = None return HTML.tag("form", div, _closed=False, **attrs)
def error_container(name, as_text=False): return HTML.tag( 'span', class_='error %s hidden' % ('fa fa-arrow-circle-down as-text' if as_text else 'fa fa-exclamation-circle'), c=HTML.tag('span'), **{'data-name': name} )
def _list(tag, items, default, attrs, li_attrs): content = [HTML.tag("li", x, **li_attrs) for x in items] if content: content = [""] + content + [""] elif default is not None: return default content = literal("\n").join(content) return HTML.tag(tag, content, **attrs)
def contact_type_icon(contact_type): assert contact_type.key in (u'phone', u'email', u'skype'), \ u"wrong contact type" if contact_type.key == u'phone': return HTML.tag('span', class_='fa fa-phone') elif contact_type.key == u'email': return HTML.tag('span', class_='fa fa-envelope') else: return HTML.tag('span', class_='fa fa-skype')
def boolicon(value): """Returns boolean value of a value, represented as small html image of true/false icons :param value: value """ if value: return HTML.tag('i', class_="icon-ok") else: return HTML.tag('i', class_="icon-minus-circled")
def button(context, permision, caption, **kwargs): html = '' if context.has_permision(permision): caption = HTML.tag('span', c=caption) icon = '' if 'icon' in kwargs: icon = HTML.tag('span', class_=kwargs.pop('icon')) button_class = "button _action " + kwargs.pop('class', '') button_class = button_class.strip() html = HTML.tag( 'a', class_=button_class, c=HTML(icon, caption), **kwargs ) return html
def _render(self, options, selected_values): tags = [] for opt in options: if isinstance(opt, OptGroup): content = self._render(opt, selected_values) tag = HTML.tag("optgroup", NL, content, label=opt.label) tags.append(tag) else: value = opt.value if opt.value is not None else opt.label selected = value in selected_values tag = HTML.tag("option", opt.label, value=opt.value, selected=selected) tags.append(tag) return HTML(*tags, nl=True)
def button(context, permision, caption, **kwargs): html = '' if context.has_permision(permision): caption = HTML.tag('span', c=caption) icon = '' if 'icon' in kwargs: icon = HTML.tag('span', class_=kwargs.pop('icon')) button_class = "button _action " + kwargs.pop('class', '') button_class = button_class.strip() html = HTML.tag('a', class_=button_class, c=HTML(icon, caption), **kwargs) return html
def th_sortable(current_order, column_order, label, url, class_if_sort_column="sort", class_if_not_sort_column=None, link_attrs=None, name="th", **attrs): """<th> for a "click-to-sort-by" column. Convenience function for a sortable column. If this is the current sort column, just display the label and set the cell's class to ``class_if_sort_column``. ``current_order`` is the table's current sort order. ``column_order`` is the value pertaining to this column. In other words, if the two are equal, the table is currently sorted by this column. If this is the sort column, display the label and set the <th>'s class to ``class_if_sort_column``. If this is not the sort column, display an <a> hyperlink based on ``label``, ``url``, and ``link_attrs`` (a dict), and set the <th>'s class to ``class_if_not_sort_column``. ``url`` is the literal href= value for the link. Pylons users would typically pass something like ``url=h.url_for("mypage", sort="date")``. ``**attrs`` are additional attributes for the <th> tag. If you prefer a <td> tag instead of <th>, pass ``name="td"``. To change the sort order via client-side Javascript, pass ``url=None`` and the appropriate Javascript attributes in ``link_attrs``. Examples: >>> sort = "name" >>> th_sortable(sort, "name", "Name", "?sort=name") literal(u'<th class="sort">Name</th>') >>> th_sortable(sort, "date", "Date", "?sort=date") literal(u'<th><a href="?sort=date">Date</a></th>') >>> th_sortable(sort, "date", "Date", None, link_attrs={"onclick": "myfunc()"}) literal(u'<th><a onclick="myfunc()">Date</a></th>') """ from webhelpers2.html import HTML if current_order == column_order: content = label class_ = class_if_sort_column else: link_attrs = link_attrs or {} content = HTML.tag("a", label, href=url, **link_attrs) class_ = class_if_not_sort_column return HTML.tag("th", content, class_=class_, **attrs)
def test_tag(self): a = HTML.tag("a", href="http://www.yahoo.com", name=None, c="Click Here") b = literal('<a href="http://www.yahoo.com">Click Here</a>') self.check(a, b)
def _input(type, name, value, id, attrs): """Finish rendering an input tag.""" attrs["type"] = type attrs["name"] = name attrs["value"] = value _set_id_attr(attrs, id, name) return HTML.tag("input", **attrs)
def auto_discovery_link(url, feed_type="rss", **attrs): """Return a link tag allowing auto-detecting of RSS or ATOM feed. The auto-detection of feed for the current page is only for browsers and news readers that support it. ``url`` The URL of the feed. (This should be the exact URLs desired. A previous version of this helper added magic prefixes; this is no longer the case.) ``feed_type`` The type of feed. Specifying 'rss' or 'atom' automatically translates to a type of 'application/rss+xml' or 'application/atom+xml', respectively. Otherwise the type is used as specified. Defaults to 'rss'. """ if "href" in attrs: raise TypeError("keyword arg 'href' is not allowed") if "type" in attrs: raise TypeError("keyword arg 'type' is not allowed") title = "" if feed_type.lower() in ('rss', 'atom'): title = feed_type.upper() feed_type = 'application/{0}+xml'.format(feed_type.lower()) attrs.setdefault("title", title) return HTML.tag("link", rel="alternate", type=feed_type, href=url, **attrs)
def image(url, alt, width=None, height=None, **attrs): """Return an image tag for the specified ``source``. ``url`` The URL of the image. (This must be the exact URL desired. A previous version of this helper added magic prefixes; this is no longer the case.) ``alt`` The img's alt tag. Non-graphical browsers and screen readers will output this instead of the image. If the image is pure decoration and uninteresting to non-graphical users, pass "". To omit the alt tag completely, pass None. ``width`` The width of the image, default is not included. ``height`` The height of the image, default is not included. Note: This version does not support the 'path' and 'use_pil' arguments, because they depended on the WebHelpers 'media' subpackage which was dropped in WebHelpers 2. """ if "path" in attrs: raise TypeError("the 'path' arg is not supported in WebHelpers2") if "use_pil" in attrs: raise TypeError("the 'use_pil' arg is not supported in WebHelpers2") if not alt: alt = "" if width is not None or height is not None: attrs['width'] = width attrs['height'] = height return HTML.tag("img", src=url, alt=alt, **attrs)
def stylesheet_link(*urls, **attrs): """Return CSS link tags for the specified stylesheet URLs. ``urls`` should be the exact URLs desired. A previous version of this helper added magic prefixes; this is no longer the case. Examples:: >>> stylesheet_link('/stylesheets/style.css') literal(u'<link href="/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" />') >>> stylesheet_link('/stylesheets/dir/file.css', media='all') literal(u'<link href="/stylesheets/dir/file.css" media="all" rel="stylesheet" type="text/css" />') """ if "href" in attrs: raise TypeError("keyword arg 'href' not allowed") attrs.setdefault("rel", "stylesheet") attrs.setdefault("type", "text/css") attrs.setdefault("media", "screen") tags = [] for url in urls: tag = HTML.tag("link", href=url, **attrs) tags.append(tag) return literal('\n').join(tags)
def radio(name, value, checked=False, label=None, label_class=None, **attrs): """Create a radio button. Arguments: ``name`` -- the field's name. ``value`` -- the value returned to the application if the button is pressed. ``checked`` -- true if the button should be initially pressed. ``label`` -- a text label to display to the right of the button. This puts a <label> tag around the input tag. ``label_class`` -- CSS class for <label> tag. This should be a keyword argument because its position may change in a future version. The id of the radio button will be set to the name + '_' + value to ensure its uniqueness. An ``id`` keyword arg overrides this. (Note that this behavior is unique to the ``radio()`` helper.) To arrange multiple radio buttons in a group, see webhelpers2.containers.distribute(). """ if checked: attrs["checked"] = "checked" if not "id" in attrs: attrs["id"] = "{0}_{1}".format(name, _make_safe_id_component(value)) # Pass None as 'id' arg to '_input()' to prevent further modification of # the 'id' attribute. widget = _input("radio", name, value, None, attrs) if label: widget = HTML.tag("label", widget, " ", label, class_=label_class) return widget
def javascript_link(*urls, **attrs): """Return script include tags for the specified javascript URLs. ``urls`` should be the exact URLs desired. A previous version of this helper added magic prefixes; this is no longer the case. Specify the keyword argument ``defer=True`` to enable the script defer attribute. Examples:: >>> print javascript_link('/javascripts/prototype.js', '/other-javascripts/util.js') <script src="/javascripts/prototype.js" type="text/javascript"></script> <script src="/other-javascripts/util.js" type="text/javascript"></script> >>> print javascript_link('/app.js', '/test/test.1.js') <script src="/app.js" type="text/javascript"></script> <script src="/test/test.1.js" type="text/javascript"></script> """ tags = [] for url in urls: tag = HTML.tag("script", "", type="text/javascript", src=url, **attrs) tags.append(tag) return literal("\n").join(tags)
def begin_row(self): self.element.set_attr('id', '%s-%s' % (self.element.getidattr(), self.wrap_type)) class_str = '%s%s%s' % (self.wrap_type, self.alt_class(), self.first_class()) self.element.add_attr('class', class_str) # HTML.tag should not close the div attrs = self.element.get_attrs() attrs['_closed'] = False self.output.inc(HTML.tag('div', **attrs))
def th_sortable(current_order, column_order, label, url, class_if_sort_column="sort", class_if_not_sort_column=None, link_attrs=None, name="th", **attrs): """<th> for a "click-to-sort-by" column. Convenience function for a sortable column. If this is the current sort column, just display the label and set the cell's class to ``class_if_sort_column``. ``current_order`` is the table's current sort order. ``column_order`` is the value pertaining to this column. In other words, if the two are equal, the table is currently sorted by this column. If this is the sort column, display the label and set the <th>'s class to ``class_if_sort_column``. If this is not the sort column, display an <a> hyperlink based on ``label``, ``url``, and ``link_attrs`` (a dict), and set the <th>'s class to ``class_if_not_sort_column``. ``url`` is the literal href= value for the link. Pylons users would typically pass something like ``url=h.url_for("mypage", sort="date")``. ``**attrs`` are additional attributes for the <th> tag. If you prefer a <td> tag instead of <th>, pass ``name="td"``. To change the sort order via client-side Javascript, pass ``url=None`` and the appropriate Javascript attributes in ``link_attrs``. """ from webhelpers2.html import HTML if current_order == column_order: content = label class_ = class_if_sort_column else: link_attrs = link_attrs or {} content = HTML.tag("a", label, href=url, **link_attrs) class_ = class_if_not_sort_column return HTML.tag("th", content, class_=class_, **attrs)
def handle_match(matchobj): all = matchobj.group() before, prefix, link, after = matchobj.group(1, 2, 3, 4) if re.match(r'<a\s', before, re.I): return all text = literal(prefix + link) if prefix == "www.": prefix = "http://www." a_options = dict(href_attrs) a_options['href'] = literal(prefix + link) return literal(before) + HTML.tag("a", text, **a_options) + literal(after)
def textarea(name, content="", id=NotGiven, **attrs): """Create a text input area. Example:: >>> textarea("body", "", cols=25, rows=10) literal(u'<textarea cols="25" id="body" name="body" rows="10"></textarea>') """ attrs["name"] = name _set_id_attr(attrs, id, name) return HTML.tag("textarea", content, **attrs)
def link_to(label, url='', **attrs): """Create a hyperlink with the given text pointing to the URL. If the label is ``None`` or empty, the URL will be used as the label. This function does not modify the URL in any way. The label will be escaped if it contains HTML markup. To prevent escaping, wrap the label in a ``webhelpers2.html.literal()``. """ attrs['href'] = url if label == '' or label is None: label = url return HTML.tag("a", label, **attrs)
def _render_tool(self, tool): tmp = "container:'#%(id)s',action:'dialog_open',url:'%(url)s'" if tool.with_row: tmp += ",property:'with_row'" kwargs = { 'data-options': tmp % {'id': self._id, 'url': tool.url} } return HTML.tag( 'a', href='#', class_='fa %(icon)s easyui-tooltip _action' % {'icon': tool.icon}, title=tool.title, **kwargs )
def javascript_link(*urls, **attrs): """Return script include tags for the specified javascript URLs. ``urls`` should be the exact URLs desired. A previous version of this helper added magic prefixes; this is no longer the case. Specify the keyword argument ``defer=True`` to enable the script defer attribute. """ tags = [] for url in urls: tag = HTML.tag("script", "", type="text/javascript", src=url, **attrs) tags.append(tag) return literal("\n").join(tags)
def js_obfuscate(content): """Obfuscate data in a Javascript tag. Example:: >>> js_obfuscate("<input type='hidden' name='check' value='valid' />") literal(u'<script type="text/javascript">\\n//<![CDATA[\\neval(unescape(\\'%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%69%6e%70%75%74%20%74%79%70%65%3d%27%68%69%64%64%65%6e%27%20%6e%61%6d%65%3d%27%63%68%65%63%6b%27%20%76%61%6c%75%65%3d%27%76%61%6c%69%64%27%20%2f%3e%27%29%3b\\'))\\n//]]>\\n</script>') """ doc_write = "document.write('%s');" % content obfuscated = ''.join(['%%%x' % ord(x) for x in doc_write]) complete = "eval(unescape('%s'))" % obfuscated cdata = HTML.cdata("\n", complete, "\n//") return HTML.tag("script", "\n//", cdata, "\n", type="text/javascript")
def js_obfuscate(content): """Obfuscate data in a Javascript tag. Example:: >>> js_obfuscate("<input type='hidden' name='check' value='valid' />") literal(u'<script type="text/javascript">\\n//<![CDATA[\\neval(unescape(\\'%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%69%6e%70%75%74%20%74%79%70%65%3d%27%68%69%64%64%65%6e%27%20%6e%61%6d%65%3d%27%63%68%65%63%6b%27%20%76%61%6c%75%65%3d%27%76%61%6c%69%64%27%20%2f%3e%27%29%3b\\'))\\n//]]>\\n</script>') """ doc_write = "document.write(%s);" % js_quote_string(content) obfuscated = ''.join(['%%%x' % ord(x) for x in doc_write]) complete = "eval(unescape('%s'))" % obfuscated cdata = HTML.cdata("\n", complete, "\n//") return HTML.tag("script", "\n//", cdata, "\n", type="text/javascript")
def stylesheet_link(*urls, **attrs): """Return CSS link tags for the specified stylesheet URLs. ``urls`` should be the exact URLs desired. A previous version of this helper added magic prefixes; this is no longer the case. """ if "href" in attrs: raise TypeError("keyword arg 'href' not allowed") attrs.setdefault("rel", "stylesheet") attrs.setdefault("type", "text/css") attrs.setdefault("media", "screen") tags = [] for url in urls: tag = HTML.tag("link", href=url, **attrs) tags.append(tag) return literal('\n').join(tags)
def content_tag(name, content, **options): """ Create a tag with content Takes the same keyword args as ``tag`` Examples:: >>> print(content_tag("p", "Hello world!")) <p>Hello world!</p> >>> print(content_tag("div", content_tag("p", "Hello world!"), class_="strong")) <div class="strong"><p>Hello world!</p></div> """ if content is None: content = '' tag = HTML.tag(name, _closed=False, **options) + HTML(content) + literal('</%s>' % name) return tag
def _render_toolbar(self): permisions = self._resource.get_permisions( self._resource, self._request ) if not permisions: return toolbar = [ self._render_tool(tool) for tool in self._tools if tool.name in permisions ] if toolbar: toolbar = HTML.tag( 'span', class_='combogrid-toolbar', id=gen_id(), c=HTML(*toolbar) ) return toolbar
def content_tag(name, content, **options): """ Create a tag with content Takes the same keyword args as ``tag`` Examples:: >>> print(content_tag("p", "Hello world!")) <p>Hello world!</p> >>> print(content_tag("div", content_tag("p", "Hello world!"), class_="strong")) <div class="strong"><p>Hello world!</p></div> """ if content is None: content = '' tag = HTML.tag(name, _closed=False, **options) + HTML(content) + literal( '</%s>' % name) return tag
def checkbox(name, value="1", checked=False, label=None, label_class=None, id=NotGiven, **attrs): """Create a check box. Arguments: ``name`` -- the widget's name. ``value`` -- the value to return to the application if the box is checked. ``checked`` -- true if the box should be initially checked. ``label`` -- a text label to display to the right of the box. This puts a <label> tag around the input tag. ``label_class`` -- CSS class for <label> tag. This should be a keyword argument because its position may change in a future version. ``id`` is the HTML ID attribute, and should be passed as a keyword argument. By default the ID is the same as the name filtered through ``_make_safe_id_component()``. Pass None to suppress the ID attribute entirely. The following HTML attributes may be set by keyword argument: * ``disabled`` - If true, checkbox will be grayed out. * ``readonly`` - If true, the user will not be able to modify the checkbox. To arrange multiple checkboxes in a group, see webhelpers2.containers.distribute(). Example:: >>> checkbox("hi") literal(u'<input id="hi" name="hi" type="checkbox" value="1" />') """ if checked: attrs["checked"] = "checked" widget = _input("checkbox", name, value, id, attrs) if label: widget = HTML.tag("label", widget, " ", label, class_=label_class) return widget
def checkbox(name, value="1", checked=False, label=None, label_class=None, id=NotGiven, **attrs): """Create a check box. Arguments: ``name`` -- the widget's name. ``value`` -- the value to return to the application if the box is checked. ``checked`` -- true if the box should be initially checked. ``label`` -- a text label to display to the right of the box. This puts a <label> tag around the input tag. ``label_class`` -- CSS class for <label> tag. This should be a keyword argument because its position may change in a future version. ``id`` is the HTML ID attribute, and should be passed as a keyword argument. By default the ID is the same as the name filtered through ``_make_safe_id_component()``. Pass None to suppress the ID attribute entirely. The following HTML attributes may be set by keyword argument: * ``disabled`` - If true, checkbox will be grayed out. * ``readonly`` - If true, the user will not be able to modify the checkbox. To arrange multiple checkboxes in a group, see webhelpers2.containers.distribute(). """ if checked: attrs["checked"] = "checked" widget = _input("checkbox", name, value, id, attrs) if label: widget = HTML.tag("label", widget, " ", label, class_=label_class) return widget
def text_to_html(text, preserve_lines=False): """Convert text to HTML paragraphs. ``text``: the text to convert. Split into paragraphs at blank lines (i.e., wherever two or more consecutive newlines appear), and wrap each paragraph in a <p>. ``preserve_lines``: If true, add <br /> before each single line break """ if text is None: return literal("") text = lit_sub(_universal_newline_rx, "\n", text) paragraphs = _paragraph_rx.split(text) for i, para in enumerate(paragraphs): if preserve_lines: para = HTML(para) para = para.replace("\n", br) paragraphs[i] = HTML.tag("p", para) return literal("\n\n").join(paragraphs)
def select(name, selected_values, options, id=NotGiven, **attrs): """Create a dropdown selection box. Arguments: * **name**: the name of this control. * **selected_values**: the value(s) that should be preselected. A string or list of strings. Some other types are allowed; see the ``Options.render`` method for details. * **options**: an ``Options`` instance, or an iterable to pass to the its constructor. See the ``Options`` class for allowed element types. * **id**: the HTML ID attribute. This should be a keyword argument if passed. By default the ID is the same as the name. filtered through ``_make_safe_id_component()``. Pass None to suppress the ID attribute entirely. The following options may only be keyword arguments: * **multiple**: if true, this control will allow multiple selections. * **prompt**: An extra option that will be prepended to the list. The argument is the option label; e.g., "Please choose ...". The generated option's value will be the empty string (""), which is equivalent to not making a selection. If you specify this and also pass an ``Options`` instance in ``options``, it will combine the two into a new ``Options`` object rather than reusing the existing one. Any other keyword args will become HTML attributes for the <select>. """ _set_id_attr(attrs, id, name) attrs["name"] = name prompt = attrs.pop("prompt", None) if prompt or not isinstance(options, Options): options = Options(options, prompt=prompt) return HTML.tag("select", NL, options.render(selected_values), **attrs)
def generate_header_link(self, column_number, column, label_text): """ This handles generation of link and then decides to call self.default_header_ordered_column_format or self.default_header_column_format based on if current column is the one that is used for sorting or not """ # implementation START # # this will handle possible URL generation # dummy get object, assume options is currently selected # normally this will be something like request.GET.mixed() GET_copy = {"order_col": "options", "order_dir": "asc"} self.order_column = GET_copy.pop("order_col", None) self.order_dir = GET_copy.pop("order_dir", None) if column == self.order_column and self.order_dir == "asc": new_order_dir = "dsc" else: new_order_dir = "asc" GET_copy["order_col"] = column GET_copy["order_dir"] = new_order_dir href = self.url_generator("https://google.com", **GET_copy) label_text = HTML.tag("a", href=href, c=label_text) # implementation END # if column == self.order_column: return self.default_header_ordered_column_format( column_number, column, label_text ) else: return self.default_header_column_format( column_number, column, label_text )
def tag(name, open=False, **options): """ Returns an XHTML compliant tag of type ``name``. ``open`` Set to True if the tag should remain open All additional keyword args become attribute/value's for the tag. To pass in Python reserved words, append _ to the name of the key. For attributes with no value (such as disabled and readonly), a value of True is permitted. Examples:: >>> print(tag("br")) <br /> >>> print(tag("br", True)) <br> >>> print(tag("input", type="text")) <input type="text" /> >>> print(tag("input", type='text', disabled='disabled')) <input disabled="disabled" type="text" /> """ return HTML.tag(name, _closed=not open, **options)
def __html__(self): if not self.condition: return HTML(self.label) return HTML.tag("a", self.label, href=self.url, **self.attrs)
def select(name, selected_values, options, id=NotGiven, **attrs): """Create a dropdown selection box. * ``name`` -- the name of this control. * ``selected_values`` -- a string or list of strings or integers giving the value(s) that should be preselected. * ``options`` -- an ``Options`` object or iterable of ``(value, label)`` pairs. The label will be shown on the form; the option will be returned to the application if that option is chosen. If you pass a string or int instead of a 2-tuple, it will be used for both the value and the label. If the `value` is a tuple or a list, it will be added as an optgroup, with `label` as label. ``id`` is the HTML ID attribute, and should be passed as a keyword argument. By default the ID is the same as the name. filtered through ``_make_safe_id_component()``. Pass None to suppress the ID attribute entirely. CAUTION: the old rails helper ``options_for_select`` had the label first. The order was reversed because most real-life collections have the value first, including dicts of the form ``{value: label}``. For those dicts you can simply pass ``D.items()`` as this argument. HINT: You can sort options alphabetically by label via: ``sorted(my_options, key=lambda x: x[1])`` The following options may only be keyword arguments: * ``multiple`` -- if true, this control will allow multiple selections. * ``prompt`` -- if specified, an extra option will be prepended to the list: ("", ``prompt``). This is intended for those "Please choose ..." pseudo-options. Its value is "", equivalent to not making a selection. Any other keyword args will become HTML attributes for the <select>. """ _set_id_attr(attrs, id, name) attrs["name"] = name if selected_values is None: selected_values = [""] elif isinstance(selected_values, six.string_types) or not hasattr(selected_values,'__iter__'): selected_values = [selected_values] # Cast integer values to strings selected_values = set(map(six.text_type, selected_values)) # Prepend the prompt prompt = attrs.pop("prompt", None) if prompt: options = [Option("", prompt)] + list(options) # Canonicalize the options and make the HTML options. if not isinstance(options, Options): options = Options(options) html_options = [] # Create the options structure def gen_opt(val, label): val = six.text_type(val) if val in selected_values: return HTML.tag("option", label, value=val, selected="selected") else: return HTML.tag("option", label, value=val) # Loop options and create tree (if optgroups presents) for opt in options: if isinstance(opt, OptGroup): optgroup_options = [] for subopt in opt.options: optgroup_options.append(gen_opt(subopt.value, subopt.label)) optgroup = HTML.tag("optgroup", NL, NL.join(optgroup_options), NL, label=opt.label) html_options.append(optgroup) else: html_options.append(gen_opt(opt.value, opt.label)) return HTML.tag("select", NL, NL.join(html_options), NL, **attrs)
def gen_opt(val, label): val = six.text_type(val) if val in selected_values: return HTML.tag("option", label, value=val, selected="selected") else: return HTML.tag("option", label, value=val)
def select(name, selected_values, options, id=NotGiven, **attrs): """Create a dropdown selection box. * ``name`` -- the name of this control. * ``selected_values`` -- a string or list of strings or integers giving the value(s) that should be preselected. * ``options`` -- an ``Options`` object or iterable of ``(value, label)`` pairs. The label will be shown on the form; the option will be returned to the application if that option is chosen. If you pass a string or int instead of a 2-tuple, it will be used for both the value and the label. If the `value` is a tuple or a list, it will be added as an optgroup, with `label` as label. ``id`` is the HTML ID attribute, and should be passed as a keyword argument. By default the ID is the same as the name. filtered through ``_make_safe_id_component()``. Pass None to suppress the ID attribute entirely. CAUTION: the old rails helper ``options_for_select`` had the label first. The order was reversed because most real-life collections have the value first, including dicts of the form ``{value: label}``. For those dicts you can simply pass ``D.items()`` as this argument. HINT: You can sort options alphabetically by label via: ``sorted(my_options, key=lambda x: x[1])`` The following options may only be keyword arguments: * ``multiple`` -- if true, this control will allow multiple selections. * ``prompt`` -- if specified, an extra option will be prepended to the list: ("", ``prompt``). This is intended for those "Please choose ..." pseudo-options. Its value is "", equivalent to not making a selection. Any other keyword args will become HTML attributes for the <select>. Examples (call, result):: >>> select("currency", "$", [["$", "Dollar"], ["DKK", "Kroner"]]) literal(u'<select id="currency" name="currency">\\n<option selected="selected" value="$">Dollar</option>\\n<option value="DKK">Kroner</option>\\n</select>') >>> select("cc", "MasterCard", [ "VISA", "MasterCard" ], id="cc", class_="blue") literal(u'<select class="blue" id="cc" name="cc">\\n<option value="VISA">VISA</option>\\n<option selected="selected" value="MasterCard">MasterCard</option>\\n</select>') >>> select("cc", ["VISA", "Discover"], [ "VISA", "MasterCard", "Discover" ]) literal(u'<select id="cc" name="cc">\\n<option selected="selected" value="VISA">VISA</option>\\n<option value="MasterCard">MasterCard</option>\\n<option selected="selected" value="Discover">Discover</option>\\n</select>') >>> select("currency", None, [["$", "Dollar"], ["DKK", "Kroner"]], prompt="Please choose ...") literal(u'<select id="currency" name="currency">\\n<option selected="selected" value="">Please choose ...</option>\\n<option value="$">Dollar</option>\\n<option value="DKK">Kroner</option>\\n</select>') >>> select("privacy", 3L, [(1, "Private"), (2, "Semi-public"), (3, "Public")]) literal(u'<select id="privacy" name="privacy">\\n<option value="1">Private</option>\\n<option value="2">Semi-public</option>\\n<option selected="selected" value="3">Public</option>\\n</select>') >>> select("recipients", None, [([("u1", "User1"), ("u2", "User2")], "Users"), ([("g1", "Group1"), ("g2", "Group2")], "Groups")]) literal(u'<select id="recipients" name="recipients">\\n<optgroup label="Users">\\n<option value="u1">User1</option>\\n<option value="u2">User2</option>\\n</optgroup>\\n<optgroup label="Groups">\\n<option value="g1">Group1</option>\\n<option value="g2">Group2</option>\\n</optgroup>\\n</select>') """ _set_id_attr(attrs, id, name) attrs["name"] = name # Accept None as selected_values meaning that no option is selected if selected_values is None: selected_values = ('',) # Turn a single string or integer into a list elif isinstance(selected_values, (six.string_types, six.integer_types)): selected_values = (selected_values,) # Cast integer values to strings selected_values = set(map(six.text_type, selected_values)) # Prepend the prompt prompt = attrs.pop("prompt", None) if prompt: options = [Option("", prompt)] + list(options) # Canonicalize the options and make the HTML options. if not isinstance(options, Options): options = Options(options) html_options = [] # Create the options structure def gen_opt(val, label): if val in selected_values: return HTML.tag("option", label, value=val, selected="selected") else: return HTML.tag("option", label, value=val) # Loop options and create tree (if optgroups presents) for opt in options: if isinstance(opt, OptGroup): optgroup_options = [] for subopt in opt.options: optgroup_options.append(gen_opt(subopt.value, subopt.label)) optgroup = HTML.tag("optgroup", NL, NL.join(optgroup_options), NL, label=opt.label) html_options.append(optgroup) else: html_options.append(gen_opt(opt.value, opt.label)) return HTML.tag("select", NL, NL.join(html_options), NL, **attrs)
def gen_opt(val, label): if val in selected_values: return HTML.tag("option", label, value=val, selected="selected") else: return HTML.tag("option", label, value=val)
def __html__(self): if not (self.content or self.render_if_empty): return HTML.EMPTY return HTML.tag(self.name, _nl=self.nl, *self.content, **self.attrs)
def render(self, **kwargs): self.set_attrs(**kwargs) displayval = self.displayval if self.displayval or self.displayval == 0 else None return HTML.tag(self.level, displayval, **self.attributes)
def textarea(name, content="", id=NotGiven, **attrs): """Create a text input area. """ attrs["name"] = name _set_id_attr(attrs, id, name) return HTML.tag("textarea", content, **attrs)