Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
ChristianPf
Participant
This is a pure "academic" project to get a better understanding of how to use UI5 Web Components without any framework such as React, Angular or Vue.

My goal is to create blog series during which we will cover following topics

  • Getting started with UI5 Web Components

  • Enhancing our example using template tag

  • Let´s create a bundle

  • I hate todo lists, so we create a shopping list example :wink:

  • Additional topics such as i18n, theming and create your own UI5 Web Components


Getting started with UI5 Web Components


Get started


This blog is a result of something I hacked together during SAP TechEd 2020. I wanted to get a first understanding how UI5 Web Components work and how I can use them.
The excellent blog post from mariusobert made me curios but I am not much familiar with React, Angular or Vue. I wanted to keep things simple. I am more a hands-on person (#HandsOnSAPDev), I get an itch to start building stuff once I understand (or think I understand :wink: ) the basic concepts.

What we will do in this first blog is to create simple webapp that will contain a UI5 table and button.
The button will trigger displaying data in our table.

At the end it should look like the table example provided on the official documentation UI5 Web Components Table.

WARNING!
I am using modern JavaScript syntax that might not work with older browsers. Please use a modern browser.

Initializing the project


So let's get our hands dirty by initializing our project using npm
mkdir ui5-webcomponents-wo-frk
cd ui5-webcomponents-wo-frk
npm init -y

We will create an HTML and a JavaScript file to keep things separate. By things I mean describing the form of the content (HTML) and the actual logic (JavaScript).

Before that we should actually know how we can create a UI5 Web Component. Looking at the official documentation there are two ways to create a UI5 Web Component element

  • Using HTML tags defined by the Web Component

  • Using the HTML DOM API e.g. createElement


Alright, let's do that and create our HTML file. To speed things up, I copied the table from the official documentation :wink: .

Nothing fancy here. We declare a table and create the columns. No table rows or cells yet to actually display any product data.
<html>

<head>
<title>UI5 Web Components w/o Framework</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>

<body>
<div>
<ui5-table id="productsTable" no-data-text="No Data" show-no-data>
<ui5-table-column slot="columns" style="width: 12rem">
<span style="line-height: 1.4rem">Product</span>
</ui5-table-column>

<ui5-table-column slot="columns" min-width="800" popin-text="Supplier">
<span style="line-height: 1.4rem">Supplier</span>
</ui5-table-column>

<ui5-table-column slot="columns" min-width="600" popin-text="Dimensions" demand-popin>
<span style="line-height: 1.4rem">Dimensions</span>
</ui5-table-column>

<ui5-table-column slot="columns" min-width="600" popin-text="Weight" demand-popin>
<span style="line-height: 1.4rem">Weight</span>
</ui5-table-column>

<ui5-table-column slot="columns">
<span style="line-height: 1.4rem">Price</span>
</ui5-table-column>
</ui5-table>
</div>

</body>

</html>

Yes we did it! We used the UI5 Web Components successfully in our HTML page. Or did we?


Well we are not there yet. Just because there is a tag does not mean the browser knows what to do with it.
We have to let the browser know the tag and how it should be rendered (UI5 and Fiori style please).

Adding UI5 Web Components Modules


UI5 Web Components are delivered as ES6 Modules. In order to use the modules we actually need to get them.
So we run:
npm install @ui5/webcomponents

Now we have the UI5 Web Components in the `node_modules` folder. Great.

Hmmm, opening the page in your favorite web browser still shows errors in the console.

What we have to achieve that the needed UI5 Web Components are actually loaded. Looking at the documentation we find the following statements.
import "@ui5/webcomponents/dist/Table.js";
import "@ui5/webcomponents/dist/TableColumn.js";

Perfect, now we know what to do but we are still not clear where to put this code.
Reading another tutorial we realize that we have to create a JavaScript file in which we place the import statements.
We want to keep the JavaScript files in a different folder so we create one real quick
mkdir src

We create a new file `index.js` and add the import statements in there. Nothing else.

In addition, we have to load the JavaScript in our HTML document.
<body>
...
</table>
<script type="module" src="./src/index.js"></script>
</body>

 

Finally! We are ready to see our beautiful UI5 table any seconds now...

WHAAAATTTT?


This error tells us we can't just load js files who are importing ES6 modules when simply opening the html file in a browser.

So we need a local web server to run our UI5 Web Components app. NPM to the rescue!

Using a local web dev server


There a many options to choose from but I found the Web Dev Server and it worked out of the box. That's all I wanted for now.
Most important is that the imported ES6 modules (which are in the node_modules folder) can be resolved by this web server without the need to involve any bundlers like Webpack, Snowpack, Rollup, Parcel, ... . We will take a look at bundlers in a later blog post.

To use it we will install it as a dev dependency
npm i --save-dev @web/dev-server

Let's edit the package.json file and add an npm command to start the server
"scripts": {
"start": "wds --node-resolve --watch --open"
},

Now all that's left to do, is to run the command and see the "magic happen".
npm run start


Jippie, we finally see our empty table :wink: . It seems like a bit of an effort but once you got the basics setup you are prepared for implementing the real thing.

Adding the button to populate data


Ok now we can add some data to our table. As a starter we will load the data from a local .json file (Fetching data from our beloved NorthWind OData Service will be added later)
[
{
"Product": "Notebook Basic 15HT-1000",
"Supplier": "Very Best Screens",
"Dimensions": "30 x 18 x 3cm",
"Weight": "4.2KG",
"Price": "956EUR"
},
{
"Product": "Notebook Basic 17HT-1001",
"Supplier": "Very Best Screens",
"Dimensions": "29 x 17 x 3.1cm",
"Weight": "4.5KG",
"Price": "1249EUR"
},
{
"Product": "Notebook Basic 18HT-1002",
"Supplier": "Very Best Screens",
"Dimensions": "28 x 19 x 2.5cm",
"Weight": "4.2KG",
"Price": "1570EUR"
},
{
"Product": "Notebook Basic 19HT-1003",
"Supplier": "Smartcards",
"Dimensions": "32 x 21 x 4cm",
"Weight": "4.2KG",
"Price": "1650EUR"
},
{
"Product": "ITelO VaultHT-1007",
"Supplier": "Technocom",
"Dimensions": "32 x 22 x 3cm",
"Weight": "0.2KG",
"Price": "299EUR"
},
{
"Product": "Notebook Professional 15HT-1010",
"Supplier": "Very Best Screens",
"Dimensions": "33 x 20 x 3cm",
"Weight": "4.3KG",
"Price": "1999EUR"
},
{
"Product": "Notebook Professional 17HT-1011",
"Supplier": "Very Best Screens",
"Dimensions": "33 x 23 x 2cm",
"Weight": "4.1KG",
"Price": "2299EUR"
},
{
"Product": "ITelO Vault NetHT-1020",
"Supplier": "Technocom",
"Dimensions": "10 x 1.8 x 17cm",
"Weight": "0.16KG",
"Price": "459EUR"
},
{
"Product": "ITelO Vault SATHT-1021",
"Supplier": "Technocom",
"Dimensions": "11 x 1.7 x 18cm",
"Weight": "0.18KG",
"Price": "149EUR"
},
{
"Product": "Comfort EasyHT-1022",
"Supplier": "Technocom",
"Dimensions": "84 x 1.5 x 14cm",
"Weight": "0.2KG",
"Price": "1679EUR"
},
{
"Product": "Comfort SeniorHT-1023",
"Supplier": "Technocom",
"Dimensions": "80 x 1.6 x 13cm",
"Weight": "0.8KG",
"Price": "512EUR"
}
]

Our button to start populating the table with our data is still missing. So let's add the UI5 Web Components button.
First things first. Let's import the button and then add the HTML tags.

./src/index.js
import "@ui5/webcomponents/dist/Button";

Inside the index.html we place the button directly underneath the table.
...
<div>
<ui5-button id="ui5Button" design="Emphasized">Populate data</ui5-button>
</div>
...

If we open our browser with the local dev web server session we will now see this


But how do we populate the data once button is clicked? Let's take a look at the documentation again. If you scroll all the way down you can see the available events for the ui5 button. It also provides a solution how we can bind to the click event.


Now we "just" have to get the ui5 button from the DOM and register an event listener.
Getting elements from the DOM can be done by using methods of the Document Web API.

We will use the powerful querySelector method to get our ui5 button. If you want to learn more about CSS selectors that can be used take a look here.
const ui5Button = document.querySelector('ui5-button')

Before we continue we should check if this actually works. Open our browser with the local dev web server session. Open up the development tools of your browser and run document.querySelector('ui5-button') in the console.


Ok great this works. Now we can continue with adding the event listener.
import "@ui5/webcomponents/dist/Table.js";
import "@ui5/webcomponents/dist/TableColumn.js";
import "@ui5/webcomponents/dist/Button";
import "@ui5/webcomponents/dist/TableRow.js";
import "@ui5/webcomponents/dist/TableCell.js";

const ui5Button = document.querySelector('ui5-button')

ui5Button.addEventListener('click', addData)

async function addData() {
const response = await fetch('./data/products.json')
const products = await response.json()

const table = document.querySelector('ui5-table')

products.forEach(product => {
const tableRow = document.createElement('ui5-table-row')

for (const [key, value] of Object.entries(product)) {
const tableCell = document.createElement('ui5-table-cell')
tableCell.innerHTML = value
tableRow.append(tableCell)
}
table.appendChild(tableRow)
});
}

Ok we actually did a lot of things in just a few lines of code. Let me guide you through

  1. In order to create UI5 Web Components HTML elements we have to import ui5-table-row and ui5-table-cell

  2. We use the Fetch API to load data from our JSON file containing the products.

  3. We have to add the data into the cells of the ui5 table. In order to add anything to the table we need to have access to it first. We use the querySelector method again.

  4. Now comes the interesting part. Just like regular HTML tables the ui5 table has rows and cells. We create a row for each product and a cell for each property of our product object.

  5. We create the ui5-table-row HTML element using the createElement method.

  6. For each property of the product object we create a ui5-table-cell. The cell contains the value of the current products property. At the end we append the cell to the row using ParentNode.append method.


Ok let's see if our button does what we hope it will do


YAAAAYYYY it actually works :sparkles: :relieved:

Of course this code is not perfect (we do not catch any potential errors, we can click the button multiple times, ...) but it works for now.

I am quite happy with the result but there is always a possibility for improvement. We create HTML elements using JavaScript and if we would add more logic we might end up in a mess. ( peter.muessig pointed that out and provided some tips how to improve the app. Thx again Peter :wink: )

Let's quickly summarize what we learned on our little journey with UI5 Web Components

  • How to install UI5 Web Components

  • Where we can get additional information about UI5 Web Components

  • How to import the ES6 modules in JavaScript

  • How to load JavaScript files in HTML when ES6 modules are used

  • How to serve a webapp with ES6 modules using a local dev server

  • How to use the HTML DOM API and some other Web APIs

  • How to create UI5 Web Component HTML elements using HTML tags and JavaScript

  • How to register an event listener for a specific event of an html element


Not too bad I would say. We will continue this journey and in the next blog post we will explore a better way how we can create the table using HTML only (almost).

Notes



  • This is my very first blog post on the SAP community. Feel free to provide feedback or ask additional questions. Or just like it in case you enjoyed reading it.

  • Kudos to all SAP community members creating blog posts for the community on a frequent basis. It is quite some work and I highly appreciate what you guys are doing

  • Thx to peter.muessig and wridge for reviewing my blog post


Related Links


4 Comments
mariusobert
Developer Advocate
Developer Advocate
A great first post 🥳.
Thanks, Christian!
wridgeu
Participant
Starting out with a banger! Great first post! 🥳
Quite useful example, thank you. I've just cloned your solution and reimplemented it with my toolset of choice: Vite (actually highly recommended on the UI5 getting started document page) as bundler, TypeScript, lit-html as lightning fast reactive DOM updater/builder, Lit Element to make the entire application a series of web components composed of other web components including the excellent UI5 web component library. With these tools you can apply a combination of reactive as well as traditional imperative (MVC/MVVM) programming paradigm. It's really great that SAP realized the potential in web components, and with UI5 web components SAP is on the front end (pun intended).
shreyashrangrej
Participant
0 Kudos

Really helpful blog thank you for sharing this information Christian.

Labels in this area