SAP Fiori Elements: Create UI Without Code (2026)

Category
UI
Published
Author
Johannes

SAP Fiori Elements automatically generates modern UIs from your RAP data model. No SAPUI5 programming required!

What Are Fiori Elements?

Fiori Elements are pre-built UI templates that are automatically rendered based on Annotations in CDS Views.

Advantages

  • No UI code: Only annotations
  • Consistent design: SAP Fiori UX Guidelines
  • Low maintenance: Updates automatically from SAP
  • Rapid development: 80% faster than custom UI
  • Responsive: Mobile & Desktop

Disadvantages

  • Limited customization: Only what SAP provides
  • Learning curve: Many annotations

When to use?

  • Transactional Apps (CRUD)
  • Analytical Apps (Reports)
  • Standard Layouts
  • NOT for highly individual UIs - use Custom SAPUI5 instead

1. Fiori Elements Types

TypeUse CaseExample
List ReportTable + FilterCustomer List
Object PageDetail ViewCustomer Details
WorklistTask ListsApproval Workflow
Analytical List PageCharts + TableSales Dashboard
Overview PageTile DashboardManagement Overview

Most common combination: List Report + Object Page


2. Basic Setup: List Report + Object Page

Step 1: RAP Business Object

(From RAP Tutorial Part 1)

/* CDS Projection View */
@EndUserText.label: 'Book - Projection'
@Metadata.allowExtensions: true
define root view entity ZC_BOOK
provider contract transactional_query
as projection on ZI_BOOK
{
key BookId,
Title,
Author,
Publisher,
Price,
CurrencyCode,
Status
}

Step 2: Metadata Extension (Annotations)

File: ZC_BOOK.ddlx

@Metadata.layer: #CORE
annotate view ZC_BOOK with
{
/* ===== HEADER INFO ===== */
@UI.headerInfo: {
typeName: 'Book',
typeNamePlural: 'Books',
title: { value: 'Title' },
description: { value: 'Author' }
}
/* ===== FACETS (Sections in Object Page) ===== */
@UI.facet: [
{
id: 'BookDetails',
purpose: #STANDARD,
type: #IDENTIFICATION_REFERENCE,
label: 'Book Details',
position: 10
}
]
/* ===== FIELDS ===== */
/* List Report: Column + Filter */
@UI.lineItem: [{ position: 10, importance: #HIGH }]
@UI.identification: [{ position: 10 }]
@UI.selectionField: [{ position: 10 }]
BookId;
@UI.lineItem: [{ position: 20, importance: #HIGH }]
@UI.identification: [{ position: 20 }]
@UI.selectionField: [{ position: 20 }]
Title;
@UI.lineItem: [{ position: 30 }]
@UI.identification: [{ position: 30 }]
@UI.selectionField: [{ position: 30 }]
Author;
@UI.lineItem: [{ position: 40 }]
@UI.identification: [{ position: 40 }]
Publisher;
@UI.lineItem: [{ position: 50 }]
@UI.identification: [{ position: 50 }]
Price;
}

Step 3: Service Binding

  1. Create OData V4 - UI Service Binding
  2. Publish
  3. Preview - Done! Your UI is ready!

3. Most Important Annotations

@UI.lineItem - Columns in List

@UI.lineItem: [
{
position: 10, /* Order */
importance: #HIGH, /* HIGH/MEDIUM/LOW */
label: 'Book ID', /* Optional: Custom Label */
criticality: 'Status' /* Optional: Traffic Light Color */
}
]
BookId;

Criticality Values:

  • 0 = Gray (Neutral)
  • 1 = Red (Negative)
  • 2 = Yellow (Critical)
  • 3 = Green (Positive)

@UI.selectionField - Filter

@UI.selectionField: [{ position: 10 }]
Title; /* Displayed as filter at top */

@UI.identification - Detail Fields

@UI.identification: [{ position: 10 }]
BookId; /* Visible in Object Page */

@UI.facet - Sections

@UI.facet: [
/* Identification Facet */
{
id: 'GeneralInfo',
purpose: #STANDARD,
type: #IDENTIFICATION_REFERENCE,
label: 'General Info',
position: 10
},
/* Reference Facet (embed another view) */
{
id: 'Orders',
purpose: #STANDARD,
type: #LINEITEM_REFERENCE,
label: 'Orders',
position: 20,
targetElement: '_Orders' /* Association */
},
/* Field Group */
{
id: 'PriceInfo',
purpose: #STANDARD,
type: #FIELDGROUP_REFERENCE,
label: 'Price Information',
targetQualifier: 'PriceGroup',
position: 30
}
]

@UI.fieldGroup - Grouped Fields

@UI.fieldGroup: [{ qualifier: 'PriceGroup', position: 10 }]
Price;
@UI.fieldGroup: [{ qualifier: 'PriceGroup', position: 20 }]
CurrencyCode;

4. Actions in UI

In BDEF:

action markAsRead result [1] $self;

In Metadata Extension:

@UI.lineItem: [
{ position: 10 },
{
type: #FOR_ACTION,
dataAction: 'markAsRead',
label: 'Mark as Read'
}
]
BookId;

Result: Button in table!


5. Value Helps (Dropdowns)

/* In CDS View */
@Consumption.valueHelpDefinition: [{
entity: {
name: 'I_Currency',
element: 'Currency'
}
}]
CurrencyCode;

Or: Custom Value Help

define view Z_STATUS_VH as select from DDCDS_CUSTOMER_DOMAIN_VALUE_T
{
key value_low as StatusCode,
text as StatusText
}
where domain_name = 'ZBOOK_STATUS';
@Consumption.valueHelpDefinition: [{
entity: { name: 'Z_STATUS_VH', element: 'StatusCode' }
}]
Status;

6. Text Associations

Problem: Status code N should be displayed as “New”.

Solution: Text Association

/* CDS View with Text */
define view ZI_BOOK as select from zbook_tab
association [0..1] to ZI_BOOK_STATUS_TEXT as _StatusText
on $projection.Status = _StatusText.StatusCode
{
key book_id as BookId,
status as Status,
/* Text Element */
_StatusText
}
/* Text View */
define view ZI_BOOK_STATUS_TEXT as select from ...
{
key status_code as StatusCode,
@Semantics.text: true
text as StatusText
}

In Projection:

@ObjectModel.text.element: ['StatusText']
Status;
@UI.hidden: true
StatusText; /* Don't display as separate field */

7. Conditional Formatting (Criticality)

Static Criticality

/* Directly in View */
case status
when 'N' then 2 /* Yellow */
when 'R' then 3 /* Green */
when 'F' then 1 /* Red */
else 0
end as StatusCriticality,

Dynamic Criticality

@UI.lineItem: [{
position: 40,
criticality: 'StatusCriticality'
}]
Status;

Result: Colorful traffic light display!


8. Charts (Analytics)

@UI.chart: [{
qualifier: 'SalesChart',
title: 'Revenue by Month',
chartType: #COLUMN,
dimensions: [ 'Month' ],
measures: [ 'Revenue' ]
}]
@UI.presentationVariant: [{
qualifier: 'Default',
visualizations: [{
type: #AS_CHART,
qualifier: 'SalesChart'
}]
}]
define view Z_SalesAnalytics as select from ...
{
@UI.lineItem: [{ position: 10 }]
month as Month,
@Aggregation.default: #SUM
revenue as Revenue
}

Chart Types:

  • #COLUMN (Columns)
  • #BAR (Bars)
  • #LINE (Line)
  • #PIE (Pie)
  • #DONUT (Donut)

9. Draft Handling

Intermediate saving for long forms

Enable in BDEF

managed with draft;
define behavior for ZI_BOOK
persistent table zbook_tab
draft table zbook_draft
{
create;
update;
delete;
draft action Edit;
draft action Activate;
draft action Discard;
draft action Resume;
draft determine action Prepare;
}

Result: “Edit”, “Save Draft”, “Activate” buttons automatically!


/* Semantic Key (for Object Page URL) */
@ObjectModel.semanticKey: ['BookId']
BookId;
/* Enable Search */
@Search.searchable: true
define view ZC_BOOK as projection on ZI_BOOK
{
@Search.defaultSearchElement: true
@Search.fuzzinessThreshold: 0.8
Title,
@Search.defaultSearchElement: true
Author
}

Result: Search field at top, searches in Title & Author!


Summary: Annotation Cheat Sheet

AnnotationWherePurpose
@UI.lineItemFieldColumn in table
@UI.selectionFieldFieldFilter at top
@UI.identificationFieldDetail field
@UI.facetViewSections
@UI.fieldGroupFieldGrouped fields
@UI.headerInfoViewTitle/Breadcrumb
@UI.chartViewCharts
@ObjectModel.text.elementFieldText display
@Consumption.valueHelpDefinitionFieldDropdown
@Search.searchableViewEnable search

See also:

Good luck with Fiori Elements!