Skip to main content

Grid

Struct Grid 

Source
#[non_exhaustive]
pub struct Grid { /* private fields */ }
Expand description

A data grid’s definition: its columns and defaults. Cheap to build, so a function returning it is the usual place for one.

Implementations§

Source§

impl Grid

Source

pub async fn export<M: Model + Serialize>( &self, query: Query<M>, request: &GridRequest, ) -> Result<Option<Response>>

Answers the export menu’s links (?export=csv|xlsx|print): None when the request isn’t an export, so the handler goes on to draw the page.

use renox::grid::{Column, Grid, GridRequest};
fn orders() -> Grid {
    Grid::new("orders").column(Column::text("number", "Order")).exports()
}

async fn index(request: GridRequest) -> Result<Response> {
    if let Some(file) = orders().export(Order::query(), &request).await? {
        return Ok(file);
    }
    let page = orders().page(Order::query(), &request).await?;
    Ok(view("orders/index.html", context! { orders => page }).into_response())
}

Custom columns are left out, and so are the columns the user hid on wide screens. Up to MAX_EXPORT_ROWS rows.

Source

pub async fn export_as<M: Model + Serialize>( &self, query: Query<M>, format: ExportFormat, request: &GridRequest, ) -> Result<Response>

Every row query matches as a file, outside the grid’s page: an “Export” action on a record’s page or in a menu (the grid’s own export menu uses Grid::export). The grid’s columns that show by default on wide screens, in their order; the request’s filters, sort and the user’s column choices don’t apply (sort the query yourself). Up to MAX_EXPORT_ROWS rows.

use renox::grid::{Column, ExportFormat, Grid, GridRequest};
fn ledger() -> Grid {
    Grid::new("ledger").column(Column::number("quantity", "Quantity"))
}

// GET /products/{id}/ledger.csv
async fn export_ledger(Path(id): Path<i64>, request: GridRequest) -> Result<Response> {
    let movements = Movement::where_eq("product_id", id).order_by("id");
    ledger().export_as(movements, ExportFormat::Csv, &request).await
}
Source§

impl Grid

Source

pub fn new(id: &str) -> Self

A grid named id (letters, digits, _ and -), which keys each user’s preferences and the element’s id.

Source

pub fn poll(self, seconds: u32) -> Self

Reloads the grid’s page every seconds (at least 5) while the tab is visible and nobody is editing, selecting or filtering in it.

Source

pub fn remember(self) -> Self

Keeps the user’s filters, search, sort, group and page size in the session: coming back to the page shows the grid as they left it.

Source

pub fn advanced_filter(self) -> Self

An advanced filter in the toolbar: rules on any filterable column (“Total is greater than 1,000,000”, “Name doesn’t contain coffee”, “Ordered before 2026-03-01”, “Email is empty”), all or any of them holding. They travel in the query string (match=any&r.0.c=total& r.0.o=gt&r.0.v=1000000), next to the headings’ filters.

Source

pub fn cards_on_mobile(self) -> Self

On phones (under 768 px) each row is a card: the columns picked for small screens stacked as label and value, with sorting and filters in the toolbar. Wider screens keep the table.

Source

pub fn groups(self, keys: &[&str]) -> Self

Columns the user may group rows by (a “Group” choice in the toolbar): each group starts with a heading (its value and how many rows it has, folding its rows away on a click) and ends with its own summaries. Rows are sorted by the group first.

Source

pub fn group_by(self, key: &str) -> Self

Groups rows by key until the user picks otherwise (it joins Grid::groups).

Source

pub fn bulk_action(self, action: Action) -> Self

An action on the selected rows: a checkbox starts each row, and selecting some shows the actions over the grid. The action is sent to its URL (with the grid’s query string, for “all matching”) as Selection; the grid reloads after a 2xx.

Source

pub fn row_action(self, action: Action) -> Self

An action in each row’s menu (⋯); {id} in its URL is the row’s id.

Source

pub fn selected<M: Model>( &self, query: Query<M>, request: &GridRequest, selection: &Selection, ) -> Result<Query<M>>

query narrowed to what a bulk action was sent for: the selected ids, or every row the grid’s filters match when the user chose “all matching”.

use renox::grid::{Action, Column, Grid, GridRequest, Selection};
fn orders() -> Grid {
    Grid::new("orders")
        .column(Column::text("status", "Status"))
        .bulk_action(Action::new("Mark paid", "/orders/paid"))
}

async fn mark_paid(State(db): State<Db>, request: GridRequest, Form(selection): Form<Selection>) -> Result<String> {
    let changed = orders()
        .selected(Order::query(), &request, &selection)?
        .update(&db, &[("status", &"paid")])
        .await?;
    Ok(format!("{changed} orders paid"))
}
Source

pub fn prefix(self, prefix: &str) -> Self

Prefixes the grid’s query string names (orders.page=2, orders.q.number=…), for pages with more than one grid. Without it the names are plain (page=2). Either way a grid keeps the query string values that aren’t its own.

Source

pub fn row_url(self, url: &str) -> Self

A click on a row (outside its buttons and links) opens this URL, {id} replaced by the row’s id; Ctrl/Cmd-click opens it in a new tab. With row details (Grid::audit, Grid::details) a click opens those instead and the row tools get a link.

Source

pub fn empty_state(self, heading: &str, description: Option<&str>) -> Self

What an empty grid (before any filter) says; the page’s call block can add buttons for column.key == "_empty".

Source

pub fn exports(self) -> Self

An export menu in the toolbar: CSV, Excel (with the xlsx feature) and a page to print or save as PDF, each of every row the filters match (not just the page), in the user’s columns. The handler answers them with Grid::export.

Source

pub fn audit(self) -> Self

A click on a row (or its chevron) opens details under it: who created and last changed the row, and when, from its created_by, created_at, updated_by and updated_at values (those it has).

Source

pub fn details(self) -> Self

A click on a row opens details under it, drawn by the page’s template: caller(row, column) with column.key == "_details". With Grid::audit, the audit fields come first.

Source

pub fn edit_url(self, url: &str) -> Self

Where edits are sent: PATCH to this URL with {id} replaced by the row’s id, the changed fields as a form (customer=…, tags=a&tags=b, paid=true). Answer with a 2xx (a Toast shows), or with Valid<T>’s 422 and the errors show next to the fields; the grid then reloads its page.

Source

pub fn reorder(self, column: &str, url: &str) -> Self

Rows can be dragged into order (or moved with the arrow keys on their handle) while the grid is sorted by column ascending; the new order of the page is POSTed to url as ids and offset (see RowOrder).

Source

pub fn title(self, title: &str) -> Self

The heading shown above the grid.

Source

pub fn column(self, column: Column) -> Self

Adds a column.

Source

pub fn per_page(self, per_page: u32) -> Self

Rows per page until the user picks another number (default 25).

Source

pub fn sort_by(self, sort: &str) -> Self

The order before the user sorts: a column key, - first for descending ("-created_at"), or several separated by commas ("region,city,-total", what merged columns want). Ties are broken by id.

Source

pub fn id(&self) -> &str

The grid’s id.

Source

pub fn columns(&self) -> &[Column]

The grid’s columns, in their defined order.

Source

pub async fn page<M: Model + Serialize>( &self, query: Query<M>, request: &GridRequest, ) -> Result<GridPage<M>>

One page of query with the request’s filters, sort and page applied, ready for the grid macro.

Source

pub fn filter<M: Model>( &self, query: Query<M>, request: &GridRequest, ) -> Query<M>

query with the request’s filters applied (also used by page): for exports or totals over every filtered row.

Trait Implementations§

Source§

impl Clone for Grid

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 Debug for Grid

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for Grid

§

impl RefUnwindSafe for Grid

§

impl Send for Grid

§

impl Sync for Grid

§

impl Unpin for Grid

§

impl UnsafeUnpin for Grid

§

impl UnwindSafe for Grid

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> 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> Fake for T

Source§

fn fake<U>(&self) -> U
where Self: FakeBase<U>,

Source§

fn fake_with_rng<U, R>(&self, rng: &mut R) -> U
where R: RngExt + ?Sized, Self: FakeBase<U>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

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

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

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

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
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