0

I have a view with tiles, each of which have an id="foo" property, and a press property pointing to a function in the controller.

The problem is I can get the id of the tile, but it is appended automatically to the view name, __xmlview1--foo1. This can change if other views have already been created; there's no guarantee it will always be xmlview1, it could be xmlview2 or any higher number.

How do I retrieve the pure id as it appears in the tile's id property? Is this switch statement the best way to perform navigation, or is there a more robust/elegant solution?

onPress: function(oEvent){
  switch(oEvent.getSource().sId) {
    case "__xmlview1--foo1":
      this.oRouter.navTo("myview1");
      break;
    case "__xmlview1--foo2":
      this.oRouter.navTo("myview2");
      break;
    case "__xmlview1--foo3":
      this.oRouter.navTo("myview3");
      break;
    case "__xmlview1--foo4":
      this.oRouter.navTo("myview4");
      break;
    case "__xmlview1--foo5":
      this.oRouter.navTo("myview5");
      break;
    default:
      console.log("No match found.");
}
MKHC
  • 461
  • 4
  • 23

3 Answers3

1

You can change the format to look like _xmlviewX--myviewX, then simply substring from -- and navigate to that link.

Elad Stern
  • 1,072
  • 13
  • 23
  • Thanks, this works. I did consider a string operation originally, but I was wondering if a better solution was available. I feel like there should be a way to get the id without having to do that. – MKHC Mar 03 '15 at 09:28
1

Please, do not try and reinvent the wheel...

UI5, just like many other more or less mature frameworks, utilize the Router paradigm for navigation.

It gives you way more freedom -- you could use bookmarking, maintain application state, is maintenance-friendly, and as such you don't need to use ugly switch / if-then-else statements.

See the excellent explanation of the Routing mechanism in the Application Best Practices or have a look at this working example. You could easily adapt for use with tiles.

(If I would do a code review, and I don't see a Router mechanism used for navigation, I would delete the code altogether and ask you to start over properly)

EDIT: It seems I was a bit misguided by the multiple switches... my apologies!

I'm assuming you are populating your tiles based on a model. So why not add the navigation target to your model?

TileCollection : [
    {
        icon   : "sap-icon://inbox",
        title  : "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
        target : "detailView1"
    },
    {
        //etc
    }
]

And the tile definition:

<TileContainer id="container" tiles="{/TileCollection}">
    <StandardTile
        icon="{icon}"
        title="{title}"
        press="handlePress" />
</TileContainer>

Your event handler which serves the press event for all your tiles can then be as simple as:

handlePress: function(oEvent) {
    var sTarget = oEvent.getSource().getBindingContext().getObject().target;
    this.oRouter.navTo(sTarget);
}

Hope this explains a bit more! :)

Qualiture
  • 4,900
  • 7
  • 27
  • 38
  • I **am** using routing. I need to determine the id of the tile so I can point the router in the right direction. I get the router in onInit and you can see `this.oRouter.navTo("myview1");` etc in the switch. – MKHC Mar 03 '15 at 11:46
  • You are right, my apologies. I was misdirected because of the multiple switch cases... see my updated answer :) – Qualiture Mar 03 '15 at 13:18
  • I originally used a model for my tiles but I couldn't see how to make it work with i18n, since putting `title="{i18n>...}"` in the json file didn't get data bound in the view. Do you know if this is actually possible? Your updated answer looks much better, I will try it out anyway, thanks very much. – MKHC Mar 03 '15 at 14:17
  • 1
    Should be perfectly possible; either directly or in code, for instance `new sap.m.StandardTile({title: oi18nModel.getText("MYTITLE")});` where `oi18nModel` is a reference to your resource model. See https://sapui5.hana.ondemand.com/sdk/#docs/guide/91f385926f4d1014b6dd926db0e91070.html for more info – Qualiture Mar 03 '15 at 14:55
  • Looks like there's hope for me yet. I'm having trouble understanding how to set up the json file, the binding in the XML view and the stuff needed in the controller to make it all work. I'll post this as a new question, though. Thanks for your help so far. – MKHC Mar 03 '15 at 16:03
  • No problem, would love to answer ;-) – Qualiture Mar 03 '15 at 16:35
0

The easiest solution would be giving up the switch and using indexOf/if..else instead:

var id = oEvent.getSource().sId;

if (id.indexOf('foo1') > -1) {
    this.oRouter.navTo("myview1");
} else if (id.indexOf('foo2') > -1) {
    this.oRouter.navTo("myview2");
} else if (id.indexOf('foo3') > -1) {
    this.oRouter.navTo("myview3");
} else if (id.indexOf('foo4') > -1) {
    this.oRouter.navTo("myview4");
} else if (id.indexOf('foo5') > -1) {
    this.oRouter.navTo("myview5");
} else {
    console.log("No match found.");
}

If you must use switch however, you can regex the id using test

onPress: function(oEvent){

    var id = oEvent.getSource().sId;

    switch(true) {
        case /foo1/.test(id):
          this.oRouter.navTo("myview1");
          break;
        case /foo2/.test(id):
          this.oRouter.navTo("myview2");
          break;
        case /foo3/.test(id):
          this.oRouter.navTo("myview3");
          break;
        case /foo4/.test(id):
          this.oRouter.navTo("myview4");
          break;
        case /foo5/.test(id):
          this.oRouter.navTo("myview5");
          break;
        default:
          console.log("No match found.");
}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test

o--oOoOoO--o
  • 770
  • 4
  • 7
  • But a `switch` is exactly a simple implementation of `if..else`. The only difference is that a switch can more easily (in terms of syntax) combine similar cases. – Elad Stern Mar 03 '15 at 09:25