Hello World !

 

Je vous propose de réaliser avec moi ce premier tutorial « Hello World! » disponible ici : https://openui5.hana.ondemand.com/#docs/guide/592f36fd077b45349a67dcb3efb46ab1.html

Il s’agit d’une simple application affichant le titre « Hello World ! » et permettant, à l’aide d’un bouton, de naviguer vers une seconde page :
Capture d’écran 2016-09-03 à 15.36.59

Cela devra ressembler à ça : https://openui5.hana.ondemand.com/#test-resources/sap/m/demokit/helloworld/index.html

Etape 1 – Création de l’application en cliquant sur « New Application » :
Capture d’écran 2016-09-03 à 15.39.38

Nommer votre application :
Capture d’écran 2016-09-03 à 15.41.09

L’application a été créée :
Capture d’écran 2016-09-03 à 15.46.01

Démarrer Web IDE en cliquant sur l’icône crayon depuis la colonne « Actions » :
Capture d’écran 2016-09-03 à 15.48.10

Here we go :

Capture d’écran 2016-09-03 à 15.48.48

L’environnement de développement SAP Web IDE est chargé à l’écran :
Capture d’écran 2016-09-03 à 15.53.38

Etape 2 – Création d’un nouveau projet à partir d’un template :
Capture d’écran 2016-09-04 à 11.17.52

Sélectionner « SAPUI5 Application » :
Capture d’écran 2016-09-04 à 11.18.40

Renseigner les informations générales du projet :
Capture d’écran 2016-09-04 à 11.22.55

Capture d’écran 2016-09-04 à 11.23.52

Le projet est initialisé :
Capture d’écran 2016-09-04 à 11.29.37

Etape 3 – Initialisation de l’application

Comme indiqué dans le tutorial, la librairie sap.m fourni un contrôle « App » agissant en tant que contrôle racine d’une application, et qui nous permettra ici de gérer les pages multiples ainsi que les animations de navigations.

On peut remarquer que la page index, générée automatiquement lors de la création du projet, contient une fonction attachée à l’event « attachInit » :
Capture d’écran 2016-09-04 à 11.46.20

Cet event est appelé automatiquement lors de l’initialisation de OpenUI5. Nous allons ainsi modifier la fonction attachée à cet event pour instancier le contrôle « App » et définir la page à afficher à l’initialisation de l’application :
Capture d’écran 2016-09-04 à 11.52.06

Etape 4 – Création des pages

Nous allons maintenant ajouter les pages 1 et 2 à notre application.

Création de la page 1 avec un titre ainsi qu’un bouton nous permettant de naviguer vers la page 2 :
Capture d’écran 2016-09-04 à 11.56.57

Création de la page 2 avec un titre. Le retour vers la page précédente est géré par l’implémentation du clic sur le bouton de navigation de la page :
Capture d’écran 2016-09-04 à 11.59.51

Enfin, nous ajoutons les deux pages à l’application :
Capture d’écran 2016-09-04 à 12.01.59

Etape 5 – Test de l’application :
Capture d’écran 2016-09-04 à 12.06.04

L’application se lance et la page 1 est automatiquement affichée :
Capture d’écran 2016-09-04 à 12.06.46

En cliquant sur le bouton, on arrive à la page 2 :
Capture d’écran 2016-09-04 à 12.08.14

Le clic sur le bouton de navigation retour nous ramène vers la page 1 :
Capture d’écran 2016-09-04 à 12.06.46

 

Quelques tutorials accessibles pour débuter et progresser sur UI5

C’est la rentrée, on s’y remet ! Cela fait un moment maintenant que j’ai un peu laissé tomber ce blog, mais que serait la rentrée sans les bonnes résolutions qui vont avec🙂 Pour ma part, je vais donc essayer de revenir ici un peu plus souvent.

Pour commencer, voici une bonne liste de tutorials pour progresser à son rythme sur UI5 : https://openui5.hana.ondemand.com/#docs/guide/8b49fc198bf04b2d9800fc37fecbb218.html

Ceux-ci sont assez bien fichus avec des étapes simples et documentées à l’aide d’explications détaillées, de captures d’écrans et de codes sources téléchargeables.

Il y a pas moins de 7 tutorials en fonction de son niveau et de son domaine d’application (basics, concept, testing, apps) :

Capture d’écran 2016-09-03 à 09.09.32 1

Je vous propose de commencer par le début avec le tutorial « Hello World » dans un second billet, suivi des autres.

Création d’une application UI5 avec service OData sur Web IDE

Maintenant nous allons voir comment consommer un service OData sur Web IDE à partir d’un exemple simple : récupérer une liste de données.

1 – Créer un nouveau projet à partir d’un template :
1

2 – Sélectionner le template « SAPUI5 Application Project » :
2.png

3 – Saisir le nom du projet :
3

4 – Saisir les détails de la vue initiale :
4

5 – La création du projet est confirmée :
5

6 – Le projet est créé :
6

7 – Ouvrir la vue avec le Layout Editor :
7

8 – La vue est affichée en mode WYSIWYG (What You See Is What You Get) :
8

9 – Ne pas hésiter à modifier les propriétés :
9

10 – Sélectionner la liste dans la bibliothèque d’objets et ajouter là dans la vue :
10

11 – La vue est chargée à l’écran :
11

12 – Il nous faut maintenant ajouter le service OData au projet. Pour ce faire, faire un clic droit sur le projet puis sélectionner « New » et enfin « OData Service » :
12

13 – Sélectionner votre service OData :
13

14 – Confirmer l’ajout du service OData :
14

15 – On remarque que le dossier « model » est automatiquement créé avec le fichier metadata correspondant au service :
15

16 – Revenir sur la View et rafraichir (F5) de façon à obtenir la popup ci-dessous et sélectionner le Data Set, puis valider :
16

17 – Le Data Set apparaît :
17

18 – Le chargement du modèle est  automatiquement implémenté :
18

19

19 – Il ne reste plus qu’à faire le mapping entre le modèle et la liste de la View :
20

20 –Test de l’application :
21

22

Création d’un Service OData

Objectif : Création d’un service Gateway sur le système SAP Gateway retournant la liste des utilisateurs du système backend basé sur la bapi BAPI_USER_GETLIST.

1 – Configuration du Gateway Hub, sur le système backend (lorsque les fonctionnalités serveurs de SAP Netweaver Gateway sont utilisées sur un serveur dédié) :

Aller en transaction SPRO :
1

Aller dans SAP Customizing Implementation Guide > SAP NetWeaver > Gateway Service Enablement > Backend OData Channel > Connection Settings to SAP NetWeaver Gateway > SAP NetWeaver Gateway Settings :
2

Ajouter le système Gateway avec sa destination RFC :
3

4

2 – Création du projet en transaction SEGW (SAP Gateway Service Builder) sur le système backend :
5

6

3 – Passer en mode édition, et créer une nouvelle Entity Type en important la structure DDIC BAPIUSNAME :
7

Il s’agit de la liste des utilisateurs retournée par le module fonction BAPI_USER_GETLIST :
8

4 – Choisir les champs à récupérer (ne prendre que ce dont vous avez réellement besoin) :
9

5 – Préciser le ou les champs clés :
10

6 – Générer les objets runtimes (on peut remarquer au passage que l’entity set associé a automatiquement été créé ainsi que le service implementation) :
11

7 – Laisser l’écran suivant renseigné avec les valeurs par défaut et valider :
12

8 – Les objets runtime sont générés :
13

9 – Nous allons maintenant implémenter la méthode GetEntitySet afin d’y appeler le module fonction BAPI_USER_GETLIST et y retourner la liste des utilisateurs. Pour cela, faire un clic droit sur « GetEntitySet » puis sélectionner « Go to ABAP Workbench » :
14

10 – Valider la popup :
15

11 – Choisir la méthode GET_ENTITYSET comme mentionné dans la popup précédente et choisir « Redefine » :
16

12 – Implémenter la méthode avec l’appel du module fonction BAPI_USER_GETLIST :
17

13 – Retourner dans la SEGW, sélectionner le système Gateway dans Service Maintenance et cliquer sur « Register » :
18.png

14 – Valider la popup :
19

15 – Choisir l’alias système de l’hub (Gateway) vers le backend (http://scn.sap.com/docs/DOC-62040) et valider :
20

16 – Laisser l’écran suivant renseigné avec les valeurs par défaut et valider :
21

17 – Une fois de retour sur l’écran suivant, vous devriez remarquer que le feu « Registration Status » devrait être vert. Nous allons maintenant tester le service en cliquant sur « Gateway Client » :
22

18 – Vous devriez arriver sur l’écran suivant (vous remarquerez au passage que vous avez été basculé sur le système Gateway) et cliquer sur « EntitySets » :
23

19 – Sélectionner votre entity set :
24

20 – La Request URI devrait être mise à jour avec l’entity set. Cliquer sur « Execute » :
25

21 – Si tout fonctionne correctement, vous devriez voir la réponse du service avec les données demandées :
26

Le service sera accessible dans n’importe quel navigateur web pour du format XML ou JSON :

http://…/sap/opu/odata/SAP/ZGW_USERS_LIST_02_SRV/BapiUsnameSet?$format=xml
27

http://…/sap/opu/odata/SAP/ZGW_USERS_LIST_02_SRV/BapiUsnameSet?$format=json
28

Il est également possible de récupérer les métadata du service avec le suffixe $metadata :
29

Celles-ci seront également accessibles par le navigateur web :
30

Installer SAP Web IDE en local

Comme vous avez pu le remarquer, SAP Web IDE fait partie intégrante de SAP HCP (Hana Cloud Platform). C’est très pratique, mais on peut alors se demander comment faire pour développer sans connexion internet. Sachez que l’on a donc la possibilité de l’installer en local et l’utiliser hors-ligne comme expliqué ici : http://scn.sap.com/community/developer-center/front-end/blog/2015/04/21/install-sap-web-ide-locally-for-trial-windows-version

Deux questions pour l’instant sur lesquelles je n’ai pas eu le temps de me pencher (si vous avez la réponse, je suis preneur):

  • Au moment du téléchargement, la version offline est-elle à jour avec la version HCP ?
  • Comment faire pour mettre à jour la version offline autrement qu’avec une nouvelle installation ?

Quoiqu’il en soit, bon à savoir🙂

 

SAP Web IDE

Après quelques mois d’absence, j’essaie enfin de me remettre à SAPUI5 et là je me dis qu’Eclipse c’est cool mais qu’il n’est quand même pas du tout pratique de devoir construire toute son interface utilisateur qu’avec du code en faisant des allers retours avec l’aperçu pour voir ce que ce que cela donne concrètement alors qu’il existe aujourd’hui SAP Web IDE pour notamment palier à ce problème.

SAP Web IDE est un outil de développement client léger permettant un développement simple et rapide d’applications UI5 grâce notamment à du drag and drop (WYSIWYG), des templates, des wizards… Je n’ai pas encore eu le temps d’essayer, mais par rapport à Eclipse ça fait rêver !

Pour plus d’infos : http://hcp.sap.com/developers/TutorialCatalog/wide100_01_getting_sap_web_ide.html

Le protocole OData

Avant de parler de OData il convient déjà de comprendre ce qu’est l’architecture REST. Comme cela est très bien résumé ici, http://www.croes.org/gerald/blog/qu-est-ce-que-rest/447/, REST est en gros un ensemble de conventions permettant de créer des services web basés sur le protocole HTTP. Par exemple, l’API de OpenWeatherMap utilisée précédemment via le web service Forecast est en fait une API REST dont la seule méthode disponible est GET.

OData dans tout ça est un protocole ouvert avec un ensemble de bonnes pratiques apportant une normalisation pour construire et consommer des APIs REST.

Si on prends par exemple le service http://services.odata.org/V4/(S(tbodsh53eaunnvmkizrjmuae))/TripPinServiceRW/People présenté sur OData.org en l’exécutant dans le navigateur, on obtiendra le résultat suivant :
2015-04-10_114155

Ce n’est pas super lisible mais on peut reconnaitre le format JSON. Ainsi pour rendre cela un peu plus clair on pourra dans ce cas encore utiliser un JSON Viewer pour rendre cela un peu plus parlant :

2015-04-10_152207

Open UI5 : Création d’une application de prévisions météo

Pour faire suite au précédent article sur la consommation de web services JSON, nous allons maintenant développer une application de prévisions météo basée sur l’API de OpenWeatherMap. Celle-ci sera composée d’une zone de recherche (pour saisir la ville pour laquelle on souhaite récupérer les prévisions météo), d’un panel avec les prévisions du jour et d’une table contenant les prévisions sur une plage de 7 jours.

Aperçu du résultat final :
2015-04-09_145244

Commençons par créer un nouveau projet avec une vue main :
2015-04-09_114737

Modifiez le controller afin d’y ajouter une fonction de chargement des données à partir d’une ville passée en paramètre. Cette fonction sera appelée lors de la validation de la zone de recherche.

LoadWeather : function(ville){
//Instanciation du model JSON :
var jsonModel = new sap.ui.model.json.JSONModel();
//Construction de l’URL :
var apiUrl = « http://api.openweathermap.org/data/2.5/forecast/daily?q= » + ville + « &mode=json&units=metric&cnt=7 »;
//Chargement des donnees :
jsonModel.loadData(apiUrl);
//Assignation des donnees :
sap.ui.getCore().setModel(jsonModel);
//Mise a jour de l’image de la journee :
jsonModel.attachRequestCompleted(function() {
var icon = jsonModel.getProperty(« /list/0/weather/0/icon »);
var image = sap.ui.getCore().byId(« imageCurrent »);
image.setSrc(« http://openweathermap.org/img/w/ » + icon + « .png »);
});
}

On distingue ainsi :

Le chargement de données pour la ville passée en paramètre :
2015-04-09_120321

Assignation du modèle :
2015-04-09_120729

Actions à effectuer une fois les données complètement chargées (mise à jour de l’icone de la prévision du jour) :
2015-04-09_120809

Modifier ensuite la vue (fonction createContent) comme suit :

createContent : function(oController) {
//Barre de recherche :
var oSearch = new sap.ui.commons.SearchField(« simpleSearch », {
enableListSuggest: false,
search: function(oEvent){
oController.LoadWeather(oEvent.getParameter(« query »)); //Fonction a appeler
}});

//Table des previsions a 7 jours :
var weatherTable = new sap.ui.table.Table({
title : « Previsions a 7 jours »,
rows : {
path : « /list »,
sorter : new sap.ui.model.Sorter(« dt »)
},
visibleRowCount:7
});

//Colonne Jour :
weatherTable.addColumn(new sap.ui.table.Column({
label : new sap.ui.commons.Label({text : « Jour »}),
template: new sap.ui.commons.TextView({ text: {
parts: [
{path: « dt », type: new sap.ui.model.type.String()} ],
//Formatage de la date au format JJ/MM/YYYY
formatter: function(dt){
var date = new Date(dt*1000); //dt est un timestamp
var dd = date.getDate();
var mm = date.getMonth()+1; //Janvier = 0
var yyyy = date.getFullYear();

if(dd<10){
dd=‘0’+dd;
}
if(mm<10){
mm=‘0’+mm;
}

return dd+‘/’+mm+‘/’+yyyy;
}
}})
}));

//Colonne Temps (icone) :
weatherTable.addColumn(new sap.ui.table.Column({
label : new sap.ui.commons.Label({text : « Temps »}),
template: new sap.ui.commons.Image().bindProperty(« src », {
parts: [
{path: « weather/0/icon »} ],
//Formatage de l’url de l’icone a charger :
formatter: function(icon){
return « http://openweathermap.org/img/w/ &raquo; + icon + « .png »;
}})}));

//Colonne Observations :
weatherTable.addColumn(new sap.ui.table.Column({
label : new sap.ui.commons.Label({text : « Observation »}),
template: new sap.ui.commons.TextView({ text: « {weather/0/description} »})}));

//Colonne Temperature moyenne :
weatherTable.addColumn(new sap.ui.table.Column({
label : new sap.ui.commons.Label({text : « Temperature moyenne »}),
template: new sap.ui.commons.TextView({ text: {
parts: [
{path: « temp/day », type: new sap.ui.model.type.String()} ],
formatter: function(day){

return day + « \u00b0 » ;
}
}})
}));

//Colonne Temperature minimum :
weatherTable.addColumn(new sap.ui.table.Column({
label : new sap.ui.commons.Label({text : « Temperature min »}),
template: new sap.ui.commons.TextView({ text: {
parts: [
{path: « temp/min », type: new sap.ui.model.type.String()} ],
formatter: function(min){

return min + « \u00b0 » ;
}
}})
}));

//Colonne Temperature max :
weatherTable.addColumn(new sap.ui.table.Column({
label : new sap.ui.commons.Label({text : « Temperature max »}),
template: new sap.ui.commons.TextView({ text: {
parts: [
{path: « temp/max », type: new sap.ui.model.type.String()} ],
formatter: function(max){

return max + « \u00b0 » ;
}
}})
}));

//Colonne Vent :
weatherTable.addColumn(new sap.ui.table.Column({
label : new sap.ui.commons.Label({text : « Vent »}),
template: new sap.ui.commons.TextView({ text: {
parts: [
{path: « speed »} ],
formatter: function(speed){
return ((speed * 3.6).toFixed(2)) +  » Km/h »;
}
}})
}));

//Label de la barre de recherche :
var oLbl = new sap.ui.commons.Label(« search »);
oLbl.setLabelFor(oSearch);
oLbl.setText(« Ville »);
//Current weather panel :
var oImage = new sap.ui.commons.Image(« imageCurrent »);
var oPanelCurrent = new sap.ui.commons.Panel(« panelcurrent », {title:new sap.ui.core.Title(« title1 », {text:« Previsions du jour »})});
var oLayout01 = new sap.ui.commons.layout.MatrixLayout(« layout01 »);
oLayout01.createRow(oImage);
var oLayout02 = new sap.ui.commons.layout.MatrixLayout(« layout02 »);
oLayout02.createRow(« Ville : « , « {/city/name} », « {/city/country} » );
oLayout02.createRow(« Observation : « , « {/list/0/weather/0/description} » );
oLayout02.createRow(« Temp. moyenne : « , « {/list/0/temp/day} » );
oLayout02.createRow(« Temp. min : « , « {/list/0/temp/min} » );
oLayout02.createRow(« Temp. max : « , « {/list/0/temp/max} » );
var oLayout00 = new sap.ui.commons.layout.MatrixLayout(« layout00 »);
oLayout00.setWidth(« 400px »);
oLayout00.setWidths(« 40px »,« 300px »);
oLayout00.createRow(oLayout01, oLayout02);
oPanelCurrent.addContent(oLayout00);
//Barre de recherche et Current weather panel :
var oCell1 = new sap.ui.commons.layout.MatrixLayoutCell;
oCell1.addContent(oLbl);
oCell1.setVAlign(sap.ui.commons.layout.VAlign.Top);
var oCell2 = new sap.ui.commons.layout.MatrixLayoutCell;
oCell2.addContent(oSearch);
oCell2.setVAlign(sap.ui.commons.layout.VAlign.Top);
var layout = new sap.ui.commons.layout.MatrixLayout(« layout »);
layout.setWidth(« 800px »);
layout.setWidths(« 25px »,« 70px »,« 200px »);
layout.createRow(oCell1, oCell2, oPanelCurrent);
//Placement de tous les elements :
var oPanel = new sap.ui.commons.Panel(« panel », {title:new sap.ui.core.Title(« title », {text:« UI5 Live Meteo »})});
oPanel.addContent(layout);
oPanel.addContent(new sap.ui.commons.HorizontalDivider());
oPanel.addContent(weatherTable);
oPanel.placeAt(‘content’);
}


Voilà, notre application météo est développée😉 :

2015-04-09_145244

Open UI5 : Consommation de web service JSON

Dans les exemples précédents, nous avons utilisé des modèles de données basés sur des données JSON écrites directement en dures dans le code. C’est sympa pour les exemples et pour comprendre comment ça marche, mais aurez compris que ce n’est évidemment pas la finalité😉

Un web service c’est en gros, une url avec tout plein de paramètres (c’est mieux pour préciser ce que l’on souhaite récupérer ;-)) qui retourne les données correspondantes à notre requête dans un certain format (généralement XML ou JSON).

Admettons que vous souhaitiez développer une application qui affichera les prévisions météo d’une ville donnée, vous pourrez alors vous tourner vers le site OpenWeatherMap qui met à disposition une API répondant parfaitement à ce besoin.

Vous voulez par exemple récupérer les prévisions météo sur 7 jours, vous pouvez pour cela utiliser l’API avec l’url suivante :  api.openweathermap.org/data/2.5/forecast/daily?q=London&mode=xml&units=metric&cnt=7.

Ainsi on retrouve dans cette url :
– La ville (q) : ici « London »
– Le type de données à retourner (mode) : ici « XML »
– L’unité de mesure (units) : ici « metric »
– Le nombre de jours (cnt) : ici « 7 »

Vous pouvez charger cette url directement dans votre navigateur préféré, vous devriez alors obtenir quelque chose comme cela :
2015-04-09_105736

On peut ainsi voir les prévisions météo sur 7 jours pour la ville de Londres dans un format XML.

De même en demandant du format JSON (en spécifiant simplement mode=json au lieu de mode=xml) :
2015-04-09_110028

Bon comme ça c’est moins compréhensible, mais pas de panique notre ami Google regorge de JSON Viewer, par exemple http://jsonviewer.stack.hu/. Collez ainsi la chaîne JSON obtenue et cliquez sur Viewer :
2015-04-09_110510

Vous devriez obtenir cela (tout de suite c’est plus clair) :
2015-04-09_110816

Dans UI5, c’est presque comme ce que l’on a pu voir précédemment. En effet, à la place d’assigner les données en dures via la méthode sap.ui.model.json.JSONModel.setData(<JSON en dur>), on utilisera la méthode sap.ui.model.json.JSONModel.loadData(<url API>).

Open UI5 : Tables en-tête et détails

Nous allons maintenant reprendre le projet « CalculatedFields » créé précédemment, que nous allons faire évoluer afin d’ajouter en table d’en-tête contenant la liste des sports. Dès lors que l’utilisateur sélectionne un sport, la table de détails (liste des sportifs) sera filtrée avec les sportifs correspondants au sport sélectionné.

Pour ce faire il conviendra de créer une nouvelle table (contenant la liste des sports donc) qui filtrera la seconde table (liste des sportifs) via la méthode attachRowSelectionChange.

Adapter la méthode createContent comme suit pour répondre à ce nouveau besoin :


createContent : function(oController) {
//Donnees de la table :
var tableData = {
//Les sports :
« sports » : [
{« sport »:« Tous »},
{« sport »:« Athletisme »},
{« sport »:« Badminton »},
{« sport »:« Basketball »},
{« sport »:« Boxe »},
{« sport »:« Tennis »},
],
//Les sportifs :
« data » : [
{« nom »:« Bolt »,« prenom »:« Usain »,« discipline »:« Athletisme »},
{« nom »:« Jordan »,« prenom »:« Michael »,« discipline »:« Basketball »},
{« nom »:« Blake »,« prenom »:« Yohan »,« discipline »:« Athletisme »},
{« nom »:« Bryant »,« prenom »:« Kobe »,« discipline »:« Basketball »},
{« nom »:« Johnson »,« prenom »:« Magic »,« discipline »:« Basketball »},
{« nom »:« Tyson »,« prenom »:« Mike »,« discipline »:« Boxe »},
{« nom »:« Kournikova »,« prenom »:« Anna »,« discipline »:« Tennis« },
{« nom »:« Holyfield »,« prenom »:« Evander »,« discipline »:« Boxe »},
{« nom »:« Lee »,« prenom »:« Chong Wei »,« discipline »:« Badminton »}
]};

//Creation de l’instance du model JSON :
var oModel = new sap.ui.model.json.JSONModel();
var oPanel = new sap.m.Panel(« panel »);
var oPanel1 = new sap.m.Panel(« panel1 », {headerText:« Les sports »});
var oPanel2 = new sap.m.Panel(« panel2 », {headerText:« Les sportifs »});

//Donnees du model :
oModel.setData(tableData);

//Creation de la table :
var oTableSports = new sap.ui.table.Table({
width: « 100% »,
columns: [
//Colonne Sport :
new sap.ui.table.Column({
label:new sap.ui.commons.Label({ text : « Sport »}),
template: new sap.ui.commons.TextView({ text: « {sport} »}),
})],
visibleRowCountMode: sap.ui.table.VisibleRowCountMode.Fixed,
visibleRowCount:oModel.getData().sports.length,
});

//Model de la table de sports :
oTableSports.setModel(oModel);
//Binding de la table de sports :
oTableSports.bindRows(« /sports »);
//Ajout de la table au Panel 1 :
oPanel1.addContent(oTableSports);

//Creation de la table :
var oTable = new sap.ui.table.Table({
width: « 100% »,
columns: [
//Colonne Nom :
new sap.ui.table.Column({
label:new sap.ui.commons.Label({ text : « Nom »}),
template: new sap.ui.commons.TextView({ text: « {nom} »}),
}),
//Colonne Prenom :
new sap.ui.table.Column({
label:new sap.ui.commons.Label({ text : « Prenom »}),
template: new sap.ui.commons.TextView({ text: « {prenom} »}),
}),
//Colonne discipline :
new sap.ui.table.Column({
label:new sap.ui.commons.Label({ text : « Discipline »}),
template: new sap.ui.commons.TextView({ text: « {discipline} »}),
}),
//Colonne Description :
new sap.ui.table.Column({
label:new sap.ui.commons.Label({ text : « Description »}),
template: new sap.ui.commons.TextView({ text: {
parts: [
{path: « nom », type: new sap.ui.model.type.String()},
{path: « prenom », type: new sap.ui.model.type.String()},
{path: « discipline », type: new sap.ui.model.type.String()} ],
formatter: function(nom, prenom,discipline){
if( discipline != null){
if( discipline.charAt(0) == « A »){
return prenom +  » «  + nom +  » est un champion d' » + discipline;
}
else{
return prenom +  » «  + nom +  » est un champion de «  + discipline;
}
}
}
}}),
}),
],
visibleRowCountMode: sap.ui.table.VisibleRowCountMode.Fixed,
visibleRowCount:oModel.getData().data.length,
});

//Model de la table de sportifs :
oTable.setModel(oModel);
//Binding de la table de sportifs :
oTable.bindRows(« /data »);
//Ajout de la table au Panel 2 :
oPanel2.addContent(oTable);

//Ajout du Panel 1 au Panel global :
oPanel.addContent(oPanel1);
//Ajout du Panel 2 au Panel global :
oPanel.addContent(oPanel2);

//Evenement selection ligne :
oTableSports.attachRowSelectionChange(function(oEvent){
//Recuperation du contexte :
var selectedRowContext = oEvent.getParameter(« rowContext »);
//Recuperation du sport selectionne :
var selectedSport = oModel.getProperty(« sport », selectedRowContext);
//Binding sur table des sportifs :
var sportifsBinding = oTable.getBinding();
if (selectedSport == « Tous »){
//Application du filtre :
sportifsBinding.filter(null);
}
else{
//Filtre sur le sport :
var oFilter = new sap.ui.model.Filter(« discipline », sap.ui.model.FilterOperator.EQ, selectedSport);
//Application du filtre :
sportifsBinding.filter(oFilter);
}
});

return new sap.m.Page({
title: « Calculated fields Demo »,
content: [
oPanel
]
});
}


A la fin vous devriez obtenir cela :
2015-04-07_185038

2015-04-07_185219

2015-04-07_185314