Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 

Sometimes SAPUI5 controls does not support a specific use case you run into. For that, an extensibility functionality is provided for all of SAPUI5’s controls.

Extending a control or even creating a new one is a simple task, which will be explained in this step-by-step post. This post will extend the sap.m.Select control, creating an option to add new items to it at runtime. It is divided in the following tasks:

  1. Create a javascript file to extend the control
  2. Add new properties and events to control
  3. Check standard control source code in OpenUI5
  4. Extend standard control’s function onBeforeRendering + init
  5. Create function to handle new option
  6. Extend standard control’s function onSelectionChange
  7. Add control to the view and test it

If you are on a hurry, you can look at the code from this sample at GitHub and check the behavior of the control at JS Bin.

Feel free to use and enhance this control if it fits your needs :smile: .

The only requirement to follow this post is having a running SAPUI5 project. If you have not already set up your project, please find helpful content here:

Create an SAPUI5 Application Project - UI Development Toolkit for HTML5 (SAPUI5) - SAP Library

Create a javascript file to extend the control

Start creating a new js file which will be the extension control:

The name of our control will be Select.js.

Add the following code to the control:

jQuery.sap.declare("<your_project_path>.<your_folder>.Select");
jQuery.sap.require(
"sap.m.Select");
jQuery.sap.require("sap.m.SelectRenderer");

sap.m.Select.extend("<your_project_path>.<your_folder>.Select", {

     renderer: "sap.m.SelectRenderer"

});


The code above is declaring the control’s name (line 1), requiring the standard controls which will be extended (lines 2 and 3), executing extend function from parent control, and defining the file that will be the renderer.


On this example the renderer will not be extended and the standard will be used.

Until now no changes were made to the control. It would behave exactly like the standard control if instantiated.

Add new properties and events to control

Now create the new properties and events this control needs. This can be done by simply creating a metadata object:


metadata: {

      properties: {

                 "addValueEnabled": {

              type: "boolean",

              defaultValue: true

         }

      },

      events: {

         "newValueCreated": {}

      }

}


The addValueEnabled property will be responsible for enabling the new “add” feature. By default it is set to true, and if the user sets it as false the control will behave exactly like the standard sap.m.Select.

In addition, the newValueCreated event will be fired when the user creates a new option.

Also, as a good practice, we are going to create two new constants bellow the metadata object. They will be responsible for the add option’s text and key.


ADD_OPTION_KEY: "__addNewValue",

ADD_OPTION_TEXT: "Add..."


Check standard control’s source code on OpenUI5 git

Most of the times, extending a control requires extending also some of its functions. For that, it is helpful knowing the standard control’s source code.

The best way to have access to an UI5 control is taking a look at the OpenUI5 git repository.

Extend sap.m.Select standard functions

Looking through the standard control’s source code, it is possible to figure out that some functions need to be extended to support our new feature.

The onBeforeRendering function will place the main code of this extension, where the new option named “Add” will be created and inserted to the select. Besides, the init function will hold a control's verification property.

init: function() {

           // define variable for control initial loading handling

           this._bInitialLoading = true;

   

     // execute standard control method

     sap.m.Select.prototype.init.apply(this, arguments);

},

   

onBeforeRendering: function() {

      if (this.getAddValueEnabled()) {

                // check if "add..." option does not exist yet. if so, create it

                if (!this.getItemByKey(this.ADD_OPTION_KEY)) {

             

           // create add value item and add it to select

           var oItem = new sap.ui.core.Item({

                          key: this.ADD_OPTION_KEY,

             text: this.ADD_OPTION_TEXT

           });

  

                      this.insertItem(oItem, 0);

        }

        // set item index if more than one option and initial loading

                if (this._bInitialLoading && this.getItems().length > 1) {

                     this.setSelectedItem(this.getItems()[1]);

         

           // the “onBeforeRendering” method will only be executed again on new option creation

           // further verifications are not necessary

                     this._bInitialLoading = false;

        }

      }

         

            // execute standard control method

      sap.m.Select.prototype.onBeforeRendering.apply(this, arguments);

}

First it is verified whether the add value feature is enabled in the control. After that, it is verified whether the “Add” option is already created. If not, the “Add” item is created and inserted to the select options. This verification will avoid the creation of multiple “Add” options, because the “onBeforeRendering” function is called always when a new option is created. Note that its key and text are the constants created in step 2.

The next validation checks if the control is in its initial load and if it has any options. In case both sentences are true, the second item (first item after the custom “Add” option) is selected.

Note that on both functions, the standard control’s apply function is being called. This function executes the standard behavior of the control, meaning that both custom and standard content will be executed.

Handling new option

Now it is necessary to create a function to handle the “Add” option. It is a simple item on the select, but will have an special treatment when selected. Instead of just displaying it, a dialog with an input will be shown for the user to add the new value.

It will be necessary to extend the onSelectionChange function from parent control. This function is called when the select value changes and will be enhanced to check whether the selected item is the “Add” option. If the add option is selected a dialog is created with an input to allow the user to enter the new value.


onSelectionChange: function(oControlEvent) {

     // get selected item

          var oItem = oControlEvent.getParameter("selectedItem");

         

          // check if the add value option is enabled and if the key is the 'add option' key

          if (this.getAddValueEnabled() && oItem.getKey() === this.ADD_OPTION_KEY) {

                this._createNewOptionDialog();

     }

        

     // execute standard control method

     sap.m.Select.prototype.onSelectionChange.apply(this, arguments);

},

   

_createNewOptionDialog: function() {

          // create dialog with input field

          var that = this;

     var oDialog = new sap.m.Dialog({

          title: 'Add value',

          content: new sap.m.Input({

               id: 'idNewValueInput'

          }),

          beginButton: new sap.m.Button({

               text: 'Add',

               press: function() {

                    that._handleNewOption();

                    oDialog.close();

               }

          }),

          afterClose: function() {

               oDialog.destroy();

          }

     });

     oDialog.open();

},

   

_handleNewOption: function() {

     // get new option value

          var oInput = sap.ui.getCore().byId("idNewValueInput");

          var sNewValue = oInput.getValue();

   

     // create new item to be added in select

     var oItem = new sap.ui.core.Item({

              key: sNewValue,

       text: sNewValue

     });

   

     // add item to select and set it as selected

     this.addItem(oItem);

     this.setSelectedItem(oItem);

               

     // fire an event in case the parent object needs to handle this

     this.fireNewValueCreated({

          value: sNewValue

     });

}


When the dialog create button is pressed, the function executed creates a new item, adds it to the select and fires the custom event newValueCreated sending the value as a parameter.

Add control to the view

Using an extension control is as simple as using any other SAPUI5 control.


<mvc:View

      xmlns:mvc="sap.ui.core.mvc"

      xmlns="sap.m"

      xmlns:l="sap.ui.layout"

      xmlns:core="sap.ui.core"

      xmlns:custom="sapui5-control-extension-demo.controls"

      controllerName="sapui5-control-extension-demo.main"

      xmlns:html="http://www.w3.org/1999/xhtml">

      <Page title="Control extension">

            <content>

                  <l:VerticalLayout width="100%">

                        <l:content>

                             <Label text="Extension Control" />

                             <custom:Select

                    width="50%"

                    newValueCreated="handleNewValue"

                    items="{/}">

                                   <core:Item

                       key="{CountryId}"

                       text="{Name}" />

                             </custom:Select>

                        </l:content>

                  </l:VerticalLayout>

            </content>

      </Page>

</mvc:View>


It is only necessary to create a new xmlns with the path to the control (or require the control, in case of a JS view) and add it to the view.

The final result is the following: Live demo

4 Comments