Additional Blogs by SAP
cancel
Showing results for 
Search instead for 
Did you mean: 

SAPUI5 comes with a collection of large number of UI Controls which you can use but there are often occasions when you would need custom controls for your UX behavior. In this post I would like to share how easy it is to create a SAPUI5 custom control.

This is what the end product will look like

If you are in real hurry you can grab the source code from here Edit fiddle - JSFiddle

Let me explain how this works.


We will extend the SAPUI5 core control, provide our own logic for rendering, specify some properties (default) and then create an instance of this control with new properties and place it in the view.

Part 1: Extend Custom Control

sap.ui.core.Control.extend("my.rpb", {})

I am naming the new custom control as "my.rpb", use your own namespace as suited, for e.g. "xyz.roundprogressbar" or so on. All UI5 controls needs to be extended from the core Control (or from existing control). I could have very well extended the existing progress bar control provided by UI5, but I didn't for now to keep it simple and generic. In the "{}" you can supply your own method set but most importantly you need to override "renderer" and "metadata". "renderer" allows you to use your own view display logic or define how the control would essentially be rendered on the screen. "metadata" allows you to specify customizable properties which you want to provide to the user of this control.

Part 2: Logic for Rendering

renderer: function(oRm, oControl) {

  var radius = parseInt(oControl.getProperty('radius'), 10);

  var thickness = parseInt(oControl.getProperty('thickness'), 10);

  var computedRadius = radius - thickness/2;

  oRm.write("<div");

  oRm.writeControlData(oControl);  // writes the Control ID and enables event handling - important!

  oRm.addStyle("width", oControl.getSize());  // write the Control property size; the Control has validated it to be a CSS size

  oRm.addStyle("height", oControl.getSize());

  oRm.writeStyles();

  oRm.addClass("rpb");        // add a CSS class for styles common to all control instances

  oRm.writeClasses();              // this call writes the above class plus enables support for Square.addStyleClass(...)

  oRm.write(">");

  oRm.write('<svg width="'+oControl.getSize()+'" height="'+oControl.getSize()+'"><circle cx="'+radius+'" cy="'+radius+'" r="'+computedRadius+'" stroke="'+oControl.getProperty('bgcolor')+'" stroke-width="'+thickness+'" fill="none" />'+

   '<path id="svgpath" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" fill="none" stroke="'+oControl.getProperty('progresscolor')+'" stroke-width="'+thickness+'"></path>'+

   '</svg>');

  oRm.write('<span class="rpb_text">');

  oRm.writeEscaped('0%'); // write another Control property, with XSS protection

  oRm.write('</span>');

  oRm.write("</div>");

  },

renderer method is supplied by two arguments, oRm and oControl. oRm is renderer manager class while the oControl refers to the instance of this control itself. Please note that since RendererManager makes a render call, this is not available inside the method, hence you need to use the oControl variable to refer to the control.

While explaining the logic is not important, you can look at the code to understand that the method basically lays out a div and SVG element to create round path for displaying the progress bar.

Part 3: Specifying properties

metadata: {

  properties: {

  "size" : {type: "sap.ui.core.CSSSize", defaultValue: "200px"},

  "radius": {type: "int", defaultValue: 100},

  "thickness": {type: "int", defaultValue: 8},

  "bgcolor": {type: "sap.ui.core.CSSColor", defaultValue: "lightgreen"},

  "progresscolor": {type: "sap.ui.core.CSSColor", defaultValue: "green"}

  }

  }

We have defined these 5 properties, while the first two size and radius needs to be always in sync with each other (radius to be exact half of size), others are user to  provide way to customize the look and feel, you can see the previous section to understand how these properties are used.

Part 4: Use this control

window.rpb = new my.rpb({size: "100px", radius: 50, thickness: 14, bgcolor: "lightblue", progresscolor: "blue"}).placeAt("content");

You can see above how you can create the instance of this new control and provide custom values for specific look and feel.