Source code for swole.widgets.base

from dominate.tags import div, label


[docs]class Widget(): """ Base class for all Widgets. Attributes: jquery_fn (str): The name of the JQuery function to use to get the value of the widget from the HTML page. Defaults to `text`. cls (list of str): List of CSS classes to apply to this widget. """ _id = 0 # Counter for the next Widget ID _declared = [] # List of all declared Widget def __init__(self, cls=None): """ Arguments: cls (str or list of str, optional): Class(es) to add to the Widget. Can be a single class (`str`) or several classes (`list of str`). If `None` is given, no additional class is added. Defaults to `None`. """ Widget._id += 1 Widget._declared.append(self) self.id = Widget._id self.jquery_fn = "text" if cls is None: self.cls = [] elif isinstance(cls, str): self.cls = [cls] elif isinstance(cls, list): self.cls = [c for c in set(cls) if isinstance(c, str)] else: raise ValueError("The given CLS class should be a string or a list of string")
[docs] def add_css_class(self, attr): """ Utils method to add the class attribute in the given dictionary. This dictionary can then be used in `dominate`. Arguments: attr (dict): The attributes dictionary to be used in `dominate` tag class. """ if len(self.cls) != 0: attr["cls"] = " ".join(self.cls)
[docs] def html(self): """ Method to get the `dominate` HTML of the widget. This HTML needs to be rendered. .. Note:: This method should be overwritten. Returns: dominate.document: HTML document corresponding to the widget. """ raise NotImplementedError()
[docs] def ajax(self): """ Method to get the Ajax request (if any) of the widget. Or `None` if there is no Ajax call for this widget. Returns: Ajax: Ajax request. `None` if there is no Ajax request. """ return None
[docs] def get(self): """ Method to get the current value of the widget. .. Note:: This method should be overwritten. Returns: object: Current value of the widget. """ raise NotImplementedError()
[docs] def get_str(self): """ Method to get the current value of the widget, as a string. Returns: str: Current value of the widget. """ return str(self.get())
[docs] def set(self, x): """ Method to set the current value of the widget. .. Note:: This method should be overwritten. Arguments: x (str): Value of the widget to set. """ raise NotImplementedError()
[docs]class WideWidget(Widget): """ Class for Widgets that can be wide. """ def __init__(self, wide=False, *args, **kwargs): """ Arguments: wide (bool, optional): If set to `True`, the widget will take all the available width. Defaults to `False`. """ super().__init__(*args, **kwargs) if wide: self.cls.insert(0, 'u-full-width')
def labeled(cls): """ Class decorator for Widget that can be labeled. This decorator simply define a sub-class of the given class, and change the constructor and the html method to add a label. """ class LabeledWidget(cls): def __init__(self, label=None, *args, **kwargs): super().__init__(*args, **kwargs) self.label = label def html(self): if self.label is None: return super().html() else: d = div() with d: label(self.label, _for=self.id) super().html() return d # Give right meta-information to the class LabeledWidget.__name__ = cls.__name__ LabeledWidget.__module__ = cls.__module__ LabeledWidget.__doc__ = cls.__doc__ LabeledWidget.__init__.__doc__ = cls.__init__.__doc__ + " label (`str`): Label to give to the Widget." return LabeledWidget