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

Open UI5 : Les champs calculés

Les champs calculés permettent le binding de plusieurs propriétés d’un ou plusieurs models à une seule et même propriété d’un contrôle. On pourra ainsi, par exemple, binder la valeur d’un contrôle à une propriété « prénom » d’un model et à une propriété « nom » d’un autre model.

Associé à ce que l’on appelle un formatter, on pourra ainsi définir la façon dont les différentes propriétés seront traitées et assignées à la valeur du contrôle (via par exemple une concaténation).

Nous allons pour cet exemple afficher une table de sportifs affichant pour chacun d’entre eux : son nom, son prénom, et un intitulé du type « <prénom> <nom> est un champion de <discipline> ».

Pour ce faire, commençons par créer un nouveau projet, « CalculatedFields » par exemple (de type mobile, pour changer) :
2015-04-07_163730

Alimenter la méthode createContent comme suit pour créer la table basée sur le model JSon correspondant à notre liste de sportifs (le champ calculé correspondant à la dernière colonne, « description ») :


createContent : function(oController) {
//Donnees de la table :
var tableData = { « data » : [
{« nom »:« Bolt »,« prenom »:« Usain »,« discipline »:« Athletisme »},
{« nom »:« Jordan »,« prenom »:« Michael »,« discipline »:« Basketball »},
{« nom »:« Tyson »,« prenom »:« Mike »,« discipline »:« Boxe »},
{« nom »:« Kournikova »,« prenom »:« Anna »,« discipline »:« Tennis »},
{« nom »:« Lee »,« prenom »:« Chong Wei »,« discipline »:« Badminton »}
]};

//Creation de l’instance du model JSON :
var oModel = new sap.ui.model.json.JSONModel();

oModel.setData(tableData);

//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,
});

oTable.setModel(oModel);
oTable.bindRows(« /data »);

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


Ce qui donne le résultat suivant :

2015-04-07_165459

OpenUI5 : Tris et Filtres

Il est possible de trier et filtrer les données d’un modèle via les méthodes Sorter (sap.ui.model.Sorter) et Filter (sap.ui.model.Filter).

Pour cet exemple nous allons créer deux ComboBox, la première permettant, au choix, de trier ou filtrer les données de la seconde :
Capture d’écran 2015-04-03 à 00.07.39

Pour ce faire nous allons créer une fonction « sortFilter » permettant d’appliquer les tris/filtres et qui sera appelée par la méthode sap.m.ComboBox.attachSelectionChange() :


sortFilter : function (oEvent) {
//Recuperation de la fonction :
var fonction = oEvent.oSource.getSelectedItem().getBindingContext(« ModelOptions »).getProperty(« id »);
//Recuperation du binding :
var oBinding = sap.ui.getCore().byId(« dataVal »).getBinding(« items »);
//Selon la fonction :
switch(fonction){
//Tri par prenom :
case « sortPrenom »:
//Reinitialisation du filtre :
oBinding.filter(null);
//Tri par prenom :
oBinding.sort(new sap.ui.model.Sorter(« prenom », false));
break;
//Tri par nom :
case « sortNom »:
//Reinitialisation du filtre :
oBinding.filter(null);
//Tri par nom :
oBinding.sort(new sap.ui.model.Sorter(« nom », false));
break;
//Tri par parent :
case « filterParent »:
//Filtre par parent :
oBinding.filter(new sap.ui.model.Filter(« fonction », sap.ui.model.FilterOperator.EQ, « parent »));
break;
//Tri par enfant :
case « filterEnfant »:
//Filtre par enfant :
oBinding.filter(new sap.ui.model.Filter(« fonction », sap.ui.model.FilterOperator.EQ, « enfant »));
break;
}
},

createContent : function(oController) {
//****************** DECLARATION DES VARIABLES *********************
//JSon data – Liste des options :
var optionList = { « selection »:« Choose an option »« options »: [
    { « id »:« sortPrenom », « text »:« Trier par prenom »},
    { « id »:« sortNom », « text »:« Trier par nom »},
    { « id »:« filterParent », « text »:« Filtrer par parent »},
    { « id »:« filterEnfant », « text »:« Filtrer par enfant »},
    ]};
//JSon data – Liste des personnages :
var dataList = { « data »: [
{« id »: « hsimpson », « nom »: « Simpson », « prenom »: « Homer »,
« sexe »:« masculin », « fonction »:« parent »,   « text »: « Homer Simpson »},
{« id »: « msimpson », « nom »: « Simpson », « prenom »: « Marge »,
« sexe »:« feminin », « fonction »:« parent », « text »: « Marge Simpson »},
{« id »: « bsimpson », « nom »: « Simpson », « prenom »: « Bart »,
« sexe »:« masculin », « fonction »:« enfant », « text »: « Bart Simpson »},
{« id »: « lsimpson », « nom »: « Simpson », « prenom »: « Lisa »,
« sexe »:« feminin », « fonction »:« enfant », « text »: « Lisa Simpson »},
{« id »: « msimpson2 », « nom »: « Simpson », « prenom »: « Maggie »,
« sexe »:« feminin », « fonction »:« enfant », « text »: « Maggie Simpson »}
]};

//Creation des instances de models :
var oModelOptions = new sap.ui.model.json.JSONModel();
var oModelData = new sap.ui.model.json.JSONModel();
//Assignation des donnees au model – Options :
oModelOptions.setData(optionList);
//Assignation des donnees au model – Data :
oModelData.setData(dataList);
//Assignation du model options :
sap.ui.getCore().setModel(oModelOptions, « ModelOptions »);
//Assignation du model data :
sap.ui.getCore().setModel(oModelData, « ModelData »);
//Panel :
var oPanel = new sap.m.Panel(« panel »);
//Layout :
var oLayout = new sap.ui.commons.layout.MatrixLayout(« layout »);
//Label Options :
var oOptionsLbl = new sap.m.Label(« optionsLbl », {text:« Options », labelFor:« oOptionsVal »});
//Options :
var oOptionsVal = new sap.m.ComboBox(« optionsVal »);
//Label Personnages :
var oDataLbl = new sap.m.Label(« dataLbl », {text:« Personnages », labelFor:« oDataVal »});
//Personnages :
var oDataVal = new sap.m.ComboBox(« dataVal »);
//Ajout des options dans le Select :
//oOptionsVal.bindAggregation(« items », {path: »ModelOptions>/options », template: new sap.ui.core.ListItem(« options », {text: « {ModelOptions>text} »,  key: « {ModelOptions>id} » })});
oOptionsVal.bindItems({path:« ModelOptions>/options », template:new sap.ui.core.ListItem(« options », {text: « {ModelOptions>text} »,  key: « {ModelOptions>id} » })});
oOptionsVal.bindValue(« ModelOptions>/selection »);
oOptionsVal.attachSelectionChange(this.sortFilter);
//Ajout des personnages dans le Select :
//oDataVal.bindAggregation(« items », {path: »ModelData>/data », template: new sap.ui.core.ListItem(« data », {text: « {ModelData>text} »,  key: « {ModelData>id} » })});
oDataVal.bindItems({path:« ModelData>/data », template:new sap.ui.core.ListItem(« data », {text: « {ModelData>text} »,  key: « {ModelData>id} » })});
//Longueur totale du layout :
oLayout.setWidth(« 100% »);
//Longueur de chaque colonne du layout :
oLayout.setWidths(« 30% »,« 70% »);
//Creation de la ligne dans le layout :
oLayout.createRow(oOptionsLbl,oOptionsVal);
//Ajout des personnes dans le select :
oLayout.createRow(oDataLbl,oDataVal);
//Ajout du layout au panel :
oPanel.addContent(oLayout);
//Ajout du panel au layout :
oPanel.placeAt(« content »);
}


A la fin vous devriez avoir le résultat suivant :
Capture d’écran 2015-04-03 à 00.07.39

Capture d’écran 2015-04-03 à 00.17.53

Capture d’écran 2015-04-03 à 00.17.17