Monthly Archives: July 2015

UI5 Version Info

Screen Shot 2015-07-31 at 13.04.2230 Days of UI5 - Day 28 by DJ Adams

Yesterday Peter Müßig from the UI5 team at SAP in Walldorf announced the multi-version capability for SAPUI5.

He also documented the details in a post on the SAP Community Network here: “Multi-Version availability of SAPUI5“. Shortly after, the announcement was also made that this would also be available for OpenUI5.

This is great news, and something that we’ve been waiting for now for a while. It makes perfect sense, and the ability to select a particular runtime version via a part of the bootstrap URL’s path info is very nice. It’s something I do locally on my workstation anyway, and I also have a ‘latest’ symbolic link that I ensure points to the latest copy of the runtime or SDK that I have locally.

Along with the announcement came a link to a simple SAPUI5 Version Overview page, built in UI5. It looks like this:

Screen Shot 2015-07-31 at 13.11.42And if you look under the covers, you’ll see a single-file app, with a lot of custom CSS, some JavaScript view stuff going on, and the retrieval of a couple of JSON resources containing the version overview info and the data from the neo-app.json file that is present in the HCP platform and which describes routes to destinations, which include the SAPUI5 runtime services, now available at different paths for different versions.

You’ll also see some complex manipulation and merging of those two datasets, and the mix of UI5 controls with raw HTML header elements.

Screen Shot 2015-07-31 at 13.22.44The result is an app that looks OK on the desktop but doesn’t look that well on a smartphone, as you can see on the right.

So I spent some time on the train down from Manchester to London early this morning to see what I could do.

I wanted to address a couple of things:

  • have the smartphone as the target device, rebuilding the UI with an App control
  • improve the binding, to a single data collection

The UI part was straightforward. I used my MVC technique (see MVC – Model View Controller, Minimum Viable Code from earlier in this series) to define a new View, declaratively in XML. I used an App control with a couple of Pages, and a simple controller for the view which handled all the view lifecycle and user-generated events, as well as being the container for the formatter functions.

I also used some of my favourite JavaScript functions to bind together the disparate data into a nice cohesive single array of maps. I left the original data manipulation as it was, and then grabbed what it produced to make my array. I could then bind the List in UI to this single array, and then confer the right binding context to the second Page for a selected item from the array.

I’ve created a small Github repo ui5versioninfo with the files. It contains a local snapshot of the two source JSON files (neo-app.json and versionoverview.json), the original versionoverview.html that produces the UI we saw earlier, and a new file, called new.html, which is my quick attempt addressing those things above.

Here’s what the result looks like:

versioninfo

I’ve tried to use some UI5 design and control best practices, while defining the UI in XML. I’ve added some functional programming style data merging to take place after the original manipulation, and a small controller with the requisite functions for event handling and formatting.

I took the screencast of the “finished” attempt on the tube from London Euston to Chiswick this morning, so it really was a rush job. But I think that it’s worth thinking about how we can improve this useful resource. How would you improve it?

 

A non-techie PM’s view of UI5

branches30 Days of UI5 – Day 27 by Jon Gregory

I’m mid-flight in my first UI5/Gateway project, working with a great team of developers who have all contributed to this 30 Days of UI5 series. As a non-techie Project Manager embarking on mobile development for the first time, I thought I’d share some of my experiences and tips.

This isn’t regular SAP configuration – this is mobile development.

My experience of SAP to date has been in software modules – EPM, BW, CRM, for example. It’s easy to think of a UI5/Gateway project in the same way because they’re SAP products, but putting the name to one side, the difference between enterprise software and mobile development is huge.

This is obvious to those familiar with mobile development, but not so obvious to those new to this area. Prior to embarking on any UI5 project, get hold of case studies, project plans, artefacts, lessons learned and people that have delivered UI5 applications to get an understanding of how to set your project up for success. If you’re experience is largely in enterprise software projects, this is going to be very different :-).

Nail your branch & review strategy early on

At the beginning of the project, work with your team to develop a branch & review strategy. Agree a process for matching short-lived feature branches to tasks, for reviewing code prior to any merging, and also ensure that development branches are tidy and up to date – that is, delete any old branches, or branches that are no longer needed.

A friend told me a story of a time when he was working in a fast moving and experienced frontend/toolkit development team. He’d had a scattering of branches lying around his local repo, and a Ukranian colleague, in a thick accent, speaking German, reprimanded him gently but firmly: “What are all these branches doing clogging up your workspace and your brain? Get rid of them!”.

Allow enough time for planning – agile doesn’t excuse poor process

I found it’s easy to run in to development with a bunch of user stories and little else. Although UI5 lends itself to agile development, there still needs to be adequate time allocated to planning sprints, and also fundamental architecture design, not only for the UI itself, but for the data design and integration. Factor this in to your plans from the very beginning and don’t budge – if anything should give as a result of time, cost or scope constraints, it mustn’t be the preparation that goes in to making sprints a success.

Embrace it

Working with UI5, I’ve discovered methods of project delivery that are entirely different from the standard Waterfall/ASAP approach so often adopted in enterprise software projects. I’ve also found it hugely rewarding to see an intuitive, easy to use application come to life and, more importantly, so has our customer (case study is in progress – more on that soon).

So in summary, my advice is:

  • Forget about normal SAP – walk in with an open mind
  • Set out development processes with your team from day one
  • Plan, plan, plan
  • Enjoy it!

I’d be really interested to hear about other experiences of managing or coordinating UI5/Gateway projects, and listen to any advice you may have.

UI5 – looking back and forward

Screen Shot 2015-07-29 at 07.33.3030 Days of UI5 - Day 26 by DJ Adams

It was in the spring of 2012 when I wrote this piece about the new kid on the block, SAPUI5:

SAPUI5 – The Future direction of SAP UI Development?

The fledgling toolkit had been released at version 1.2 earlier that year, and while it had clearly been in gestation for a while inside SAP, it was still new and raw enough to make folks wonder what it was all about. More than the newness or the rawness was how it was different, how it changed the rules. And what made it even more interesting was the fact that while SAP had changed a lot of rules since the 80s, this time, it was SAP embracing common practices and growing standards outside its own development ecosphere. And that was a good thing.

So SAPUI5 was not just a toolkit, it was more than that. It was arguably the poster child for how SAP was changing, changing to embrace, adopt and build upon open standards and protocols.

Of course, that had been happening for a while, most notably, at least in my opinion, by the introduction of the Internet Communication Manager (and corresponding user-space Internet Communication Framework) to the R/3 architecture, allowing SAP systems to speak HTTP natively. And there was OData, which SAP adopted as a REST-informed protocol and format for the next generation of business integration. It had been a long time coming; the journey from service-orientation to resource-orientation starting from the mid 2000’s — with posts like this: “Forget SOAP – Build Real Web Services with the ICF” :-) — was long and arduous.

So it was met by some with trepidation, wonder, cynicism even. But the rise and rise of UI5’s success has been undeniable. Success not only in becoming the engine powering the first SAP Fiori UX revolution, but also in the move towards a more open and outward facing development approaches.

The UI5 teams of designers and developers themselves, in Walldorf and around the world, have open software and standards in their DNA. UI5 itself has been open sourced. The development standards and processes are, out of necessity, different. And we can see that first hand. Just look at the home of UI5 on the web – at https://github.com/SAP/openui5. Github!

Screen Shot 2015-07-29 at 07.18.18

The development process is there for us to see, warts and all. The smallest changes are being done, in public. Look at the one authored 11 hours ago in this screenshot. It’s a simple improvement for variable declaration in the code for the Message Popover control in the sap.m library. It doesn’t matter what it is, what matters is that it’s open. For us all to see, scrutinise, and most importantly, learn from.

UI5 powers SAP Fiori, the services of their cloud offerings (for example in the form of the Web IDE, written in UI5) and of course the S/4HANA business suite. It’s destined to become a part of the future normal. It’s a toolkit with a strong pedigree, a toolkit that is not perfect (I can’t think of any software that is) but a toolkit with passionate folks behind it. It’s gaining some adoption outside of the SAP ecosphere too, and in some cases is almost becoming part of the furniture – not the focus of energy, but the enabler of solutions. It Just Works(tm) and gets out of the way. That for me is a sign of growing maturity.

The experimental Client operation mode

Screen Shot 2015-07-28 at 12.53.4530 Days of UI5 - Day 25 by DJ Adams

A few months ago a preview release of 1.28 was made available. In the blog post that accompanied it, a number of the new features were introduced. Without much fanfare, certainly without any cool looking screenshots, the experimental “Client” operation mode was announced for the OData Model mechanism.

OData Model – Server-side

The OData Model is special, in that it is classified as a server-side model, unlike its client-side siblings such as the JSON Model or the XML Model (or the Resource Model, for that matter). This means that the data “home” is seen as the server, rather than the client (the browser). Consequently, any operations on that data, even read-only operations such as sorting and filtering, take place on the server. That means extra network calls. There are truly marvellous advantages also, which the margin [of this post] is too narrow to contain. 

There are circumstances, even when dealing with entity sets in OData services, where sorting and filtering could and should take place on the client, rather than on the server. To this end, 1.28 brought an initial experimental feature to the OData Model mechanism – the OData Operation Mode.

Operation Mode

The Operation Mode joins a small but important set of modes relating to the OData Model mechanism. By default, the Operation Mode is “Server”. But it can be set to “Client”, which causes all data to be loaded from the server and for subsequent sorting and filtering operations to be performed in the client, without further network calls. As the blog post mentions, this only really makes sense as long as there isn’t a ton of data.

Note that the Operation Mode is related to the OData Model mechanism instantiation in that it is the default for that model instance. You actually specify the mode for a binding, as shown in the code snippet in the blog post:

oTable.bindRows({
   path: "/Product_Sales_for_1997",
   parameters: {
      operationMode: sap.ui.model.odata.OperationMode.Client
   }
});

Experiment!

This experimental feature was crying out for … well, experimentation. So I threw together an MVC (model view controller, minimum viable code) based app to test it out. Here’s the result:

clientoperationmode

Here we have a test app with a List, where the items aggregation is bound to the Categories entity set in the public Northwind OData service at http://services.odata.org/V2/Northwind/Northwind.svc/.

Note that the Operation Mode is only available on the v2 version of the OData Model mechanism, so that’s what I’m using here.

Initially the binding to the List’s items aggregation is with the (default) value of “Server” for the Operation Mode. You can see the network calls that are made to ask the OData service to return the entities in a specific order (with the $orderby OData parameter) each time I hit the sort button, which is toggling between ascending and descending sorting of the category names.

But then, in the console, I grab the List, and re-bind the items aggregation, to the same path (“/Categories”) but in “Client” Operation Mode. The result is that a new call is made to fetch the entities to satisfy that (new) binding, but further sorts are done entirely on the client – there are no more network calls made.

I’d call that experiment a success, and I’m looking forward to developments in this area. Nice work, UI5 team!

An introduction to sap.ui.define

Screen Shot 2015-07-27 at 11.04.0230 Days of UI5 - Day 24 by DJ Adams

If you’ve followed this series you’ll have come across the OpenUI5 Walkthrough, a “a great multi-step walkthrough of many of the features and practices of UI5 development”.

In Step 5 of the walkthrough, on “Controllers”, we’re introduced to something that looks unfamiliar. Especially to those who have written large numbers of controllers thus far, for example. The way the XML View’s Controller is defined is … different. Step 5 doesn’t say much specifically about how this works, but Step 6, on “Modules”, does.

This is what the Controller source code looks like:

Screen Shot 2015-07-27 at 10.13.53

So what’s happening here?

Well, what’s happening is that we’re seeing the beginning of a migration to an Asynchronous Module Definition (AMD) style mechanism. And the principle vehicle for this is a new function sap.ui.define, which was introduced to the world in 1.28 (1.27 internally).

There’s already some API documentation for this experimental new way to define modules that you can read in the API reference guide for sap.ui.define itself. There you’ll see how there’s a transition planned away from synchronous, and towards asynchronous loading. You’ll see for example that the optional fourth parameter “bExport” of sap.ui.define is there to support that transition.

While there’s plenty to read there, let’s just take a quick look at what it means for those like us at the UI5 coalface. We’ll take the code in the screenshot above as an example:

Instead of calling something like this …

sap.ui.core.mvc.Controller.extend("your.name.here", {
  // your controller logic here
});

… we can use the new more generic sap.ui.define to first of all declare dependencies and then define the factory function that becomes the controller, in this case. Let’s take a look at the code and examine it line by line:

Screen Shot 2015-07-27 at 10.42.52

1-14: The call to sap.ui.define extends across all the lines here; and we can see that out of the four total possible parameters described in the API reference, only two are used: the optional list of dependencies (represented here by the array) and the factory function that has a single statement returning an extended controller.

2-3: These are the dependencies. We’re defining a Controller, so we’ll want to extend UI5’s core controller (in the same way that we often do, such as in the example earlier). For that, we have a dependency on sap.ui.core.mvc.Controller. We’re also using the Message Toast’s “show” function, so we declare a dependency on sap.m.MessageToast. Note that the dependencies are expressed as resource paths (with the .js suffix omitted of course).

4: The second parameter passed in the call to sap.ui.define is the factory, and we can see the function definition start here. Note that each dependency reference is given to this factory function, in the same order that they’re declared in the dependency list. By convention, the most significant part of the resource path name is used for the parameter name (for example “Controller” for sap.ui.more.mvc.Controller).

5: The call to “use strict” is not specifically a feature of the new module definition syntax, but it is significant in that there is growing focus on JavaScript syntax correctness and linting. For more on this, see another post in this series: “UI5 and Coding Standards“.

7-12: The rest of the source code looks fairly familiar. There’s one exception though, and it’s a result of the dependency mechanism described earlier. The function has “Controller” and “MessageToast” available to it, and so we can and should use these to refer to the sap.ui.core.mvc.Controller and sap.m.MessageToast resources throughout. This is nice, and makes for slightly neater code too.

It’s early days for the new define mechanism, and there’s clearly a journey ahead for those in the core UI5 team looking after fundamental module and dependency loading and management mechanisms. But even at this early stage, it’s worth paying attention to the direction UI5 is going in this regard, and start to experiment. I know I will be!

Taming the Resource Model Files

30 Days of UI5 – Day 23 by Nathan Adams

UI5’s support for multiple-languages, out of the box (see the post “Multi-language support out of the box – UI5’s pedigree” in this series) is impressive and easy to use. Creating a message resource bundle in your Component.js file is straightforward, especially if picking up the user’s language preferences in the browser.

What can be less straightforward though is organising these files into something manageable, for plenty of projects, your i18n file might be on the small side, but it’s pretty easy to build up a large file. An application I’m currently working on, which perhaps has only 50% of its views defined, already has just 100 definitions in the i18n file. (A quick look at the Fiori My Travel Expenses App v2 shows there are around 1000 lines, and about 500 definitions in the resource file and whilst reasonably well documented with comments – you may well be hunting for usage of a text).

#XBUT,20: Button that distributes (shares) the total amount evenly between all attendees
DISTRIBUTE_EVENLY=Distribute Amounts Evenly

#XBUT,20: add internal attendee button
ADD_INTERNAL_ATTENDEE=Add Internal Attendee

#XBUT,20: add external attendee button
ADD_EXTERNAL_ATTENDEE=Add External Attendee

#XFLD,20: FirstName – LastName in the right order, e.g. EN: Smith, John
ATTENDEE_FULLNAME_ARTIFACT={1}, {0}

#XTIT: title of Add Internal Attendees select dialog
INTERNAL_ATTENDEES_TIT=Add Internal Attendees

#XTIT: title of Add External Attendees dialog
EXTERNAL_ATTENDEES_TIT=Add External Attendees

Example of a Fiori Resource Model file from ‘My Travel Expenses’

Before we dive into the structure of the key value pairs of the file though, it’s worth thinking about if one file for all your texts makes sense. In the majority of cases, you really wouldn’t want to add further complexity by adding more files. in my experience though, there are some cases where creating additional resource files may be useful.

  • You may have texts which are more prone to change, perhaps email / telephone contact details in messages; putting these into a separate file might make sense to de-risk the process of updating them when they need to change
  • Common elements across a suite of applications
  • Master data texts, if you have a lot of these, then consider separate files for them
  • You may have texts, or elements of texts which don’t need translation, and you want to keep consistent across all languages (that email example above, you don’t want to update that in multiple language files every time)
  • Lastly just like code – if it’s too long, break it up. Large app with 100’s if not 1000’s of terms? Split it up, maybe by view, or group of views.

As we move on into the structure of these files, it might not seem to be important (you can always search for a term in your chosen IDE after all), but like all good coding practices, structure can be immensely helpful in the following regards

  • Identifying gaps in language files becomes easier – so you don’t discover in the first round of translation that you had some texts hardcoded into your XML views
  • Making changes to texts, when a change is requested becomes a lot easier
  • When sending out for translation, identifying which text is which becomes easier
  • Because the file can be more easily understood, then it becomes an easier artefact to distribute, potentially removing the need for conversion back and forth between spreadsheets

How you choose to organise the language file is a matter of preference, however in my experience there are two key things I like to highlight and organise in the language file:

  • Common terms
  • Terms organised by View or Fragment / Control / Property

I’ll define all the common terms at the beginning of my language file. My preference for all my keys, is to use a dot notation to specify them (as it lines up nicely with identification of components). So here’s an example

#Common Terms
common.thing=Foo
common.items=Items
common.add=Add

Thing is though, common terms feel like something I should have in my application; you want to make sure that when you call a thing, Foo it’s always a Foo and when it’s requested to change to Bar I can change the common term, and my job is done. In practice though, this never really works. Why? Well I might be able to define those common terms, but in the majority of cases I always need to fit them into a longer text, such as Create a Foo or Delete Foos.

OK so maybe I can define some common texts, and do some clever pre-processing with Grunt to expand placeholders in my text, or do the same when I load the resource file

#Specifc Terms (pre-process)
master.things.addThing=Add {common.thing}
master.things.deleteThings=Delete {common.thing}s

#Specific Terms (post-process)
master.things.addThing=Add Foo
master.things.deleteThings=Delete Foos

Nice? Well not really, it’s not a great practice to make longer texts out of shorter texts. Consider the need to correctly handle plurals or other modifications you might require. Let’s say we can have Foos but it’s not Bars but Baren then my nice easy change above isn’t going to work. Then other languages might not have the same syntactic structures, and I could finish up chasing my tail trying to get it right across all languages, or finishing up like those pre-recorded train announcements made up of single recorded chunks – they work, but just sound awful.

There is one valid place for common terms, and you might therefore still want to define them in your main i18n file (or even a separate one you don’t load). That’s as a glossary to help those maintaining the file. Adding common.thing=Foo to the head of the file, even if never used will help those coming along after to understand how things are referred to. It’s a good UX practice, and fundamental to building a consistent experience.

So most of my definitions though, will be very specific to a view or fragment, and therefore, I like to identify these, in this manner, with the application as an implied root. If I’m developing a Split App, which has for example the following views

  • Tasks (Master)
  • Services (Master)
  • Rounds (Detail)
  • Details (Fragment used in Rounds)

then I’ll structure my language file, very specifically to reference the view, the control(s) in the view, and where appropriate the property. Which might result in something like.

#Master views
#Tasks
master.tasks.title=Maintenance Tasks
#Services
master.services.title=Active Services
master.services.toolbar.button.add=Add Service
master.services.toolbar.button.delete=Delete Services
#Detail Views
#Rounds
detail.rounds.title=Round Definition
detail.rounds.tabBar.tab.details=Details
detail.rounds.tabBar.tab.vehicles=Vehicles
#Rounds / Vehicles fragment
detail.rounds.fragment.vehicles.column.title.service=Service
detail.rounds.fragment.vehicles.column.title.capacity=Capacity

Admittedly this is quite a verbose approach, and it requires a little discipline to use, but the advantages are plain to see – I immediately get a sense of where a text might appear in the user interface, I also can get a sense of if anything is missing (for example I’d expect every view to have a {view}.title attribute.

By taking a structured approach to the language file, it also makes it easier to set up controls with bindings to the language file, as there is no need to try and think of a name. It goes without saying that you should be building your xml views with bindings for texts from the very start of development – no one wants to go back and to add them all in at a later date (if you do, that’s precious velocity you’re wasting).

Who thought such a straightforward flat structured concept could require so many considerations?

Merging lists with UI5

30 Days of UI5 – Day 22 by Chris Choy

Whilst recently developing a custom UI5 app with an SAP PI backend, I came across some useful mechanisms. My aim was to merge 2 sets of data from 2 service calls into an Object List Item.  Having already bound one set of data my XML View my initial thought was to perhaps use a formatter and pass in 2 arrays of objects and manipulate the data within the Formatter.js file. As you probably guessed, this simply didn’t work, I should mention that both service calls return data in a JSON format rather than standard OData. My next approach was to manipulate the 2 arrays in the View’s controller and merge them both into a new sorted array assigning it to the Component’s Model. One of the benefits of doing this is that you can define your own attribute names and data which is then globally accessible within the app.

Using the code below you can specify a path to set your new data:

this.oModel.setProperty("/newPath", mergedArray);

One other related issue was the searching of specific object attributes within an array of objects. The context of this search was to allow a user to select an item from an Object List Item and load additional data in a new View. Having already passed the relevant parameters within my Router it was jQuery to the rescue. The jQuery.grep function allows you to perform wildcard search on an array of attributes without the need to manually loop through each element. By passing an array as an argument a test against a defined index is performed returning all the entries that satisfy the function as a new array.

var aResult = $.grep(dataArray, function (e) {
  return e.attributeName.indexOf(("searchAttribute",) == 0;
});

One last interesting mechanism used was the storing of hidden Custom Data objects within an XML View. Using the following:

xmlns:app="http://schemas.sap.com/sapui5/extension/sap.ui.core.CustomData/1"
<ObjectListItem
  title=”List”
  app:key="{hiddenKey}" />

you can access the Custom Data object using the data() method within the Controller of your View.

For additional information checkout the following links jQuery.grep and CustomData objects.

 

Spreading the UI5 Message

Michael Graf at OSCON (photo by Janina Blaesius)

30 Days of UI5 – Day 21 by DJ Adams

If you’re reading this post, or this whole series, it’s very likely that you already know something about UI5. Whether that’s coming from the SAP enterprise angle with the SAPUI5 flavour, or from the Open Source angle with the OpenUI5 flavour. But there are plenty of other souls out there that are still missing the UI5 salvation :-). And so I thought I’d briefly review the sorts of activities that have been happening over the last couple of years as far as evangelism, education, and advocacy are concerned.

This is very timely, as this year’s OSCON has just finished in Portland, and a couple of UI5 team members Janina Blaesius and Michael Graf were there with a session on OpenUI5 : “No more web app headaches“. Good work folks! OSCON is O’Reilly’s Open Source Convention, a venerable conference that I’ve been lucky enough to attend and speak at on and off since 2001. Last year, I co-presented a tutorial session on OpenUI5 at OSCON with Andreas Kunz and Frederic Berg – two more heroes from the same UI5 team as Janina and Michael.

Not only that, but the great news is that at the EU version of OSCON, taking place in Amsterdam in October this year, there’s another session “Don’t Disconnect Me! The challenges of building offline-enabled web apps” by another mighty UI5 team combo of Christiane Kurz and Matthias Oßwald. Awesome!

And even if you omit the usual suspect conferences such as SAP TechEd, there’s plenty more, far too much to list in this single post. But here’s a quick selection:

FOSDEM : OpenUI5 at FOSDEM 2015

Mastering SAP : Speaking at Mastering SAP Technologies

SAP Arch & Dev : Speaking at the SAP Architect & Developer Summit

Fluent : OpenUI5 at Fluent Conference 2015

JSNext : OpenUI5 at JSNext Bulgaria

DevoxxUK : DevoxxUK – One does like to code!

SAP Inside Track : SAP Inside Track ManchesterSAP Inside Track Sheffield – UK

SAP CodeJam : SAP CodeJam Liverpool – OpenUI5

Bacon : OpenUI5 at BACON Conference

In September there’s another SAP Inside Track in Sheffield, where there will be talks on UI5 of course (well, I’m going! ;-) and a whole second day dedicated to learning and hacking with UI5.

I’m sure I’ve missed out some UI5 activities, so please let me know of others that have happened. And perhaps more importantly, let me know of any that are coming up, especially any that you’re planning, and I can add them here. Share & enjoy!

 

Fragments and Minimum Viable Code

30 Days of UI5 – Day 20 by DJ Adams

In an earlier post in this series, MVC – Model View Controller, Minimum Viable Code, I showed how you could write a single-file UI5 app but still embrace and use the concepts of Model View Controller, having separate controller definitions and declarative XML Views. I also mentioned you could use XML Fragments in this way too, and Robin van het Hof asked if I could explain how. So here we go, thanks Robin!

If we take the code from the previous post and run it, we end up with a UI that looks like this:

Screen Shot 2015-07-21 at 17.33.38

Let’s add some behaviour to the Button so that it instantiates and opens a Dialog control. We’ll define this Dialog control in an XML Fragment.

In the same way that we defined the XML View, we’ll define the XML Fragment inside a <script> element, this time with a “ui5/xmlfragment” type, like this:

Screen Shot 2015-07-21 at 17.43.19

It’s a standard XML Fragment definition, and even though it only contains a single root control –the Dialog — I’m using the Fragment Definition wrapper explicitly anyway (as I think it’s good practice).

When we press the Button, we want this Dialog to appear, like this:

Screen Shot 2015-07-21 at 17.39.49

So let’s rewrite the handler “onPress” which is attached to the Button’s press event, so it now looks like this:

Screen Shot 2015-07-21 at 17.42.59

This is a common pattern for fragments, so let’s examine the code line by line:

48: We’re going to be storing a reference to the Dialog fragment’s instance in a controller variable “_oDialogFragment” so we declare it explicitly, mostly to give those reading our code a clue as to our intentions.

51-56: Ensuring we only instantiate the Dialog once, we use the sap.ui.xmlfragment call, with the fragmentContent property, passing the content of the fragment script with jQuery’s help (remember, the name of the fragment script is “dialog”). Once instantiated we add it as a dependent to the current XML View.

57: At this stage we know we have a Dialog ready, so we just open it up.

60-62: The onClose function handles the press event of the “Close” Button in the Dialog’s buttons aggregation.

And that’s pretty much it. Use <script> elements to embed XML Views and Fragments, and use sap.ui.xmlview and sap.ui.xmlfragment to instantiate them, with jQuery to grab the actual content.

A Short UI5 Debugging Journey

30 Days of UI5 – Day 19 by DJ Adams

In an earlier post in this series, entitled “The UI5 Support Tool – Help Yourself!“, we looked at the Support Tool, examining the information available in the Control Tree. In particular we looked at the Properties and Binding Infos tabs. While exploring the new UI5 1.30 features with the Explored app, I re-noticed a small addition to the Explored UI – a Button that allowed me to switch to full screen mode to view control samples.

fullscreentoggle

I thought it would be fun to use the Support Tool and other debugging techniques to see what was exactly happening in the Explored app when we toggled that control.

Identifying the Button

First, we need to identify the Button control – by its ID. We can use a context menu feature of Chrome which will open up the Developer Tools: Right-click on the Button and select Inspect Element. This will show us the ID in the highlighted sections in the screenshot:

Screen Shot 2015-07-20 at 09.13.22

Here, the full ID highlighted is “__xmlview2–toggleFullScreenBtn-img”, as we right clicked on the image part of the Button. Go up a couple of levels in the HTML element hierarchy and you’ll see the <button> with an ID without the “-img” suffix. That’s what we want.

Stopping at the Press Event

We could at this stage play an instant and use sap.ui.getCore().byId to get a handle on the control with this ID. But instead let’s look at the Support Tool and how it can expose event breakpoints.

Opening the Support Tool, and the Control Tree section within, we can search for the ID “__xmlview2–toggleFullScreenBtn”. When we find it, we can switch to the Breakpoints tab and set a breakpoint for the firePress function (as that is what will be happening when we press the Button – a “press” event will be fired):

Screen Shot 2015-07-20 at 09.18.35

Now when we press the Button, we land inside Breakpoint.js:

Screen Shot 2015-07-20 at 09.22.29

Finding the Event Handler

Now that we’re here, there’s plenty to explore, but let’s cut to the chase and look at the Button instance. In particular, we’ll look at an internal property “mEventRegistry” which is a map that holds the functions to be called when specific events are fired. Remember that this is an internal property, which we can’t use, or rely upon, when building apps (for more details on this, see the post “JavaScript Do’s and Don’ts in UI5” in this series). But we’re not building, we’re debugging, so all bets are off.

The ‘this’ here is the Button control instance, and so we can see that the “this.mEventRegistry” map has an entry for “press”:

this.mEventRegistry
-> Object {press: Array[1]}

Looking at this single entry in the array for the “press” event, we can see that the function handler is in a controller (surprise surprise):

this.mEventRegistry["press"][0].fFunction
-> sap.ui.controller.onToggleFullScreen(oEvt)

Unless you’re using an older version of Chrome, you should be able to click on the function name to bring you to the “onToggleFullScreen” function definition:

Screen Shot 2015-07-20 at 09.29.55

Nice!

Examining What Happens

We can now put a breakpoint on line 163 (which I had done already before taking the screenshot above) and hit continue, to be able to then step into what this function calls (the updateMode function) when the stack gets here. This is what the updateMode function looks like:

Screen Shot 2015-07-20 at 09.34.58

It sets the Split App’s mode to the appropriate value (the default of “ShowHideMode”, or “HideMode” for the full screen effect). It also modifies the containing Shell control’s appWidthLimited property so that a real full screen effect can be properly achieved.

So that’s it! If you can become comfortable helping yourself with these tools, you’ll be a better UI5 developer.