12

How can I implement an if-else condition in a XML-View in SAPUI5 that uses a flag (condition) from a JSONModel?

So far I have a Controller:

sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/ui/model/json/JSONModel"
], function (Controller, JSONModel) {
    "use strict";

    return Controller.extend("sap.ui.demo.myApp.myController", {
        onInit: function () {
            //// set data model on view
            var oData = {
                title: "A cool title",
                values: [{name: "Text 1", marketed: true}, {name: "Text 2", marketed: false}, {name: "Text 3", , marketed: true}]
            };

            var oModel = new JSONModel(oData);
            this.getView().setModel(oModel);
        }
    });
});

and a View:

<mvc:View
    controllerName="sap.ui.demo.myApp.myController"
    xmlns="sap.m">

    <!-- using aggregation binding -->
    <Panel expandable="true" expanded="true" headerText="{/title}" width="100%" content="{/values}">
        <content>
            <Label text="{name}"/>
            <!-- if {marketed} 
                    <Label text="product is marketed"/> 
                 else 
                    add nothing
            -->
        </content>
    </Panel>

</mvc:View>

Edit:

Is there a better way to do it than by implementing an overkill-feeling XML-Preprocessor?

Mike
  • 14,010
  • 29
  • 101
  • 161
Benvorth
  • 7,416
  • 8
  • 49
  • 70

4 Answers4

15

OpenUI5 supports Preprocessing Instructions and Expression Binding.

With Preprocessing Instructions you can do stuff like this:

<template:if test="{marketed}">
    <template:then>
        <Label text="product is marketed" />
    </template:then>
    <template:else>
        <Image src="path.jpg" />
    </template:else>
</template:if>

I am not sure if the test in the first line tests for null/not null or true/false. This is where the Expression Binding might be handy: it allows for complex expressions within the curly brackets:

<template:if test="{= ${marketed} === true}">

Edit

The following solution might be more simple, but seems a little hacky.

Embed both elements in your XML view, but toggle the visibility with complex expression binding:

<Label text="product is marketed" visible="{= ${marketed} === true}"/>
<Image src="path.jpg" visible="{= ${marketed} === false}"/>
Mike
  • 14,010
  • 29
  • 101
  • 161
Marc
  • 6,051
  • 5
  • 26
  • 56
  • Afaik I have to implement a XML-Preprocessor to use the Preprocession Instructions you metion. How can I do this in this context? Also, what is the `template` namespace you mention? The Preprocessor output? – Benvorth Jan 07 '16 at 13:28
  • 1
    https://openui5.hana.ondemand.com/1.28.19/docs/guide/5ee619fc1370463ea674ee04b65ed83b.html The `template` namespace is defined as `xmlns:template="http://schemas.sap.com/sapui5/extension/sap.ui.core.template/1"`. The link also contains a small example – Marc Jan 07 '16 at 13:35
  • This link does not provide a running example of a XML-Preprocessor implementation and I can't make it work in my code. Do you have a running example at hand? – Benvorth Jan 07 '16 at 14:18
  • There is a working example, right where the yellow highlighting begins. There is even a link to an example in their explored app. This example contains a Component.js, a view (template) and a fragment (template) – Marc Jan 07 '16 at 14:22
  • I just get a message saying `This is meant to be a pure code sample. (To run it, you would need a proxy which is configured properly.)` The `Template.view.xml` is not used... – Benvorth Jan 07 '16 at 14:26
  • Yes, but it would work, if you had a proxy running. See the following warning on the page I linked to: **The OData model is based on GWSAMPLE_BASIC and will not work unless a suitable proxy for back-end access is used**. Which means that this code works as is, just not for you (or me.. or anyone without access to their backend). It should be absolutely doable to modify this code to fulfill your needs. – Marc Jan 07 '16 at 14:33
  • 2
    ok, thanks for your input. The XML-Preprocessor seems to be a possible solution but feels like overkill for such a "small" thing like if/else. Is there perhaps a better way? – Benvorth Jan 07 '16 at 16:21
  • 1
    I updated my post. I think it's not better, but it has a lot less overhead. **Edit** Seems like @user2808624 had the same idea :D – Marc Jan 08 '16 at 09:55
  • 4
    I can't believe that UI5 templating doesn't offer such simple things as if/else constructs. I saw the page on the preprocessor, and it would be ok if this just worked out of the box. But I did not manage to get this preprocessor up and running. The samples are not helpful at all. No wonder that this lib doesn't get any love from outside the SAP community. – waldgeist Oct 24 '18 at 12:06
6

I am not sure I got your requirement, but it looks like simply binding the visible attribute to the marketed-flag would do.

If you need to bind in a negated way you can use expression binding like

 visible="{= !${/marketed}}"
user2808624
  • 2,502
  • 14
  • 28
  • haha, very ... free-spirited! I like it :-) Unfortunately this does not allow to control the view in a more complex way. – Benvorth Jan 07 '16 at 22:08
4

If I've understood your question propery, you could use a formatter function.

<Label text="{
    path: 'marketed'
    formatter: '.formatter.marketed'
}"/>

.formatter.marketed in this example references a function in a separate formatter.js file:

marketed: function(marketed) {
    if(marketed) {
        return 'product is marketed';
    } else {
        return '';
    }
}

See the ui5 SDK for hpow to set up the formatter function correctly:

https://sapui5.hana.ondemand.com/sdk#docs/guide/0f8626ed7b7542ffaa44601828db20de.html

In your example, as this is just a label, we're returning an empty string, so it will just be blank. The Label will still be rendered, but it's an empty string, so there's nothing to show, so the user will never know it's there. I'm not entirely sure, but if you return undefined instead of an empty string, the label may not be rendered at all.

JamieC
  • 567
  • 3
  • 11
  • it has to be more simple, not that ugly and cumbersome, ah enterprise such an enterprise... – bora89 Jul 20 '23 at 20:25
1

In the context of XML Templating as one of the Preprocessing Instructions, another option is to define Fragment's fragmentName as an Expression Binding like this:

<core:Fragment fragmentName="{= ${path: 'facet>Target', formatter: 'sap.ui.model.odata.AnnotationHelper.isMultiple'} === 'true'
    ? 'sap.ui.core.sample.ViewTemplate.scenario.TableFacet'
    : 'sap.ui.core.sample.ViewTemplate.scenario.FormFacet' }" type="XML"/>

Documentation: https://ui5.sap.com/#/topic/65da02badf704e03a4fd6bd4c5aba8f4

Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170
MegaCookie
  • 5,017
  • 3
  • 21
  • 25