3

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

Milo Chen
  • 3,617
  • 4
  • 20
  • 36
huynv
  • 49
  • 5
  • 2
    Hi ~ The code is not working return pc.center( pc.list([ ["name","age","job","action"], ["John",20, "Developer", "Update"], ["May",23, "Designer", "Update"], ]) ). Where is the document to show ```pc.list``` on pynecone official website? – Milo Chen Mar 27 '23 at 07:46
  • 2
    Here is the documentation of the pyncone.list component: https://pynecone.io/docs/library/datadisplay/list – huynv Mar 27 '23 at 09:44
  • 2
    The list is not what you think. Your purpose is to make something like a table. But it is a one-dimension list only. I'm writing a working example for you. Please wait a minute. – Milo Chen Mar 27 '23 at 09:50

1 Answers1

3

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",                                                            
            )
        ),
    )
)
Milo Chen
  • 3,617
  • 4
  • 20
  • 36
  • 2
    what is the purpose of importing `config` ? I have removed that importing line and nothing changes, is it related to usage of **pynecone database** ? Should `State.get_members()` returns `List[Member]` instead of `list[list[str]]`? – huynv Mar 28 '23 at 08:05
  • 2
    @huynv Don't use ```get_members(): list[list[str]]``` because it can not work. It's only work for List[Member]. Thanks for your feedback I forget to remove get_members() function. – Milo Chen Mar 29 '23 at 16:53