Table

Renders a table.

Read more Read less

This component is a pre-styled wrapper around Flop.Phoenix.table/1. A subset of attributes are available and others have been renamed to follow our terminology.

Examples

<.table id="users" rows={@users}>
  <:col :let={user} label="id"><%= user.id %></:col>
  <:col :let={user} label="username"><%= user.username %></:col>
</.table>

Sorting

# To make a row sortable, include the field attribute on the col slot:

<.table id="users" rows={@users}>
  <:col :let={user} field={:name}>
    <%= user.name %>
  </:col>
</.table>

You must also include a handle_params callback in your LiveView.

table-single-default table
Column headers with links are sortable Name Column headers with links are sortable Company Column headers with links are sortable Fruit Column headers with links are sortable Rank
Leela Planet Express 🍏 2
Fry Planet Express 🍌 4
Bender PlanEx 🍇 3
Mom Mom Corp 🍉 1

Services haven't been added for this supplier yet.

Services haven't been added for this supplier yet.

<.row space="base">
  <.table
    id="table-single-default"
    meta={%Meta{backend: nil, current_offset: nil, current_page: nil, end_cursor: nil, next_offset: nil, next_page: nil, page_size: nil, previous_offset: nil, previous_page: nil, schema: nil, start_cursor: nil, total_count: nil, total_pages: nil, errors: [], flop: %Flop{after: nil, before: nil, first: nil, last: nil, limit: nil, offset: nil, order_by: nil, order_directions: nil, page: nil, page_size: nil, decoded_cursor: nil, filters: []}, has_next_page?: false, has_previous_page?: false, opts: [], params: %{}}}
    path="/data_presentation/table"
    rows={[%{id: 0, name: "Leela", rank: 2, company: "Planet Express", fruit: "🍏"}, %{id: 1, name: "Fry", rank: 4, company: "Planet Express", fruit: "🍌"}, %{id: 2, name: "Bender", rank: 3, company: "PlanEx", fruit: "🍇"}, %{id: 3, name: "Mom", rank: 1, company: "Mom Corp", fruit: "🍉"}]}
  >
    <:col :let={user} label="Name" field={:name}>
      {user.name}
    </:col>
    <:col :let={user} label="Company" field={:company}>
      {user.company}
    </:col>
    <:col :let={user} label="Fruit" field={:rank} type="short">
      {user.fruit}
    </:col>
    <:col :let={user} label="Rank" field={:rank} type="number">
      {user.rank}
    </:col>
    <:empty
      message="Services haven't been added for this supplier yet."
    />
  </.table>
</.row>
table-single-without-thead table
Leela Planet Express 2
Fry Planet Express 4
Bender PlanEx 3
Mom Mom Corp 1

Services haven't been added for this supplier yet.

Services haven't been added for this supplier yet.

<.row space="base">
  <.table
    id="table-single-without-thead"
    meta={%Meta{backend: nil, current_offset: nil, current_page: nil, end_cursor: nil, next_offset: nil, next_page: nil, page_size: nil, previous_offset: nil, previous_page: nil, schema: nil, start_cursor: nil, total_count: nil, total_pages: nil, errors: [], flop: %Flop{after: nil, before: nil, first: nil, last: nil, limit: nil, offset: nil, order_by: nil, order_directions: nil, page: nil, page_size: nil, decoded_cursor: nil, filters: []}, has_next_page?: false, has_previous_page?: false, opts: [], params: %{}}}
    path="/data_presentation/table"
    rows={[%{id: 0, name: "Leela", rank: 2, company: "Planet Express"}, %{id: 1, name: "Fry", rank: 4, company: "Planet Express"}, %{id: 2, name: "Bender", rank: 3, company: "PlanEx"}, %{id: 3, name: "Mom", rank: 1, company: "Mom Corp"}]}
  >
    <:col :let={user} label="Name" field={:name}>
      {user.name}
    </:col>
    <:col :let={user} label="Company" field={:company}>
      {user.company}
    </:col>
    <:col :let={user} label="Rank" field={:rank} type="number">
      {user.rank}
    </:col>
    <:empty
      message="Services haven't been added for this supplier yet."
    />
  </.table>
</.row>
table-single-with-edit-actions table
Column headers with links are sortable Name Column headers with links are sortable Company Column headers with links are sortable Rank
Column heading unavailable
Leela Planet Express 2
Fry Planet Express 4
Bender PlanEx 3
Mom Mom Corp 1

Services haven't been added for this supplier yet.

Services haven't been added for this supplier yet.

<.row space="base">
  <.table
    id="table-single-with-edit-actions"
    meta={%Meta{backend: nil, current_offset: nil, current_page: nil, end_cursor: nil, next_offset: nil, next_page: nil, page_size: nil, previous_offset: nil, previous_page: nil, schema: nil, start_cursor: nil, total_count: nil, total_pages: nil, errors: [], flop: %Flop{after: nil, before: nil, first: nil, last: nil, limit: nil, offset: nil, order_by: nil, order_directions: nil, page: nil, page_size: nil, decoded_cursor: nil, filters: []}, has_next_page?: false, has_previous_page?: false, opts: [], params: %{}}}
    path="/data_presentation/table"
    rows={[%{id: 0, name: "Leela", rank: 2, company: "Planet Express"}, %{id: 1, name: "Fry", rank: 4, company: "Planet Express"}, %{id: 2, name: "Bender", rank: 3, company: "PlanEx"}, %{id: 3, name: "Mom", rank: 1, company: "Mom Corp"}]}
  >
    <:col :let={user} label="Name" field={:name}>
      {user.name}
    </:col>
    <:col :let={user} label="Company" field={:company}>
      {user.company}
    </:col>
    <:col :let={user} label="Rank" field={:rank} type="number">
      {user.rank}
    </:col>
    <:action :let={user}>
      <.action_menu id={"user-action-menu-#{user.id}"} label="actions">
        <:item icon="calendar-blank" on_click={Phoenix.LiveView.JS.patch("/edit/#{user.id}")}>Edit</:item>
        <:item icon="calendar-blank" on_click={Phoenix.LiveView.JS.patch("/show/#{user.id}")}>Show</:item>
      </.action_menu>
    </:action>
    <:empty
      message="Services haven't been added for this supplier yet."
    />
  </.table>
</.row>
table-single-many-columns table
Column headers with links are sortable Name Column headers with links are sortable ID Column headers with links are sortable Company Column headers with links are sortable Rank Column headers with links are sortable On Call Column headers with links are sortable Vehicle Column headers with links are sortable Uniform
Column heading unavailable
Leela 0 Planet Express 2 false Old Bessie md
Fry 1 Planet Express 4 true none lg
Bender 2 PlanEx 3 false none
Mom 3 Mom Corp 1 true any sm

Services haven't been added for this supplier yet.

Services haven't been added for this supplier yet.

<.row space="base">
  <.table
    id="table-single-many-columns"
    meta={%Meta{backend: nil, current_offset: nil, current_page: nil, end_cursor: nil, next_offset: nil, next_page: nil, page_size: nil, previous_offset: nil, previous_page: nil, schema: nil, start_cursor: nil, total_count: nil, total_pages: nil, errors: [], flop: %Flop{after: nil, before: nil, first: nil, last: nil, limit: nil, offset: nil, order_by: nil, order_directions: nil, page: nil, page_size: nil, decoded_cursor: nil, filters: []}, has_next_page?: false, has_previous_page?: false, opts: [], params: %{}}}
    path="/data_presentation/table"
    rows={[%{id: 0, name: "Leela", rank: 2, company: "Planet Express", on_call: false, uniform_size: "md", vehicle: "Old Bessie"}, %{id: 1, name: "Fry", rank: 4, company: "Planet Express", on_call: true, uniform_size: "lg", vehicle: "none"}, %{id: 2, name: "Bender", rank: 3, company: "PlanEx", on_call: false, uniform_size: nil, vehicle: "none"}, %{id: 3, name: "Mom", rank: 1, company: "Mom Corp", on_call: true, uniform_size: "sm", vehicle: "any"}]}
  >
    <:col :let={user} label="Name" field={:name}>
      {user.name}
    </:col>
    <:col :let={user} label="ID" field={:id} type="number">
      {user.id}
    </:col>
    <:col :let={user} label="Company" field={:company}>
      {user.company}
    </:col>
    <:col :let={user} label="Rank" field={:rank} type="number">
      {user.rank}
    </:col>
    <:col :let={user} label="On Call" field={:on_call}>
      {user.on_call}
    </:col>
    <:col :let={user} label="Vehicle" field={:vehicle}>
      {user.vehicle}
    </:col>
    <:col :let={user} label="Uniform" field={:uniform_size}>
      {user.uniform_size}
    </:col>
    <:action :let={user}>
      <.action_menu id={"user-action-menu-#{user.id}"} label="actions">
        <:item icon="calendar-blank" on_click={Phoenix.LiveView.JS.patch("/edit/#{user.id}")}>Edit</:item>
        <:item icon="calendar-blank" on_click={Phoenix.LiveView.JS.patch("/show/#{user.id}")}>Show</:item>
      </.action_menu>
    </:action>
    <:empty
      message="Services haven't been added for this supplier yet."
    />
  </.table>
</.row>
table-single-empty table
Column headers with links are sortable Name

Services haven't been added for this supplier yet.

Services haven't been added for this supplier yet.

<.row space="base">
  <.table
    id="table-single-empty"
    meta={%Meta{backend: nil, current_offset: nil, current_page: nil, end_cursor: nil, next_offset: nil, next_page: nil, page_size: nil, previous_offset: nil, previous_page: nil, schema: nil, start_cursor: nil, total_count: nil, total_pages: nil, errors: [], flop: %Flop{after: nil, before: nil, first: nil, last: nil, limit: nil, offset: nil, order_by: nil, order_directions: nil, page: nil, page_size: nil, decoded_cursor: nil, filters: []}, has_next_page?: false, has_previous_page?: false, opts: [], params: %{}}}
    path="/data_presentation/table"
    rows={[]}
  >
    <:col :let={supplier_service} label="Name" field={:name}>
      {supplier_service.name}
    </:col>
    <:empty
      message="Services haven't been added for this supplier yet."
    />
  </.table>
</.row>
table-single-mobile table
Column headers with links are sortable Name Column headers with links are sortable Company Column headers with links are sortable Rank
Leela Planet Express 2
Fry Planet Express 4
Bender PlanEx 3
Mom Mom Corp 1

Services haven't been added for this supplier yet.

Services haven't been added for this supplier yet.

Bender

Company

PlanEx


Fry

Company

Planet Express


Leela

Company

Planet Express


Mom

Company

Mom Corp


Services haven't been added for this supplier yet.

Services haven't been added for this supplier yet.

<.row space="base">
  <.table
    id="table-single-mobile"
    meta={%Meta{backend: nil, current_offset: nil, current_page: nil, end_cursor: nil, next_offset: nil, next_page: nil, page_size: nil, previous_offset: nil, previous_page: nil, schema: nil, start_cursor: nil, total_count: nil, total_pages: nil, errors: [], flop: %Flop{after: nil, before: nil, first: nil, last: nil, limit: nil, offset: nil, order_by: nil, order_directions: nil, page: nil, page_size: nil, decoded_cursor: nil, filters: []}, has_next_page?: false, has_previous_page?: false, opts: [], params: %{}}}
    path="/data_presentation/table"
    rows={[%{id: 0, name: "Leela", rank: 2, company: "Planet Express"}, %{id: 1, name: "Fry", rank: 4, company: "Planet Express"}, %{id: 2, name: "Bender", rank: 3, company: "PlanEx"}, %{id: 3, name: "Mom", rank: 1, company: "Mom Corp"}]}
  >
    <:col :let={user} label="Name" field={:name}>
      {user.name}
    </:col>
    <:col :let={user} label="Company" field={:company}>
      {user.company}
    </:col>
    <:col :let={user} label="Rank" field={:rank} type="number">
      {user.rank}
    </:col>
    <:mobile>
      <.stack space="base">
        <.table_card
          :for={{name, company} <- %{"Leela" => "Planet Express", "Fry" => "Planet Express", "Bender" => "PlanEx", "Mom" => "Mom Corp"}}
          title={name}
          id={name <> "-action_menu"}
        >
          <:item label="Company">{company}</:item>
          <:action on_click={%JS{}}>Action 1</:action>
          <:button on_click={%JS{}}>Control</:button>
        </.table_card>
      </.stack>
    </:mobile>
    <:empty
      message="Services haven't been added for this supplier yet."
    />
  </.table>
</.row>
table-single-empty-responsive table
Column headers with links are sortable Name

Services haven't been added for this supplier yet.

Services haven't been added for this supplier yet.

Services haven't been added for this supplier yet.

Services haven't been added for this supplier yet.

<.row space="base">
  <.table
    id="table-single-empty-responsive"
    meta={%Meta{backend: nil, current_offset: nil, current_page: nil, end_cursor: nil, next_offset: nil, next_page: nil, page_size: nil, previous_offset: nil, previous_page: nil, schema: nil, start_cursor: nil, total_count: nil, total_pages: nil, errors: [], flop: %Flop{after: nil, before: nil, first: nil, last: nil, limit: nil, offset: nil, order_by: nil, order_directions: nil, page: nil, page_size: nil, decoded_cursor: nil, filters: []}, has_next_page?: false, has_previous_page?: false, opts: [], params: %{}}}
    path="/data_presentation/table"
    rows={[]}
  >
    <:col :let={supplier_service} label="Name" field={:name}>
      {supplier_service.name}
    </:col>
    <:mobile>
      <.table_card :for={row <- []} title={row.name} />
    </:mobile>
    <:empty
      message="Services haven't been added for this supplier yet."
    />
  </.table>
</.row>
table-single-with-edit-actions-and-without-meta table
NameCompanyRank Actions
Leela Planet Express 2
Fry Planet Express 4
Bender PlanEx 3
Mom Mom Corp 1

Services haven't been added for this supplier yet.

Services haven't been added for this supplier yet.

<.row space="base">
  <.table
    id="table-single-with-edit-actions-and-without-meta"
    path="/data_presentation/table"
    rows={[%{id: 0, name: "Leela", rank: 2, company: "Planet Express"}, %{id: 1, name: "Fry", rank: 4, company: "Planet Express"}, %{id: 2, name: "Bender", rank: 3, company: "PlanEx"}, %{id: 3, name: "Mom", rank: 1, company: "Mom Corp"}]}
    class=""
  >
    <:col :let={user} label="Name" field={:name}>
      {user.name}
    </:col>
    <:col :let={user} label="Company" field={:company}>
      {user.company}
    </:col>
    <:col :let={user} label="Rank" field={:rank} type="number">
      {user.rank}
    </:col>
    <:action :let={user}>
      <.row space="none" justify="end">
        <.action_menu id={"user-action-menu-#{user.id}"} label="actions">
          <:item icon="calendar-blank" on_click={Phoenix.LiveView.JS.patch("/edit/#{user.id}")}>Edit</:item>
          <:item icon="calendar-blank" on_click={Phoenix.LiveView.JS.patch("/show/#{user.id}")}>Show</:item>
        </.action_menu>
      </.row>
    </:action>
    <:empty
      message="Services haven't been added for this supplier yet."
    />
  </.table>
</.row>
table-single-sticky-headers table
Column headers with links are sortable Name Column headers with links are sortable Company Column headers with links are sortable Fruit Column headers with links are sortable Rank
Leela Planet Express 🍏 2
Fry Planet Express 🍌 4
Bender PlanEx 🍇 3
Mom Mom Corp 🍉 1
Zoidberg Planet Express 🥥 6
Farnsworth Planet Express 🫐 5
Amy Mars University 🥭 7
Hermes Planet Express 🍍 8
Scruffy Planet Express 🥝 9
Zapp DOOP 🍑 10
Kif DOOP 🫒 11
Lrrr Omicron Persei 8 🌶️ 12

Services haven't been added for this supplier yet.

Services haven't been added for this supplier yet.

<.row space="base">
  <.table
    id="table-single-sticky-headers"
    meta={%Meta{backend: nil, current_offset: nil, current_page: nil, end_cursor: nil, next_offset: nil, next_page: nil, page_size: nil, previous_offset: nil, previous_page: nil, schema: nil, start_cursor: nil, total_count: nil, total_pages: nil, errors: [], flop: %Flop{after: nil, before: nil, first: nil, last: nil, limit: nil, offset: nil, order_by: nil, order_directions: nil, page: nil, page_size: nil, decoded_cursor: nil, filters: []}, has_next_page?: false, has_previous_page?: false, opts: [], params: %{}}}
    path="/data_presentation/table"
    sticky
    rows={[%{id: 0, name: "Leela", rank: 2, company: "Planet Express", fruit: "🍏"}, %{id: 1, name: "Fry", rank: 4, company: "Planet Express", fruit: "🍌"}, %{id: 2, name: "Bender", rank: 3, company: "PlanEx", fruit: "🍇"}, %{id: 3, name: "Mom", rank: 1, company: "Mom Corp", fruit: "🍉"}, %{id: 4, name: "Zoidberg", rank: 6, company: "Planet Express", fruit: "🥥"}, %{id: 5, name: "Farnsworth", rank: 5, company: "Planet Express", fruit: "🫐"}, %{id: 6, name: "Amy", rank: 7, company: "Mars University", fruit: "🥭"}, %{id: 7, name: "Hermes", rank: 8, company: "Planet Express", fruit: "🍍"}, %{id: 8, name: "Scruffy", rank: 9, company: "Planet Express", fruit: "🥝"}, %{id: 9, name: "Zapp", rank: 10, company: "DOOP", fruit: "🍑"}, %{id: 10, name: "Kif", rank: 11, company: "DOOP", fruit: "🫒"}, %{id: 11, name: "Lrrr", rank: 12, company: "Omicron Persei 8", fruit: "🌶️"}]}
  >
    <:col :let={user} label="Name" field={:name}>
      {user.name}
    </:col>
    <:col :let={user} label="Company" field={:company}>
      {user.company}
    </:col>
    <:col :let={user} label="Fruit" field={:rank} type="short">
      {user.fruit}
    </:col>
    <:col :let={user} label="Rank" field={:rank} type="number">
      {user.rank}
    </:col>
    <:empty
      message="Services haven't been added for this supplier yet."
    />
  </.table>
</.row>
table-single-row-click table
NameDescription Actions Actions
Icon It's an icon!
Button I like BUTTONS!
Badge Wear it with honour, or don't.
Calendar Don't be late.

Services haven't been added for this supplier yet.

Services haven't been added for this supplier yet.

<.row space="base">
  <.table
    id="table-single-row-click"
    path="/data_presentation/table"
    rows={[%{id: 0, name: "Icon", path: "/icons_and_images/icon", description: "It's an icon!"}, %{id: 1, name: "Button", path: "/buttons/button", description: "I like BUTTONS!"}, %{id: 2, name: "Badge", path: "/data_presentation/badge", description: "Wear it with honour, or don't."}, %{id: 3, name: "Calendar", path: "/data_presentation/calendar", description: "Don't be late."}]}
    class="foo"
  >
    <:col :let={component} label="Name" field={:name} navigate={& &1.path}>
      {component.name}
    </:col>
    <:col :let={component} label="Description" field={:company}>
      {component.description}
    </:col>
    <:action>
      <.button ghost>Control</.button>
    </:action>
    <:action>
      <DesignSystem.action_menu id="table-row-click" label="Actions">
        <:item on_click={JS.navigate("/welcome")}>Welcome</:item>
      </DesignSystem.action_menu>
    </:action>
    <:empty
      message="Services haven't been added for this supplier yet."
    />
  </.table>
</.row>