AG Grid (or table) with edit, update and delete buttons #1833
Replies: 3 comments 12 replies
-
Thanks for sharing, @Dronakurl! I managed to reduce it to this: data = [
{"name": "Alice", "age": 18},
{"name": "Bob", "age": 21},
{"name": "Carol", "age": 42},
]
def update_data_from_table_change(e):
data[e.args["rowIndex"]] = e.args["data"]
table = ui.aggrid({
"columnDefs": [
{"field": "name", "editable": True, "sortable": True},
{"field": "age", "editable": True},
],
"rowData": data,
"rowSelection": "multiple",
"stopEditingWhenCellsLoseFocus": True,
}).on("cellValueChanged", update_data_from_table_change)
async def delete_selected():
selected_rows = await table.get_selected_rows()
data[:] = [row for row in data if row not in selected_rows]
table.update()
def new_row():
data.append({"name": "New default name", "age": None})
table.update()
ui.button("Delete selected", on_click=delete_selected)
ui.button("New row", on_click=new_row)
ui.label().bind_text_from(globals(), "data", lambda data: f"Current data: {data}") In your code it looks like you're mixing ID and index of selected rows. I simply compare complete row dictionaries instead. This causes duplicates to be removed even if only one of them was selected. But I guess without a unique field there's no way to know for sure which of them was selected. |
Beta Was this translation helpful? Give feedback.
-
Now, here comes a version with ui.table. It's longer, but does not need this ID hack. from nicegui import events, ui
columns = [
{"name": "name", "label": "Name", "field": "name", "align": "left"},
{"name": "age", "label": "Age", "field": "age"},
]
rows = [
{"id": 0, "name": "Alice", "age": 18},
{"id": 1, "name": "Bob", "age": 21},
{"id": 2, "name": "Carol", "age": 20},
]
def rename(e: events.GenericEventArguments) -> None:
for row in rows:
if row["id"] == e.args["id"]:
row.update(e.args)
ui.notify(f"Table.rows is now: {table.rows}")
def delete(e: events.GenericEventArguments) -> None:
rows[:] = [row for row in rows if row["id"] != e.args["id"]]
ui.notify(f"Delete {e.args['id']}")
table.update()
def addrow() -> None:
newid = max(dx["id"] for dx in rows) + 1
rows.append({"id": newid, "name": "New guy", "age": 21})
ui.notify(f"Added new row with id {newid}")
table.update()
table = ui.table(columns=columns, rows=rows, row_key="name").classes("w-72")
table.add_slot(
"header",
r"""
<q-tr :props="props">
<q-th auto-width />
<q-th v-for="col in props.cols" :key="col.name" :props="props">
{{ col.label }}
</q-th>
</q-tr>
""",
)
table.add_slot(
"body",
r"""
<q-tr :props="props">
<q-td auto-width >
<q-btn size="sm" color="warning" round dense icon="delete" :props="props"
@click="() => $parent.$emit('delete', props.row)" >
</q-td>
<q-td key="name" :props="props">
{{ props.row.name }}
<q-popup-edit v-model="props.row.name" v-slot="scope"
@update:model-value="() => $parent.$emit('rename', props.row)" >
<q-input v-model="scope.value" dense autofocus counter @keyup.enter="scope.set" />
</q-popup-edit>
</q-td>
<q-td key="age" :props="props" class="w-8">
{{ props.row.age }}
<q-popup-edit v-model="props.row.age" v-slot="scope"
@update:model-value="() => $parent.$emit('rename', props.row)" >
<q-input v-model.number="scope.value" type="number" dense autofocus counter @keyup.enter="scope.set" />
</q-popup-edit>
</q-td>
</q-tr>
""",
)
table.add_slot(
"bottom-row",
r"""
<q-tr :props="props">
<q-td colspan="3" class="text-center">
<q-btn color="accent" icon="add" class="w-full" @click="() => $parent.$emit('addrow')"/>
</q-td>
</q-tr>
""",
)
table.on("rename", rename)
table.on("delete", delete)
table.on("addrow", addrow)
ui.run() |
Beta Was this translation helpful? Give feedback.
-
see lod_grid in http://ngdemo.bitplan.com/components/WolfgangFahl_nicegui_widgets |
Beta Was this translation helpful? Give feedback.
-
It would be nice to have an editable table with a functionality to edit, update and delete data.
The data structure with which the table was created (list of dicts or pandas df), should be updated with the changes.
(see also https://discord.com/channels/1089836369431498784/1161029777759670454)
I got an example to work with AG Grid, since I though this would be the most versatile element.
The
run_javascript
part could be put in a methodaggrid.get_selected_row_ids
It works, but it does not look ... nice.
Beta Was this translation helpful? Give feedback.
All reactions