Skip to main content

Table

Struct Table 

Source
pub struct Table<M> { /* private fields */ }
Expand description

Table description of a Resource’s list view declaring columns and how they map to queries.

A clone shares every column, filter and projection.

The list keeps its whole state in the URL: ?q= searches, ?sort= and ?dir= sort, ?page=, ?per_page=, ?after= and ?before= page, ?f.<name>= filters and ?group_by= groups. Each row is keyed by its record’s primary key, which the action URLs and bulk checkboxes carry; a composite key has no URL form, so its rows render without row actions or bulk selection.

  • Search matches a row any searchable column contains the term in. It escapes % and _, trims the term and caps it at 128 characters, and matches case-insensitively: PostgreSQL runs it as ILIKE, SQLite (for ASCII) and MySQL (under its default collations) as LIKE.
  • Without a ?sort= naming a sortable column, the rows sort by the default_sort, else by the first sortable column, ascending. The primary key breaks ties, so a sort over duplicate values pages deterministically, and a page number past the last page reads as the last.
  • A filter that cannot apply, an unknown name, a value the filter rejects or one past the limits, is never dropped silently: the list shows a warning banner naming it, and the export answers 400. At most 32 filters apply, each with at most 64 values and parts, each name, part and value at most 256 bytes. Active filters combine with AND.
  • Grouping runs on the loaded page, so its counts cover that page; a ?group_by= the table does not declare is ignored.
  • The list updates in place: a search, filter, sort or page reruns the page through the runtime, keeping focus and scroll, and without JavaScript its links and its search form load the page. A table that fails to load shows an error state with a retry link in place of the rows.

When the policy allows DeleteAny, or RunAny for an action placed on the bulk bar, the list adds a checkbox column and a bulk bar; a row that no delete or bulk action allows gets no checkbox. A bulk delete takes at most 400 records, runs in one transaction and skips the records the policy refuses Delete. Both deletes ask first through a confirmation dialog, which needs JavaScript; a POST not confirmed through it answers 400. Each lands back on the list as it was left.

§Export

GET {list}/-/export returns the list as a CSV file named {slug}.csv, with the current search, filters and sort applied and the relations the columns include loaded. It leaves out the rows the policy refuses View, delivers at most 10,000 rows and answers 413 rather than a truncated file when more match. It writes each column’s formatted value, a date column’s stored value, and escapes a cell a spreadsheet would read as a formula; ?bom=1 prefixes the file with a byte-order mark for Excel.

Implementations§

Source§

impl<M> Table<M>

Source

pub fn default_sort<T>(self, path: impl Into<Path<M, T>>) -> Self
where M: Model,

Sort by path’s column, smallest first, when the URL names no sortable column; by the first sortable column, ascending, by default.

use tablo_core::{Table, TextColumn, lens};

Table::new(TextColumn::new(lens!(Post.title)).sortable()).default_sort(lens!(Post.title));

A path whose column the table does not declare sortable is a declaration error.

Source

pub fn default_sort_desc<T>(self, path: impl Into<Path<M, T>>) -> Self
where M: Model,

Sort by path’s column, largest first, when the URL names no sortable column, as default_sort does ascending.

use tablo_core::{DateColumn, Table, TextColumn, lens};

// The newest posts first.
Table::new((
    TextColumn::new(lens!(Post.title)).sortable(),
    DateColumn::new(lens!(Post.published_at)).sortable(),
))
.default_sort_desc(lens!(Post.published_at));
Source

pub fn default_sort_by(self, sort: Sort) -> Self

Sort by the sortable column sort names when the URL names none: the default for a column of your own, whose name no field path spells. A field’s column takes default_sort, whose path a rename fails to compile.

use tablo_core::{Sort, Table, TextColumn, lens};

// "revenue" is the name a column of your own returns.
Table::new(TextColumn::new(lens!(Post.title))).default_sort_by(Sort::desc("revenue"));

A name the table declares no sortable column for is a declaration error.

Source§

impl<M> Table<M>

Source

pub fn new(cols: impl IntoColumns<M>) -> Self
where M: Model + IntoExpr<M>,

Declare a table of cols.

Each row is keyed by its record’s primary key, which the row’s action URLs carry.

Source

pub fn column(self, column: impl Column<M> + 'static) -> Self

Append column after the declared ones.

Source

pub fn filters(self, filters: impl IntoFilters<M>) -> Self
where M: Model,

Declare filters.

Source

pub fn group_by<T>(self, lens: Lens<M, T>) -> Self
where M: Model + Send + Sync + 'static, T: FormScalar + Send + Sync + 'static,

Offer grouping the page’s rows by the field lens reads, under the field’s name.

Source

pub fn pagination(self, pagination: Pagination) -> Self

Page through the rows as pagination says; Pagination::Pages by default.

Source

pub fn action_layout(self, layout: ActionLayout) -> Self

Put a row’s actions where layout says; ActionLayout::Inline by default.

Source

pub fn per_page_options(self, options: impl IntoIterator<Item = usize>) -> Self

The page sizes a reader may pick, beside the table’s own; none offers no choice. DEFAULT_PER_PAGE_OPTIONS by default. A cursor table offers none.

Source

pub fn paginate(self, per_page: usize) -> Self

Set the page size.

Source

pub fn declaration_errors(&self) -> Vec<DeclarationErrorKind>

What is wrong with this declaration.

Source

pub fn page_size(&self) -> usize

The page size.

Source

pub fn pagination_mode(&self) -> Pagination

How the table pages.

Source

pub fn row_action_layout(&self) -> ActionLayout

Where the table puts a row’s actions.

Render no search toolbar in the table.

Source

pub fn hide_filter_menu(self) -> Self

Render no filter menu in the table’s toolbar.

Trait Implementations§

Source§

impl<M> Clone for Table<M>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<M> Debug for Table<M>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<M> !RefUnwindSafe for Table<M>

§

impl<M> !UnwindSafe for Table<M>

§

impl<M> Freeze for Table<M>
where Vec<Arc<dyn Column<M>>>: Freeze, Vec<Arc<dyn Filter<M>>>: Freeze, Option<GroupDef<M>>: Freeze, fn(&M) -> String: Freeze, PhantomData<M>: Freeze,

§

impl<M> Send for Table<M>
where Vec<Arc<dyn Column<M>>>: Send, Vec<Arc<dyn Filter<M>>>: Send, Option<GroupDef<M>>: Send, fn(&M) -> String: Send, PhantomData<M>: Send,

§

impl<M> Sync for Table<M>
where Vec<Arc<dyn Column<M>>>: Sync, Vec<Arc<dyn Filter<M>>>: Sync, Option<GroupDef<M>>: Sync, fn(&M) -> String: Sync, PhantomData<M>: Sync,

§

impl<M> Unpin for Table<M>
where Vec<Arc<dyn Column<M>>>: Unpin, Vec<Arc<dyn Filter<M>>>: Unpin, Option<GroupDef<M>>: Unpin, fn(&M) -> String: Unpin, PhantomData<M>: Unpin,

§

impl<M> UnsafeUnpin for Table<M>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneAny for T
where T: Any + Clone,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more