Petstore: Sold Pets
The Sold pets page, served at /console/pets/sold, is the smallest table page in the petstore: every pet that has
been marked sold, with a species filter. It exists to show the contrast with the main Pets
page. Same bean, but a different data mode and a much shorter template.
What this page shows
- A table in client mode. The endpoint returns all the rows in one response and the browser does the filtering,
sorting and paging. There is no server-side query, so the endpoint is a plain
GETreturning a list. - A ribbon option group that filters on the
speciescolumn in the browser, with no request to the server. - A minimal page template: no tab attribute, no URL state, no row actions.
Client mode is the right choice when the full row set is small. When it is not, use server mode, as the Pets page does.
Template
The template is pets-sold.ftlh. The card body is trimmed here to its essentials.
<@page toolkit="views">
<@card type="datatables" id="sold" title="Sold pets">
{
rowType: 'Pet',
dataMode: 'client',
dataUrl: '/console/pets/sold/rows',
columns: [ { key: 'id', label: 'Id' }, { key: 'name', label: 'Name' }, { key: 'species', label: 'Species' } ],
ribbon: [
{ type: 'optionGroup', id: 'species', title: 'Species', options: [
{ id: 'dogs', title: 'Dogs', column: 'species', value: '$eq(DOG)' },
{ id: 'cats', title: 'Cats', column: 'species', value: '$eq(CAT)' } ] },
{ type: 'refresh' } ]
}
</@card>
</@page>
The filter values use the BeanQuery search syntax ($eq(DOG)). In client mode the table applies them locally; in server
mode the same strings are sent to the server.
Builder twin
PetsPageBuilders.sold builds the same page. Request /console/pets/sold?builder to render it.
PageSpec.create().toolkit("views")
.table(TableSpec.create("sold").rowType("Pet").dataMode(DataMode.CLIENT).dataUrl("/console/pets/sold/rows")
.columns(Column.create("id").label("Id"), Column.create("name").label("Name"))
.ribbon(
RibbonItem.optionGroup("species",
RibbonItem.option("dogs").title("Dogs").column("species").value("$eq(DOG)"),
RibbonItem.option("cats").title("Cats").column("species").value("$eq(CAT)")).title("Species"),
RibbonItem.refresh()), "Sold pets");
The data endpoint
GET /console/pets/sold/rows is served by PetsRest.soldRows. It returns every pet whose status is SOLD, sorted
by id. Marking a pet sold is a separate action on the Pets page (POST /console/pets/{id}/sell), after which the pet
appears here on the next refresh.
Source and tests
Source: juneau-petstore/juneau-petstore-core, classes PetsRest and PetsPageBuilders (in the pages package)
and the template pets-sold.ftlh.
Tests: PetsRest_Test (the sold/rows endpoint), PetstorePages_ContractTest (the page contract) and
PetstoreTwins_Test (template equals builder).
See also
- Twin pattern: see 19.17. Template and Builder Twins.
- Petstore: Pets: the server-mode counterpart.
- Data Tables: client mode versus server mode.
- Rich Table Views: what a table card can do.
- Building a Console Page: the end-to-end tutorial.