Skip to Content
Technical Articles
Author's profile photo yao lu

Using Smart Field Value Help with normal Input Field

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%20value%20help%20dialog%20from%20Smart%20Field%20which%20opened%20by%20normal%20Input%20Field

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

Thank you.

Assigned Tags

      1 Comment
      You must be Logged on to comment or reply to a post.
      Author's profile photo Jun Wu
      Jun Wu

      don't know what you are doing....

      sounds nonsense to me.