alexP
alexP

Reputation: 3765

Pass Static Value to Formatter Parameters in XML View

I want to call the function getCountdown with two parameters:

This is my code:

<ObjectStatus
  title="Time"
  text="{
    parts: [
      {path: 'AuctionEnd'},
      {path: 'Time'}
    ],
    formatter: '.formatter.getCountdown'
  }"
/>

In formatter.js, there is only the first parameter as seen in my console log:

["2016-05-20T12:00:00", undefined]

In JS, I would do it this way:

var AuctionEnd = "2016-05-20T12:00:00";
getCountdown(AuctionEnd, "Time");

Upvotes: 7

Views: 31827

Answers (6)

Boghyon Hoffmann
Boghyon Hoffmann

Reputation: 18044

As of UI5 1.61 (commit), you can add static values to the binding info object. The syntax is value instead of path.

parts: [
  { path: '/modelPath' },
  { value: 123 }
],

Same as with path, you can enhance the value binding info with more settings as shown in this demo ==> https://jsbin.com/yeguhow/edit?js,output



⚡ Bug in UI5 1.79 and below

As reported on GitHub issue #2916, there is a bug which was fixed first in UI5 1.80.
Consider adding { value: 123, model: <modelName> } as a temporary solution, or removing the model name from the path (binding from a default model) to circumvent the issue.

Upvotes: 18

IceRevenge
IceRevenge

Reputation: 1583

I found another possibility, maybe not completely for the usecase of this question but it was what I was looking for when I found this question.

If the "constant" or "static" text you want to set is an actual translatable text you can define it in the i18n model and then access it like this:

<ObjectStatus
  title="Time"
  text="{
    parts: [
      {path: 'AuctionEnd'},
      {path: 'i18n>/Time'}
    ],
    formatter: '.formatter.getCountdown'
  }"
/>

Maybe a more fitting usecase would be setting the title of a table column and adding an unit from a model to the end like this: "Space [m^2]". Since "Space" has to be translated anyways, you can just pull it from the model directly.

Upvotes: 4

Heinrich
Heinrich

Reputation: 11

Solution for version < 1.61:

  1. Register a model to view in init method

    onInit: function() { // JSONModel required from "sap/ui/model/json/JSONModel"
      var oModelConstants = new JSONModel(Object.freeze({ myConstant: 123 }));
      oModelConstants.setDefaultBindingMode("OneTime");
      this.getView().setModel(oModelConstants, "constants");
    }
    
  2. In XML view, assign your formatter with the following parts:

    <ObjectStatus text="{
      parts: [
        'AuctionEnd',
        'constants>/myConstant'
      ],
      formatter: '.formatter.getCountdownTime'
    }" />
    

For version 1.61 and above, see answer 53609552.

Upvotes: 1

Branislav Popadič
Branislav Popadič

Reputation: 532

For passing static value to formatter you can use i18n model with no translation (since if you look for property that doesn't exist in i18n.prop it returns the key-word you are looking for):

I was trying to represent 'X, , ,X' as list of check boxes:

// will format the first of values boolvalues.split(',')[index]
selected="{parts: [ 'modelName>/boolvalues', 'i18n>0'], formatter: '.formatter.checkBoxFormatter'}" 

In this case I later followed different approach when I realiesd I don't even need formatter:

selected="{= ${modelName>/boolvalues}.split(',')[0] === 'X' }

Upvotes: 1

Mike Turner
Mike Turner

Reputation: 86

I think the aspect @hirse whereas you cannot add static parts to the formatter is correct.

I recommend you to put the static values into an ViewModel-Property like >/countdownType. Then set this property in your controller before binding the objectstatus-text (also in your controller). For this approach you have to give your ObjectStatus an id. Then you cand bind the property text with your formatter.

Your formatter would look something like this:

    getCountdown: function(auctionEnd){

        var sType = this.getView().getModel("<yourviewmodelname>").getProperty("/countdownType");
        //whatever you want to do

    }

And your controller something like this:

var sType = "<yourLogicToDefineEitherTimeOrStatus>";
this.getView().getModel("<yourviewmodelname>").setProperty("/countdownType", sType);

var oObjectStatus = this.getView().byId("<yourNewImplementedObjectStatusId>");
oObjectStatus.bindProperty("text", {
    path: "AuctionEnd",
    formatter: this.formatter.getCountdown.bind(this)
});

Hope this helps.

Regards, Mike

Upvotes: 0

hirse
hirse

Reputation: 2412

As far as I know, you cannot add static parts to the formatter, it can only take model values. For a combination of dynamic and static parts in a property see Expression Binding and Complex Binding Syntax.

For your case, you could add two more specialized formatter functions and call the one you need:

<ObjectStatus text="{parts: ['AuctionEnd'], formatter: '.formatter.getCountdownTime'}" />

(You can just provide an array of path-strings in the part array.)

formatter.getCountdownTime = function (auctionEnd) {
    return formatter.getCountdown(auctionEnd, "Time");
}

formatter.getCountdownStatus = function (auctionEnd) {
    return formatter.getCountdown(auctionEnd, "Status");
}

Upvotes: 0

Related Questions