How to create a table with buttons element in a column with Pynecone?

Question:

The table’s last column (action) contains pc.button, that can get data in the row that the button residing in, and then send that data to a State variable.
Some thing like this:

name age job action
John 20 Developer Update
May 23 Designer Update

I have tried pc.list like this:

return pc.center(
   pc.list([
     ["name","age","job","action"],
     ["John",20, "Developer", pc.button("Update", on_click=State.update_employee)],
     ["May",23, "Designer", pc.button("Update", on_click=State.update_employee)],
   ])
)

but pc.list can only take in python primitive types (str,int,float…). Is there any way to add multiple components progamatically to another Pynecone component

Asked By: huynv

||

Answers:

https://youtube.com/shorts/u-TUSQ9DkCw <– Example here
I write the following full example for what you want.

The simple answer is to use table_container.
But we need to care about some detail.

from pcconfig import config
import pynecone as pc
class Member(pc.Model, table=True):
    ename:str # The attribute cannot be call "name", so we use ename here
    age:int
    job:str
    def __init__(self, ename,age,job):
        self.ename=ename
        self.age =age
        self.job =job
    def __repr__(self) -> str:
        return "("+self.ename+","+self.age+","+self.job+")"

class State(pc.State):    
    members:list[Member] = [
        Member("John",20,"Developer"),
        Member("May",23,"Design"),
        Member("Milo",18,"Teacher"),
        Member("Aloha",48,"CEO"),
    ]    

    def delete_member(self,member_name:str):
        del_idx:int = -1
        for i in range(len(self.members)):
            if(self.members[i].ename == member_name):
                del_idx = i
                break
        if(del_idx > -1):
            del self.members[del_idx]
        return

def index() -> pc.Component:
    return pc.center(
        pc.vstack(
            pc.vstack(
                pc.hstack(
                    pc.heading("Members"),
                ),
                pc.table_container(
                    pc.table(
                        pc.thead(
                            pc.tr(
                                pc.th("Name"),
                                pc.th("Age"),
                                pc.th("Job"),
                                pc.th("Action"),
                            )
                        ),
                        pc.tbody(
                            pc.foreach( State.members, lambda member: 
                                pc.tr(
                                    pc.td(member.ename),
                                    pc.td(member.age),
                                    pc.td(member.job),
                                    pc.td(
                                        pc.button(
                                            "Delete",
                                            on_click=lambda: State.delete_member(member.ename),
                                            bg="red",
                                            color="white",                                                            
                                        )
                                    ),
                                )
                            )
                        ),
                    ),
                    bg="#F7FAFC ",
                    border="1px solid #ddd",
                    border_radius="25px",
                ),
                align_items="left",
                padding_top="7em",
            ),
        ),
        padding="1em",
    )


# Add state and page to the app.
app = pc.App(state=State)
app.add_page(index, title="table container")
app.compile()

(1) You need to define a class.
In my case, it is Member(pc.Model, table=True).
You must add (pc.Model, table=True)
Can we use [list[list[str]] to represent the self.members?
The answer is NO.
That’s we we use members:list[Member] in State but not members:list[list[str]].

(2) When your code satisfies the above condition 1, then we can
use pc.foreach() to generate table’s data in UI.

pc.foreach( State.members, lambda member: 
    pc.tr(
        pc.td(member.ename),
        pc.td(member.age),
        pc.td(member.job),
        pc.td(
            pc.button(
                "Delete",
                on_click=lambda: State.delete_member(member.ename),
                bg="red",
                color="white",                                                            
            )
        ),
    )
)
Answered By: Milo Chen
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.