Skip to main content

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 GET returning a list.
  • A ribbon option group that filters on the species column 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​