Loading

Browse Views

The public record catalogue — cards from your own template, filters and search, sorting including by distance, and an optional map.

Overview of Browse Views

A Browse View is a configurable listing of datastore rows for end users. Where the auto-generated data table shows every column an admin has access to, a Browse View lets you tailor what end users see — the columns, the filters, the search controls, and the row-level actions.

Almost every page in an end-user-facing application that displays a list of records is, under the hood, a Browse View. Customer portals, order dashboards, product catalogues, ticket queues — all built from Browse Views configured against the underlying datastores.

Why use Browse Views

Three reasons that come up over and over:

  • Different roles need different columns and actions on the same datastore. A Customer Service rep looking at orders cares about status and shipping date. A Finance rep looking at the same orders cares about total value and payment status. Two browse views, one underlying table.
  • End-user portals need a cleaner, more focused listing than the admin view. The admin view shows every column and every action; the end-user view shows a focused subset that fits the user's task.
  • You want to apply baseline filters. A "My Open Tickets" view filters to the logged-in user's own tickets, in Open status. A "This Week's Bookings" view filters to bookings whose date is within the current week.

What's configurable

For every Browse View you control:

  • Which columns appear, in what order, with what width.
  • Which columns are searchable from the global search box.
  • Which columns are sortable (the heading becomes clickable to sort).
  • Built-in filter controls — dropdowns, date ranges, toggles — above the table.
  • Row-action buttons (Edit, View, Delete, plus custom actions).
  • Pagination size and default sort order.
  • Baseline filters that always apply ("only open tickets", "only this user's records", etc.).
  • Empty-state messaging for when there are no rows to display.
  • Per-role visibility rules (who can see this view at all).

Three real-world Browse Views

Example 1: Customer Order Portal

Datastore: orders. Browse View shown to the logged-in customer:

  • Columns: Order Number, Date, Status, Total, Tracking Link.
  • Filters: Status (Open / Shipped / Cancelled), Date Range.
  • Row actions: View Details only.
  • Baseline filter: customer_id = current_user_id via row-level security.
  • Default sort: Date descending (newest first).

Example 2: Internal Sales Dashboard

Datastore: orders. Browse View shown to sales reps:

  • Columns: Order Number, Customer, Salesperson, Status, Total, Margin.
  • Filters: Status, Salesperson, Date Range, Total Above.
  • Row actions: View, Edit, Add Note, Email Customer.
  • Baseline filter: none (sales sees all orders).
  • Default sort: Total descending (highest value first).

Example 3: Finance Audit View

Datastore: orders. Browse View shown to Finance:

  • Columns: Order Number, Date, Customer Name, Payment Status, Total, VAT Calculation, Invoice Sent Date.
  • Filters: Payment Status, Date Range, Customer.
  • Row actions: View, Mark Paid, Generate Invoice, Export.
  • Baseline filter: only paid or pending-payment orders (no draft orders).
  • Default sort: Date descending.

Where they're managed

From the Architect Panel → Browse Views. Each browse view is anchored to a single datastore (it can't span tables; for that, use a Custom Query View) and can be surfaced via:

  • A Friendly URL (e.g. /orders, /my-tickets).
  • Embedded inside a Page Builder page using a Browse View block.
  • Linked from a navigation menu or sidebar.
  • As the destination of a Row Action button on another view.
Tip: Browse Views and Data Layouts work hand-in-hand. A Browse View defines the available columns and filters; a Data Layout saves a specific arrangement of them. Users with appropriate permissions can save their own layouts on a view, and admins can share layouts across teams.

Sorting by distance, and the map

A browse view can also order its results by how near they are to the visitor, filter to a radius, and show them on a map. That needs a field on the record holding a postcode or coordinates — or a link to a parent record that holds one — and postcode lookup enabled for the installation. Distances are straight-line rather than by road.

See Sorting by Distance, The Radius Filter and The Map View in this section, and Postcode Lookup under Integrations.

Configuring Columns

The column list is the bulk of a Browse View's configuration. For each column you decide what's shown, how it's rendered, how wide it is, and whether the user can interact with it (sort, search, filter).

Per-column settings

Open a Browse View and find the Columns section. Add a column for each field you want shown; for each column configure:

  • Field — which datastore column this Browse View column reads from.
  • Display Name — column heading (overrides the datastore's Friendly Name if you want to be more specific in this view's context).
  • Width — pixel value (150px) or percent (10%).
  • Searchable — whether the global search box matches against this column.
  • Sortable — whether the column heading is clickable to re-sort.
  • Default Sort — whether this column drives the default sort order, and whether ascending or descending.
  • Display Format — optional template using ##AMDATA_fieldname## tokens to combine multiple raw values into one display.

Display Format examples

The Display Format setting is one of the most powerful column features. Three patterns that come up:

1. Combine name fields into one column

Format: ##AMDATA_firstname## ##AMDATA_lastname##. Renders "Jane Smith" in a single column even though firstname and lastname are separate fields on the datastore.

2. Embed multiple values with formatting

Format: <strong>##AMDATA_companyname##</strong><br/><small>##AMDATA_email##</small>. Renders the company name in bold with the email underneath in smaller text — a two-line column showing both fields.

3. Conditional display

For more complex logic, use a Custom PHP Code field as a derived column. The PHP can inspect the row's data and return whatever HTML you want, including conditional content ("Overdue" badge on tickets past their SLA, status icons coloured by state, etc.).

Hidden columns for context

Sometimes you need a column included in the underlying query (for example to enable a row-action URL that needs the row's ID) without showing it in the table. Set its Width to hide — the column is fetched into the result set but not displayed.

This pattern is essential when row actions link to URLs like /orders/##AMDATA_id## — the ID needs to be in the row data even if you don't want to show it as a visible column.

Three real-world column configurations

Example 1: Customer list for sales reps

  • Company Name (200px, sortable, searchable).
  • Primary Contact (combined firstname + lastname via Display Format, 150px, searchable).
  • Email (200px, searchable).
  • Total Spend (100px, sortable, right-aligned).
  • Last Activity Date (120px, sortable).
  • Tags (200px, multi-pill rendering).
  • Status (80px, badge-style rendering via Custom PHP).

Example 2: Order queue for fulfilment team

  • Order Number (100px, sortable).
  • Customer Name (150px, searchable).
  • Items (combined count + summary via Display Format, 300px).
  • Status (80px, badge).
  • Required-by Date (120px, sortable; rows highlight red if overdue via row-styling).
  • Action (hidden column carrying the row ID for the action URL).

Example 3: Ticket dashboard for support team

  • Reference (80px, sortable).
  • Subject (300px, searchable; truncated to one line).
  • Customer (150px).
  • Assignee (120px).
  • Priority (60px, sortable, coloured badge).
  • SLA Status (combined SLA-due + elapsed-time via Display Format, 120px).
  • Last Update (120px, sortable).
Tip: Keep column count under 7 if possible. Tables with more columns become unreadable on smaller screens — the human eye struggles to scan beyond about 7 vertical columns. If you need more data per row, consider expanding rows to show detail rather than adding more columns.

Filters and Search Boxes

Beyond the global search input, Browse Views support dedicated filter controls above the table — dropdowns, date pickers, toggles, range sliders. Configure them once and your users get a far better browsing experience than typing into a generic search box.

Why filters beat search

Search is universal but blunt. The user has to know what they're searching for and type it accurately. Filters are domain-specific and forgiving — a Status dropdown lists the available options so the user doesn't have to remember them; a Date Range picker constrains valid input; a toggle is binary so there's no typing involved.

For any browse view where users will return repeatedly to similar subsets of the data, filters give a much better experience than search. Add both; users will gravitate to filters once they discover them.

Adding a filter

In the Browse View's configuration, find the Filters section and click Add. For each filter specify:

  • Field — which datastore column the filter narrows on.
  • Display type — dropdown (single-select or multi-select), date range, search box (textual contains-match), toggle (boolean on/off), range slider (numeric min/max), pills (visual multi-select).
  • Default value — what the filter is set to when the user first lands on the view.
  • Label — text shown above the filter control.
  • Width — pixel or percent value for the filter's horizontal space.

Stacking filters

Multiple filters are AND-combined. A user can pick a Status, a Date Range, and an Owner — and the resulting list reflects all three constraints. Filters with no selection contribute nothing (they pass everything through).

The platform's filter UI clearly shows which filters are active, with a quick "Clear all" button to reset. Active filter counts also show in the URL, so users can bookmark or share specific filtered states.

Three real-world filter sets

Example 1: Customer browse view (sales)

  • Status (dropdown) — Active / Inactive / All. Default: Active.
  • Owner (dropdown) — list of salespeople. Default: All.
  • Total Spend Above (number) — Default: blank.
  • Last Activity (date range) — Default: blank.
  • Tags (multi-select pills) — Default: blank.

Example 2: Order queue for fulfilment

  • Status (multi-select dropdown) — Pending / Picking / Packed / Shipped. Default: Pending+Picking.
  • Required-by Date (date range) — Default: today + next 7 days.
  • Warehouse (dropdown) — Default: current user's primary warehouse.
  • Priority (pills) — Standard / High / Urgent.

Example 3: Ticket dashboard for support

  • Status (multi-select pills) — Open / In Progress / Awaiting Customer / Resolved.
  • Assignee (dropdown) — Default: "My Tickets" (current user).
  • Priority (pills).
  • SLA Status (toggle) — On = only show breaching SLA.
  • Customer Tier (multi-select) — Bronze / Silver / Gold / Platinum.

Saved filter sets

If a particular combination is used often, users can save it as a Data Layout — see the Data Layouts section. The Data Layout captures every filter setting plus the column arrangement plus the sort order, giving the user a one-click way back to their preferred view.

Permission-respecting filters

Filter dropdowns that source their options from a datastore (e.g. a Salesperson filter listing the users group) respect the same permission rules as the rest of the platform. A user without read access to the Salespeople table sees no options in the filter — which is correct, but worth knowing when debugging "why doesn't this filter have any options for this user?".

Row Actions

Row Actions are the buttons that appear next to each row in a Browse View — typically Edit, View, Delete, plus any custom actions you add. They're the primary way users interact with individual records on a list page.

Standard row actions

Every datastore-backed Browse View can show some or all of these standard actions automatically. Their visibility per row depends on the user's permissions on the underlying datastore:

  • View — opens the row's read-only detail page. Always safe to expose to users with Read permission.
  • Edit — opens the auto-generated edit form, pre-populated. Requires Edit permission.
  • Copy — duplicates the row into a new draft. Requires Write permission.
  • Delete — soft-deletes the row. Requires Delete permission.
  • Audit History — shows every change to this row over time (if audit mode is on). Requires Read permission.

Custom row actions

Beyond the standards, add any number of bespoke actions per Browse View. For each you configure:

  • Button label and icon (Font Awesome class).
  • Style — primary / secondary / danger / success colour variants.
  • What clicking it does — one of four destination types (covered below).
  • Conditional visibility — only show the button on certain rows based on field values.
  • Per-role permission — which security groups can see this action.
  • Confirmation dialog — optional "are you sure?" prompt before the action fires.

The four destination types for custom actions

1. Open a URL

The simplest. Clicking the button takes the user to a URL, with merge tokens substituted from the row data. Common patterns:

  • /page/orderdetails/##AMDATA_id## — deep-link to a custom page.
  • mailto:##AMDATA_email## — open the user's email client.
  • https://external-system.com/lookup?ref=##AMDATA_refnumber## — open an external lookup.

2. Call a Javascript function

For client-side interactivity that doesn't need a page load. The button calls a function in your platform's loaded JS with the row data passed as an argument. Useful for opening modals, copying values to clipboard, triggering animations.

3. Run a Custom Form

Opens a pre-configured Custom Form pre-populated with the row's data. The form acts on the row when submitted. Examples:

  • A "Quick Update" form that lets the user change just one or two fields without opening the full edit dialog.
  • A "Send Notification" form that prompts for a subject and body, then emails the customer.
  • A "Log Call" form that creates a child record (a call-log entry) linked to the customer.

4. Trigger an AJAX endpoint

Calls a configured endpoint in the background (no page load) with the row ID as a parameter. The endpoint does whatever you need — typically a state change on the row, like marking a ticket resolved or shipping an order.

Conditional visibility

Most row actions shouldn't appear on every row. The conditional-visibility rule lets you restrict where the button shows up. Three common patterns:

  • State-based — "Mark as Shipped" only appears on rows where status = "Packed".
  • Permission-based — "Cancel" only appears for users in the Customer Service group.
  • Computed — "Resend Invoice" only appears when invoice_sent_date IS NOT NULL.

Three real-world action sets

Example 1: Order management

  • View — always visible.
  • Edit — only when status is not Shipped or Cancelled.
  • Mark as Shipped — only when status is Packed.
  • Generate Invoice — only when status is Shipped and invoice not yet generated.
  • Cancel — only when status is Pending.
  • Refund — only when status is Shipped or Delivered, and only for Finance team.

Example 2: Ticket queue

  • View — always.
  • Take (assign to me) — only when ticket is unassigned.
  • Resolve — only when status is In Progress and assigned to current user.
  • Escalate — always for support team.

Example 3: Customer profile

  • View — always.
  • Edit — for customer success team only.
  • Send Welcome Email — only for new customers (less than 30 days old).
  • Schedule Call — opens a booking calendar pre-filled with the customer.
  • Open Support Tickets — links to the tickets browse view filtered to this customer.
Tip: Don't expose too many actions per row. More than 4-5 buttons becomes overwhelming. Group secondary actions into a dropdown menu ("more actions") to keep the primary row clean.

Sorting by Distance

A browse view can offer Nearest First alongside its other sort options. The visitor supplies a starting point and the catalogue reorders around them.

Where to find it

Architect Panel → Layout & Pages:

  • Browse Views — the builder, and its Location & Distance settings

Architect Panel → Integration & Connections:

  • Postcode Lookup — the geocoding this depends on

Architect Panel → Configuration:

  • Site Settings — Look postcodes up — the master switch

Two things must be true

  1. Postcode lookup is enabled for the installation.
  2. The view has a location field configured.

Without the first, the option does not work; without the second, it is not offered. Both are deliberate — a browse view with no location configured does not load any of this machinery at all.

Where the record's location comes from

Point the view at a field that can hold one. Four kinds qualify, and the view works out what to do from the field's own type rather than asking you to declare it:

  • A text field holding a postcode.
  • A Postal Address field — the postcode is read out of it.
  • A Geolocation field — this already holds coordinates, so it needs no lookup and no cache entry at all.
  • A field on a parent record, reached through a link field on this table.

The parent-table case is the useful one

Catalogues frequently hold the thing and not the place: courses at a venue, staff at an office, products at a branch. Rather than copying a postcode onto every record — which then has to be kept in step — point the view at the link field and the postcode on the record it leads to.

One address, one place to correct it, and every child record moves with it.

The visitor's starting point

A postcode box appears beside the sort dropdown when Nearest First is chosen, with a Use my location button. The button uses the browser's own geolocation and passes the coordinates straight through — no lookup, no cost, and no round trip to convert coordinates into a postcode and back.

The typed postcode is remembered in the browser, so a returning visitor does not retype it. Browse views are anonymous, so there is no session to keep it in.

A bad postcode is not an empty catalogue

If the starting point cannot be resolved, the view says so beside the input rather than returning nothing.

That distinction matters more than it sounds: "we could not find that postcode" and "this catalogue is empty" look identical if both produce a blank list, and the visitor draws the wrong conclusion about your service rather than about their typing.

Records that cannot be placed sort last

A record whose postcode is missing or unresolvable still appears — at the end, after everything with a distance. It is not silently dropped, which would be a worse failure for a catalogue where being listed is the point.

The view can also report how many records could not be placed, which is worth surfacing while you are getting the data right.

Show the distance on the card

Two tags are available to the item template: ##AMDATA_AMdistancetext## gives a formatted distance such as "3.4 miles", and ##AMDATA_AMdistance## gives the number alone for when you want to style the unit yourself.

Miles or kilometres

Set per view. It affects the displayed distance and the radius steps together, so the two cannot disagree.

Warm the cache first

On a large catalogue, use the builder's Warm postcode cache button before anybody uses the feature. Otherwise the first visitor triggers the geocoding, bounded by the per-request ceiling, and sees an incomplete ordering until it catches up.

Worked example

A training provider lists 600 courses held at 40 venues. The view points at the link to Venue and the postcode on the venue record, so no course carries an address. The cache is warmed from the builder — 40 postcodes, one call. A visitor enters their postcode and the courses reorder, each card showing "12.4 miles" from the distance tag.

Recommendations

  • Use the parent-table option rather than copying addresses onto child records.
  • Warm the cache before launch and after every bulk import.
  • Put the distance on the card — it is the reason the visitor sorted.
  • Check how many records cannot be placed before you go live.

The Radius Filter

Alongside sorting, a browse view can filter to a radius — everything within five miles, ten, twenty-five.

Where to find it

Architect Panel → Layout & Pages:

  • Browse Views — the builder — the radius steps and the unit

Architect Panel → Integration & Connections:

  • Postcode Lookup — the distances this filters on

Setting it up

Enter the steps as a comma-separated list — 1,3,5,10,25,50. They are cleaned up for you: blanks and anything non-numeric are dropped, duplicates removed, and the rest sorted ascending. Leave it blank and no radius filter is offered.

The steps are in the view's chosen unit, so a view set to kilometres offers kilometre steps.

Choosing the steps

Match them to how your catalogue is actually distributed. A national directory wants 10, 25, 50 and 100; a city one wants 1, 2 and 5. Steps where nothing ever falls are dead options that make the filter look broken.

Five or six is plenty. A long list of radii is a harder decision than it deserves to be, and visitors mostly want "near me" and "a bit further".

Always include a way out

The filter offers an "any distance" option alongside the steps. Make sure your smallest step is not so tight that a visitor's first attempt returns nothing — the most common cause of somebody leaving is an empty result they do not know how to widen.

Unplaced records are excluded

This is the important behavioural difference from sorting. When sorting by distance, a record with no usable postcode appears at the end. When a radius filter is applied, it is excluded.

That is the correct answer to the question being asked. "Show me everything within five miles" is a request for proof of proximity, and a record whose location is unknown cannot supply it. Including it would assert something you do not know.

It does mean a radius filter over a catalogue with poor postcode data quietly hides records. Check how many cannot be placed before offering the filter.

It needs a starting point

The radius has nothing to measure from until the visitor supplies a postcode or uses their location, so it only becomes meaningful once they have. Design the interface so that is obvious rather than presenting a filter that appears to do nothing.

Straight-line, again

"Within 5 miles" means within five miles as the crow flies. In a city that is a good approximation of convenience; across a river, a firth or a mountain it is not. Where the difference matters to your visitors, say which you mean.

Combine it with your other filters

The radius sits alongside the view's ordinary filters, so "within 10 miles" and "evening sessions" work together. That combination is usually what somebody actually wants, and it is worth checking the counts still look sensible once both are applied.

Worked example

A community directory offers 1, 3, 5, 10 and 25 miles with "any distance" as the default. Analysis of a month's use shows almost nobody selects 25, and a good many select 1 and get nothing — so the steps are changed to 2, 5, 10 and 20, and the empty-result rate falls.

Recommendations

  • Match the steps to your data's spread, not to round numbers.
  • Keep "any distance" available and prominent.
  • Check your unplaced record count before offering a radius.
  • Say that distance is straight-line where it could mislead.

The Map View

A browse view can offer a Map alongside its list, showing the same results as pins.

Where to find it

Architect Panel → Layout & Pages:

  • Browse Views — the builder — enable the map, choose a provider, write the pin template

Architect Panel → Integration & Connections:

  • Postcode Lookup — the coordinates the pins use

Architect Panel → Security:

  • Cookie Consent — the consent both providers require

It needs a location, not a distance

The map draws whatever the view returns, so a visitor need not have entered a postcode. Sorting and the radius filter are optional companions rather than prerequisites — but the view still needs a location field configured, because pins need coordinates.

Two providers

  • OpenStreetMap, drawn with Leaflet, which is served from your own installation.
  • Google Maps, which is already loaded for address autocomplete so there is nothing extra to install.

Each view can choose, or leave it blank to follow the installation-wide default. Setting it per view is useful when one catalogue is public-facing and another internal.

Choosing between them

OpenStreetMap avoids sending your visitors to a third party and has no usage billing. Google looks more familiar to most people and has better coverage of business detail. For a public directory the first is usually the better default; for an internal tool the difference rarely matters.

Both require cookie consent

This is the part to plan for rather than discover. Both providers are registered with the consent manager under preferences, so on a consent-enabled page the map is blocked until the visitor accepts.

That is correct behaviour and it has a visible consequence: a visitor who declines preferences cookies must get a click-to-load placeholder explaining why the map is not there, rather than an empty grey box. An unexplained blank area reads as a broken page, and they will not know that accepting would fix it.

Check this deliberately — decline the cookies yourself and look at the page.

The pin popup

Pins use their own template, falling back to the list card template when you have not written one. Write one: a card designed for a list is usually too big for a popup, and the useful content differs — a name, an address and a link is normally enough.

Markers are capped

Worth understanding, because it is visible on the map in a way it is not in a list. A browse view returns the whole table and the front end trims it, so an unbounded catalogue would put every record on the map at once.

The map draws the nearest set and reports how many were not shown. If that number is large, the answer is a filter or a radius rather than a bigger map — a map with two thousand pins is not more informative than one with fifty.

Records without coordinates do not appear

Unavoidably — there is nowhere to put them. That makes the map a good way to spot data quality problems: a catalogue that looks complete as a list and sparse as a map is telling you about its postcodes.

Test both providers if you offer both

They are different implementations behind one interface, and the ways they fail differ — a missing key, a blocked tile server, a consent state. If your installation uses both across different views, check both.

Worked example

A directory enables the map with OpenStreetMap and a short pin template showing the name, town and a link. Declining preferences cookies shows a click-to-load panel explaining that the map needs them. Switching a second, internal view to Google is a per-view setting and needed no other change.

Recommendations

  • Write a dedicated pin template rather than reusing the card.
  • Test the page with consent declined.
  • Use filters to reduce pins, not a larger cap.
  • Treat a sparse map as a data quality signal.