| 1619 | # helpers and subsidiary classes |
| 1620 | |
| 1621 | class Item: |
| 1622 | def __init__(self, control, attrs, index=None): |
| 1623 | label = _get_label(attrs) |
| 1624 | self.__dict__.update({ |
| 1625 | "name": attrs["value"], |
| 1626 | "_labels": label and [label] or [], |
| 1627 | "attrs": attrs, |
| 1628 | "_control": control, |
| 1629 | "disabled": "disabled" in attrs, |
| 1630 | "_selected": False, |
| 1631 | "id": attrs.get("id"), |
| 1632 | "_index": index, |
| 1633 | }) |
| 1634 | control.items.append(self) |
| 1635 | |
| 1636 | def get_labels(self): |
| 1637 | """Return all labels (Label instances) for this item. |
| 1638 | |
| 1639 | For items that represent radio buttons or checkboxes, if the item was |
| 1640 | surrounded by a <label> tag, that will be the first label; all other |
| 1641 | labels, connected by 'for' and 'id', are in the order that appear in |
| 1642 | the HTML. |
| 1643 | |
| 1644 | For items that represent select options, if the option had a label |
| 1645 | attribute, that will be the first label. If the option has contents |
| 1646 | (text within the option tags) and it is not the same as the label |
| 1647 | attribute (if any), that will be a label. There is nothing in the |
| 1648 | spec to my knowledge that makes an option with an id unable to be the |
| 1649 | target of a label's for attribute, so those are included, if any, for |
| 1650 | the sake of consistency and completeness. |
| 1651 | |
| 1652 | """ |
| 1653 | res = [] |
| 1654 | res.extend(self._labels) |
| 1655 | if self.id: |
| 1656 | res.extend(self._control._form._id_to_labels.get(self.id, ())) |
| 1657 | return res |
| 1658 | |
| 1659 | def __getattr__(self, name): |
| 1660 | if name=="selected": |
| 1661 | return self._selected |
| 1662 | raise AttributeError(name) |
| 1663 | |
| 1664 | def __setattr__(self, name, value): |
| 1665 | if name == "selected": |
| 1666 | self._control._set_selected_state(self, value) |
| 1667 | elif name == "disabled": |
| 1668 | self.__dict__["disabled"] = bool(value) |
| 1669 | else: |
| 1670 | raise AttributeError(name) |
| 1671 | |
| 1672 | def __str__(self): |
| 1673 | res = self.name |
| 1674 | if self.selected: |
| 1675 | res = "*" + res |
| 1676 | if self.disabled: |
| 1677 | res = "(%s)" % res |
| 1678 | return res |