sapui5tutors SAPUI5 • Fiori • SAP BTP Step-by-step tutorials Real project examples Interview Q&A
Practical SAPUI5 • Fiori • SAP BTP tutorials and interview prep

Fiori Elements Floorplans: List Report and Object Page Explained

"The simplest app you can build on a single OData service" — if you've been around Fiori Elements, you've heard this line. It refers to the List Report floorplan: point the framework at an OData entity set, add a few annotations, and you get a working app with search, sorting, filtering, and navigation. No view code. No controller code. Just metadata.

This post explains the two floorplans that carry most Fiori apps — List Report and Object Page — how they work together, and what the framework actually generates from your annotations.


What a floorplan is

A floorplan is a standardized page layout with built-in behavior. Instead of designing each screen from scratch, you pick the floorplan that matches the user's task, and the framework renders it according to rules driven by OData annotations. Same floorplan, same behavior, across every app — that's where Fiori's consistency comes from.

Fiori Elements offers several floorplans (Overview Page, Analytical List Page, Worklist), but two dominate real projects: List Report for finding and acting on collections, and Object Page for viewing and editing a single object. They almost always appear as a pair.

A floorplan is a contract: you supply annotated OData, the framework supplies the entire UI. Your job shifts from building screens to describing data well.

List Report: find it, then act on it

The List Report answers "which one?" — the user searches, filters, sorts a collection, picks an item, and navigates to its Object Page. Purchase orders, sales orders, employee records, service tickets: if the task starts with a list, it starts here.

What the framework generates from annotations:

The filter bar comes from @UI.SelectionFields — each listed property becomes a filter field. Add @UI.FilterFacets and related entities get their own filter groups.

The table comes from @UI.LineItem — each entry becomes a column, in order, with the specified labels and formatting. This is why the annotation vocabulary matters so much: the annotation is the UI specification.

annotate service.Orders with @(
  UI.SelectionFields : [ status, customer_ID ],
  UI.LineItem : [
    { $Type : 'UI.DataField', Value : orderID, Label : 'Order' },
    { $Type : 'UI.DataField', Value : customer.name, Label : 'Customer' },
    { $Type : 'UI.DataField', Value : netAmount, Label : 'Net Value' },
    { $Type : 'UI.DataField', Value : status, Label : 'Status',
      Criticality : statusCriticality }
  ]
);

Four annotation entries, and the framework renders a filter bar with two filters plus a four-column table with status highlighting. The Criticality reference even colors the status column — green, yellow, red — with no UI code.

Actions come from bound OData actions or from @UI.DataFieldForAction entries. They render as toolbar buttons, enabled or disabled based on the action's applicability annotations.

This is the "simplest app" claim made concrete: one entity set, one annotation block, and you have a searchable, sortable, filterable list with navigation. The generator in Fiori tools scaffolds exactly this in about two minutes.


Object Page: everything about one thing

The Object Page answers "tell me everything about this one" — the user arrives from the List Report (or a tile, or a notification) and sees the full picture: header attributes, line items, related entities, attachments, all editable according to the draft and authorization annotations.

Its structure mirrors the DynamicPage control from freestyle UI5, because that's what the framework renders under the hood:

The header comes from @UI.HeaderInfo (title, description, image) plus @UI.FieldGroup annotations grouped into @UI.Facets. Each facet becomes a section — either a field group rendered as a form, or a reference facet pointing at a related entity set.

Line items — the order's items, the employee's assignments — come from @UI.LineItem on the related entity, surfaced through a UI.ReferenceFacet. The framework renders them as embedded tables with their own actions.

annotate service.Orders with @(
  UI.HeaderInfo : {
    TypeName : 'Order',
    Title : { Value : orderID },
    Description : { Value : customer.name }
  },
  UI.Facets : [
    { $Type : 'UI.ReferenceFacet', Label : 'General',
      Target : '@UI.FieldGroup#General' },
    { $Type : 'UI.ReferenceFacet', Label : 'Items',
      Target : 'items/@UI.LineItem' }
  ],
  UI.FieldGroup #General : {
    Data : [
      { Value : orderDate, Label : 'Order Date' },
      { Value : status, Label : 'Status' },
      { Value : netAmount, Label : 'Net Value' }
    ]
  }
);

Two facets: a General form section and an Items table section. Add a third facet pointing at an attachment entity and you get an attachments section. The page grows by annotation, not by code.


How they connect: navigation

The List Report → Object Page navigation needs no configuration when both floorplans target the same OData service. The framework wires it through the entity's navigation properties: tapping a row navigates to the Object Page bound to that entity instance, with the key in the URL hash for bookmarking.

Cross-entity navigation — from an order's Object Page to the customer's Object Page — works through @UI.DataFieldForIntentBasedNavigation or plain navigation properties. And intent-based navigation (semantic object + action) lets a List Report link out to apps the generator never knew about, resolved by the launchpad at runtime.

The List Report finds, the Object Page explains. If your app's flow is "search a collection, inspect one item, act on it," these two floorplans are the whole app — everything else is annotations.

When floorplans aren't enough

Floorplans cover standard patterns brilliantly and custom patterns not at all. The escape hatches, in increasing order of effort:

Building blocks let you embed floorplan pieces (a filter bar, a table, a form) inside a freestyle app. You get the annotation-driven behavior for the standard parts and hand-built UI for the exotic parts.

Custom sections and columns extend the List Report and Object Page themselves — a custom facet on the Object Page, a custom column in the List Report table, a custom action with its own dialog. Most real projects land here: 90% floorplan, 10% custom.

Freestyle is the full custom build. Reach for it when the UX doesn't map to any floorplan — complex wizards, canvas-style editors, highly custom dashboards. You lose the free behavior, so make sure the design genuinely needs it.


Bottom line

List Report for collections, Object Page for single objects, annotations as the UI specification. Learn the dozen annotations that drive these two floorplans and you can build — and more importantly, maintain — most Fiori apps without writing view code. The framework does the rendering; your expertise goes into the data model where it belongs.