Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
yaolu
Discoverer
0 Kudos

Introduction


With OData and Smart Field, we can using the value help defined by Annotation without Extra JavaScript/XML Code. In some scenario, the page is just too complex to using Fiori Elements or Smart Field.

But the value help from Annotation is convenient and useful feature, so I tried to use value help from OData with Annotation in normal Input Field by creating a "virtual" Smart Field.

View


As the rendering strategy of SAPUI5 is to not add invisible controls to the View tree, so Instead of defining the HBox with property visible= "false", we define a visible HBox and use CSS to set its visibility to "hidden". So the "virtual" Smart Field added to this HBox will be invisible.
            <Input id="test1" width="10rem" showValueHelp="true" valueHelpRequest="onValueRequest"/> 
<HBox width="1px" height="1px" id="invisibleBox" class="invisible">
</HBox>
<Input/>

Controller


In the JavaScript, what we did is mainly three parts:

  1. Create a Smart Field and bind the OData Model(contains value help annotation) to it

  2. Fire the "valueHelpRequest" of Smart Field we have created

  3. Set the selected value from Value Help Dialog to the Input Field


              onValueRequest: function() {                
/*create the smartfield for using its value help*/
var oSmartFiled = new SmartField({
value:{
path: 'salesOrganization'
}
});
/* Set the selected value to Input Field*/
oSmartFiled.attachChange(() => {
var sValue = oSmartFiled.getValue();
this.getView().byId("test1").setValue(sValue);
oSmartFiled.destroy();
})
/* overwrite the prototype function of this smartfield for adding custom logic to
Promise chain,
Source Code copied from sap.ui.comp.smartfield.SmartField*/
oSmartFiled._createICRenderedDeferred = function () {
var oDef;
oDef = new Deferred();
this._oRenderedWithContext = oDef;
Promise.all([
new Promise(function (fnResolve) {
this.attachInnerControlsCreated(fnResolve);
}.bind(this)),
new Promise(function (fnResolve) {
var oDelegate = {
onAfterRendering: function (oEvent) {
var oFocusCatcher = this._getFocusCatcher(),
oEditControl = this._oControl.edit,
oContent = this.getAggregation("_content");
if (
oEditControl &&
oEditControl.getDomRef() &&
oEditControl.getFocusDomRef() &&
oEditControl === oContent &&
(
!oFocusCatcher ||
!oFocusCatcher.getDomRef()
)
) {
this.removeEventDelegate(oDelegate);
fnResolve();
}
}.bind(this)
};
this.addEventDelegate(oDelegate);
}.bind(this))
]).then(function () {
oDef.resolve();
})
/*Add custom code to the Promise chain for ensure getting the rendered inner
InputField of Smartfield,
and then fire its "ValueHelpRequest" Event to show the Value Help Dialog
*/
.then(
() => {
try{
var sId = oSmartFiled.getId();
var oInput = sap.ui.getCore().byId(`${sId}-input`);
oInput.fireValueHelpRequest();
}catch(reason) {

}
}
);
};
/* Get the ODatamodel which be defined in manefest.json,
bind the ODatamodel to smartfield
add the smartfield to invisible FlexBox
*/
var oSalesModel = this.getOwnerComponent().getModel("salesOData");
var oNewItem = oSalesModel.createEntry("/Z_C_SOHEADER_L2");
oSmartFiled.setModel(oSalesModel);
oSmartFiled.setBindingContext(oNewItem);
var oFlexBox = this.getView().byId("invisibleBox");
oFlexBox.addItem(oSmartFiled);
}

And  the result will be:


The value help dialog from Smart Field which opened by normal Input Field


Thank you.
1 Comment
Labels in this area