Closed johnrtipton closed 1 year ago
Did you try tag="q-table"
To define an html table, you will still need to create an Element (class), and define the basic template (based on Vue templates).
As I said in another comment, you will need to create your own Nicegui element, to get the standard HTML table.
I'm enjoying creating elements for Nicegui, so I decided to create this one too.
Below is the code I sent to PR #442.
html_table.py
from nicegui.element import Element
from nicegui.dependencies import register_component
register_component("html_table", __file__, "html_table.js")
def parser_style(table):
m_style = ["<style>"]
for key in table._style.keys():
m_style.append(key + " {" + table._style[key] + "}")
m_style.append("</style>")
return "\n".join(m_style)
def parser_columns(table):
m_thead = ["<thead><tr>"]
for col in table._columns:
m_thead.append(f"<th>{col}</th>")
m_thead.append("</tr></thead>")
return "\n".join(m_thead)
def parser_rows(table):
m_tbody = ["<tbody>"]
for row in table._rows:
m_data = ["<tr>"]
for col in row.keys():
m_data.append(f"<td>{row[col]}</td>")
m_data.append("</tr>")
m_tbody.append("\n".join(m_data))
m_tbody.append("</tbody>")
return "\n".join(m_tbody)
class HTMLTable(Element):
def __init__(self, columns=[], rows=[], style={}):,
"""HTML Table
"""
super().__init__("html_table")
self._columns = columns
self._rows = rows
self._style = style
self.sync_config()
def sync_config(self):
data = f"{parser_columns(self)} {parser_rows(self)} {parser_style(self)}"
self._props["table_config"] = data
self.update()
html_table.js
export default {
template: '<table v-html="this.table_config"></table>',
props: {
table_config: String,
},
};
exemple.py
from nicegui.ui import run
from html_table import HTMLTable
cols = ["Name", "Age", "Sex", "Height", "Weight"]
rows = [
{"name": "John", "age": 30, "sex": "Male", "height": 180, "weight": 80},
{"name": "Jane", "age": 25, "sex": "Female", "height": 160, "weight": 60},
]
style = {
"table": "border-collapse: collapse; margin: 25px 0; font-size: 0.9em; font-family: sans-serif;",
"tr": "background-color: #5898d4; color: #ffffff; text-align: left; border-bottom: 1px solid #dddddd;",
"th, td": "padding: 12px 15px;",
}
table = HTMLTable(columns=cols, rows=rows, style=style)
run()
@Diegiwg thanks very much for the quick response. This looks interesting, but I was thinking of being able to create a table and with my own rows and cells to allow more freedom to fully customize the table. Like adding my own components within the table. There are times when we need more control, instead of feeding it json to build it out dynamically.
I've been using JustPy and have build my own customized tables to meet my needs there.
Based on your example above, it looks like I was missing the:
register_component("html_table", __file__, "html_table.js")
In principle, the idea of deriving from Element
and calling super().__init__
with the tag name "table" is correct. You shouldn't need to implement a custom component for this.
However, we have a naming issue, here: Our AG Grid component, which is currently named ui.table
, registers a component we the tag name "table". So when you try to create a plain HTML table, you end up using an AG Grid accidentally.
You can try removing the register_component
line in table.py
. Then you can create a table as follows:
with ui.element('table'):
with ui.element('tr'):
with ui.element('td'):
ui.label('Name')
with ui.element('td'):
ui.label('Age')
Of course, this is no permanent solution. Changing the naming from ui.table
to ui.aggrid
(#370) might help, but will not be completed in near future since we need to deprecate ui.table
slowly. Maybe we can undo the register_component
for the specific case where you need an HTML table...
But there is a simple solution. Using ui.html
you can add arbitrary HTML code:
ui.html('''
<table>
<tr>
<td>Name</td>
<td>Age</td>
</tr>
</table>
''')
Note that the table will be wrapped into a div tag. Apart from that, it might be what you're looking for.
Two more workarounds:
Remove the table
component:
from nicegui.dependencies import js_components
del js_components['table']
with ui.element('table'):
...
Note that the normal ui.table
won't work anymore.
Display a div as a table:
with ui.element('div').style('display: table'):
...
Thanks @falkoschindler I will try this:
del js_components['table']
Thanks for the help, I was able to generate a very basic table using the following:
from nicegui.dependencies import js_components
from nicegui.elements.mixins.text_element import TextElement
from nicegui import ui
from nicegui.element import Element
del js_components['table']
class Table(Element):
def __init__(self) -> None:
super().__init__('table')
class Thead(Element):
def __init__(self) -> None:
super().__init__('thead')
class Tr(Element):
def __init__(self) -> None:
super().__init__('tr')
class Th(TextElement):
def __init__(self, text: str = '') -> None:
super().__init__(tag='th', text=text)
class Tbody(Element):
def __init__(self) -> None:
super().__init__('tbody')
class Td(TextElement):
def __init__(self, text: str = '') -> None:
super().__init__(tag='td', text=text)
with Table() as table:
with Thead():
with Tr():
Th('col 1')
Th('col 2')
with Tbody():
with Tr():
Td('val 1')
Td('val 2')
ui.run()
Great! I'll close this issue, since we found multiple workaround for the unfortunate naming conflict between ui.table
and the HTML <table>
.
In version 1.1.10 we will rename ui.table
into ui.aggrid
and deprecate the use of ui.table
. This resolves the conflict with <table>
and makes room for a new ui.table
based on Quasar's QTable (#370). There won't be a conflict, since Quasar uses the tag <q-table>
.
I see there has been some discussion about qtable and AgGrid. I would also like to have the ability to create a simple html table.
When I try this it refuses to name the tag
table
:But this just generates this:
I can name it
tabl
, but nottable
it seems something is preventing this.