This could be considered a part 2 of my original post related to creating a Toolbar component using SAPUI5 Framework.  You can read that blog for the rationale behind the toolbar idea (Design Studio 1.2 SDK – Building a SAPUI5 Toolbar)

In this entry I wanted to focus on a different approach for the same component.  In the initial attempt, I used SAPUI5 technically to create the component, but without any clear direction on how to render it, I used SAPUI5’s placeAt() function to attach it to my DIV container that the SDK provides, based on known examples to-date.  In the subsequent comments on that post, Reiner Hille-Doering mentioned that this may not be the best approach and said that there is a more direct, yet undocumented method.

Based on some subsequent comments in another thread, I think I’ve derived the cleaner method that Reiner may have been alluding to.  Below is my (undocumented, unsupported for now, I’d assume) approach at implementing the same toolbar by using the sapui5 handler instead of the div handler.

GitHub Link:

Design-Studio-Repository/sapui5.toolbar/SAPUI5 Toolbar at master · entmike/Design-Studio-Repository · GitHub

In the component.xml file, I only needed to change handlerType from “div” to “sapui5”.  The rest of the changes I will call out below which occured mainly in component.js.

I also used some SAPUI5 documentation I found here:

Documentation/AdvancedTopics/OnTheFlyControlDefinition – SAPUI5 Wiki (TIP CORE User Interface)

The code below clocks in just under 100 lines, and I’ve commented the important functions and details to call out.


sap.ui.commons.Toolbar.extend("com.sample.menu.ToolbarMenu", {
  // SAP UI5 Metadata convenience at work - Setter and getter are created behind the scenes, including data binding and type validation
  metadata : { // Not to be confused with the Data Source metadata property
  properties : {
  "name" : "string",
  "showCaptions" : {defaultValue : "X", type : "string" },
  "buttonClicked" : {defaultValue : -1, type : "int" },
  "buttonClickedTitle" : {defaultValue : "Nothing Clicked YET",  type : "string" }
  }
    },
    // SAPUI5 Renderer, we can leave it alone
    renderer : {
  /*render : function(rm, oControl){
  alert(oControl.getProperty("buttonClickedTitle"));
  }*/
  },
  // Called by sap.designstudio.sdkui5.Handler  (sdkui5_handler.js)
  initDesignStudio : function() {
  try{
  // Make 100 setters and getters until SDK supports properties that are Arrays
  for(var i=0;i<=100;i++){
         this.btns[i] = {};
         for(var meta in this.autoProperties){
          this.btns[i][meta] = this.autoProperties[meta];
          var setter = "set" + meta.charAt(0).toUpperCase() + meta.slice(1) + i; // Camel Case per SAPUI5 (e.g. setTitle0)
          var getter = "get" + meta.charAt(0).toUpperCase() + meta.slice(1) + i; // Camel Case per SAPUI5 (e.g. getTitle0)
          // Make setters and getters on the fly
          this[getter] = function(meta,i){
          return function(s){
              return this.btns[i][meta];
          };
          }(meta,i);
          this[setter] = function(meta,i){
          return function(s){
          this.btns[i][meta] = s;
          this.populateIcons();
          };
          }(meta,i);
         }
     }
  this.setStandalone(false);
  this.populateIcons();
  }catch(e){
  alert(e); // Aw snap
  }
  },
    btns : [], // Button Storage
    autoProperties : { // Button Properties and default values
    title : "",
    visible : false,
    enabled : false,
    icon : ""
    },
    // Override default getter for custom logic
    getButtonClickedTitle : function(){
    if(this.getButtonClicked() < 0) return "[Nothing Clicked Yet]";
  return this.btns[this.getButtonClicked()].title;
    },
    // Override the SAPUI5 setter so that we can instruct the component to redraw some buttons
    setShowCaptions : function(v){
  this.setProperty("showCaptions",v);
  this.populateIcons();
  },
  populateIcons : function(){ // Main button redraw routine
    this.removeAllItems(); // Blow away existing buttons
    for(var i=0;i<this.btns.length;i++){ // Recreate all buttons
    var b=this.btns[i];
    var bt;
    if(b && (b.title!=""||b.icon!="")){
    if(b.title=="sep") {
    bt = new sap.ui.commons.ToolbarSeparator();
    }else{
      var that = this;
    bt = new sap.ui.commons.Button({
                     text : this.getProperty("showCaptions")?b.title:"",
                     // lite : true,
                     tooltip : b.title,
                     enabled : b.enabled,
                     visible : b.visible,
                     icon : b.icon,
                     press : function(j){
                      return function(){
                      that.setProperty("buttonClicked",j);
                      that.fireDesignStudioPropertiesChanged(["buttonClicked","buttonClickedTitle"]); // SDK proxies these properties, must inform of change
                        that.fireDesignStudioEvent("onclick");
                      };
                     }(i)
      });
    }
    this.addItem(bt);
    }
    }
    }
});

I like this approach better because you can more directly bind the SAPUI5 properties to the SDK Properties exposed in contribution.xml, and override just where needed.  Also the component.ztl accounts for the SAPUI5 setters and getters notation (versus how the DIV handler uses a fluent setter/getter notation).

In the GitHub Repo, I also attached a sample Design Studio application project, to show how the functionality is identical to the original implementation using the DIV handler.

Hope this helps any other SAPUI5 guys out there who may wish to get their feet wet with Design Studio 1.2 SDK!

Enjoy.

To report this post you need to login first.

4 Comments

You must be Logged on to comment or reply to a post.

  1. Leandro Cardoso

    Hi Michael,

    Great post, I’m using it right now.

    I have one question, the component that i’m using a data source and I need to manipulate it.

    I don’t know where to put my code,

    I tried

    afterUpdate : function(){

      alert(“test”);

      },

    No luck, on the initDesignStudio the data source is not loaded yet, and

    renderer, i probably have to return something, because when i implement it, nothing shows up on the sIreen, what happens when i overwrite it?

    Best

    Leandro

    (0) 
    1. Mike Howles Post author

      The sapui5 handler does not make use of afterupdate.  You will have to handler any updates to properties in the setter.  For example, for metadata, a databound property, if you want to know when it changes, override the default getMetadata and setMetadata functions that are made for you with new ones.

      setMetadata : function(v){

           alert(“Hey there.”);

      },

      getMetadata : function() {

        …

      }

      You can learn more about UI5 getters and setters and how they are autocreated and overridden, such as above, in this link:

      Documentation/AdvancedTopics/OnTheFlyControlDefinition – SAPUI5 Wiki (TIP CORE User Interface)

      Also, do not confuse the metadata property of ui5 with the metadata property of Design Studio, they are two different things.

      (0) 
      1. Leandro Cardoso

        Michael,

        Thanks again for taking your time to help me.

        I noticed that the SAPUI5 respects the order if the properties created, so I coded what I needed on the last property.

        Now I’m having another problem, on the contribution.ztl file, I created the following code

        String getSelectedValue(){*

          return this.selectedValue;

          *}

        Which I fire when the value is changed on the combobox, with the following code.

        that.setProperty(“selectedValue”,that.getValue());

          that.fireDesignStudioPropertiesChanged([“selectedValue”]);

          that.fireDesignStudioEvent(“onchange”);

        But it always return undifined when I try to show the result of the function getSelectedValue.

        My code is here

        https://github.com/olafecorcam/com.leandro.gp.combobox

        I’ll also post a question on the forum.

        Best

        Leandro

        (0) 

Leave a Reply