OpenUI5 version: all
Steps to reproduce the problem:
What is the expected result?
there should be a way to get the reference to the UI element
@hatelove85911 If you define your formatter in a separate file, this will refer to the control being formatted
@qualiture I did, I defined a formatter in util/formatter.js, but that won't work, in the formatter, this always points to the controller, it's documented in the developer guide->Essentials->Model view controller->views->implementing xml views->Handling Events in XML Views . So there's no option to say I want the context object of format function to be the control.
Not sure what goes wrong then... See this working example: http://plnkr.co/edit/ifqIStF1AY4akC8IpCSD?p=preview. The code in the formatter:
formatCell : function (sValue) {
this.addStyleClass("myCellStyle1");
return sValue;
}
adds a style to this (in this case, the sap.m.Text element being formatted, and not the controller), and returns the value as-is
Formatters are not event handlers. The documentation in the developer guide, that @hatelove85911 referenced above, is true for event handlers. But for formatters it doesn't apply. Their context depends on the syntax of the name that is specified in the binding:
A name that starts with a dot (e.g. ".foo") is searched for in the controller of the view and the execution context will be enforced to being the controller.
All other names are resolved starting from the window object ("nl.qualiture.formatter.formatter.formatCell" in @qualiture's example) and they get the control/element as context which holds the binding.
The reason for the controller formatters being handled differently is a) consistency with the controller event handlers and b) to allow them to access other helpers or data from the controller instance.
Addressing a formatter via a global name instead of via controller local name is the easiest way to get access to the control. Polluting the controller with control specific formatters also would be a technical solution, but I guess it is feasible only in rare cases (e.g. formatter is used only once in the view).
There is already an internal ticket that tracks the lack of proper documentation reg. this: 1570822965.
@qualiture @codeworrior, thanks for your reply, it clears the doubt I have. The initial problem I has is: I don't remember exactly which part of the developer guide I followed, I created the formatter in AMD fashion in a separate file and I add a "formatter" property to the controller and it's assigned as the formatter module which is required in sap.ui.define. So in the xml view, I refer to the formatter function as
.formatter.xxx, see below. Now in the formatter function, the context object is always the controller. Because I didn't refer to it with global name.

===== divider =======================================================
But I run into another stupid awkward issue, what I want:
The above 2 points lead to a stupid situation:
jQuery.sap.require to load the AMD module synchronously jQuery.sap.declare, if my formatter has other dependencies, I have to change them too!...You IMHO could
sap.ui.define([....], function() {
var MyUtil = {
myformatter : function(v) {
return this.getId() + v;
}
};
// export formatter under a global name
// for hierarchical names you might use jQuery.sap.setObject("name", myformatter)
window.myformatter = MyUtil.myformatter;
// standard AMD Style module value
return MyUtil;
});
As the controller is loaded by the view before bindings can be resolved, any dependency should be loaded in time. Also the global name for the formatter should be established in time then.
However, I must admit that this is not a perfect solution as AMD and the use of global names don't really fit together. We already discussed some months ago the idea of allowing dependency declarations ("requires") in the XML view (similar to namespace definitions). They could introduce shortcuts names that would be evaluated when resolving event handlers, formatters etc. But so far this idea didn't make it into our backlog.
great solution, thanks!
I was facing this particular issue and finally came across this post. Thanks first of all for the solution. But how do we get to know about all these in the first place so that these type of issue don't arise.
Reference the same discussion here: https://stackoverflow.com/questions/32222703/how-to-pass-control-reference-to-formatter-in-xmlview/51093375#51093375
Related source code: https://github.com/SAP/openui5/blob/f76d2efea1b2099680e0649c19e6024b4ec02876/src/sap.ui.core/src/sap/ui/base/BindingParser.js#L164
Most helpful comment
Formatters are not event handlers. The documentation in the developer guide, that @hatelove85911 referenced above, is true for event handlers. But for formatters it doesn't apply. Their context depends on the syntax of the name that is specified in the binding:
A name that starts with a dot (e.g. ".foo") is searched for in the controller of the view and the execution context will be enforced to being the controller.
All other names are resolved starting from the window object ("nl.qualiture.formatter.formatter.formatCell" in @qualiture's example) and they get the control/element as context which holds the binding.
The reason for the controller formatters being handled differently is a) consistency with the controller event handlers and b) to allow them to access other helpers or data from the controller instance.
Addressing a formatter via a global name instead of via controller local name is the easiest way to get access to the control. Polluting the controller with control specific formatters also would be a technical solution, but I guess it is feasible only in rare cases (e.g. formatter is used only once in the view).
There is already an internal ticket that tracks the lack of proper documentation reg. this: 1570822965.