SAPUI5 single file template using XMLViews, Controllers, Fragments and Custom Controls for bug illustrations, support requests or demos

As the UI5 community is growing every day I have experienced that people new to UI5 find it hard to create simple demos demonstrating their issues. I have seem many questions on Stackoverflow and also on SCN with textual questions only. However, this makes it harder for others to help without a demo. Actually, there are good platforms on the web which can be used to create simple demos, such as jsbin, JSFIDDLE, or Plunker. Plunker is kind of more sophisticated as it allows to create folders and subfolders. Using Plunker is really great, because you can simply upload your complete app including all of your dev resources and create a demo. However, sometimes you can't or don't want to upload everything for whatever reason. In such cases creating a one-file demo could help, especially if you want to hide the complexity of a complete app.

This article offers you a simple SAPUI5 single file template that uses XMLViews, Controllers, Fragments and Custom Controls. Using it allows you to easily illustrate bugs or issues. You can use it for creating a jsbin example - just copy and paste the code into jsbin. Using this template for creating demos increases the chances to get answers to you support requests on SCN or Stackoverflow. Feel free to use it - it's free as beer (attributions are still welcome)! But what's the benefit of this template? Well, you can better explain your issues and it helps others to understand and help you faster.

Here is the template (see below). First you decide what UI5 version you want to use. The template has one XMLView that contains a sap.m.Table control. The items of that table are bound via bindItems() in the corresponding controller. The template for bindItems() comes from an XMLFragment which is also part of this single file template. The Controller uses the Northwind OData services to fill the table with some data (this is just for illustration purposes). Change the code as you wish so that it fits your own scenario.

Hint: I have been asked many times how to use Custom Controls in XMLViews. This article also illustrates how you use Custom Controls in XMLViews.

Hint: The template uses sap.ui.define(). If you prefer the "old" way without sap.ui.define() here is the same template without sap.ui.define().


SAPUI5 Single File Template (live demo in new window)
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>SAPUI5 single file template | nabisoft</title>
        <!-- decide what version you want to use, see http://scn.sap.com/community/developer-center/front-end/blog/2015/07/30/multi-version-availability-of-sapui5:
        <script src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
        <script src="https://sapui5.hana.ondemand.com/1.28.28/resources/sap-ui-core.js"
        <script src="https://openui5beta.hana.ondemand.com/resources/sap-ui-core.js"
        <script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
        <script src="https://openui5.hana.ondemand.com/1.36.12/resources/sap-ui-core.js"
        -->
        <script src="https://openui5.hana.ondemand.com/1.36.12/resources/sap-ui-core.js"
            id="sap-ui-bootstrap"
            data-sap-ui-theme="sap_bluecrystal"
            data-sap-ui-libs="sap.m"
            data-sap-ui-bindingSyntax="complex"
            data-sap-ui-compatVersion="edge"
            data-sap-ui-preload="async"></script>
            <!-- use "sync" or change the code below if you have issues -->

        <!-- XMLView -->
        <script id="myXmlView" type="ui5/xmlview">
            <mvc:View
                controllerName="MyController"
                xmlns="sap.m"
                xmlns:core="sap.ui.core"
                xmlns:mvc="sap.ui.core.mvc"
                xmlns:nabisoft="nabisoft.ui">

                <!-- use our custom control, see below -->
                <nabisoft:Headline text="SAPUI5 single file template using XMLViews, Controllers, Fragments and Custom Controls for bug illustrations, support requests or demos"/>

                <Table
                    id="myTable"
                    growing="true"
                    growingThreshold="10"
                    growingScrollToLoad="true"
                    busyIndicatorDelay="0">
                    <headerToolbar>
                        <Toolbar>
                            <Title text="Orders of ALFKI"/>
                            <ToolbarSpacer/>
                        </Toolbar>
                    </headerToolbar>
                    <columns>
                        <Column>
                            <Text text="OrderID"/>
                        </Column>
                        <Column>
                            <Text text="Order Date"/>
                        </Column>
                        <Column>
                            <Text text="To Name"/>
                        </Column>
                        <Column>
                            <Text text="Ship City"/>
                        </Column>
                    </columns>
                    <items>
                        <!-- filled via bindItems() in controller -->
                    </items>
                </Table>

            </mvc:View>
        </script>

        <!-- XML Fragment -->
        <script id="myXMLFragment" type="ui5/fragment">
            <core:FragmentDefinition
                xmlns="sap.m"
                xmlns:core="sap.ui.core">
                <ColumnListItem type="Active">
                    <cells>
                        <ObjectIdentifier title="{OrderID}"/>

                        <Text
                            text="{
                                path:'OrderDate',
                                type:'sap.ui.model.type.Date',
                                formatOptions: { style: 'medium', strictParsing: true}
                            }"/>

                        <Text text="{ShipName}"/>

                        <Text text="{ShipCity}"/>

                    </cells>
                </ColumnListItem>
            </core:FragmentDefinition>
        </script>

        <script>
            sap.ui.getCore().attachInit(function () {
                "use strict";

                //### Custom Control ###
                // remove the first parameter in "real" apps
                sap.ui.define("nabisoft/ui/Headline",[
                    "sap/ui/core/Control"
                ], function(Control) {
                    "use strict";

                    return Control.extend("nabisoft.ui.Headline", {
                        metadata : {
                            properties : {
                                text: {type : "string"}
                            },
                            aggregations : { },
                            associations : { },
                            events : { }
                        },

                        init : function () { },

                        renderer : function (oRM, oControl) {
                            oRM.write("<h3");
                            oRM.writeControlData(oControl);
                            oRM.addClass("nabiUiHeadline");
                            oRM.writeClasses();
                            oRM.write(">");
                            oRM.writeEscaped(oControl.getText());
                            oRM.write("</h3>");
                        }
                    });
                });

                //### Controller ###
                sap.ui.define([
                    "sap/ui/core/mvc/Controller",
                    "sap/ui/model/odata/v2/ODataModel"
                ], function (Controller, ODataModel) {
                    "use strict";

                    return Controller.extend("MyController", {
                        onInit : function () {
                            this.getView().setModel(
                                new ODataModel("https://cors-anywhere.herokuapp.com/services.odata.org/V2/Northwind/Northwind.svc/", {
                                    json : true,
                                    useBatch : false
                                })
                            );

                            var sPath = "/Customers('ALFKI')/Orders";
                            var oTable = this.byId("myTable");
                            var oTemplate =  sap.ui.xmlfragment({
                                fragmentContent : jQuery("#myXMLFragment").html()
                            });

                            oTable.bindItems(sPath, oTemplate, null /*oSorter*/, null /*aFilters*/);
                        }
                    });
                });

                //### THE APP: place the XMLView somewhere into DOM ###
                sap.ui.xmlview({
                    viewContent : jQuery("#myXmlView").html()
                }).placeAt("content");

            });
        </script>

    </head>

    <body class="sapUiBody">
        <div id="content"></div>
    </body>
</html>

And here is the live demo (open in new window):

Comments
Answer for : Extend Controller from BaseController
posted by Rajendra Patade
Sat Apr 25 20:19:28 UTC 2020
Entry for data-sap-ui-resourceroots  was missing. Thank you.
Extend Controller from BaseController
posted by Rajendra Patade
Sat Apr 25 18:48:25 UTC 2020
Thank you for the nice explanation. I want to Extend Controller from BaseController. BaseController is used in some other application also and hence and want to resue. I dont want to rewrite  BaseController again in single html template. I have done this in other application but how to do this in single template html file. I am bit confused with syntax. PLease guide.
Extend in XML
posted by Jeferson
Thu Jan 05 10:49:34 UTC 2017
Hi, interesting article, but is it possible to take a multiple UI5 controls (like a textbox+button) from a XML view and transform into a custom control? So far I've only found examples of JS extending existing ones, but I have a combination of UI5 controls that I'd like people to just declare <MyUI5Control> and it will bring the whole thing to be rendered, without messing up with HTML or anything like that, just using standard UI5 controls.. (pretty much like wrapping a view into a single UI5 control)..
RE: Question for Fragment
posted by Nabi
Fri Sep 30 12:20:37 UTC 2016
The short answer is no and yes.
No because in the fragment itself you cannot define a controller (in contrast to views).
Yes because fragments can be used in different controllers/views. When you get an instance of the fragment in any given controller then you can simply pass the controller (or any other object) as the second parameter: 

sap.ui.xmlfragment("sap.ui.demo.wt.view.HelloDialog", this); 

For details have a look at the walkthrough tutorial step 17: https://openui5.hana.ondemand.com/#docs/guide/354f98ed2b514ba9960556333428d35e.html
Question for Fragment
posted by abhishek Kumar
Wed Sep 28 13:40:50 UTC 2016
Hello,

To develop a project we are told to create multiple fragments with respective controller. 
Can we assocoate a fragment with a controller without a View ?
 if yes how ?
So I will be devloping fragments and its controller.

Thanks for your clarification,
Abhishek