
Sapui5
- 253 installs
- 399 repo stars
- Updated August 4, 2026
- secondsky/sap-skills
Helps with ai & agent building tasks.
About
sapui5 is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- sapui5
- AI & Agent Building
- AI-coding skill
Sapui5 by the numbers
- 253 all-time installs (skills.sh)
- +44 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #2,521 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/secondsky/sap-skills --skill sapui5Add your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 253 |
|---|---|
| repo stars | ★ 399 |
| Last updated | August 4, 2026 |
| Repository | secondsky/sap-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
SAPUI5 Development Skill
Related Skills
- sap-fiori-tools: Use for rapid Fiori application development, Page Editor configuration, and deployment automation
- sap-cap-capire: Use for backend service integration, OData model binding, and CAP service consumption
- sap-btp-cloud-platform: Use for deployment options, HTML5 Application Repository service, and BTP integration
- sap-abap: Use when connecting to ABAP backends or consuming OData services from SAP systems
- sap-api-style: Use when documenting UI5 application APIs or following REST/OData standards
- sap-dependency-security: Use for secure dependency upgrades, lockfile policies, supply-chain controls, and exact MCP server pins in SAPUI5 frontend toolchains
When to Use This Skill
Use this skill when building SAPUI5/OpenUI5 applications, XML views, controllers, custom controls, routing, OData v2/v4 model binding, Fiori Elements integrations, QUnit/OPA5 tests, accessibility/security/performance improvements, or UI5 MCP-assisted scaffolding and API lookup.
Comprehensive skill for building enterprise applications with SAP UI5 framework.
Using MCP Tools (New in v2.0.0)
This skill integrates with the official @ui5/mcp-server for live development tools:
- Scaffolding: Create projects with
ui5-app-scaffolderagent or/ui5-scaffoldcommand - API Reference: Lookup controls with
ui5-api-exploreragent or/ui5-apicommand - Code Quality: Run linter with
ui5-code-quality-advisoragent or/ui5-lintcommand - Migration: Upgrade versions with
ui5-migration-specialistagent - Version Info: Check releases with
/ui5-versioncommand - Tool Catalog: List all MCP tools with
/ui5-mcp-toolscommand
For setup and troubleshooting, see references/mcp-integration.md. MCP package pins are governed by sap-dependency-security and validated by npm run validate:mcp-security.
Graceful Fallback: All features work without MCP by using reference files and built-in templates.
Table of Contents
1. Quick Start 2. Core Concepts 3. SAP Fiori Elements 4. Metadata-Driven Controls (MDC) 5. Testing 6. Best Practices 7. Common Patterns 8. Troubleshooting 9. Development Tools 10. Bundled Resources
---
Quick Start
Creating a Basic SAPUI5 App
Use UI5 Tooling (recommended) or SAP Business Application Studio:
# Install UI5 CLI
npm install -g @ui5/cli
# Create new project
mkdir my-sapui5-app && cd my-sapui5-app
npm init -y
# Initialize UI5 project
ui5 init
# Add UI5 dependencies
npm install --save-dev @ui5/cli
# Start development server
ui5 serveProject Structure:
my-sapui5-app/
├── webapp/
│ ├── Component.js
│ ├── manifest.json
│ ├── index.html
│ ├── controller/
│ │ └── Main.controller.js
│ ├── view/
│ │ └── Main.view.xml
│ ├── model/
│ │ └── formatter.js
│ ├── i18n/
│ │ └── i18n.properties
│ ├── css/
│ │ └── style.css
│ └── test/
│ ├── unit/
│ └── integration/
├── ui5.yaml
└── package.jsonTemplates Available:
templates/basic-component.js: Component templatetemplates/manifest.json: Application descriptor templatetemplates/xml-view.xml: XML view with common patternstemplates/controller.js: Controller with best practicestemplates/formatter.js: Common formatter functions
Use templates by copying to your project and replacing placeholders ({{namespace}}, {{ControllerName}}, etc.).
---
Core Concepts
1. MVC Architecture
- Model: Data layer (JSON, OData, XML, Resource models)
- View: Presentation layer (XML, JavaScript, JSON, HTML)
- Controller: Business logic layer
- Binding: Synchronizes model and view (One-way, Two-way, One-time)
Reference: references/core-architecture.md for detailed architecture concepts.
2. Component & Manifest
- Component.js: Entry point, initializes router and models
- manifest.json: Central configuration (models, routing, dependencies, data sources)
Key manifest sections:
sap.app: Application metadata and data sourcessap.ui: UI technology and device typessap.ui5: UI5-specific configuration (models, routing, dependencies)
3. Data Models
JSON Model (client-side):
var oModel = new JSONModel({
products: [...]
});
this.getView().setModel(oModel);OData V2 Model (server-side):
"": {
"dataSource": "mainService",
"settings": {
"defaultBindingMode": "TwoWay",
"useBatch": true
}
}Resource Model (i18n):
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "my.app.i18n.i18n"
}
}Reference: references/data-binding-models.md for comprehensive guide.
4. Views & Controllers
XML View (recommended):
<mvc:View
controllerName="my.app.controller.Main"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<Page title="{i18n>title}">
<List items="{/products}">
<StandardListItem title="{name}" description="{price}"/>
</List>
</Page>
</mvc:View>5. Routing & Navigation
Navigate programmatically:
this.getOwnerComponent().getRouter().navTo("detail", {
objectId: sId
});Reference: references/routing-navigation.md for routing patterns.
---
SAP Fiori Elements
Build applications without JavaScript UI code using OData annotations.
Application Types
1. List Report: Searchable, filterable tables/charts 2. Object Page: Detailed view with sections and facets 3. Analytical List Page: Visual filters and analytics 4. Overview Page: Card-based dashboards 5. Worklist: Simplified list for tasks
Quick Setup
manifest.json for List Report + Object Page:
{
"sap.ui5": {
"dependencies": {
"libs": {
"sap.fe.templates": {}
}
},
"routing": {
"targets": {
"ProductsList": {
"type": "Component",
"name": "sap.fe.templates.ListReport",
"options": {
"settings": {
"contextPath": "/Products",
"variantManagement": "Page"
}
}
}
}
}
}
}Key Annotations:
@UI.LineItem: Table columns@UI.SelectionFields: Filter bar fields@UI.HeaderInfo: Object page header@UI.Facets: Object page sections
Reference: references/fiori-elements.md for comprehensive guide.
---
Metadata-Driven Controls (MDC)
The sap.ui.mdc library provides metadata-driven controls for building dynamic UIs at runtime.
Key Controls
- MDC Table: Data display with dynamic columns based on metadata
- MDC FilterBar: Complex filter conditions with PropertyInfo
- MDC Value Help: Assisted data input with suggestions
Quick Example
<mdc:Table
id="mdcTable"
delegate='{name: "my/app/delegate/TableDelegate", payload: {}}'
p13nMode="Sort,Filter,Column"
type="ResponsiveTable">
<mdc:columns>
<mdcTable:Column propertyKey="name" header="Name">
<Text text="{name}"/>
</mdcTable:Column>
</mdc:columns>
</mdc:Table>Reference: references/mdc-typescript-advanced.md for comprehensive MDC guide with TypeScript.
---
Testing
Unit Tests (QUnit)
Test individual functions and modules:
QUnit.module("Formatter Tests");
QUnit.test("Should format price correctly", function(assert) {
var fPrice = 123.456;
var sResult = formatter.formatPrice(fPrice);
assert.strictEqual(sResult, "123.46 EUR", "Price formatted");
});Integration Tests (OPA5)
Test user interactions and flows:
opaTest("Should navigate to detail page", function(Given, When, Then) {
Given.iStartMyApp();
When.onTheWorklistPage.iPressOnTheFirstListItem();
Then.onTheObjectPage.iShouldSeeTheObjectPage();
Then.iTeardownMyApp();
});Mock Server
Simulate OData backend:
var oMockServer = new MockServer({
rootUri: "/sap/opu/odata/sap/SERVICE_SRV/"
});
oMockServer.simulate("localService/metadata.xml", {
sMockdataBaseUrl: "localService/mockdata"
});
oMockServer.start();Reference: references/testing.md for comprehensive testing guide.
---
Best Practices
1. Always Use Async - sap.ui.define, async:true in manifests 2. Use XML Views - declarative and tooling-friendly 3. Proper Namespacing - com.mycompany.myapp.controller.Main 4. Internationalization - always use i18n for texts 5. Data Binding Over Manual Updates - automatic XSS protection 6. Security - enable CSP, validate input, use HTTPS 7. Performance - component preload, lazy loading, batch requests 8. Accessibility - semantic controls, labels, keyboard navigation
---
Common Patterns
CRUD Operations
// Create
oModel.create("/Products", oData, {success: function() {MessageToast.show("Created");}});
// Read
oModel.read("/Products", {filters: [new Filter("Price", FilterOperator.GT, 100)]});
// Update
oModel.update("/Products(1)", {Price: 200}, {success: function() {MessageToast.show("Updated");}});
// Delete
oModel.remove("/Products(1)", {success: function() {MessageToast.show("Deleted");}});Filtering & Sorting
var oBinding = this.byId("table").getBinding("items");
oBinding.filter([new Filter("price", FilterOperator.GT, 100)]);
oBinding.sort([new Sorter("name", false)]);Dialog Handling
if (!this.pDialog) {
this.pDialog = this.loadFragment({
name: "my.app.view.fragments.MyDialog"
});
}
this.pDialog.then(function(oDialog) {oDialog.open();});---
Troubleshooting Common Issues
Binding not working
1. Check model set on view/component 2. Verify correct binding path 3. Confirm data loaded 4. Debug: console.log(this.getView().getModel().getData())
OData call failing
1. Verify service URL in manifest.json 2. Check CORS configuration 3. Test authentication 4. Use browser Network tab
View not displaying
1. Check view registration in manifest.json 2. Verify routing configuration 3. Match controller name 4. Check browser console for errors
Performance problems
1. Enable component preload 2. Use growing lists for large datasets 3. Implement OData paging 4. Use one-way binding when possible
---
Development Tools
UI5 Tooling
ui5 serve # Development server
ui5 build # Build for production
npm test # Run testsUI5 Inspector
- Browser extension for debugging
- View control tree and bindings
- Performance analysis
Support Assistant
- Press
Ctrl+Alt+Shift+S - Built-in quality checker
---
Bundled Reference Files
This skill includes comprehensive reference documentation (15 files):
1. references/glossary.md: Complete SAPUI5 terminology and concepts (100+ terms) 2. references/core-architecture.md: Framework architecture, components, MVC, bootstrapping 3. references/data-binding-models.md: Data binding, models, filters, sorters 4. references/testing.md: QUnit, OPA5, mock server, test automation 5. references/fiori-elements.md: Fiori Elements templates, annotations, configuration 6. references/typescript-support.md: TypeScript setup, configuration, migration 7. references/routing-navigation.md: Routing, navigation, Flexible Column Layout 8. references/performance-optimization.md: Performance best practices, optimization 9. references/accessibility.md: WCAG 2.1 compliance, screen readers, ARIA 10. references/security.md: XSS prevention, CSP, authentication, CSRF 11. references/mdc-typescript-advanced.md: MDC controls, TypeScript control libraries 12. references/mcp-integration.md: MCP setup, troubleshooting, and fallback behavior 13. references/code-quality-checklist.md: Review checklist for UI5 projects 14. references/migration-patterns.md: Upgrade and modernization patterns 15. references/scaffolding-templates.md: Project scaffolding guidance
Access these files for detailed information on specific topics while keeping the main skill concise.
---
Templates Included
Ready-to-use templates in templates/ directory:
1. basic-component.js: Component.js template with best practices 2. manifest.json: Complete application descriptor template 3. xml-view.xml: XML view with common patterns 4. controller.js: Controller template with lifecycle hooks 5. formatter.js: Common formatter functions
---
Instructions for Claude
When using this skill:
1. Always use async patterns - sap.ui.define, async:true 2. Prefer XML views - more declarative and tooling-friendly 3. Use data binding - automatic XSS protection 4. Refer to reference files - for detailed information 5. Use templates - copy from templates/ and replace placeholders 6. Follow best practices - security, performance, accessibility 7. Provide working examples - test code patterns before suggesting
---
Bundled Resources
Reference Documentation
references/accessibility.md- Accessibility best practicesreferences/core-architecture.md- Framework architecture and component patternsreferences/data-binding-models.md- Data binding and model usagereferences/fiori-elements.md- Fiori Elements templates and annotationsreferences/mdc-typescript-advanced.md- MDC and TypeScript guidancereferences/mcp-integration.md- MCP setup and troubleshootingreferences/migration-patterns.md- Migration from older versionsreferences/performance-optimization.md- Performance optimization techniquesreferences/testing.md- Testing strategies and frameworksreferences/security.md- XSS, CSP, authentication, and CSRF guidance
Templates
templates/basic-component.js- Component development templatetemplates/controller.js- Controller templatetemplates/xml-view.xml- XML view templatetemplates/formatter.js- Formatter helper templatetemplates/manifest.json- Application manifest template
---
License: GPL-3.0 Next Review: 2026-02-27 (Quarterly)
SAPUI5 Development Skill
Comprehensive skill for developing enterprise web applications with SAP UI5 framework.
Capability Index
| Capability | Status |
|---|---|
| Commands | 5: /ui5-api, /ui5-lint, /ui5-mcp-tools, /ui5-scaffold, /ui5-version |
| Agents | 4: ui5-api-explorer, ui5-app-scaffolder, ui5-code-quality-advisor, ui5-migration-specialist |
| Hooks | Yes: hooks/hooks.json |
| MCP | Yes: .mcp.json |
| LSP | No |
| Source Freshness | last_verified: 2026-05-31; UI5 MCP/tooling package evidence tracked in audit report. |
| Verification | npm run validate; app-specific preview/build checks require a target UI5 app. |
Auto-Trigger Keywords
This skill is automatically triggered when Claude Code detects these keywords in user requests:
Framework & Core
sapui5, ui5, openui5, sap ui5, sap-ui5, ui5 framework, sapui5 framework, ui5 application, sapui5 app, ui5 development, sapui5 development
Project Setup
ui5 init, ui5 serve, ui5 build, ui5 tooling, ui5 cli, @ui5/cli, ui5.yaml, ui5-project, ui5 configuration, sap business application studio, sap web ide
Application Structure
Component.js, manifest.json, application descriptor, ui5 component, sap.ui.core.UIComponent, component-based, ui5 manifest, sap.app, sap.ui5, ui5 routing
Views & Controllers
xml view, json view, javascript view, html view, mvc:View, sap.ui.core.mvc.Controller, controller.js, view.xml, ui5 controller, ui5 view, view controller binding
Data Binding & Models
data binding, property binding, aggregation binding, element binding, expression binding, json model, odata model, odata v2, odata v4, xml model, resource model, i18n model, sap.ui.model, two-way binding, one-way binding, binding mode, binding path, binding context
Controls & Libraries
sap.m, sap.ui.table, sap.f, sap.uxap, sap.ui.layout, sap.tnt, sap.suite.ui.commons, ui5 controls, mobile controls, table control, list control, button control, input control, dialog control, popover control, responsive table, analytical table, tree table
Fiori Elements
fiori elements, sap fiori elements, list report, object page, analytical list page, overview page, worklist, fiori template, sap.fe.templates, ui annotations, odata annotations, @UI.LineItem, @UI.SelectionFields, @UI.HeaderInfo, @UI.Facets, @UI.FieldGroup, building blocks, flexible column layout
Routing & Navigation
ui5 routing, sap.m.routing.Router, router configuration, route pattern, routing targets, navigation, navTo, route matched, hash navigation, url parameters, deep linking
Testing
qunit, opa5, ui5 testing, unit test, integration test, opa test, mock server, sap.ui.test, test automation, ui5 inspector, support assistant, code coverage, karma ui5, test journey, page object
OData Integration
odata service, odata binding, odata batch, odata filter, odata read, odata create, odata update, odata delete, $expand, $select, $filter, $orderby, $skip, $top, odata metadata, service metadata, odata v2 model, odata v4 model, draft handling, function import
Performance & Optimization
component preload, lazy loading, bundling, minification, cache buster, async loading, ui5 performance, table virtualization, growing list, batch request, preload, ui5 build optimization
Security
xss prevention, content security policy, csp, ui5 security, input validation, output encoding, csrf token, clickjacking, secure programming, browser security
Accessibility
aria, accessibility, screen reader, keyboard navigation, high contrast, a11y, sapUiSizeCompact, sapUiSizeCozy, content density, rtl, right-to-left
Theming
sap_horizon, sap_fiori_3, sap_fiori_3_dark, sap_belize, ui5 theme, theme parameter, custom theme, ui theme designer, theme css
Deployment & Build
ui5 deployment, sapui5 deployment, bsp repository, abap repository, cloud foundry deployment, btp deployment, fiori launchpad, flp integration, ui5 build, production build
Error Handling
ui5 error, binding error, odata error, runtime error, ui5 debug, console error, error handling, message handling, sap.m.MessageBox, sap.m.MessageToast, sap.m.MessageStrip
Fragments
ui5 fragment, xml fragment, fragment definition, dialog fragment, loadFragment, fragment reuse, core:FragmentDefinition
Formatters & Types
formatter, data type, sap.ui.model.type, format date, format currency, format number, custom formatter, expression binding, composite binding
State Management
view model, json model, device model, app model, local storage, session storage, state management, variant management, personalization
Custom Controls
custom control, control development, control renderer, control metadata, control properties, control events, control aggregations, sap.ui.core.Control, composite control
Metadata-Driven Controls (MDC)
sap.ui.mdc, mdc controls, mdc table, mdc filterbar, mdc value help, metadata-driven controls, control delegates, PropertyInfo, TypeMap, VariantManagement, mdc personalization, p13nMode, mdc delegate
TypeScript Control Libraries
control library typescript, ts-interface-generator, @ui5/ts-interface-generator, ui5-tooling-transpile, typescript control library, library.ts, enum registration, ObjectPath, TypeScript UI5 library
APF (Analysis Path Framework)
apf, analysis path framework, apf configuration, apf modeler, analysis step, apf representation, smart filter bar apf
Common Issues & Troubleshooting
ui5 troubleshooting, binding not working, odata not loading, view not displaying, routing not working, cors error ui5, 404 error ui5, metadata error, service error, component not found
File Extensions
.controller.js, .view.xml, .fragment.xml, Component.js, manifest.json, i18n.properties, ui5.yaml, .qunit.html, .opa.js
Development Tools
ui5 tooling, yeoman ui5, generator-easy-ui5, ui5 snippets, ui5 linter, ui5 typescript, ui5 migration
SAP Technologies
sap gateway, sap netweaver, sap s/4hana, sap btp, sap cloud platform, sap fiori launchpad, sap business suite
What This Skill Covers
Application Development
- Freestyle SAPUI5 applications
- SAP Fiori Elements applications
- Component-based architecture
- Project structure and organization
- manifest.json configuration
- UI5 Tooling setup
MVC Pattern
- XML, JSON, JavaScript, and HTML views
- Controllers with lifecycle hooks
- Model types (JSON, OData v2/v4, XML, Resource)
- Data binding patterns
- Routing and navigation
Data Management
- OData v2 and v4 integration
- CRUD operations
- Batch requests
- Filters and sorters
- Data types and formatters
- Expression binding
UI Development
- sap.m controls (mobile/responsive)
- Tables and lists
- Forms and inputs
- Dialogs and popovers
- Layouts (FlexBox, Grid, Dynamic Page)
- Fragments for reuse
Fiori Elements
- List Report applications
- Object Page applications
- Analytical List Page
- Overview Page
- Worklist
- OData annotations (@UI, @Common, @Capabilities)
- Building blocks
- Extension points
Testing
- Unit testing with QUnit
- Integration testing with OPA5
- Mock server setup
- Test automation
- Code coverage
- Page objects and journeys
Advanced Features
- Custom control development
- Application extensions
- Draft handling
- Flexible Column Layout
- Variant management
- Personalization
Security & Performance
- XSS prevention
- Content Security Policy
- Performance optimization
- Lazy loading
- Bundling and minification
- Accessibility implementation
Templates Included
1. basic-component.js: Component template with router and device model 2. manifest.json: Complete application descriptor 3. xml-view.xml: XML view with table, search, and filters 4. controller.js: Controller with CRUD operations and event handlers 5. formatter.js: Common formatters (date, currency, status, etc.)
Reference Documentation
1. glossary.md: Complete SAPUI5 terminology (100+ terms) 2. core-architecture.md: Framework architecture and concepts 3. data-binding-models.md: Data binding and model usage 4. testing.md: Testing strategies and best practices 5. fiori-elements.md: Fiori Elements configuration and annotations 6. typescript-support.md: TypeScript setup, configuration, and migration 7. routing-navigation.md: Routing, navigation, and Flexible Column Layout 8. performance-optimization.md: Performance best practices and optimization 9. accessibility.md: WCAG 2.1 compliance, screen readers, ARIA, keyboard navigation 10. security.md: XSS prevention, CSP, authentication, CSRF, secure coding 11. mdc-typescript-advanced.md: Metadata-Driven Controls (sap.ui.mdc), TypeScript control library development
Official Documentation
- Main Docs: https://github.com/SAP-docs/sapui5
- Demo Kit: https://sapui5.hana.ondemand.com/
- API Reference: https://sapui5.hana.ondemand.com/#/api
Version
- Skill Version: 2.0.0
- Minimum UI5 Version: 1.120.0
- Latest SAPUI5 Version Verified: 1.148.1
- Last Updated: 2026-05-31
- Status: Production
What's New in v2.0.0 (2025-12-28) - MCP Integration & Plugin-Dev Best Practices
- ✅ MCP Integration: Official @ui5/mcp-server with 9 live tools
- ✅ 4 Specialized Agents: Scaffolding, API Explorer, Code Quality, Migration
- ✅ 5 Slash Commands: /ui5-api, /ui5-scaffold, /ui5-lint, /ui5-version, /ui5-mcp-tools
- ✅ Validation Hooks: PreToolUse and PostToolUse quality gates (user approval)
- ✅ 15 Reference Files: +4 new guides (MCP integration, scaffolding, migration, quality)
- ✅ User Settings: Configurable preferences via sapui5.local.md
- ✅ Graceful Degradation: Full functionality without MCP (reference file fallback)
- ✅ Keywords: +20 new auto-trigger keywords for agents and commands
What's New in v1.4.0
- ✅ Major SKILL.md optimization: 855 → 452 lines (47% reduction)
- ✅ Added comprehensive Table of Contents for improved navigation
- ✅ Implemented progressive disclosure architecture
- ✅ Fixed frontmatter name mismatch (critical for discovery)
- ✅ Token efficiency improved from ~45% to ~70%
- ✅ Better organized content with clear reference pointers
What's New in v1.3.0
- ✅ Added Metadata-Driven Controls (MDC) documentation (sap.ui.mdc library)
- ✅ Added TypeScript control library development guide
- ✅ New reference file:
mdc-typescript-advanced.md(~10KB) - ✅ Sources: SAP-samples/ui5-mdc-json-tutorial, SAP-samples/ui5-typescript-control-library
- ✅ Enhanced coverage from 10 to 11 reference files (~190KB total documentation)
What's New in v1.2.0
- ✅ Added comprehensive accessibility guide (WCAG 2.1, screen readers, ARIA, keyboard navigation)
- ✅ Added security best practices (XSS, CSP, clickjacking, CSRF, authentication)
- ✅ Enhanced coverage from 8 to 10 reference files (~180KB total documentation)
- ✅ 100% coverage of critical enterprise requirements
What's New in v1.1.0
- ✅ Added TypeScript support reference (setup, configuration, types, migration)
- ✅ Added comprehensive routing & navigation guide (hash-based, FCL, parameters)
- ✅ Added performance optimization reference (async loading, CDN, preload, OData)
- ✅ Enhanced coverage from 5 to 8 reference files (~150KB total documentation)
- ✅ All 1,416 documentation files from official SAP SAPUI5 docs reviewed
License
GPL-3.0
---
Maintained by: Eduard Jiglau | hello@sap-ai-skills.com | sap-ai-skills.com | https://github.com/secondsky/sap-skills
SAPUI5 Accessibility Guide
Source: Official SAP SAPUI5 Documentation Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/05_Developing_Apps Last Updated: 2025-11-21
---
Overview
Accessibility in SAPUI5 ensures applications are usable by everyone, including people with disabilities. SAPUI5 controls include built-in accessibility features, but developers must implement them correctly.
Standards: SAPUI5 follows WCAG 2.1 (Web Content Accessibility Guidelines) Level AA.
Key Principles: 1. Perceivable: Information must be presentable to users in ways they can perceive 2. Operable: User interface components must be operable 3. Understandable: Information and operation must be understandable 4. Robust: Content must be robust enough to work with assistive technologies
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/05_Developing_Apps (search: accessibility)
---
Screen Reader Support
Overview
Screen readers announce UI content to visually impaired users. SAPUI5 controls provide built-in screen reader support through ARIA attributes.
Supported Screen Readers:
- JAWS (Windows)
- NVDA (Windows)
- VoiceOver (macOS, iOS)
- TalkBack (Android)
Implementation
Automatic Support: Most SAP UI5 controls include screen reader support automatically:
<Button
text="Save"
icon="sap-icon://save"
press=".onSave"/>
<!-- Automatically announces: "Save button" -->Custom Labels:
<Input
value="{/email}"
ariaLabelledBy="emailLabel"/>
<Label
id="emailLabel"
text="Email Address"
labelFor="emailInput"/>ARIA Descriptions:
<Button
text="Delete"
ariaDescribedBy="deleteHint"/>
<InvisibleText
id="deleteHint"
text="This action cannot be undone"/>Invisible Text
Provide information only for screen readers:
<InvisibleText
id="statusHint"
text="Status: {status}. Last updated: {lastUpdate}"/>
<ObjectStatus
text="{status}"
state="{statusState}"
ariaDescribedBy="statusHint"/>Use Cases:
- Additional context not visible on screen
- Status changes announcements
- Navigation instructions
- Form validation messages
Invisible Messaging
Announce dynamic content changes to screen readers:
sap.ui.require([
"sap/ui/core/InvisibleMessage",
"sap/ui/core/library"
], function(InvisibleMessage, coreLibrary) {
var InvisibleMessageMode = coreLibrary.InvisibleMessageMode;
// Get instance
var oInvisibleMessage = InvisibleMessage.getInstance();
// Announce politely (after current announcement)
oInvisibleMessage.announce("Data loaded successfully", InvisibleMessageMode.Polite);
// Announce assertively (interrupts current announcement)
oInvisibleMessage.announce("Error: Form submission failed", InvisibleMessageMode.Assertive);
});Modes:
Polite: Wait for current announcement to finishAssertive: Interrupt current announcement immediately
Use Cases:
- Loading states
- Error messages
- Success confirmations
- Dynamic content updates
---
Keyboard Navigation
Overview
All functionality must be accessible via keyboard without requiring a mouse.
Standard Keys:
- Tab: Move focus forward
- Shift+Tab: Move focus backward
- Enter/Space: Activate buttons, links
- Arrow Keys: Navigate within components
- Esc: Close dialogs, cancel actions
- Home/End: Jump to first/last item
Focus Management
Visible Focus Indicator: All focusable elements must have a visible focus indicator (automatically provided by SAPUI5 controls).
Focus Order:
<!-- Logical focus order -->
<VBox>
<Input id="firstName" value="{/firstName}"/>
<Input id="lastName" value="{/lastName}"/>
<Input id="email" value="{/email}"/>
<Button text="Submit" press=".onSubmit"/>
</VBox>Programmatic Focus:
// Set focus to control
this.byId("emailInput").focus();
// Set focus after dialog opens
oDialog.attachAfterOpen(function() {
oDialog.getInitialFocus().focus();
});Keyboard Handling
Handling Keyboard Events:
onKeyDown: function(oEvent) {
// Check for specific key
if (oEvent.keyCode === jQuery.sap.KeyCodes.ENTER) {
this.onSave();
oEvent.preventDefault();
}
// Check for Escape
if (oEvent.keyCode === jQuery.sap.KeyCodes.ESCAPE) {
this.onCancel();
}
}Item Navigation: For custom list-like controls:
sap.ui.require([
"sap/ui/core/delegate/ItemNavigation"
], function(ItemNavigation) {
onAfterRendering: function() {
// Create item navigation
this._oItemNavigation = new ItemNavigation();
// Set root element and items
this._oItemNavigation.setRootDomRef(this.getDomRef());
this._oItemNavigation.setItemDomRefs(this.$().find(".item").toArray());
// Configure navigation
this._oItemNavigation.setCycling(false);
this._oItemNavigation.setPageSize(10);
// Attach to element
this.addDelegate(this._oItemNavigation);
},
onExit: function() {
if (this._oItemNavigation) {
this._oItemNavigation.destroy();
}
}
});Fast Navigation
F6 key for quick navigation between major screen regions:
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/core/CustomData"
], function(Controller, CustomData) {
"use strict";
return Controller.extend("my.app.controller.Main", {
onInit: function() {
// Mark sections for F6 navigation
this.byId("headerSection").addCustomData(
new CustomData({
key: "sap-ui-fastnavgroup",
value: "true"
})
);
this.byId("contentSection").addCustomData(
new CustomData({
key: "sap-ui-fastnavgroup",
value: "true"
})
);
}
});
});Use Cases:
- Skip from header to content
- Jump to footer
- Navigate between major sections
---
ARIA Implementation
ARIA Attributes
role: Defines element type:
<div role="navigation">...</div>
<div role="main">...</div>
<div role="complementary">...</div>aria-label: Provides accessible name:
<Button
icon="sap-icon://delete"
aria-label="Delete item"/>aria-labelledby: References label element:
<Label id="nameLabel" text="Full Name"/>
<Input ariaLabelledBy="nameLabel"/>aria-describedby: References description:
<Input
value="{/password}"
ariaDescribedBy="passwordHint"/>
<Text id="passwordHint" text="Must be at least 8 characters"/>aria-live: Announces dynamic updates:
<Text
text="{statusMessage}"
aria-live="polite"/>aria-expanded: Indicates expanded/collapsed state:
<Button
text="Show Details"
aria-expanded="{detailsVisible}"
press=".onToggleDetails"/>Landmark Regions
Define major page sections using landmarks:
sap.ui.require([
"sap/ui/core/AccessibleLandmarkRole"
], function(AccessibleLandmarkRole) {
// In XML view
<Page
landmarkInfo="{
rootRole: 'Region',
rootLabel: 'Product Details',
contentRole: 'Main',
contentLabel: 'Product Information',
headerRole: 'Banner',
headerLabel: 'Page Header',
footerRole: 'Region',
footerLabel: 'Page Actions'
}">
</Page>
});Standard Roles:
banner: Site headernavigation: Navigation sectionmain: Main contentcomplementary: Supporting contentcontentinfo: Site footerregion: Generic landmarksearch: Search functionality
---
Labeling & Tooltips
Labels
Always Provide Labels:
<!-- Good -->
<Label text="First Name" labelFor="firstName"/>
<Input id="firstName" value="{/firstName}"/>
<!-- Bad (no visible label) -->
<Input placeholder="First Name"/> <!-- Placeholders are not labels -->Required Fields:
<Label
text="Email"
required="true"
labelFor="email"/>
<Input
id="email"
value="{/email}"
required="true"/>Tooltips
Provide additional information:
<Button
icon="sap-icon://hint"
tooltip="Click for more information"
press=".onShowHelp"/>Rich Tooltips:
<Button icon="sap-icon://action-settings">
<customData>
<core:CustomData
key="tooltip"
value="Settings (Ctrl+,)"/>
</customData>
</Button>---
Form Accessibility
Field Labels
<form:SimpleForm>
<Label text="First Name" required="true"/>
<Input value="{/firstName}" required="true"/>
<Label text="Last Name" required="true"/>
<Input value="{/lastName}" required="true"/>
<Label text="Email"/>
<Input value="{/email}" type="Email"/>
<Label text="Phone"/>
<Input value="{/phone}" type="Tel"/>
</form:SimpleForm>Error Messages
<Input
value="{/email}"
valueState="{= ${/emailValid} ? 'None' : 'Error'}"
valueStateText="Please enter a valid email address"/>Field Groups
<VBox>
<Title text="Personal Information"/>
<Input value="{/firstName}" ariaLabelledBy="personalInfoTitle"/>
<Input value="{/lastName}" ariaLabelledBy="personalInfoTitle"/>
</VBox>---
Table Accessibility
Column Headers
<Table items="{/products}">
<columns>
<Column>
<Text text="Product Name"/>
</Column>
<Column>
<Text text="Price"/>
</Column>
<Column>
<Text text="Status"/>
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Text text="{name}"/>
<Text text="{price}"/>
<ObjectStatus text="{status}" state="{statusState}"/>
</cells>
</ColumnListItem>
</items>
</Table>Row Actions
<ColumnListItem type="Active" press=".onRowPress">
<cells>
<Text text="{name}"/>
</cells>
<customData>
<core:CustomData
key="aria-label"
value="View details for {name}"/>
</customData>
</ColumnListItem>---
High Contrast Themes
Overview
High contrast themes help users with visual impairments.
Available Themes:
sap_fiori_3_hcb: High Contrast Blacksap_fiori_3_hcw: High Contrast Whitesap_horizon_hcb: Horizon High Contrast Blacksap_horizon_hcw: Horizon High Contrast White
Testing
Test your app with high contrast themes:
// Switch theme programmatically
sap.ui.getCore().applyTheme("sap_horizon_hcb");In URL:
http://myapp.com/index.html?sap-ui-theme=sap_horizon_hcbCSS Considerations
Use theme parameters, not hard-coded colors:
/* Good */
.myClass {
color: var(--sapUiContentForegroundColor);
background-color: var(--sapUiBaseBG);
}
/* Bad */
.myClass {
color: #333333;
background-color: #ffffff;
}---
Right-to-Left (RTL) Support
Overview
Support languages written right-to-left (Arabic, Hebrew, etc.).
Configuration
Enable RTL:
<script
src="resources/sap-ui-core.js"
data-sap-ui-rtl="true">
</script>Or programmatically:
sap.ui.getCore().getConfiguration().setRTL(true);CSS for RTL
Use logical properties:
/* Good (automatically flipped in RTL) */
.myClass {
padding-inline-start: 1rem;
margin-inline-end: 0.5rem;
border-inline-start: 1px solid;
}
/* Bad (not flipped) */
.myClass {
padding-left: 1rem;
margin-right: 0.5rem;
border-left: 1px solid;
}Text Direction
<Text text="{description}" textDirection="Inherit"/>
<!-- Force LTR for codes/IDs -->
<Text text="{productId}" textDirection="LTR"/>---
Testing Accessibility
Manual Testing
1. Keyboard Navigation:
- Tab through all interactive elements
- Verify focus visibility
- Test Enter/Space activation
- Test Esc key behavior
2. Screen Reader:
- Test with JAWS, NVDA, or VoiceOver
- Verify all content is announced
- Check announcements are meaningful
- Test dynamic content updates
3. High Contrast:
- Switch to high contrast theme
- Verify all content is visible
- Check color contrast ratios
4. Zoom:
- Zoom to 200%
- Verify layout doesn't break
- Check text remains readable
Automated Testing
Use UI5 Support Assistant:
// Enable support assistant
sap.ui.require(["sap/ui/support/RuleAnalyzer"], function(RuleAnalyzer) {
RuleAnalyzer.analyze();
});Or via keyboard: Ctrl+Alt+Shift+S
Checks:
- Missing labels
- Invalid ARIA attributes
- Keyboard navigation issues
- Color contrast problems
---
Accessibility Checklist
General
- [ ] All functionality keyboard accessible
- [ ] Focus indicators visible
- [ ] Logical focus order
- [ ] No keyboard traps
- [ ] Esc key closes dialogs
Labeling
- [ ] All form fields have labels
- [ ] Required fields marked
- [ ] Error messages clear and accessible
- [ ] Buttons have meaningful labels
- [ ] Images have alt text
ARIA
- [ ] Proper ARIA roles used
- [ ] aria-label or aria-labelledby on inputs
- [ ] aria-describedby for additional info
- [ ] aria-live for dynamic updates
- [ ] Landmark regions defined
Screen Readers
- [ ] Test with screen reader
- [ ] All content announced
- [ ] Announcements meaningful
- [ ] InvisibleText used where needed
- [ ] Dynamic updates announced
Visual
- [ ] Color contrast sufficient (4.5:1 for text)
- [ ] Works with high contrast themes
- [ ] Text remains readable at 200% zoom
- [ ] No information by color alone
Tables
- [ ] Column headers defined
- [ ] Row headers where appropriate
- [ ] Summary/caption provided
- [ ] Complex tables avoided
---
Common Issues
Issue: Input without label
Bad:
<Input placeholder="Search..."/>Good:
<Label text="Search" labelFor="searchInput"/>
<Input id="searchInput" placeholder="Enter search term..."/>Issue: Button with only icon
Bad:
<Button icon="sap-icon://delete" press=".onDelete"/>Good:
<Button
icon="sap-icon://delete"
tooltip="Delete item"
ariaLabel="Delete item"
press=".onDelete"/>Issue: Dynamic content not announced
Bad:
this.byId("statusText").setText("Loading complete");Good:
this.byId("statusText").setText("Loading complete");
// Announce to screen reader
var oInvisibleMessage = sap.ui.core.InvisibleMessage.getInstance();
oInvisibleMessage.announce("Loading complete", "Polite");---
Official Documentation
- Accessibility: https://github.com/SAP-docs/sapui5/tree/main/docs/05_Developing_Apps (search: accessibility)
- Screen Reader Support: https://github.com/SAP-docs/sapui5/tree/main/docs/05_Developing_Apps (search: screen-reader)
- Keyboard Handling: https://github.com/SAP-docs/sapui5/tree/main/docs/05_Developing_Apps (search: keyboard)
- ARIA: https://www.w3.org/WAI/ARIA/
- WCAG 2.1: https://www.w3.org/WAI/WCAG21/quickref/
---
Note: This document covers accessibility implementation in SAPUI5. Accessibility is not optional - it's a requirement for enterprise applications. Always test with keyboard and screen readers.
UI5 Code Quality Checklist
Table of Contents
1. Architecture Review 2. Performance Checklist 3. Security Checklist 4. Accessibility Checklist 5. Testing Checklist 6. Build Configuration 7. Code Style Checklist 8. Documentation Checklist 9. Pre-Deployment Checklist
---
Architecture Review
MVC Pattern Compliance
- [ ] Controllers: No business logic, only view logic
- Controllers orchestrate view and model
- No direct DOM manipulation
- No SQL queries or complex calculations
- [ ] Models: All data access through models
- JSON Model for local data
- OData Model for backend data
- No hardcoded data in views or controllers
- [ ] Views: Declarative XML views (preferred)
- No JavaScript in views
- Data binding for all dynamic content
- Proper use of fragments for reusable UI
Component Structure
- [ ] Component-based architecture: Application uses Component.js
- [ ] Manifest-first: All configuration in manifest.json
- Models defined in manifest
- Routing configured in manifest
- Dependencies listed in manifest
- [ ] Proper namespace: Reverse domain notation
✅ com.mycompany.myapp
❌ myapp- [ ] No global variables: All code in proper modules
- [ ] Dependency injection: Use sap.ui.define for all modules
File Organization
- [ ] Logical grouping: Controllers and views grouped by feature
webapp/
├── controller/
│ ├── products/
│ │ ├── List.controller.js
│ │ └── Detail.controller.js
│ └── orders/
│ └── List.controller.js
├── view/
│ ├── products/
│ │ ├── List.view.xml
│ │ └── Detail.view.xml
│ └── orders/
│ └── List.view.xml- [ ] Shared code in model/: Formatters, utilities, constants
- [ ] i18n folder: All translatable texts
- [ ] No duplicate code: Reusable code extracted to utilities
---
Performance Checklist
Component Preload
- [ ] Component-preload.js: Generated during build
- [ ] ui5.yaml configured: componentPreload enabled
builder:
componentPreload:
paths:
- "webapp/Component.js"- [ ] Production build: Always use
ui5 build --all
Lazy Loading
- [ ] On-demand module loading: Use
sap.ui.requirefor non-critical modules
sap.ui.require(["sap/m/MessageBox"], function(MessageBox) {
MessageBox.show("Loaded on demand");
});- [ ] Fragment lazy loading: Load fragments only when needed
- [ ] Image optimization: Use appropriate image formats (WebP, SVG)
Data Binding Optimization
- [ ] Batch requests: OData batch mode enabled
useBatch: true- [ ] Server-side operations: Filtering, sorting, paging on server
<Table items="{
path: '/Products',
parameters: {
$select: 'ID,Name,Price',
$top: 20
}
}">- [ ] Auto-expand-select: OData V4 auto-expansion
autoExpandSelect: trueList Virtualization
- [ ] Large lists: Use
sap.ui.table.Table(virtualized) for 100+ items
<!-- ❌ Wrong for large data -->
<m:List items="{/Products}">
<!-- ✅ Correct for large data -->
<table:Table rows="{/Products}" visibleRowCount="20">- [ ] Growing lists: Use growing feature for mobile
<m:List growing="true" growingThreshold="20">Resource Optimization
- [ ] Minimize bundle size: Remove unused libraries from manifest
- [ ] Compression: Enable gzip/brotli on server
- [ ] CDN usage: Load UI5 from SAP CDN (production)
<script src="https://ui5.sap.com/1.120.0/resources/sap-ui-core.js"></script>- [ ] Cache headers: Set proper cache headers for static resources
---
Security Checklist
XSS Prevention
- [ ] Data binding: Always use data binding, never innerHTML
<!-- ✅ Correct -->
<Text text="{/userName}"/>
<!-- ❌ Wrong -->
<HTML content="{/userInput}"/>- [ ] Input validation: Validate all user input
var sInput = oEvent.getParameter("value");
if (!/^[a-zA-Z0-9]+$/.test(sInput)) {
oInput.setValueState("Error");
return;
}- [ ] Sanitize HTML: Use
jQuery.sap.encodeHTML(if needed)
Content Security Policy (CSP)
- [ ] No inline scripts: All JS in external files
- [ ] No eval(): Never use eval, new Function(), or setTimeout with strings
- [ ] CSP headers: Configure CSP headers on server
Content-Security-Policy: default-src 'self'; script-src 'self' ui5.sap.comAuthentication & Authorization
- [ ] Session management: Proper session timeout
- [ ] Token-based auth: Use JWT or OAuth tokens
- [ ] CSRF protection: Enable CSRF tokens for OData
// OData V2
oModel.setHeaders({
"X-CSRF-Token": "Fetch"
});- [ ] Role-based access: Check user permissions before actions
Secure Communication
- [ ] HTTPS only: Never use HTTP in production
- [ ] Secure cookies: HttpOnly and Secure flags
- [ ] CORS configuration: Whitelist specific domains
Access-Control-Allow-Origin: https://myapp.com---
Accessibility Checklist
WCAG 2.1 AA Compliance
- [ ] Semantic HTML: Use proper HTML5 elements
- [ ] ARIA attributes: Add ARIA labels where needed
<Button text="Delete" ariaLabelledBy="deleteLabel"/>
<Text id="deleteLabel" text="Delete selected item"/>- [ ] Keyboard navigation: All functionality accessible via keyboard
- Tab through all interactive elements
- Enter/Space activates buttons
- Arrow keys navigate lists
- [ ] Focus indicators: Visible focus outlines
/* Don't remove focus outlines */
*:focus {
outline: 2px solid #0854A0; /* SAP Blue */
}Screen Reader Support
- [ ] Alt text: All images have alt text
<Image src="logo.png" alt="Company Logo"/>- [ ] Form labels: All inputs have labels
<Label text="Name" labelFor="nameInput"/>
<Input id="nameInput" value="{/name}"/>- [ ] Status messages: Announce dynamic content changes
sap.ui.require(["sap/ui/core/InvisibleMessage"], function(InvisibleMessage) {
InvisibleMessage.getInstance().announce("Item added to cart", "polite");
});Visual Accessibility
- [ ] Color contrast: Minimum 4.5:1 for text
- [ ] Text size: Minimum 12px, better 14px+
- [ ] Content density: Support cozy and compact modes
// Component.js
this.getModel("device").setProperty("/contentDensity",
sap.ui.Device.support.touch ? "cozy" : "compact");- [ ] Responsive design: Works on all screen sizes
---
Testing Checklist
Unit Testing (QUnit)
- [ ] Coverage target: ≥80% code coverage
- [ ] Test all functions: Every public function has tests
- [ ] Test edge cases: Null, undefined, empty strings, boundary values
- [ ] Mocking: Mock external dependencies
QUnit.module("Formatter", {
beforeEach: function() {
this.formatter = Formatter;
}
});
QUnit.test("formatCurrency", function(assert) {
assert.strictEqual(this.formatter.formatCurrency(1000, "USD"), "$1,000.00");
assert.strictEqual(this.formatter.formatCurrency(null, "USD"), "");
});- [ ] Run tests:
npm run test:unit
Integration Testing (OPA5)
- [ ] User journeys: Test complete user workflows
- [ ] Page objects: Use page object pattern
// pages/ProductList.js
Opa5.createPageObjects({
onTheProductListPage: {
actions: {
iPressOnFirstProduct: function() {
return this.waitFor({
controlType: "sap.m.ColumnListItem",
success: function(aItems) {
aItems[0].$().trigger("tap");
}
});
}
},
assertions: {
iShouldSeeProducts: function() {
return this.waitFor({
controlType: "sap.m.Table",
success: function(aTables) {
Opa5.assert.ok(aTables[0].getItems().length > 0, "Products visible");
}
});
}
}
}
});- [ ] Run tests:
npm run test:integration
Manual Testing
- [ ] Cross-browser: Chrome, Firefox, Safari, Edge
- [ ] Mobile devices: iOS Safari, Android Chrome
- [ ] Accessibility: Screen reader testing
- [ ] Performance: Lighthouse score >90
---
Build Configuration
ui5.yaml
- [ ] Framework version: Specified in ui5.yaml
specVersion: '3.0'
framework:
name: OpenUI5
version: "1.120.0"- [ ] Build tasks: Component preload, minification, cache buster
builder:
resources:
excludes:
- "/test/**"
- "/localService/**"
componentPreload:
paths:
- "webapp/Component.js"
minify:
enabled: true
cachebuster:
enabled: truepackage.json
- [ ] Scripts defined: Build, test, serve
{
"scripts": {
"start": "ui5 serve",
"build": "ui5 build --all",
"test:unit": "karma start",
"test:integration": "wdio wdio.conf.js"
}
}- [ ] Dependencies locked: package-lock.json committed
- [ ] Vulnerability scan:
npm audit
Production Build
- [ ] Source maps: Disabled for production
builder:
sourceMap:
enabled: false # Production only- [ ] Minification: Enabled
- [ ] Component preload: Verified in dist/
- [ ] Cache buster: Hashed filenames
---
Code Style Checklist
Naming Conventions
- [ ] camelCase: Variables and functions
var productName = "Widget";
function getProductById(id) { }- [ ] PascalCase: Classes and constructors
var MyController = Controller.extend("com.myapp.controller.MyController", { });- [ ] UPPER_SNAKE_CASE: Constants
var MAX_RESULTS = 100;
var API_BASE_URL = "/api/v1";Async Patterns
- [ ] Promises: Use promises for async operations
// ❌ Callbacks
oModel.read("/Products", {
success: function(data) { },
error: function(err) { }
});
// ✅ Promises
oModel.read("/Products").then(function(data) {
// Handle data
}).catch(function(err) {
// Handle error
});- [ ] Async/Await: Use async/await in TypeScript
async onPress(): Promise<void> {
try {
const data = await this.loadData();
this.processData(data);
} catch (error) {
MessageBox.error("Failed to load data");
}
}Error Handling
- [ ] Try-catch: Wrap risky operations
- [ ] User-friendly messages: Display meaningful errors
try {
var result = JSON.parse(response);
} catch (error) {
MessageBox.error("Failed to parse server response. Please try again.");
Log.error("JSON parse error", error);
}- [ ] Log errors: Always log to console
sap.ui.require(["sap/base/Log"], function(Log) {
Log.error("Error message", error);
});Code Comments
- [ ] JSDoc: Document public functions
/**
* Formats a currency value
* @param {number} value - The numeric value
* @param {string} currency - Currency code (USD, EUR, etc.)
* @returns {string} Formatted currency string
*/
formatCurrency: function(value, currency) {
return value.toFixed(2) + " " + currency;
}- [ ] Inline comments: Explain complex logic only
- [ ] TODO comments: Track pending work
// TODO: Optimize this query for large datasets---
Documentation Checklist
README.md
- [ ] Project description: What the app does
- [ ] Installation: How to set up locally
## Installation
1. Clone repository
2. Run `npm install`
3. Run `ui5 serve`- [ ] Usage: How to use the app
- [ ] Testing: How to run tests
- [ ] Deployment: How to deploy
API Documentation
- [ ] JSDoc: All public APIs documented
- [ ] Code examples: Include usage examples
- [ ] Generated docs: Use jsdoc or typedoc
Changelog
- [ ] CHANGELOG.md: Track all changes
## [1.2.0] - 2025-12-28
### Added
- User authentication
- Dark mode support
### Fixed
- Performance issue with large lists---
Pre-Deployment Checklist
Code Quality
- [ ] Linter: No linter errors
ui5 lint- [ ] Unit tests: All passing
- [ ] Integration tests: All passing
- [ ] Code review: Peer reviewed
Performance
- [ ] Lighthouse: Score >90
- [ ] Bundle size: <2MB
- [ ] Load time: <3 seconds (3G)
Security
- [ ] Vulnerability scan:
npm auditclean - [ ] Dependency updates: No outdated critical packages
- [ ] Security headers: CSP, HSTS configured
Accessibility
- [ ] aXe scan: No critical issues
- [ ] Screen reader test: Works with NVDA/JAWS
- [ ] Keyboard navigation: All functionality accessible
Documentation
- [ ] README updated: Reflects current state
- [ ] Deployment guide: Up to date
- [ ] User manual: Available (if needed)
Deployment
- [ ] Environment variables: Configured correctly
- [ ] Database migrations: Applied (if applicable)
- [ ] Backup: Production backup created
- [ ] Rollback plan: Documented
---
Tools for Quality Assurance
Automated Tools
- UI5 Linter: https://github.com/UI5/linter
- ESLint: JavaScript linting
- Lighthouse: Performance and accessibility
- aXe: Accessibility testing
- npm audit: Vulnerability scanning
- SonarQube: Code quality metrics
Manual Tools
- Chrome DevTools: Performance profiling
- NVDA/JAWS: Screen reader testing
- BrowserStack: Cross-browser testing
- Postman: API testing
---
Last Updated: 2025-12-28 Plugin Version: 3.0.0
SAPUI5 Core Architecture & Concepts
Source: Official SAP SAPUI5 Documentation Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials Last Updated: 2025-11-21
---
Framework Architecture
Component-Based Architecture
SAPUI5 applications are built around Components - self-contained, reusable units with:
- manifest.json: Application descriptor with metadata and configuration
- Component.js: Component controller with initialization logic
- View/Controller pairs: UI definition and business logic
- i18n: Internationalization resources
- model: Optional local data models
Key Benefits:
- Reusability across applications
- Clear separation of concerns
- Standardized configuration via manifest
- Dependency management
- Lifecycle management
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials (search: component)
---
Model-View-Controller (MVC) Pattern
SAPUI5 implements MVC for clean separation:
Model (Data Layer):
- Provides data to UI
- Notifies views of changes
- Types: JSON, OData v2/v4, XML, Resource
- Supports binding for automatic UI updates
View (Presentation Layer):
- Defines UI structure
- Available types: XML (recommended), JSON, JavaScript, HTML
- Contains controls and layout
- No business logic
Controller (Logic Layer):
- Event handlers for user interactions
- Business logic
- Data formatting
- Navigation
- Lifecycle hooks: onInit, onBeforeRendering, onAfterRendering, onExit
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials (search: mvc, controller, view)
---
Module System
SAPUI5 uses AMD (Asynchronous Module Definition):
Module Definition:
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/m/MessageToast"
], function(Controller, MessageToast) {
"use strict";
return Controller.extend("my.namespace.controller.Main", {
onPress: function() {
MessageToast.show("Button pressed");
}
});
});Module Loading:
sap.ui.require([
"sap/m/MessageBox"
], function(MessageBox) {
MessageBox.success("Loaded asynchronously");
});Key Points:
- sap.ui.define: For defining modules (always use this)
- sap.ui.require: For loading modules dynamically
- Async loading prevents blocking
- Dependencies declared explicitly
- Supports lazy loading
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials (search: module, define, require)
---
Bootstrapping
Initialize SAPUI5 in index.html:
Basic Bootstrap:
<script
id="sap-ui-bootstrap"
src="resources/sap-ui-core.js"
data-sap-ui-theme="sap_horizon"
data-sap-ui-libs="sap.m"
data-sap-ui-resourceroots='{
"my.namespace": "./"
}'
data-sap-ui-async="true"
data-sap-ui-onInit="module:my/namespace/index"
data-sap-ui-compatVersion="edge">
</script>Key Configuration Options:
data-sap-ui-theme: UI theme (sap_horizon, sap_fiori_3, etc.)data-sap-ui-libs: Preloaded librariesdata-sap-ui-resourceroots: Namespace-to-path mappingdata-sap-ui-async="true": Async loading (always use)data-sap-ui-compatVersion="edge": Latest featuresdata-sap-ui-onInit: Module to run after initialization
CDN Options:
- SAP CDN:
https://sapui5.hana.ondemand.com/resources/sap-ui-core.js - OpenUI5 CDN:
https://openui5.hana.ondemand.com/resources/sap-ui-core.js - Specific version:
https://sapui5.hana.ondemand.com/1.120.0/resources/sap-ui-core.js
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials (search: bootstrap, initialization)
---
Libraries
SAPUI5 provides multiple control libraries:
Main Libraries:
- sap.m: Mobile/responsive controls (Button, Table, List, etc.)
- sap.ui.core: Core framework (mvc, routing, etc.)
- sap.ui.table: High-performance tables
- sap.f: SAP Fiori controls (FlexibleColumnLayout, etc.)
- sap.uxap: UX Add-on (ObjectPageLayout, etc.)
- sap.ui.layout: Layout controls (Grid, Splitter, etc.)
- sap.tnt: Tool Navigation Template (SideNavigation, etc.)
- sap.suite.ui.commons: Suite controls (charts, micro-charts)
Library Loading:
// In manifest.json
{
"sap.ui5": {
"dependencies": {
"libs": {
"sap.m": {},
"sap.ui.table": {},
"sap.f": {}
}
}
}
}Lazy Loading:
sap.ui.getCore().loadLibrary("sap.ui.table", { async: true })
.then(function() {
// Library loaded
});Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/02_Read-Me-First (search: library, supported-library-combinations)
---
Namespacing
Proper namespacing prevents conflicts:
Structure:
com.mycompany.myapp/
├── Component.js
├── manifest.json
├── controller/
│ └── Main.controller.js
├── view/
│ └── Main.view.xml
├── model/
│ └── formatter.js
└── i18n/
└── i18n.propertiesNaming Conventions:
- Reverse domain:
com.mycompany.myapp - PascalCase for classes:
Main.controller.js - camelCase for files:
formatter.js - Folder names: lowercase (controller, view, model)
Resource Root Registration:
// In index.html
data-sap-ui-resourceroots='{
"com.mycompany.myapp": "./"
}'Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/05_Developing_Apps (search: folder-structure, namespace)
---
Control Tree & Rendering
SAPUI5 builds a tree of controls:
Control Hierarchy:
- Root Element:
<body>or specific<div> - Component Container: Hosts component
- View: Contains controls
- Controls: UI elements (Button, Input, Table, etc.)
- Aggregations: Child controls (items, content, etc.)
Rendering Process: 1. Initial Rendering: Creates HTML from control tree 2. Re-rendering: Updates DOM when model/property changes 3. Invalidation: Marks controls for re-rendering 4. Batching: Groups re-renders for performance
Lifecycle Hooks:
onBeforeRendering(): Before DOM updateonAfterRendering(): After DOM update (DOM manipulation here)
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials (search: rendering, control-tree)
---
Fragments
Reusable UI snippets without controller:
XML Fragment (recommended):
<core:FragmentDefinition
xmlns="sap.m"
xmlns:core="sap.ui.core">
<Dialog
title="{i18n>dialogTitle}"
type="Message">
<Text text="{i18n>dialogText}"/>
<buttons>
<Button text="{i18n>close}" press=".onCloseDialog"/>
</buttons>
</Dialog>
</core:FragmentDefinition>Loading Fragments:
// In controller
onOpenDialog: function() {
if (!this.pDialog) {
this.pDialog = this.loadFragment({
name: "my.namespace.view.fragments.MyDialog"
});
}
this.pDialog.then(function(oDialog) {
oDialog.open();
});
}Benefits:
- Reuse across views
- Smaller view files
- Modular UI definition
- No separate controller
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials (search: fragment)
---
Application Descriptor (manifest.json)
Central configuration file:
Structure:
{
"sap.app": {
"id": "com.mycompany.myapp",
"type": "application",
"title": "{{appTitle}}",
"description": "{{appDescription}}",
"applicationVersion": {
"version": "1.0.0"
},
"dataSources": {
"mainService": {
"uri": "/sap/opu/odata/sap/SERVICE_SRV/",
"type": "OData",
"settings": {
"odataVersion": "2.0"
}
}
}
},
"sap.ui": {
"technology": "UI5",
"deviceTypes": {
"desktop": true,
"tablet": true,
"phone": true
}
},
"sap.ui5": {
"rootView": {
"viewName": "com.mycompany.myapp.view.App",
"type": "XML",
"async": true,
"id": "app"
},
"dependencies": {
"minUI5Version": "1.120.0",
"libs": {
"sap.m": {},
"sap.ui.core": {}
}
},
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "com.mycompany.myapp.i18n.i18n"
}
},
"": {
"dataSource": "mainService",
"settings": {
"defaultBindingMode": "TwoWay"
}
}
},
"routing": {
"config": {
"routerClass": "sap.m.routing.Router",
"type": "View",
"viewType": "XML",
"path": "com.mycompany.myapp.view",
"controlId": "app",
"controlAggregation": "pages",
"async": true
},
"routes": [],
"targets": {}
}
}
}Key Sections:
- sap.app: General app info and data sources
- sap.ui: UI technology and device types
- sap.ui5: UI5-specific config (models, routing, dependencies)
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials (search: manifest, descriptor)
---
Core Concepts
Properties, Events, Aggregations
Properties:
- Simple values (text, enabled, visible)
- Accessed via getters/setters
- Support data binding
- Example:
oButton.setText("Click me")
Events:
- User interactions or state changes
- Attach handlers with
.attachEvent()or in XML - Event object contains source and parameters
- Example:
press,change,selectionChange
Aggregations:
- Child controls (items, content, buttons)
- One-to-many relationships
- Managed by parent control
- Example: Table has
items, Page hascontent
Associations:
- References to other controls
- Not parent-child relationship
- Example: Label's
labelForassociation
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials (search: property, event, aggregation)
---
Device Adaptation
Responsive design features:
Content Density:
- Cozy: Touch-friendly (larger targets) - default on phones
- Compact: Mouse-friendly (smaller) - default on desktops
- Set via CSS class:
sapUiSizeCozyorsapUiSizeCompact
Device Detection:
sap.ui.Device.system.phone
sap.ui.Device.system.tablet
sap.ui.Device.system.desktopResponsive Controls:
- Use
sap.mcontrols (designed for responsive) - FlexBox for flexible layouts
- Grid for responsive grids
- Avoid fixed pixel sizes
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials (search: device, responsive, content-density)
---
Theming
Visual design system:
Available Themes:
- sap_horizon: Latest SAP theme (recommended)
- sap_fiori_3: SAP Fiori 3.0 theme
- sap_fiori_3_dark: Dark variant
- sap_fiori_3_hcb: High contrast black
- sap_fiori_3_hcw: High contrast white
Setting Theme:
<!-- In index.html -->
data-sap-ui-theme="sap_horizon"// Dynamically
sap.ui.getCore().applyTheme("sap_horizon");Theme Parameters:
- Use in custom CSS for consistency
- Example:
@sapUiBaseColor,@sapUiBaseBG - Access via:
Parameters.get("sapUiBaseColor")
Custom Themes:
- Use UI Theme Designer
- Based on SAP theme
- Only override needed parameters
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/02_Read-Me-First (search: theme, supported-combinations)
---
Performance Optimization
Best Practices:
1. Async Loading:
- Always use
data-sap-ui-async="true" - Use
sap.ui.definefor modules - Lazy load libraries when needed
2. Component Preload:
- Build creates Component-preload.js
- Bundles all component resources
- Reduces HTTP requests
3. Data Binding:
- Use one-way binding when possible
- Avoid complex formatters in loops
- Use
bindingMode: "OneTime"for static data
4. List/Table Optimization:
- Use growing lists for large datasets
- Enable table virtualization
- Use OData paging ($skip, $top)
5. Model Management:
- Use batch requests for OData
- Set size limits appropriately
- Destroy models when not needed
6. Rendering:
- Avoid frequent re-renders
- Use
busystate during loading - Minimize DOM manipulations
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/05_Developing_Apps (search: performance)
---
Security
Key Security Features:
1. XSS Prevention:
- Automatic output encoding
- Use data binding (never innerHTML)
- Sanitize user input
2. Content Security Policy (CSP):
- SAPUI5 supports CSP
- Avoid inline scripts
- Use nonce or hash for inline styles
3. Clickjacking Prevention:
- Frame-options header
- CSP frame-ancestors directive
4. Input Validation:
- Use data types
- Validate on client and server
- Use constraints (maxLength, pattern)
5. Secure Communication:
- Always use HTTPS in production
- Enable CORS properly
- Use CSRF tokens
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/05_Developing_Apps (search: security, secure-programming)
---
Links to Official Documentation
- Core Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials
- App Development: https://github.com/SAP-docs/sapui5/tree/main/docs/05_Developing_Apps
- Getting Started: https://github.com/SAP-docs/sapui5/tree/main/docs/03_Get-Started
- Read Me First: https://github.com/SAP-docs/sapui5/tree/main/docs/02_Read-Me-First
- API Reference: https://sapui5.hana.ondemand.com/#/api
- Demo Kit: https://sapui5.hana.ondemand.com/
---
Note: This document provides core architecture concepts for SAPUI5 development. For specific implementation details, refer to the official documentation links provided throughout this document.
SAPUI5 Data Binding & Models
Source: Official SAP SAPUI5 Documentation Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials Last Updated: 2025-11-21
---
Data Binding Overview
Data binding connects UI controls to data sources, automatically synchronizing changes bidirectionally.
Key Benefits:
- Automatic UI updates when data changes
- Reduced boilerplate code
- Clean separation of data and presentation
- Type conversion and formatting
- Validation support
Binding Types: 1. Property Binding: Single value (text, enabled, visible) 2. Aggregation Binding: Collections (table items, list items) 3. Element Binding: Object context 4. Expression Binding: Inline calculations
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials (search: binding, data-binding)
---
Binding Modes
One-Way Binding:
- Data flows model → view only
- UI updates when model changes
- User input doesn't update model
- Use for read-only data
// In manifest.json
"models": {
"": {
"dataSource": "mainService",
"settings": {
"defaultBindingMode": "OneWay"
}
}
}Two-Way Binding:
- Data flows model ↔ view bidirectionally
- Model updates when user changes input
- View updates when model changes
- Use for editable forms
"defaultBindingMode": "TwoWay"One-Time Binding:
- Data loaded once at initialization
- No updates after initial load
- Best performance for static data
<Text text="{path: '/title', mode: 'OneTime'}"/>Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials (search: binding-mode)
---
Model Types
JSON Model
Client-side model for JavaScript objects. Best for small datasets and local data.
Creation:
// In controller
var oModel = new JSONModel({
products: [
{ id: 1, name: "Product 1", price: 100 },
{ id: 2, name: "Product 2", price: 200 }
],
selectedProduct: null
});
this.getView().setModel(oModel);From File:
var oModel = new JSONModel();
oModel.loadData("model/data.json");
this.getView().setModel(oModel);Usage:
<List items="{/products}">
<StandardListItem
title="{name}"
description="Price: {price}"/>
</List>Key Methods:
setData(oData): Set complete datasetProperty(sPath, oValue): Set single propertygetProperty(sPath): Get property valueloadData(sURL): Load from URL
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials (search: json-model)
---
OData V2 Model
Server-side model for OData v2 services. Automatic CRUD operations.
Creation:
// In manifest.json
{
"sap.app": {
"dataSources": {
"mainService": {
"uri": "/sap/opu/odata/sap/SERVICE_SRV/",
"type": "OData",
"settings": {
"odataVersion": "2.0",
"localUri": "localService/metadata.xml"
}
}
}
},
"sap.ui5": {
"models": {
"": {
"dataSource": "mainService",
"settings": {
"defaultBindingMode": "TwoWay",
"defaultCountMode": "Inline",
"useBatch": true
}
}
}
}
}Reading Data:
// Simple read
this.getView().getModel().read("/Products", {
success: function(oData) {
console.log(oData);
},
error: function(oError) {
MessageBox.error("Failed to load data");
}
});
// With filters and sorters
this.getView().getModel().read("/Products", {
filters: [new Filter("Price", FilterOperator.GT, 100)],
sorters: [new Sorter("Name", false)],
urlParameters: {
"$expand": "Category"
},
success: function(oData) {
console.log(oData);
}
});Creating Entries:
var oModel = this.getView().getModel();
oModel.create("/Products", {
Name: "New Product",
Price: 150,
CategoryID: 1
}, {
success: function() {
MessageToast.show("Product created");
},
error: function(oError) {
MessageBox.error("Failed to create product");
}
});Updating Entries:
var oModel = this.getView().getModel();
oModel.update("/Products(1)", {
Price: 200
}, {
success: function() {
MessageToast.show("Product updated");
}
});Deleting Entries:
oModel.remove("/Products(1)", {
success: function() {
MessageToast.show("Product deleted");
}
});Batch Requests:
oModel.setUseBatch(true);
oModel.setDeferredGroups(["myGroup"]);
// Add to batch
oModel.create("/Products", oData, { groupId: "myGroup" });
oModel.create("/Products", oData2, { groupId: "myGroup" });
// Submit batch
oModel.submitChanges({
groupId: "myGroup",
success: function() {
MessageToast.show("Batch successful");
}
});Key Settings:
useBatch: Enable batch requestsdefaultCountMode: How to get counts (Inline, Request, None)refreshAfterChange: Auto-refresh after updatesdefaultBindingMode: One-way or two-way
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials (search: odata-v2-model)
---
OData V4 Model
Modern OData v4 model with improved performance and features.
Creation:
// In manifest.json
{
"sap.app": {
"dataSources": {
"mainService": {
"uri": "/sap/opu/odata4/sap/service/srvd/sap/api/0001/",
"type": "OData",
"settings": {
"odataVersion": "4.0"
}
}
}
},
"sap.ui5": {
"models": {
"": {
"dataSource": "mainService",
"settings": {
"synchronizationMode": "None",
"operationMode": "Server",
"autoExpandSelect": true,
"earlyRequests": true
}
}
}
}
}Key Differences from V2:
- Server-side operations (filter, sort, page)
- Automatic $expand and $select
- Better performance
- Stricter adherence to OData standard
- No client-side models
Reading with List Binding:
<Table items="{
path: '/Products',
parameters: {
$expand: 'Category',
$select: 'ID,Name,Price',
$filter: 'Price gt 100',
$orderby: 'Name'
}
}">Creating Entries:
var oListBinding = this.byId("table").getBinding("items");
var oContext = oListBinding.create({
Name: "New Product",
Price: 150
});
// Save
oContext.created().then(function() {
MessageToast.show("Product created");
});Updating:
var oContext = this.byId("table").getSelectedItem().getBindingContext();
oContext.setProperty("Price", 200);
// Save changes
oContext.getModel().submitBatch("$auto").then(function() {
MessageToast.show("Updated");
});Deleting:
var oContext = this.byId("table").getSelectedItem().getBindingContext();
oContext.delete("$auto").then(function() {
MessageToast.show("Deleted");
});Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials (search: odata-v4-model)
---
Resource Model (i18n)
Model for internationalization texts.
Setup:
// In manifest.json
{
"sap.ui5": {
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "com.mycompany.myapp.i18n.i18n",
"supportedLocales": ["en", "de", "fr"],
"fallbackLocale": "en"
}
}
}
}
}i18n.properties:
appTitle=My Application
appDescription=A sample SAPUI5 application
# Buttons
btnSave=Save
btnCancel=Cancel
btnDelete=Delete
# Messages
msgSaveSuccess=Data saved successfully
msgDeleteConfirm=Do you want to delete this item?
# Placeholders with parameters
msgItemCount=You have {0} items selected
msgWelcome=Welcome, {0}!Usage in XML:
<Page title="{i18n>appTitle}">
<Button text="{i18n>btnSave}" press=".onSave"/>
<Text text="{i18n>appDescription}"/>
</Page>Usage in Controller:
var oBundle = this.getView().getModel("i18n").getResourceBundle();
var sTitle = oBundle.getText("appTitle");
// With parameters
var sMessage = oBundle.getText("msgItemCount", [5]);
MessageBox.success(sMessage);Locale Files:
i18n.properties: Default (fallback)i18n_de.properties: Germani18n_en.properties: Englishi18n_fr.properties: French
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials (search: resource-model, i18n)
---
XML Model
Client-side model for XML data structures.
Creation:
var oModel = new XMLModel();
oModel.loadData("model/data.xml");
this.getView().setModel(oModel, "xml");Usage:
<List items="{xml>/products/product}">
<StandardListItem
title="{xml>name}"
description="{xml>price}"/>
</List>Use Cases:
- Legacy XML data sources
- Configuration files
- Small datasets
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials (search: xml-model)
---
Binding Syntax
Property Binding
Simple Binding:
<Text text="{/companyName}"/>
<Input value="{/employeeName}"/>Named Models:
<Text text="{invoice>/company/name}"/>
<Input value="{customer>/email}"/>Binding Options:
<Text text="{
path: '/price',
type: 'sap.ui.model.type.Currency',
formatOptions: {
showMeasure: false
},
constraints: {
minimum: 0
}
}"/>Composite Binding:
<Text text="{
parts: [
{path: '/firstName'},
{path: '/lastName'}
],
formatter: '.formatFullName'
}"/>Controller:
formatFullName: function(sFirstName, sLastName) {
return sFirstName + " " + sLastName;
}---
Aggregation Binding
List Binding:
<List items="{/products}">
<StandardListItem
title="{name}"
description="{description}"
info="{price} EUR"/>
</List>Table Binding:
<Table items="{
path: '/products',
sorter: {
path: 'name'
},
filters: {
path: 'price',
operator: 'GT',
value1: 50
}
}">
<columns>
<Column><Text text="Name"/></Column>
<Column><Text text="Price"/></Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Text text="{name}"/>
<Text text="{price}"/>
</cells>
</ColumnListItem>
</items>
</Table>With Parameters:
<Table items="{
path: '/Products',
parameters: {
expand: 'Category',
select: 'ID,Name,Price'
}
}">---
Element Binding
Sets binding context for entire control:
<Panel binding="{/selectedProduct}">
<VBox>
<Text text="{name}"/>
<Text text="{description}"/>
<Text text="{price} EUR"/>
</VBox>
</Panel>// In controller
onProductSelect: function(oEvent) {
var oItem = oEvent.getParameter("listItem");
var sPath = oItem.getBindingContext().getPath();
this.byId("detailPanel").bindElement({
path: sPath,
parameters: {
expand: "Category"
}
});
}---
Expression Binding
Inline calculations without formatter:
<!-- Conditional text color -->
<Text
text="{price}"
color="{= ${price} > 100 ? 'red' : 'green'}"/>
<!-- Conditional visibility -->
<Button
visible="{= ${status} === 'approved'}"
text="Process"/>
<!-- Calculations -->
<Text text="{= ${quantity} * ${price}}"/>
<!-- String operations -->
<Text text="{= ${firstName} + ' ' + ${lastName}}"/>
<!-- Comparisons -->
<Button enabled="{= ${quantity} > 0 && ${stock} >= ${quantity}}"/>Supported Operations:
- Arithmetic:
+,-,*,/,% - Comparison:
===,!==,>,<,>=,<= - Logical:
&&,||,! - Ternary:
condition ? true : false - String concatenation:
+
Limitations:
- Simple expressions only
- No function calls
- Use formatters for complex logic
---
Formatters & Data Types
Custom Formatters
Definition:
// In controller or separate formatter.js
formatPrice: function(sPrice) {
if (!sPrice) return "";
return parseFloat(sPrice).toFixed(2) + " EUR";
},
formatStatus: function(sStatus) {
var mStatusText = {
"A": "Approved",
"R": "Rejected",
"P": "Pending"
};
return mStatusText[sStatus] || sStatus;
},
formatDate: function(oDate) {
if (!oDate) return "";
var oDateFormat = sap.ui.core.format.DateFormat.getDateInstance({
pattern: "dd.MM.yyyy"
});
return oDateFormat.format(oDate);
}Usage:
<Text text="{path: 'price', formatter: '.formatPrice'}"/>
<Text text="{path: 'status', formatter: '.formatStatus'}"/>
<Text text="{path: 'createdAt', formatter: '.formatDate'}"/>Multiple Parameters:
<Text text="{
parts: ['quantity', 'price'],
formatter: '.formatTotal'
}"/>formatTotal: function(iQuantity, fPrice) {
return (iQuantity * fPrice).toFixed(2) + " EUR";
}---
Built-in Data Types
String Type:
<Input value="{
path: '/name',
type: 'sap.ui.model.type.String',
constraints: {
maxLength: 50,
minLength: 2
}
}"/>Integer Type:
<Input value="{
path: '/quantity',
type: 'sap.ui.model.type.Integer',
constraints: {
minimum: 1,
maximum: 999
}
}"/>Float Type:
<Input value="{
path: '/price',
type: 'sap.ui.model.type.Float',
constraints: {
minimum: 0,
maximum: 99999.99
},
formatOptions: {
minFractionDigits: 2,
maxFractionDigits: 2
}
}"/>Date Type:
<DatePicker value="{
path: '/orderDate',
type: 'sap.ui.model.type.Date',
formatOptions: {
pattern: 'dd.MM.yyyy'
}
}"/>DateTime Type:
<DateTimePicker value="{
path: '/createdAt',
type: 'sap.ui.model.type.DateTime',
formatOptions: {
pattern: 'dd.MM.yyyy HH:mm:ss'
}
}"/>Currency Type:
<Text text="{
parts: [
{path: 'price'},
{path: 'currency'}
],
type: 'sap.ui.model.type.Currency',
formatOptions: {
showMeasure: true
}
}"/>Boolean Type:
<CheckBox selected="{
path: '/isActive',
type: 'sap.ui.model.type.Boolean'
}"/>---
Filters & Sorters
Filters
Simple Filter:
var oFilter = new Filter("price", FilterOperator.GT, 100);
var oBinding = this.byId("table").getBinding("items");
oBinding.filter([oFilter]);Multiple Filters (AND):
var aFilters = [
new Filter("price", FilterOperator.GT, 100),
new Filter("category", FilterOperator.EQ, "Electronics")
];
oBinding.filter(aFilters); // AND conditionMultiple Filters (OR):
var aFilters = [
new Filter("status", FilterOperator.EQ, "Approved"),
new Filter("status", FilterOperator.EQ, "Pending")
];
var oCombinedFilter = new Filter({
filters: aFilters,
and: false // OR condition
});
oBinding.filter([oCombinedFilter]);Complex Filters:
var oPriceFilter = new Filter({
filters: [
new Filter("price", FilterOperator.GT, 100),
new Filter("price", FilterOperator.LT, 500)
],
and: true
});
var oStatusFilter = new Filter({
filters: [
new Filter("status", FilterOperator.EQ, "A"),
new Filter("status", FilterOperator.EQ, "P")
],
and: false
});
var oCombinedFilter = new Filter({
filters: [oPriceFilter, oStatusFilter],
and: true
});
oBinding.filter([oCombinedFilter]);Filter Operators:
EQ: EqualsNE: Not equalsGT: Greater thanGE: Greater or equalLT: Less thanLE: Less or equalContains: Contains textStartsWith: Starts with textEndsWith: Ends with textBT: Between (requires value1 and value2)
Custom Filter Function:
var oFilter = new Filter({
path: "price",
test: function(oValue) {
return oValue > 100 && oValue < 500;
}
});---
Sorters
Simple Sort:
var oSorter = new Sorter("name", false); // false = ascending
var oBinding = this.byId("table").getBinding("items");
oBinding.sort(oSorter);Multiple Sorters:
var aSorters = [
new Sorter("category", false),
new Sorter("price", true) // true = descending
];
oBinding.sort(aSorters);Sort with Grouping:
var oSorter = new Sorter("category", false, true); // third param = group
oBinding.sort(oSorter);Custom Group Function:
var oSorter = new Sorter("price", false, function(oContext) {
var fPrice = oContext.getProperty("price");
if (fPrice < 100) return { key: "low", text: "Low Price" };
if (fPrice < 500) return { key: "medium", text: "Medium Price" };
return { key: "high", text: "High Price" };
});---
Links to Official Documentation
- Data Binding: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials (search: data-binding)
- Models: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials (search: model)
- OData: https://github.com/SAP-docs/sapui5/tree/main/docs/04_Essentials (search: odata)
- Get Started Tutorials: https://github.com/SAP-docs/sapui5/tree/main/docs/03_Get-Started
- API Reference: https://sapui5.hana.ondemand.com/#/api
---
Note: This document covers data binding and model usage in SAPUI5. For specific implementation details and advanced scenarios, refer to the official documentation links provided.
SAP Fiori Elements Guide
Source: Official SAP SAPUI5 Documentation Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/06_SAP_Fiori_Elements Last Updated: 2025-11-21
---
Overview
SAP Fiori Elements provides metadata-driven templates for creating enterprise applications without writing JavaScript UI code. Applications are configured through OData annotations and manifest.json settings.
Key Benefits:
- Rapid application development
- Consistent UX across apps
- Automatic updates with framework upgrades
- Reduced maintenance effort
- Built-in best practices
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/06_SAP_Fiori_Elements
---
Application Types
List Report
Displays data in searchable, filterable tables or charts.
Use Cases:
- Product catalogs
- Sales orders
- Employee lists
- Any tabular data display
Key Features:
- Smart filter bar
- Multi-view (table/chart)
- Export to Excel/PDF
- Variant management
- Mass editing
Annotations:
<!-- In metadata annotations -->
<Annotations Target="Service.Products">
<!-- Selection fields (filter bar) -->
<Annotation Term="UI.SelectionFields">
<Collection>
<PropertyPath>Category</PropertyPath>
<PropertyPath>Price</PropertyPath>
<PropertyPath>Status</PropertyPath>
</Collection>
</Annotation>
<!-- Table columns -->
<Annotation Term="UI.LineItem">
<Collection>
<Record Type="UI.DataField">
<PropertyValue Property="Value" PropertyPath="ProductID"/>
</Record>
<Record Type="UI.DataField">
<PropertyValue Property="Value" PropertyPath="Name"/>
<PropertyValue Property="Label" String="Product Name"/>
</Record>
<Record Type="UI.DataField">
<PropertyValue Property="Value" PropertyPath="Price"/>
<PropertyValue Property="Label" String="Price"/>
</Record>
<Record Type="UI.DataFieldForAnnotation">
<PropertyValue Property="Target" AnnotationPath="@UI.DataPoint#Rating"/>
<PropertyValue Property="Label" String="Rating"/>
</Record>
</Collection>
</Annotation>
</Annotations>manifest.json Configuration:
{
"sap.ui5": {
"routing": {
"targets": {
"ProductsList": {
"type": "Component",
"id": "ProductsList",
"name": "sap.fe.templates.ListReport",
"options": {
"settings": {
"contextPath": "/Products",
"variantManagement": "Page",
"initialLoad": true,
"tableSettings": {
"type": "ResponsiveTable",
"selectAll": true
}
}
}
}
}
}
}
}---
Object Page
Displays detailed information about a single business object across multiple sections.
Use Cases:
- Product details
- Sales order details
- Employee profile
- Any detailed view with related data
Key Features:
- Header with key info
- Sections and subsections
- Facets (forms, tables, charts)
- Edit mode
- Actions (approve, reject, etc.)
- Related objects navigation
Annotations:
<Annotations Target="Service.Product">
<!-- Header info -->
<Annotation Term="UI.HeaderInfo">
<Record>
<PropertyValue Property="TypeName" String="Product"/>
<PropertyValue Property="TypeNamePlural" String="Products"/>
<PropertyValue Property="Title">
<Record Type="UI.DataField">
<PropertyValue Property="Value" PropertyPath="Name"/>
</Record>
</PropertyValue>
<PropertyValue Property="Description">
<Record Type="UI.DataField">
<PropertyValue Property="Value" PropertyPath="Description"/>
</Record>
</PropertyValue>
</Record>
</Annotation>
<!-- Header facets (quick view) -->
<Annotation Term="UI.HeaderFacets">
<Collection>
<Record Type="UI.ReferenceFacet">
<PropertyValue Property="Target" AnnotationPath="@UI.DataPoint#Price"/>
</Record>
<Record Type="UI.ReferenceFacet">
<PropertyValue Property="Target" AnnotationPath="@UI.DataPoint#Stock"/>
</Record>
</Collection>
</Annotation>
<!-- Sections -->
<Annotation Term="UI.Facets">
<Collection>
<!-- General section -->
<Record Type="UI.CollectionFacet">
<PropertyValue Property="Label" String="General Information"/>
<PropertyValue Property="ID" String="GeneralInfo"/>
<PropertyValue Property="Facets">
<Collection>
<Record Type="UI.ReferenceFacet">
<PropertyValue Property="Target" AnnotationPath="@UI.FieldGroup#General"/>
</Record>
</Collection>
</PropertyValue>
</Record>
<!-- Related items table -->
<Record Type="UI.ReferenceFacet">
<PropertyValue Property="Label" String="Sales Orders"/>
<PropertyValue Property="Target" AnnotationPath="SalesOrders/@UI.LineItem"/>
</Record>
</Collection>
</Annotation>
<!-- Field group -->
<Annotation Term="UI.FieldGroup" Qualifier="General">
<Record>
<PropertyValue Property="Data">
<Collection>
<Record Type="UI.DataField">
<PropertyValue Property="Value" PropertyPath="ProductID"/>
</Record>
<Record Type="UI.DataField">
<PropertyValue Property="Value" PropertyPath="Category"/>
</Record>
<Record Type="UI.DataField">
<PropertyValue Property="Value" PropertyPath="Price"/>
</Record>
</Collection>
</PropertyValue>
</Record>
</Annotation>
</Annotations>manifest.json Configuration:
{
"sap.ui5": {
"routing": {
"targets": {
"ProductObjectPage": {
"type": "Component",
"id": "ProductObjectPage",
"name": "sap.fe.templates.ObjectPage",
"options": {
"settings": {
"contextPath": "/Products",
"editableHeaderContent": true,
"showRelatedApps": true
}
}
}
}
}
}
}---
Analytical List Page
Combines visual filters, charts, and tables for analytical data exploration.
Use Cases:
- Sales analytics
- Financial reporting
- KPI dashboards
- Performance monitoring
Key Features:
- Visual filters (bar, line, donut charts)
- Interactive charts
- Smart filter bar
- Table view
- Drill-down capabilities
Annotations:
<Annotations Target="Service.SalesData">
<!-- Chart definition -->
<Annotation Term="UI.Chart">
<Record>
<PropertyValue Property="Title" String="Sales by Region"/>
<PropertyValue Property="ChartType" EnumMember="UI.ChartType/Column"/>
<PropertyValue Property="Dimensions">
<Collection>
<PropertyPath>Region</PropertyPath>
</Collection>
</PropertyValue>
<PropertyValue Property="Measures">
<Collection>
<PropertyPath>Sales</PropertyPath>
</Collection>
</PropertyValue>
</Record>
</Annotation>
<!-- Presentation variant -->
<Annotation Term="UI.PresentationVariant">
<Record>
<PropertyValue Property="Visualizations">
<Collection>
<AnnotationPath>@UI.Chart</AnnotationPath>
<AnnotationPath>@UI.LineItem</AnnotationPath>
</Collection>
</PropertyValue>
<PropertyValue Property="SortOrder">
<Collection>
<Record Type="Common.SortOrderType">
<PropertyValue Property="Property" PropertyPath="Sales"/>
<PropertyValue Property="Descending" Bool="true"/>
</Record>
</Collection>
</PropertyValue>
</Record>
</Annotation>
</Annotations>---
Overview Page
Card-based dashboard displaying key metrics and lists.
Use Cases:
- Executive dashboards
- Overview screens
- KPI monitoring
- Multi-source data aggregation
Key Features:
- Cards (list, analytical, table)
- Automatic refresh
- Filter bar
- Navigation to detail apps
- Responsive layout
Card Configuration:
{
"sap.ovp": {
"cards": {
"salesCard": {
"model": "mainService",
"template": "sap.ovp.cards.charts.analytical",
"settings": {
"title": "Sales by Region",
"subTitle": "Current Year",
"entitySet": "SalesData",
"chartAnnotationPath": "com.sap.vocabularies.UI.v1.Chart",
"selectionAnnotationPath": "com.sap.vocabularies.UI.v1.SelectionVariant",
"presentationAnnotationPath": "com.sap.vocabularies.UI.v1.PresentationVariant"
}
},
"productsCard": {
"model": "mainService",
"template": "sap.ovp.cards.list",
"settings": {
"title": "Top Products",
"entitySet": "Products",
"listType": "extended",
"sortBy": "Sales",
"sortOrder": "desc"
}
}
}
}
}---
Worklist
Simplified list report for task-oriented applications.
Use Cases:
- Task lists
- Approval workflows
- Simple data management
- To-do lists
Key Features:
- Table with basic filtering
- Search
- Item count
- Quick navigation
- Simplified UI compared to List Report
---
Common Annotations
UI Annotations
@UI.LineItem: Table columns @UI.SelectionFields: Filter bar fields @UI.HeaderInfo: Object page header @UI.HeaderFacets: Header quick view @UI.Facets: Object page sections @UI.FieldGroup: Grouped fields @UI.DataPoint: KPI or micro-chart @UI.Chart: Chart definition @UI.Identification: Form fields
Common Annotations
@Common.Label: Field label @Common.Text: Display text for coded values @Common.ValueList: Value help @Common.SemanticObject: Navigation target
Capabilities Annotations
@Capabilities.FilterRestrictions: Filter limitations @Capabilities.SortRestrictions: Sort limitations @Capabilities.InsertRestrictions: Create permissions @Capabilities.UpdateRestrictions: Edit permissions @Capabilities.DeleteRestrictions: Delete permissions
Communication Annotations
@Communication.Contact: Contact information @Communication.Address: Address fields
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/06_SAP_Fiori_Elements (search: annotations)
---
Actions
Standard Actions
Automatically available for editable entities:
- Create
- Edit
- Delete
- Save
- Cancel
Custom Actions
OData Action Definition:
<Action Name="ApproveOrder" IsBound="true">
<Parameter Name="_it" Type="Service.SalesOrder"/>
<ReturnType Type="Service.SalesOrder"/>
</Action>Annotation:
<Annotations Target="Service.SalesOrder">
<Annotation Term="UI.LineItem">
<Collection>
<!-- Regular fields -->
<Record Type="UI.DataField">
<PropertyValue Property="Value" PropertyPath="OrderID"/>
</Record>
<!-- Action button -->
<Record Type="UI.DataFieldForAction">
<PropertyValue Property="Label" String="Approve"/>
<PropertyValue Property="Action" String="Service.ApproveOrder"/>
<PropertyValue Property="InvocationGrouping" EnumMember="UI.OperationGroupingType/Isolated"/>
</Record>
</Collection>
</Annotation>
</Annotations>Determining Actions: Actions shown in object page footer:
<Annotation Term="UI.Identification">
<Collection>
<Record Type="UI.DataFieldForAction">
<PropertyValue Property="Label" String="Approve"/>
<PropertyValue Property="Action" String="Service.ApproveOrder"/>
<PropertyValue Property="Determining" Bool="true"/>
</Record>
</Collection>
</Annotation>Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/06_SAP_Fiori_Elements (search: actions)
---
Draft Handling
Enable users to save incomplete work:
OData Service:
<EntityType Name="SalesOrder">
<Property Name="OrderID" Type="Edm.Int32"/>
<Property Name="IsActiveEntity" Type="Edm.Boolean"/>
<Property Name="HasActiveEntity" Type="Edm.Boolean"/>
<Property Name="HasDraftEntity" Type="Edm.Boolean"/>
</EntityType>Annotations:
<Annotations Target="Service.SalesOrder">
<Annotation Term="Common.DraftRoot">
<Record>
<PropertyValue Property="ActivationAction" String="Service.draftActivate"/>
<PropertyValue Property="EditAction" String="Service.draftEdit"/>
<PropertyValue Property="PreparationAction" String="Service.draftPrepare"/>
</Record>
</Annotation>
</Annotations>Behavior:
- Edit creates draft copy
- Save updates draft
- Save & Exit activates draft
- Cancel discards draft
- Warning on navigation if unsaved changes
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/06_SAP_Fiori_Elements (search: draft)
---
Flexible Column Layout
Multi-column responsive layout for master-detail-detail views:
manifest.json:
{
"sap.ui5": {
"routing": {
"config": {
"routerClass": "sap.f.routing.Router",
"flexibleColumnLayout": {
"defaultTwoColumnLayoutType": "TwoColumnsMidExpanded",
"defaultThreeColumnLayoutType": "ThreeColumnsMidExpanded"
}
},
"routes": [
{
"pattern": "",
"name": "ProductsList",
"target": ["ProductsList"]
},
{
"pattern": "Products({key})",
"name": "ProductDetail",
"target": ["ProductsList", "ProductDetail"]
},
{
"pattern": "Products({key})/Items({itemKey})",
"name": "ItemDetail",
"target": ["ProductsList", "ProductDetail", "ItemDetail"]
}
]
}
}
}Layout Types:
- OneColumn
- TwoColumnsBeginExpanded
- TwoColumnsMidExpanded
- ThreeColumnsMidExpanded
- ThreeColumnsEndExpanded
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/10_More_About_Controls (search: flexible-column-layout)
---
Building Blocks
Reusable UI components for custom pages:
Usage:
<macros:Table
id="productTable"
contextPath="/Products"
metaPath="@com.sap.vocabularies.UI.v1.LineItem"
readOnly="true"/>
<macros:FilterBar
id="filterBar"
contextPath="/Products"
metaPath="@com.sap.vocabularies.UI.v1.SelectionFields"/>
<macros:Form
id="productForm"
contextPath="/Products"
metaPath="@com.sap.vocabularies.UI.v1.FieldGroup#General"/>Available Building Blocks:
- Table
- Chart
- FilterBar
- Form
- Field
- MicroChart
- ValueHelp
Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/06_SAP_Fiori_Elements (search: building-blocks)
---
Extension Points
Customize Fiori Elements apps without modifying templates:
Controller Extensions
manifest.json:
{
"sap.ui5": {
"extends": {
"extensions": {
"sap.ui.controllerExtensions": {
"sap.fe.templates.ListReport.ListReportController": {
"controllerName": "com.mycompany.myapp.ext.ListReportExtension"
}
}
}
}
}
}ext/ListReportExtension.controller.js:
sap.ui.define([
"sap/ui/core/mvc/ControllerExtension"
], function(ControllerExtension) {
"use strict";
return ControllerExtension.extend("com.mycompany.myapp.ext.ListReportExtension", {
override: {
onInit: function() {
// Custom initialization
},
routing: {
onBeforeBinding: function(oBindingContext) {
// Custom logic before binding
}
}
},
customAction: function() {
// Custom function
}
});
});Fragment Extensions
Add custom content to specific locations:
manifest.json:
{
"sap.ui5": {
"extends": {
"extensions": {
"sap.ui.viewExtensions": {
"sap.fe.templates.ListReport.ListReport": {
"ResponsiveTableColumnsExtension::Products": {
"className": "sap.ui.core.Fragment",
"fragmentName": "com.mycompany.myapp.ext.CustomColumns",
"type": "XML"
}
}
}
}
}
}
}ext/CustomColumns.fragment.xml:
<core:FragmentDefinition
xmlns="sap.m"
xmlns:core="sap.ui.core">
<Column>
<Text text="Custom Column"/>
</Column>
</core:FragmentDefinition>Documentation: https://github.com/SAP-docs/sapui5/tree/main/docs/06_SAP_Fiori_Elements (search: extensibility, extension-points)
---
manifest.json Configuration
Complete Example:
{
"_version": "1.42.0",
"sap.app": {
"id": "com.mycompany.products",
"type": "application",
"title": "{{appTitle}}",
"description": "{{appDescription}}",
"applicationVersion": {
"version": "1.0.0"
},
"dataSources": {
"mainService": {
"uri": "/sap/opu/odata/sap/PRODUCT_SRV/",
"type": "OData",
"settings": {
"annotations": ["annotation"],
"localUri": "localService/metadata.xml",
"odataVersion": "2.0"
}
},
"annotation": {
"type": "ODataAnnotation",
"uri": "annotations/annotation.xml",
"settings": {
"localUri": "annotations/annotation.xml"
}
}
}
},
"sap.ui5": {
"dependencies": {
"minUI5Version": "1.120.0",
"libs": {
"sap.fe.templates": {}
}
},
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "com.mycompany.products.i18n.i18n"
}
},
"": {
"dataSource": "mainService",
"preload": true,
"settings": {
"defaultBindingMode": "TwoWay",
"defaultCountMode": "Inline",
"refreshAfterChange": false,
"metadataUrlParams": {
"sap-value-list": "none"
}
}
}
},
"routing": {
"config": {
"flexibleColumnLayout": {
"defaultTwoColumnLayoutType": "TwoColumnsMidExpanded",
"defaultThreeColumnLayoutType": "ThreeColumnsMidExpanded"
},
"routerClass": "sap.f.routing.Router"
},
"routes": [
{
"pattern": ":?query:",
"name": "ProductsList",
"target": ["ProductsList"]
},
{
"pattern": "Products({key}):?query:",
"name": "ProductDetail",
"target": ["ProductsList", "ProductDetail"]
}
],
"targets": {
"ProductsList": {
"type": "Component",
"id": "ProductsList",
"name": "sap.fe.templates.ListReport",
"options": {
"settings": {
"contextPath": "/Products",
"variantManagement": "Page",
"navigation": {
"Products": {
"detail": {
"route": "ProductDetail"
}
}
},
"initialLoad": true,
"tableSettings": {
"type": "ResponsiveTable",
"selectAll": true,
"selectionMode": "Multi"
}
}
}
},
"ProductDetail": {
"type": "Component",
"id": "ProductDetail",
"name": "sap.fe.templates.ObjectPage",
"options": {
"settings": {
"contextPath": "/Products",
"editableHeaderContent": true
}
}
}
}
}
},
"sap.fiori": {
"registrationIds": [],
"archeType": "transactional"
}
}---
Links to Official Documentation
- Fiori Elements Overview: https://github.com/SAP-docs/sapui5/tree/main/docs/06_SAP_Fiori_Elements
- Annotations: https://github.com/SAP-docs/sapui5/tree/main/docs/06_SAP_Fiori_Elements (search: annotations)
- Building Blocks: https://github.com/SAP-docs/sapui5/tree/main/docs/06_SAP_Fiori_Elements (search: building-blocks)
- Extensions: https://github.com/SAP-docs/sapui5/tree/main/docs/06_SAP_Fiori_Elements (search: extensibility)
- Draft Handling: https://github.com/SAP-docs/sapui5/tree/main/docs/06_SAP_Fiori_Elements (search: draft)
---
Note: This document covers SAP Fiori Elements configuration and usage. For specific templates and advanced scenarios, refer to the official documentation links provided.
/**
* SAPUI5 Component Template
*
* Usage: Replace placeholders with actual values:
* - {{namespace}}: Your app namespace (e.g., com.mycompany.myapp)
* - {{appId}}: Application ID
*
* File: Component.js
*/
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/model/json/JSONModel",
"sap/ui/Device"
], function(UIComponent, JSONModel, Device) {
"use strict";
return UIComponent.extend("{{namespace}}.Component", {
metadata: {
manifest: "json"
},
/**
* Component initialization
* Called once when component is instantiated
*/
init: function() {
// Call parent init
UIComponent.prototype.init.apply(this, arguments);
// Create device model
var oDeviceModel = new JSONModel(Device);
oDeviceModel.setDefaultBindingMode("OneWay");
this.setModel(oDeviceModel, "device");
// Create router
this.getRouter().initialize();
},
/**
* Get content density class based on device
* @returns {string} CSS class
*/
getContentDensityClass: function() {
if (!this._sContentDensityClass) {
if (!Device.support.touch) {
this._sContentDensityClass = "sapUiSizeCompact";
} else {
this._sContentDensityClass = "sapUiSizeCozy";
}
}
return this._sContentDensityClass;
}
});
});
/**
* SAPUI5 Controller Template
*
* Usage: Replace placeholders with actual values:
* - {{namespace}}: Your app namespace
* - {{ControllerName}}: Controller name
*
* File: controller/{{ControllerName}}.controller.js
*/
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel",
"sap/ui/model/Filter",
"sap/ui/model/FilterOperator",
"sap/m/MessageToast",
"sap/m/MessageBox",
"{{namespace}}/model/formatter"
], function(Controller, JSONModel, Filter, FilterOperator, MessageToast, MessageBox, formatter) {
"use strict";
return Controller.extend("{{namespace}}.controller.{{ControllerName}}", {
formatter: formatter,
/* =========================================================== */
/* lifecycle methods */
/* =========================================================== */
/**
* Called when controller is instantiated
*/
onInit: function() {
// Create view model
var oViewModel = new JSONModel({
busy: false,
selectedItemsCount: 0,
title: ""
});
this.getView().setModel(oViewModel, "view");
// Get router
var oRouter = this.getOwnerComponent().getRouter();
oRouter.getRoute("{{routeName}}").attachPatternMatched(this._onObjectMatched, this);
},
/**
* Called before view is rendered
*/
onBeforeRendering: function() {
// Preparation before rendering
},
/**
* Called after view is rendered
*/
onAfterRendering: function() {
// DOM manipulation if needed
},
/**
* Called when controller is destroyed
*/
onExit: function() {
// Cleanup
},
/* =========================================================== */
/* event handlers */
/* =========================================================== */
/**
* Refresh data
*/
onRefresh: function() {
var oBinding = this.byId("table").getBinding("items");
if (oBinding) {
oBinding.refresh();
MessageToast.show(this.getResourceBundle().getText("refreshSuccess"));
}
},
/**
* Search handler
* @param {sap.ui.base.Event} oEvent Search event
*/
onSearch: function(oEvent) {
var sQuery = oEvent.getParameter("query") || oEvent.getParameter("newValue");
var aFilters = [];
if (sQuery && sQuery.length > 0) {
aFilters.push(new Filter({
filters: [
new Filter("{{Field1}}", FilterOperator.Contains, sQuery),
new Filter("{{Field2}}", FilterOperator.Contains, sQuery)
],
and: false
}));
}
this.byId("table").getBinding("items").filter(aFilters);
},
/**
* Item press handler
* @param {sap.ui.base.Event} oEvent Press event
*/
onPress: function(oEvent) {
var oItem = oEvent.getSource();
var oContext = oItem.getBindingContext();
var sObjectId = oContext.getProperty("{{IdField}}");
this.getOwnerComponent().getRouter().navTo("detail", {
objectId: sObjectId
});
},
/**
* Selection change handler
* @param {sap.ui.base.Event} oEvent Selection change event
*/
onSelectionChange: function(oEvent) {
var iSelectedItems = this.byId("table").getSelectedItems().length;
this.getView().getModel("view").setProperty("/selectedItemsCount", iSelectedItems);
},
/**
* Add button press handler
*/
onAdd: function() {
var oModel = this.getView().getModel();
var oContext = oModel.createEntry("/{{EntitySet}}", {
properties: {
{{Field1}}: "",
{{Field2}}: "",
{{Field3}}: 0
}
});
// Navigate to detail page or open dialog
MessageToast.show(this.getResourceBundle().getText("addSuccess"));
},
/**
* Delete button press handler
*/
onDelete: function() {
var that = this;
var aSelectedItems = this.byId("table").getSelectedItems();
if (aSelectedItems.length === 0) {
MessageBox.warning(this.getResourceBundle().getText("noItemsSelected"));
return;
}
MessageBox.confirm(
this.getResourceBundle().getText("deleteConfirm", [aSelectedItems.length]),
{
onClose: function(sAction) {
if (sAction === MessageBox.Action.OK) {
that._deleteSelectedItems(aSelectedItems);
}
}
}
);
},
/* =========================================================== */
/* internal methods */
/* =========================================================== */
/**
* Route pattern matched handler
* @param {sap.ui.base.Event} oEvent Pattern matched event
* @private
*/
_onObjectMatched: function(oEvent) {
var sObjectId = oEvent.getParameter("arguments").objectId;
this.getView().bindElement({
path: "/{{EntitySet}}('" + sObjectId + "')",
events: {
dataRequested: function() {
this.getView().getModel("view").setProperty("/busy", true);
}.bind(this),
dataReceived: function() {
this.getView().getModel("view").setProperty("/busy", false);
}.bind(this)
}
});
},
/**
* Delete selected items
* @param {Array} aSelectedItems Selected items
* @private
*/
_deleteSelectedItems: function(aSelectedItems) {
var oModel = this.getView().getModel();
var that = this;
this.getView().getModel("view").setProperty("/busy", true);
var aPromises = aSelectedItems.map(function(oItem) {
var sPath = oItem.getBindingContext().getPath();
return new Promise(function(resolve, reject) {
oModel.remove(sPath, {
success: resolve,
error: reject
});
});
});
Promise.all(aPromises)
.then(function() {
that.getView().getModel("view").setProperty("/busy", false);
MessageToast.show(that.getResourceBundle().getText("deleteSuccess"));
that.byId("table").removeSelections();
})
.catch(function(oError) {
that.getView().getModel("view").setProperty("/busy", false);
MessageBox.error(that.getResourceBundle().getText("deleteError"));
});
},
/**
* Get resource bundle for i18n
* @returns {sap.ui.model.resource.ResourceModel} Resource bundle
* @private
*/
getResourceBundle: function() {
return this.getOwnerComponent().getModel("i18n").getResourceBundle();
}
});
});