Create widgets using ToUI ========================= **Note**: make sure to have some background in object-oriented programming (classes), otherwise this example might be confusing. When creating an app, sometimes you find that you need to duplicate some HTML code in various places. This is sometimes inconvenient, but one of the solutions is to create a "widget". A "widget" here means a shortcut for a group of HTML elements. For example, we can create a widget for a table: .. code-block:: python from toui import Element class TableWidget: def __init__(self): # Create an `Element` object inside the widget self.element = Element() self.element.from_str( """
Column A Column B
1 12
21 22
""" ) When you create an instance of `TableWidget`, a string containing the table HTML element is stored in `TableWidget.element`. However, the purpose of creating a widget is not only to store some HTML code, but to make it easier to edit the HTML code. For example, if we want to frequently update the data inside the table, we can create a new method inside `TableWidget`: .. code-block:: python from toui import Element class TableWidget: def __init__(self): # Create an `Element` object inside the widget self.element = Element() self.element.from_str( """
""" ) def from_list(self, table_list): """Update the data inside the table using a Python list""" self.element.set_content("") headers = table_list[0] headers_element = Element("tr") for header in headers: headers_element.add_content(f"{header}") self.element.add_content(headers_element) for row in table_list[1:]: row_element = Element("tr") for value in row: row_element.add_content(f"{value}") self.element.add_content(row_element) The method `from_list` will take the data from a Python list and insert it into the table. This is convenient because you do not need to write the Python code that will insert data to the table everytime since you can just call the method `from_list`. The preferred method of creating a widget is to create a class and create an attribute inside it called `element`. The attribute `element` is an object of the `Element` class. Another method is to create a class that inherits the `Element` class: .. code-block:: python class TableWidget2(Element): def __init__(self): # The widget itself is an instance of `Element` class. super().__init__() self.from_str( """
""" ) def from_list(self, table_list): self.set_content("") headers = table_list[0] headers_element = Element("tr") for header in headers: headers_element.add_content(f"{header}") self.add_content(headers_element) for row in table_list[1:]: row_element = Element("tr") for value in row: row_element.add_content(f"{value}") self.add_content(row_element) However, in the second approach, you might find some difficulty in creating a widget from an already existent HTML code. For example, if a `` element already exists in the HTML document and you want to convert it to a widget, the second approach might not be helpful. Below is a complete example that creates widgets. The example uses the HTML file "test9.html": .. code-block:: html Document

Table 1

Table 2

The example Python code: .. code-block:: python import sys sys.path.append("..") from toui import Element, Page, Website class TableWidget: def __init__(self): # Create an `Element` object inside the widget self.element = Element() self.element.from_str( """
""" ) def from_list(self, table_list): self.element.set_content("") headers = table_list[0] headers_element = Element("tr") for header in headers: headers_element.add_content(f"{header}") self.element.add_content(headers_element) for row in table_list[1:]: row_element = Element("tr") for value in row: row_element.add_content(f"{value}") self.element.add_content(row_element) class TableWidget2(Element): def __init__(self): # The widget itself is an instance of `Element` class. super().__init__() self.from_str( """
""" ) def from_list(self, table_list): self.set_content("") headers = table_list[0] headers_element = Element("tr") for header in headers: headers_element.add_content(f"{header}") self.add_content(headers_element) for row in table_list[1:]: row_element = Element("tr") for value in row: row_element.add_content(f"{value}") self.add_content(row_element) # Create an app app = Website(name=__name__, assets_folder="assets", secret_key="some long string") # Create a page pg = Page("assets/test9.html", url="/") # Create a function that adds a table to the page def add_table1(): pg = app.get_user_page() # Create a table widget table_widget = TableWidget() # Add data to the table widget using `from_list` method table_widget.from_list([ ["Column A", "Column B"], ["1", "2"], ["3", "4"] ]) pg.get_element("table-1").set_content(table_widget.element) # Create a function that adds another type of table to the page def add_table2(): pg = app.get_user_page() # Create a table widget table_widget = TableWidget2() # Add data to the table widget using `from_list` method table_widget.from_list([ ["Column A", "Column B"], ["1", "2"], ["3", "4"] ]) pg.get_element("table-2").set_content(table_widget) # Call a function when the button `add-table-1` is clicked pg.get_element("add-table-1").onclick(add_table1) # Call a function when the button `add-table-2` is clicked pg.get_element("add-table-2").onclick(add_table2) # Add the page to the app app.add_pages(pg) # Run if __name__ == "__main__": app.run(debug=True)