Instructor Notes: • Use this schedule as a ballpark. Depending on the level of skill in the class, some lessons may go more quickly or run into the next day. Qualify the skill level of the class as a whole and then determine how to best cover all the content in 3 days.
Instructor Notes: • How to Achieve Design Innovation: • The whole idea of Design innovation started 10 years ago when Hasso Plattner was at Sapphire and read an article about Design thinking. It was then he decided that was the approach SAP needed to take. • What exactly does design innovation mean? o First it means understanding the business needs (primarily viability) o The next part is understanding technology or feasibility o Finally you need to understand the human values. This is probably the most important part of design innovation. Understanding what usability and desirability mean to your business users. • Only when these three components are combined together will you be able t truly achieve design innovation.
Instructor Notes: • What is the current situation? • The world is changing and consumer experience is the new standard for enterprise applications • Think for a minute about the websites you access daily, like google, amazon or social media sites • All of these sites have created a new standard for speed and simplicity where consumers today now demand the same ease of use with business applications. • Take for example, purchasing something personal online like a television. That same user would expect if they needed to order something from work, say a new cell phone that the process would be the same in terms or ease and simplicity. This idea has set the bar for expectations when using business applications. Consumerization is the growing tendency for new information technology to emerge first in the consumer market and then spread into business and government organizations. This is evidenced today more so then ever before. People are used to the application user experience they interact with their daily applications such as google and social media apps. This experience has been embraced and accepted by people to the point where it is now the new standard. People want to have the same easy, feature rich experience they have with their personal sites in the business place. SAP has recognized this change in society and made it our goal to meet this new standard.
Instructor Notes: • Once SAP understood Design Innovation we developed a vision to provide leading user experience for business applications. • We did our homework on how to see our vision through and later developed our current mission which is to deliver attractive applications that make people successful at work.
Instructor Notes: • SAP developed a user experience strategy consisting of 3 main components: New, Renew and Enable. • During our research phase we realized that most users still use the SAP GUI to access applications. • The GUI contains approximately 300,000 screens and consist of a vast number of functionalities. • We looked at all the functionality offered in our GUI and developed a list of the most frequently used applications, namely manager and employee functions such as leave request or travel expenses. We decided it was time to renew these top scenarios to make good on our mission. • It was from this idea that SAP Fiori and SAPUI5 were born. • SAP also decided to renovate business suite programs and enable customers to improve their user experience on their own. • For example, SAP developed SAP Screen Personas which allows customers to optimize and simplify any screen in the GUI. While developing SAP Fiori we also decided to renovate our business suite programs and provide enablement tools to enable customers to improve their user experience on their own – take for example, SAP screen personas that allows customers to optimize and simplify any screen in the GUI • While SAP was working on renewing existing solutions and enabling customers SAP also continues to develop new applications. All the while, SAP is continuing to create new innovative applications to fulfill customer demands and needs. • However, SAP also has made the tools such as SAPUI5 available for customers and partners to innovate as well.
Instructor Notes: This slide details the components that encompass the SAP User Experience Strategy: • New, Renew and Enable which we have already introduced • UX design services which is an element that came from customers who wanted to help transfer our strategy into their own reality using SAP UX tools.
Instructor Notes: • Here you can see some of the new consumer apps developed by SAP. 1. 2. 3. 4. • •
Recalls Plus PhotoTribe Fan Experience MyRunway When SAP started building consumer apps a couple years ago, SAP wanted to better understand how people and consumers work with software. SAP then took that knowledge to understand how it related to enterprise software. • Focus on the Fan Experience App as an example – the business problem consisted of stadiums needing to develop a way to know what type of consumers came to the stadium. In past people purchased game tickets and then gave them to other people making consumer profiling very difficult. To rectify this issue, SAP mobilized ticket purchases and made it so fans can use their mobile phone for access to games. The customer also realized that retail sales of sporting merchandise wasn’t good because fans never wanted to leave the game to shop. So SAP built a mobile store that allowed fans to access retail merchandise while sitting in their seats watching the game.
Instructor Notes: • In Q1 2013 SAP released 2 new applications that were in alignment with the new consumer user experience standard. • •
The first, SAP Fraud Management is powered by the SAP HANA Platform and is an application for detecting, investigating and deterring fraud. On the right you can see the SAP customer engagement intelligence application that provides sales, service and marketing teams with the deep customer insight they need to deliver engaging, personalized experiences.
Instructor Notes: • SAP Fiori is the way SAP renewed the most widely used top scenarios. • SAP Fiori uses HTML5 and SAPUI5 technology and it can run on all devices. SAPUI5 is also the focus of this course. For an understanding of HTML5, lead students to the SAPX04 course, which is a pre-requisite for this course (SAPX05). • Depending on the device SAP Fiori adapts visualization to the device specifically and uses responsive design. • If you look at the tablet in this image you’ll see the detail list on the left side and the main pane. Now look to the mobile phone and notice only the main pane is visible. The detail list can be accessed by swiping the phone but both panes will not fit at once. Responsive design is credited for automatically completing the look on our UI framework. • An important thing to note with SAP Fiori is it can be deployed in the customers existing landscape. SAP customers running ECC 6.0 or Suite on Hana will need gateway to the backend system and add-ons making it an easy to deploy and use solution.
Instructor Notes: • Design principals 1. Role-based – we decomposed the vast amount of SAP transactions into a task based experience, only showing the relevant information for the task users are working on 2. Responsive design – runs on all sizes of devices (phone, tablet, desktop), versions (browser/phone versions), styles (touch, keyboard) and channels (iOS, Android, Windows, Mac etc.) 3. Simple –Focused on user experience outcomes over features and functionalities by sticking to the 1-1-3 rule – 1 user, 1 use case, 3 screens 4. Ensure coherence – meaning all apps speak the same language – people expect the same task to be done in the same way (for example all approval apps (approve vacation, expenses etc.) are designed in the same way. 5. Instant value - Achieve low barrier to adoption.
Instructor Notes: • SAP provides various enablement tools to allow and enable customers to improve the User Experience of their existing screens. SAP Screen Personas, for example, works for all SAP GUI screens. • Let’s take a look at some examples: • Screen 1: classical SAP start easy access menu – this is what it could look like. • Screen 2: SAP tx create plant maintenance notification – with screen personas, we brought only the relevant fields on one simple screen – easy to enter, less clicks. • Screen 3: sales orders – could have a nice screen that only shows relevant information. • Therefore, Screen Personas is a great tool that allows you to achieve fast value. Prerequisite: transactions need to run in the web version of the GUI.
Instructor Notes: • This slide details some of SAPs Key Enablement Tools • We just reviewed SAP Screen Personas • Floorplan Manager which is based on ABAP web dynpro and allows customers to build new screens and adapt floorplan manager screens • SAP UI5 application development tools are available so customers can build, or adapt fiori apps on their own or build their own ui5 applications • NW business client, side panel and we offer a theme designer which is a tool that allows to adapt the branding of customer specific branding (colors,fonts, logos, change stylesheets etc.)
Instructor Notes: • Overview of key UI technologies SAPUI5 and UI5 application development tools to change, adapt or develop new applications. Web dynpro ABAP and Floorplan manager – tool that can be used for adoption or creating new apps. SAP dynpro – which includes SAP Screen Personas to optimize SAP GUI screens. Also notice the connections to the backend – dynpro screens have a close relationship to the backend, they are very interwoven. Screen Personas, for example, is only a layer on the dynpro where you can reduce fields, merge tops, combine fields but you cannot add business functionality – this only works on the UI level. SAPUI5 with gateway there is a clear separation between UI and business logic. This setup enables you to be much more flexible in the future. Gateway does not need to run on the same machine as the backend. You can see theme designer running up the right side of the screen that allows for the branding of UIs. Basic fundamental architectural change is that we decoupled UI and business logic and are very flexible in reacting to change in UI technology, it was more difficult in the past. This keeps evolving and I’m sure in the coming years this ill continue to improve into new UI technologies.
Instructor Notes: • Why is focusing on the User experience important? • Because having a great User experience has an impact on business value • Many people believe User Experience is simply colors, and fonts however we’ve learned throughout this presentaton that that is simply not true. If a great User Experience is achieved people gain productivity and can work faster and more efficiently. increase adoption, decrease errors and save training costs. All very positive outcomes that immediately impact the overall business value.
Instructor Notes: • SAP had several escalations at customers about the user experience of our products. • So, we went out and observed how people worked with our products. We took designers, researchers, User experience professionals and observed how they worked. We saw some of the issues could be resolved with existing SAP tools but IT departments weren’t aware of it. • We also saw that IT needs to better understand their end users. We realized end users perceive custom built screens as SAP screens, which was very interesting to us. The result was recognizing that they lacked design skills. SAP SAPUI5 and other tools helps to enforce a design standard that will help customers better reach design goals.
• Main UI5 Offerings: Client side: Control libraries (JavaScript, CSS and image files) Core (JavaScript Files) Test suite (HTML, JavaScript files) Server side (optional): Application development tools in Eclipse Control development tools in Eclipse Resource handler in Java and ABAP Theming generator
Instructor Notes: • The system is a 1:N WTS, so the naming and uniqueness is important. Make sure that each student is in their own workshop uniquely named by their login. • FireFox is installed but the Firebug plugin will need to be installed and enabled. This activity is in the next slides as the first exercise to be performed by students. • The Eclipse version is Version: 4.3.1, Build id: M20130911-1000 (Kepler). All labs have been tested in both Eclipse and FireFox. If students prefer, they can use Google Chrome to test their applications, but the setup exercise will go through the set up of FireFox and FireBug.
• First, make sure you have at SAP NetWeaver Developer Studio 7.3 or higher installed. The UI5 tools will not work with older NWDS versions. • The toolset can be downloaded from the SAP Service Marketplace (SMP). • Go to https://service.sap.com -> SAP Support Portal -> SAP Software Download Center -> Support Packages and Patches -> A - Z index -> N -> UI ADD-ON FOR SAP NETWEAVER -> UI ADD-ON 1.0 FOR NW 7.03 -> Support Package Stack Download. The file that you need is at the bottom of the list: SAPUI5 TOOLS IDE PLUGIN 1.00. Make sure you pick the latest version (currently this is SPS 02).
• In NWDS, go to Help - Install New Software... • Add a new Local Update Site (named "UI5 Tools") and point it to the folder where you have extracted the files before.
• Needs to be added, because the Shell is not part of the sap.ui.commons library but of sap.ui.ux3 • Additional libraries are added to the attribute data-sap-ui-libs.
1. Create a new SAPUI5 Applicationi Project with the name SAPUI5-Exc01-HelloWorld 2. Open the index.html and add the following lines between the script-Tag
var lbl = sap.ui.commons.Label("lbl"); lbl.setText("Hello World!"); lbl.placeAt("content"); 3. Save and run the application using the Web App preview - Select the index.html and choose from the context menu Run As -> Web App Preview
• Notation and types of configuration attributes: • The type String just a string, but escaped according to the HTML conventions • Boolean true and x are both accepted as true value (case insensitive), all others are false. Nevertheless false is preferred for false values • Int any integer value • Array of string comma separated list of values, comma is not supported in the values (no escaping) • Map from String to String a JavaScript object literal (preferably JSON syntax) • The function sap.ui.getCore().getConfiguration().getFormatSettings() returns an object of type sap.ui.core.FormatSettings. This object provides access to the formatting setting of data formatting and parsing.
• You can find further information on the configuration options at: https://sapui5.netweaver.ondemand.com/sdk/#docs/guide/Configuration.html#ListofConfi gurationOptions
}); oTransNode1.addNode(oTransNode2); oTransNode2.addNode(oTransNode3); oTransNode2.addNode(oTransNode4); // add Tree Node root to the Tree oTransTree.addNode(oTransNode1); oTransTree.attachSelect(this.handle);
• The columns property can be used to add column objects to the table ui element. The column-ui control uses the template property to specify which specific UI-element should be rendered inside each cell. var oTable = new sap.ui.table.Table({ columns: [ new sap.ui.table.Column({ label: new sap.ui.commons.Label({ text: "First Name" }), template: new sap.ui.commons.TextView({ text: "{firstName}" }), width: "150px" }), new sap.ui.table.Column({ label: new sap.ui.commons.Label({ text: "Last Name" }), template: new sap.ui.commons.TextView({ text: "{lastName}" }), width: "150px" })}) ] });
• The Shell-UI-element is part of the sap.ui.ux3 library. You have to add this library to the data-sap-ui-libs attribute in the index.html. The Shell-element provides a application frame with navigation functionalities. var mContent = {}; // map holding the Shell content mContent.musicstore = new sap.ui.view({ viewName : "sapui5-ex12-solution.musicstore", type : sap.ui.core.mvc.ViewType.JS }); mContent.tf = new sap.ui.commons.TextField(); oShell.setContent(mContent.musicstore); oShell.attachWorksetItemSelected( function(evt) { var key = evt.getParameter("key"); oShell.setContent(mContent[key]); });
• To place multiple UI-areas to the UI you have to define div-areas with unique identifiers. index.html: To attach a UI-control to a specific UI-area you have to invoke the placeAt-function on the UIcontrol and pass the name of the UI-area to the method xxx.view.js: oTextView.placeAt("content1"); oTextView2.placeAt("content2");
1) Create a new SAPUI5 project called WDE350-Ex02 and create an initial view called PersonData 2) Open the file PersonData.view.js and implement the createContent-method 1) Create a new Panel and set its text-property to “Enter Data” 2) Create a MatrixLayout with the following content 1) Two labels for “First Name” and “Last Name” 2) Two TextFields for entering the first name and the last name of a person 3) Create a submit-Button 3) Add the created UI-controls to the layout with the createRow()-method 4) Add the layout-object to the panel object with the addContent()-method 5) Add a event handler for the press-event. attachPress(function() { … } 6) Implement the press-event, show the inserted values of the two textfiels (first name and last name) inside a message box (alert). Hint: getValue-method of the referenced TextFields. 7) Place your content to the content-div-element of index.html 3) Test your application
• PersonData.view.js: createContent : function(oController) { var oPanel = new sap.ui.commons.Panel({ text : "Enter Data"}); var oLabel1 = new sap.ui.commons.Label({text : "First Name:"}); var oTextField1 = new sap.ui.commons.TextField(); var oLabel2 = new sap.ui.commons.Label({text : "Last Name:"}); var oTextField2 = new sap.ui.commons.TextField(); var oButton = new sap.ui.commons.Button({text : "Submit"}); var oLayout = new sap.ui.commons.layout.VerticalLayout("Layout1", { content : [ oLabel1, oTextField1, oLabel2, oTextField2, oButton ]}); oPanel.addContent(oLayout).placeAt("content");
1) Open your solution of the previous exercise WDE350-Ex02 2) Open the PersonData.view.js 3) Enhance the existing implementation with an application header and a menu 1) Create two new UI-areas in the index.html above your content-area. Called header and menu. 2) Create a new object of ApplicationHeader and set the the properties displayWelcome and displayLogoff to false (use the setter-Methods) 3) Add the applicationHeader-object to the appropriate UI-area 4) Create a new menubar with two menu items and place them to the appropriate area.
• Implement the following lines of code inside the createContent-method: //create content for UI Area 'header' var oAppHeader = new sap.ui.commons.ApplicationHeader("appHeader"); oAppHeader.setLogoText("SAPUI5 Overview Exercises"); oAppHeader.setDisplayWelcome(false); oAppHeader.setDisplayLogoff(false); oAppHeader.placeAt("header"); //create content for UI Area 'menu' var oMenubar = new sap.ui.commons.MenuBar; var oMenubarItem1 = new sap.ui.commons.MenuItem("menuitem-1", {text:"Menu-Item 1"}); oMenubar.addItem(oMenubarItem1); var oMenubarItem2 = new sap.ui.commons.MenuItem("menuitem-2“ ,{text:"Menu-Item 2"}); oMenubar.addItem(oMenubarItem2); oMenubar.placeAt("menu");
1) Open your solution of exercise 3 Note: Please notice that the solution is implemented in a Project called wde350-ex04solution. Please make sure that your naming is based on your project settings. 2) Add the unique names Field1 and Field2 to your TextFields 3) Change the implementation of the submit event handler a) Show the values of the text fields using the getValue method of coreobject b) Show also the type of the root element using the domById-method
//the content for UI Area 'content' var oPanel = new sap.ui.commons.Panel("panel",{text:"Enter Data"}); var oLabel1 = new sap.ui.commons.Label({text: "First Name:"}); var oTextField1 = new sap.ui.commons.TextField("Field1"); var oLabel2 = new sap.ui.commons.Label({text: "Last Name:"}); var oTextField2 = new sap.ui.commons.TextField("Field2"); var oButton = new sap.ui.commons.Button({text: "Submit"}); var oLayout = new sap.ui.commons.layout.VerticalLayout("Layout1", { content: [oLabel1, oTextField1,oLabel2, oTextField2, oButton] }); oPanel.addContent(oLayout).placeAt("content"); // add handler to alert textfield values oButton.attachPress(function() { var msg = "First Name: " + sap.ui.getCore().byId("Field1").getValue() + "\n" + "Last Name: " + sap.ui.getCore().byId("Field2").getValue() + "\n" + "HTML element type: " + jQuery.sap.domById("panel"); alert(msg); });
1) Open your solution of exercise 4 2) Create a new view for the view types JavaScript, XML and JSON. a) You can use the wizard for the view creation b) Select your code folder and choose from the context menu New -> other -> SAPUI5 Application Development -> View c) Enter the name of your view (e.g. json) and choose the appropriate Development Paradigm. Implement each of the views. The implementation should consists of one Submit-Button and an event-handler assigned to the submit event of the button. The submit-event should show an alert-message.
• Exercise 05 – Detailed Steps: 1) Open the PersonData.view.js file of your project. Note: Please notice that the solution is implemented in a Project called wde350-ex05-solution. Please make sure that your naming is based on your project settings. 2) Create a new Panel: var oPanel2 = new sap.ui.commons.Panel("Views",{text:"View Options"}); sap.ui.localResources("wde350-ex05-solution"); 3) Instantiate each view type: var jsview = sap.ui.view({id:"js1", viewName:"wde350-ex05-solution.jsview", type:sap.ui.core.mvc.ViewType.JS}); var xmlview = sap.ui.xmlview({id:"js2", viewName:"wde350-ex05-solution.xmlview", type:sap.ui.core.mvc.ViewType.XML}); var jsonview = sap.ui.jsonview({id:"js3", viewName:"wde350-ex05-solution.jsonview", type:sap.ui.core.mvc.ViewType.JSON}); 4) Add the view instances to a layout of type HorizontalLayout: var oLayout2 = new sap.ui.commons.layout.HorizontalLayout("Layout2", { content: [jsview,xmlview,jsonview] }); 5) Add the layout to the panel: oPanel2.addContent(oLayout2).placeAt('content');
• JSONModel: The JSONModel can be used to bind controls to JavaScript object data (usually serialized in the JSON format). It is a clientside model, so it is meant for small datasets, which are completely available on the client, it does not contain any mechanisum for server based paging or loading of deltas. It does support TwoWayBinding. • XMLModel: The XMLModel allows to bind controls to XML data. It is a client-side model, so it is meant for small datasets, which are completely available on the client, it does not contain any mechanism for server based paging or loading of deltas. It does support TwoWay-Binding. • ODataModel: The ODataModel enables binding of controls to data from Odata services. The ODataModel is a server-side model, so the whole dataset is only available on the server, the client only nows the currently visible rows and fields. This also means sorting and filtering on the client is not possible, the client has to send a request to the server to accomplish these tasks. The default binding mode of the ODataModel is OneWay, but there is experimental write-support implemented, so TwoWay binding can be enabeld. Note: Please be aware of the Same-Origin-Policy security concept which prevents access to backends on different domains/sites.
• Solution Details: 1) Open the controller PersonData.controller.js and implement the model creation inside the onInit-function var data = {firstName: "John", lastName: "Doe",}; var oModel = new sap.ui.model.json.JSONModel(); oModel.setData(data); sap.ui.getCore().setModel(oModel); 2) Open your PersonData.view.js and add the following lines to your implementation. If you are using the last exercise as template, it is not necessary to add the Panel, the Label and the Textfield-objects, but you have to do the binding for the TextFields and the TextView. var oPanel = new sap.ui.commons.Panel("panel",{text:"Enter Data"}); var oLabel1 = new sap.ui.commons.Label({text: "First Name:"}); var oTextField1 = new sap.ui.commons.TextField("Field1",{value: "{/firstName}"});
var oTextView1 = new sap.ui.commons.TextView("textView1", {text: "{/firstName}"}); var oLabel2 = new sap.ui.commons.Label( {text: "Last Name:"}); var oTextField2 = new sap.ui.commons.TextField("Field2", {value: "{/lastName}"}); var oTextView2 = new sap.ui.commons.TextView("textView2", {text: "{/lastName}"}); var oButton = new sap.ui.commons.Button("btn", { text: "Submit", press:oController.update }); var oLayout = new sap.ui.commons.layout.MatrixLayout(); oLayout.createRow(oLabel1,0).createRow( oTextField1, oTextView1); oLayout.createRow(oLabel2,0).createRow( oTextField2, oTextView2); oLayout.createRow(oButton,0); oPanel.addContent(oLayout).placeAt("content"); 3) Open the file PersonData.controller.js and implement the update function: update : function() { var firstName = sap.ui.getCore().getModel().getProperty( "/firstName"); var lastName = sap.ui.getCore().getModel().getProperty( "/lastName"); alert("Hello " + firstName + " " + lastName); }
• Extend the TextView with a formatter: var oTextView2 = new sap.ui.commons.TextView("textView2", text: { path: "/lastName", formatter: oController.upperCase }});
{
Implement the upperCase-function inside the controller: function upperCase(sVal) { if (!sVal) return; return sVal.toUpperCase(); };
sap.ui.model.type.integer minIntegerDigits: 1, // minimal number of non-fraction digits maxIntegerDigits: 99, // maximal number of non-fraction digits minFractionDigits: 0, // minimal number of fraction digits maxFractionDigits: 0, // maximal number of fraction digits groupingEnabled: false, // enable grouping (show the grouping separators) groupingSeparator: ",", // the used grouping separator decimalSeparator: "." // the used decimal separator sap.ui.model.type.float minIntegerDigits: 1, // minimal number of non-fraction digits maxIntegerDigits: 99, // maximal number of non-fraction digits minFractionDigits: 0, // minimal number of fraction digits maxFractionDigits: 99, // maximal number of fraction digits groupingEnabled: true, // enable grouping (show the grouping separators) groupingSeparator: ",", // the used grouping separator decimalSeparator: "." // the used decimal separator
sap.ui.model.type.string The String type supports the following validation constraints: maxLength (expects an integer number) minLength (expects an integer number) startsWith (expects a string) startsWithIgnoreCase (expects a string) endsWith (expects a string) endsWithIgnoreCase (expects a string) contains (expects a string) equals (expects a string) search (expects a regular expression) sap.ui.model.type.boolean sap.ui.model.type.date sap.ui.model.type.time sap.ui.model.type.datetime
• Details: var oLabel3 = new sap.ui.commons.Label({text: "First Names, between A and M:"}); var oTextField1 = new sap.ui.commons.TextField({id : 'Field3',value : ''}); var oItemTemplate = new sap.ui.core.ListItem("name", {text:"{text}",key:"{key}"}); var oComboBox = new sap.ui.commons.ComboBox("ComboBox",{ items:{path:"/data",template:oItemTemplate,sorter: oSorter}, change: function(oEvent){ sap.ui.getCore().byId("Field1"). setValue(oEvent.oSource.getSelectedKey());} }); var oComboBox2 = new sap.ui.commons.ComboBox("ComboBox2",{ items:{path:"/data",template:oItemTemplate,filters: [oFilter]}, change: function(oEvent){ sap.ui.getCore().byId("Field1"). setValue(oEvent.oSource.getSelectedKey());} }); oComboBox.setModel(model); oComboBox.bindValue("/selection"); oComboBox2.setModel(model); oComboBox2.bindValue("/selection");
var oModel3 = new sap.ui.model.json.JSONModel(tableData); var oTable = new sap.ui.table.Table({ columns: [ new sap.ui.table.Column({ label: new sap.ui.commons.Label({ text: "First Name" }), template: new sap.ui.commons.TextView({ text: "{firstName}" }), width: "150px" }), new sap.ui.table.Column({ label: new sap.ui.commons.Label({ text: "Last Name" }), template: new sap.ui.commons.TextView({ text: "{lastName}" }), width: "150px" }), new sap.ui.table.Column({ label: new sap.ui.commons.Label({ text: "Description" }), template: new sap.ui.commons.TextView({ text: { parts: [ {path: "gender"}, {path: "firstName"}, {path: "lastName"}, {path: "occupation"}], formatter: function(gender,firstName,lastName,occupation){ if (gender && firstName && lastName && occupation) { if (gender == "male") { return "Mister " + firstName + " " + lastName + " works as " + occupation; } else { return "Miss " + firstName + " " + lastName + " works as " + occupation; } } return null; } }}) }) ] }); • Assign the model to the tables model and bind the rows to the aggregation teamMember: oTable.setModel(oModel3); oTable.bindRows("/teamMembers"); Place the table-UI-element at the panel. oPanel4.addContent(oTable).placeAt("content");
Copy the project WDE350-Ex12-Template to WDE350-Ex12 In createContent of the Shell View, add one more workset item (text: „Music Store“, key: „musicstore“) to the Shell Instantiate the new View and assign it to mContent.musicstore In createContent of the musicstore View, create the following controls: • One sap.ui.commons.SearchField, calling the Controller‘s „doSearch“ method with the Controller being the „this“ context: search:[oController.onSearch, oController] • One sap.ui.table.Table (new control library “sap.ui.table” to be added to bootstrap!); use an extended binding object to bind and sort the Table rows: • One sap.ui.commons.layout.VerticalLayout with width set to “100%”
Add three columns to the Table, binding them to certain attributes (artworkUrl30,trackName,artistName) – including an Image column (artworkUrl30) In the controller, implement the „onInit“ method, create an empty JSONModel, assign it to „this.model“ and set it on the View: this.model = new sap.ui.model.json.JSONModel(); this.getView().setModel(this.model); In onSearch, read the event parameter „query“, put it into an iTunes search URL and set the data on the JSONModel: var searchTerm = oEvent.getParameter("query"); var url = "http://itunes.apple.com/search?term=" + searchTerm +
"&country=FR&media=music&entity=song&callback=?"; this.model.setData(data); 11. Open the Shell.view.js and implement the commented steps
Open the SAPUI5 Developer Studio, and create a new JSView in the „training“ project, name it „musicstore“ In createContent of the Shell View, add one more workset item (text: „Music Store“, key: „musicstore“) to the Shell Instantiate the new View and assign it to mContent.musicstore In createContent of the musicstore View, create the following controls: • One sap.ui.commons.SearchField, calling the Controller‘s „doSearch“ method with the Controller being the „this“ context: search:[oController.onSearch, oController] • One sap.ui.table.Table (new control library “sap.ui.table” to be added to bootstrap!); use an extended binding object to bind and sort the Table rows: new sap.ui.table.Table({ rows:{ path:"/results", sorter: new sap.ui.model.Sorter("artistName") } rowSelectionChange:[oController.onSelectionChange, oController] }) •One sap.ui.commons.layout.VerticalLayout with width set to “100%”
5.
Add SearchField and Table to the layout and return it
6.
Implement both controller methods (empty for now): onSearch and onSelectionChange
7. 8.
Test the UI and verify the Music Store comes up (empty table) Add three columns to the Table, binding them to certain attributes – including an Image column: oTable.addColumn(new sap.ui.table.Column({ label: new sap.ui.commons.Label({text:"Cover"}), template: new sap.ui.commons.Image({src:"{artworkUrl30}"}) })); oTable.addColumn(new sap.ui.table.Column({ label: new sap.ui.commons.Label({text:"Title"}), template: new sap.ui.commons.TextView({text:"{trackName}"}) }));
oTable.addColumn(new sap.ui.table.Column({ label: new sap.ui.commons.Label({text:"Artist Name"}), template: new sap.ui.commons.TextView({text:"{artistName}"})})); 9.
In the controller, implement the „onInit“ method, create an empty JSONModel, assign it to „this.model“ and set it on the View:
this.model = new sap.ui.model.json.JSONModel(); this.getView().setModel(this.model); 10. In onSearch, read the event parameter „query“, put it into an iTunes search URL and set the data on the JSONModel: var searchTerm = oEvent.getParameter("query"); var url = "http://itunes.apple.com/search?term=" + searchTerm +"&country=FR&media=music&entity=song&callback=?"; this.model.setData(data); 11. Open the file Shell.view.js and implement the commented steps as follows: 1) mContent.musicstore = new sap.ui.view({ viewName : "sapui5-ex12-solution.musicstore", type : sap.ui.core.mvc.ViewType.JS }); 2) oShell.setContent(mContent.musicstore); 3) oShell.attachWorksetItemSelected(function(evt) { var key = evt.getParameter("key"); oShell.setContent(mContent[key]); });
• http://services.odata.org/OData/OData.svc/Categories(1)/Products/?$top=2 • http://services.odata.org/OData/OData.svc/Categories(1)/Products/?$top=2&$format=JS ON
• You can find further information about resources are handled in JavaServer Faces at: • http://javaserverfaces-spec-public.java.net/nonav/snapshots/jsf-spec-2.020090304/javadocs/javax/faces/application/ResourceHandler.html
• Note: with the current data binding implementation, you can't pass parameters to your texts within the resource bundle. If you have to pass parameters you must do this on your own. As a convenience, you can access the resource bundle directly from the model instead of loading it: var myBundle = oModel.getResourceBundle(); • After the instance has been created, you have a model containing the resource bundle texts as data.
var oBundle = jQuery.sap.resources({ url : "i18n/i18n.properties", locale : sap.ui.getCore().getConfiguration().getLanguage() }); var oPanel = new sap.ui.commons.Panel({text : oBundle.getText("enterdata")}); var oLabel1 = new sap.ui.commons.Label({text : oBundle.getText("firstname")}); var oTextField1 = new sap.ui.commons.TextField(); var oLabel2 = new sap.ui.commons.Label({text : oBundle.getText("lastname")}); var oTextField2 = new sap.ui.commons.TextField(); var oButton = new sap.ui.commons.Button({ text : oBundle.getText("submit")});
Copy your solution of Exercise 2 to SAPUI5-Ex15 Within the controller of the PersonData implement/uncomment the onInit method Create a new sap.ui.model.resource.ResourceModel with bundleUrl: "i18n/i18n.properties" (the current language is automatically used) Set this ResourceModel as model on the View or (globally) on the Core, but set it as named model (name: “i18n”) •….setModel(oModel, "i18n"); Now use data binding to bind the translated texts
PersonData.controller.js onInit: function() { var oModel = new sap.ui.model.resource.ResourceModel({ bundleUrl: "i18n/i18n.properties", bundleLocale: sap.ui.getCore().getConfiguration().getLanguage() }); sap.ui.getCore().setModel(oModel, "i18n"); }, PersonData.view.js var oPanel = new sap.ui.commons.Panel({text : "{i18n>enterdata}"}); var oLabel1 = new sap.ui.commons.Label({ text : "{i18n>firstname}"}); var oTextField1 = new sap.ui.commons.TextField(); var oLabel2 = new sap.ui.commons.Label({text : "{i18n>lastname}"}); var oTextField2 = new sap.ui.commons.TextField(); var oButton = new sap.ui.commons.Button({text : "{i18n>submit}"});
• For detailed information you can find more complex samples in the demos of this course: • The project WDE350-Smpl-NotepadCtrls-GoogleMap implements a renderer within the controller. • The project WDE350-Smpl-NotepadCtrls-GoogleMapRenderer contains an implementation of a separate renderer class. • Note - See also more complex samples WDE350-Smpl-NotepadCtrls-
GoogleMap and WDE350-Smpl-NotepadCtrls-GoogleMapRenderer
• Normal Methods: Any method, either public or private, is just appended to the implementation object. The convention is that private methods that may not be called from outside a Control start with an underscore. All other methods are considered public except the following: init, render and the event handler methods • Event handler methods: Methods that have a name starting with "on" are reserved for event handlers. For common events such as "click" or "keydown", browser event handlers for these methods are registered automatically by the SAPUI5 core. So it is sufficient to simple add a handler method, and it will automatically be called. Additionally, the SAPUI5 core fires events with a richer semantic meaning, so control developers do not need to check so many keycodes etc. The name of these events starts with "sap", they are defined in jquery.sap.events.js. One example for such an event is sapnext which is triggered by "arrow down" or "arrow right" (or "arrow left" in right-to-left mode). Therefore, multiple checks would be required to check whether the user wants to navigate to the next item. The sapnext event takes over all these checks. The "evt" object given to the handler method contains more information. These methods are considered to be private and may only be called by the UI5 core.
• The Renderer Method/Object: This method is responsible for creating the HTML structure that makes up the Control. It is different from the other methods, as it is a static one, so the "this" keyword is not available. Instead, a Control instance and a RenderManager instance are given to the method. The RenderManager is used as a sort of "writer" - it is a collector for string fragments and takes care of efficiently concatenating them and placing them into the appropriate DOM position. renderer: function(oRenderManager, oControl) { oRenderManager.write("
", oControl.getText(), "
"); } • All the features and rules of writing the Control Renderer in normal Control development apply here as well. E.g. the Control must have only ONE HTML element as root node and inside this node oRenderManager.writeControlData(oControl); must be called, so this root element can be marked as UI5 control root and the ID of the Control will be written.
• The RenderManager is responsible for injecting the generated markup into the DOM. • For control rendering purposes, the following three classes are relevant: • The Control class - the control that is to be rendered • The RenderManager class - responsible for injecting the generated markup into the DOM and offering helper functionality • The Renderer class - the base class of all control renderers
Copy or extend your exercise 12 and navigate to „musicstore.controller.js“ Implement a new „AudioPlayer“ control before before your controller implementation Add a new column to the table and instantiate the new „Audioplayer“ control as row content Open the index.html in browser that can interpret the