class Input(VoidElement): """An HTML <input> element. >>> input_ = Input("text", "description") >>> input_.size = 20 >>> input_.placeholder = "Enter description..." For most input types, a specific sub-class is provided. """ def __init__(self, type_="text", name=""): """Create an HTML input element. The type_ argument sets the HTML type attribute. Possible values are 'text', 'email', 'password', 'submit', etc. For most of these types, a more specific sub-class is provided. The optional name argument sets this input element's name, used when submitting a form. """ super().__init__("input") self.type = type_ self.name = name name = html_attribute("name", default="") value = html_attribute("value", default="") readonly = boolean_html_attribute("readonly") disabled = boolean_html_attribute("disabled") type = html_attribute("type") autocomplete = html_attribute("autocomplete") placeholder = html_attribute("placeholder") size = int_html_attribute("size") focus = boolean_html_attribute("autofocus")
class _CheckableInput(Input): def __init__(self, type_, name, value): super(_CheckableInput, self).__init__(type_, name) if value: self.value = value checked = boolean_html_attribute("checked")
class TextArea(Element): """An HTML <textarea> element. >>> area = TextArea("element-name") >>> area.placeholder = "Placeholder text ..." >>> area.append("Initial text area content.") """ def __init__(self, name=""): super(TextArea, self).__init__("textarea") self.name = name name = html_attribute("name", default="") readonly = boolean_html_attribute("readonly") disabled = boolean_html_attribute("disabled") columns = int_html_attribute("cols") rows = int_html_attribute("rows") placeholder = html_attribute("placeholder")
class Option(Element): """An HTML selection list option (<option>) element. >>> option = Option("Label") >>> str(option) '<option>Label</option>' >>> option = Option("Label", "test-value") >>> str(option) '<option value="test-value">Label</option>' """ def __init__(self, label, value=None): super(Option, self).__init__("option") self.value = value self.append(label) disabled = boolean_html_attribute("disabled") selected = boolean_html_attribute("selected") @property def value(self): """Return the value of this option. >>> option = Option("Label", "value") >>> option.value 'value' If no explicit value is given, return the children as string. >>> option = Option("Label") >>> option.value 'Label' """ return self.get_attribute("value", str(self.children)) @value.setter def value(self, value): if value is None: self.remove_attribute("value") else: self.set_attribute("value", value)
class Button(Element): """An HTML <button> element. >>> button = Button("My Label") """ def __init__(self, *content): super(Button, self).__init__("button") self.extend(content) disabled = boolean_html_attribute("disabled")
class OptionGroup(Element): """An HTML selection list option group (<optgroup>) element.""" def __init__(self, label): super(OptionGroup, self).__init__("optgroup") self.label = label label = html_attribute("label") disabled = boolean_html_attribute("disabled") def create_option(self, label, value=None): """Create and append an option.""" option = Option(label, value) self.append(option) return option
class Select(Element): """An HTML selection list (<select>) element. >>> select = Select("element-name") >>> option1 = select.create_option("Option 1", "v1") >>> option2 = select.create_option("Option 2", "v2", selected=True) >>> option2 is select.selected_option True >>> option2.value == select.selected_value True >>> select.selected_value = "v1" >>> option1 is select.selected_option True It is also possible to use option groups: >>> select = Select() >>> group = select.create_group("Group 1") >>> option1 = group.create_option("Option 1") >>> option2 = group.create_option("Option 2") At the moment, multiple selection lists are not supported. """ def __init__(self, name=""): super().__init__("select") self.name = name name = html_attribute("name", default="") disabled = boolean_html_attribute("disabled") autocomplete = html_attribute("autocomplete") def create_group(self, label): """Create and append an option group.""" group = OptionGroup(label) self.append(group) return group def create_option(self, label, value=None, selected=False): """Create and append an option.""" option = Option(label, value) self.append(option) if selected: self.selected_option = option return option @property def _options_iter(self): for child in self.children.children: if is_element(child, "option"): yield child elif is_element(child, "optgroup"): for sub_child in child.children.children: if is_element(sub_child, "option"): yield sub_child @property def selected_option(self): """Return the first selected option object. If no option is selected, return None. """ for child in self._options_iter: if child.selected: return child return None @selected_option.setter def selected_option(self, option): """Set the selected option object. All other selected options will be deselected. """ for child in self._options_iter: child.selected = False option.selected = True @property def selected_value(self): """Return the value of the first selected option. If no option is selected, return None. """ option = self.selected_option return option.value if option else None @selected_value.setter def selected_value(self, selected_value): """Set the selected option by its value. If no option has the supplied value, raise a ValueError. """ for option in self._options_iter: if option.value == selected_value: self.selected_option = option break else: raise ValueError( "no option with value '{}' found".format(selected_value))
class MyElement(Element): attr = boolean_html_attribute("data-attr")