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: 
mike_howles4
Active Contributor

I recently saw a question in the SAP BusinessObjects Design Studio space asking how to make a selectable version of the Simple Table example provided with the Design Studio SDK.  Below was my approach that others may find useful.

I began by simply copying the 'com.sap.sample.simpletable' project to a new one called 'com.sample.sapui5table'.  I then renamed all the references to the old component in the MANIFEST.MF, component.xml, component.ztl and component.js files.

Next, I decided instead of using HTML string fragments and JQuery syntax, that I would use the SAPUI5 table component so that I could utilize the row selection API and JSONModel to build in the data.  Below is the new component.js code


sap.designstudio.sdk.Component.subclass("com.sample.sapui5table.SAPUI5Table", function() {
  var that = this;
  var column1_data = null;
  var column2_data = null;
  var column3_data = null;
  var meta_data = null;
  var myUI5Table = null;
  var myModel = null;
  var concatenatedDimension = "";
    // Simple getter/setter
    this.rowClicked = function(value){
    if(value===undefined) {
    // Getter
    return concatenatedDimension;
    }else{
    // Setter (fluent interface)
    return this;
    }
    };
  
  this.rowChanged = function(evt){
  concatenatedDimension = "";
  var rowContext = evt.getParameters().rowContext;
  if(rowContext){
  concatenatedDimension = myModel.getProperty(rowContext+"/headingColumn");
  }else{
  concatenatedDimension = "";
  }
  that.firePropertiesChanged(["rowClicked"]); // SDK proxies these properties, must inform of change
  that.fireEvent("onclick");
  };
  this.init = function() {
  myUI5Table = new sap.ui.table.Table({
  selectionMode: sap.ui.table.SelectionMode.Single,
  rowSelectionChange : this.rowChanged
  });
  this.$().css("overflow-y", "scroll");
  myUI5Table.placeAt(this.$()); // Until SAP gives us an official way...
  };
  this.afterUpdate = function() {
  try{
  var tabularData = [];
  if(column1_data){
  for (var i = 0; i < column1_data.data.length; i++) {
  var newRow = {};
  var tuple = column1_data.tuples[i];
  var rowHeaderText = "";
  for (var j = 0; j < tuple.length; j++) {
  if (column1_data.selection[j] == -1) {
  rowHeaderText += " " + meta_data.dimensions[j].members[tuple[j]].text;
  }
  }
  rowHeaderText = rowHeaderText.replace("|", " "); // Delimiter used for multiple presentations
  newRow.headingColumn = rowHeaderText;
  newRow.col1 = formatValue(column1_data.data[i], column1_data.tuples[i]);
  if(column2_data) newRow.col2 = formatValue(column2_data.data[i], column2_data.tuples[i]);
  if(column3_data) newRow.col3 = formatValue(column3_data.data[i], column3_data.tuples[i]);
  tabularData.push(newRow);
  }
  }
  myUI5Table.removeAllColumns();
  if(column1_data){
  var columnHeaderText = "";
  for (var i = 0; i < column1_data.selection.length; i++) {
  var selectionIndex = column1_data.selection[i];
  if (selectionIndex != -1) columnHeaderText += " " + meta_data.dimensions[i].members[selectionIndex].text;
  }
  myUI5Table.addColumn(new sap.ui.table.Column({
  label: new sap.ui.commons.Label({text : "Concatenated Dimension"}),
  template: new sap.ui.commons.TextView().bindProperty("text", "headingColumn"),
  sortProperty: "headingColumn",
  filterProperty: "headingColumn"
  }));
  myUI5Table.addColumn(new sap.ui.table.Column({
  label: new sap.ui.commons.Label({text : columnHeaderText}),
  template: new sap.ui.commons.TextView().bindProperty("text", "col1"),
  sortProperty: "col1",
  filterProperty: "col1"
  }));
  if(column2_data){
  var columnHeaderText = "";
  for (var i = 0; i < column2_data.selection.length; i++) {
  var selectionIndex = column2_data.selection[i];
  if (selectionIndex != -1) columnHeaderText += " " + meta_data.dimensions[i].members[selectionIndex].text;
  }
  myUI5Table.addColumn(new sap.ui.table.Column({
  label: new sap.ui.commons.Label({text : columnHeaderText}),
  template: new sap.ui.commons.TextView().bindProperty("text", "col2"),
  sortProperty: "col2",
  filterProperty: "col2"
  }));
  }
  if(column3_data){
  var columnHeaderText = "";
  for (var i = 0; i < column3_data.selection.length; i++) {
  var selectionIndex = column3_data.selection[i];
  if (selectionIndex != -1) columnHeaderText += " " + meta_data.dimensions[i].members[selectionIndex].text;
  }
  myUI5Table.addColumn(new sap.ui.table.Column({
  label: new sap.ui.commons.Label({text : columnHeaderText}),
  template: new sap.ui.commons.TextView().bindProperty("text", "col3"),
  sortProperty: "col3",
  filterProperty: "col3"
  }));
  }
  myModel = new sap.ui.model.json.JSONModel();
  myModel.setData({modelData: tabularData});
  myUI5Table.setModel(myModel);
  myUI5Table.bindRows("/modelData");
  myUI5Table.setVisibleRowCount(column1_data.data.length);
  };
  }catch(e){
  alert(e);
  }
  };
  function formatValue(value, tuple) {
  if (value === null) {
  return "";
  }
  if (meta_data) {
  for (var i = 0; i < meta_data.dimensions.length; i++) {
  var strFormat = meta_data.dimensions[i].members[tuple[i]].formatString;
  if (strFormat) {
  // use CVOM library to format cell value
  sap.common.globalization.NumericFormatManager.setPVL(meta_data.locale);
  return sap.common.globalization.NumericFormatManager.format(value, strFormat);
  }
  }
  }
  return value;
  }
  // called from Additional Properties Sheet JavaScript file
  this.getMetadataAsString = function() {
  return JSON.stringify(this.metadata());
  };
  // property setter/getter functions
  this.column1 = function(value) {
  if (value === undefined) {
  return column1_data;
  } else {
  column1_data = value;
  return this;
  }
  };
  this.column2 = function(value) {
  if (value === undefined) {
  return column2_data;
  } else {
  column2_data = value;
  return this;
  }
  };
  this.column3 = function(value) {
  if (value === undefined) {
  return column3_data;
  } else {
  column3_data = value;
  return this;
  }
  };
  this.metadata = function(value) {
  if (value === undefined) {
  return meta_data;
  } else {
  meta_data = value;
  return this;
  }
  };
});

Next, I updated the component.xml file to hold the new properties of onclick and rowSelected:


<?xml version="1.0" encoding="UTF-8"?>
<sdkExtension xmlns="http://www.sap.com/bi/zen/sdk"
  title="SAP UI5 Table"
  version="1.0"
  vendor="SAP"
  id="com.sample.sapui5table">
  <component id="SAPUI5Table"
  title="SAP UI5 Table"
  icon="res/icon.png"
  handlerType="div"
  propertySheetPath="res/additional_properties_sheet/additional_properties_sheet.html"
  databound="true">
  <stdInclude kind="cvom" />
  <jsInclude>res/js/component.js</jsInclude>
  <property id="column1" type="ResultCellList" title="Column 1" group="DataBinding"/>
  <property id="column2" type="ResultCellList" title="Column 2" group="DataBinding"/>
  <property id="column3" type="ResultCellList" title="Column 3" group="DataBinding"/>
  <property type="ScriptText" title="On Row Click" id="onclick" group="Events"></property>
  <property type="String" title="Row Clicked" id="rowClicked" visible="false"></property>
  <initialization>
  <defaultValue property="WIDTH">100</defaultValue>
  <defaultValue property="HEIGHT">100</defaultValue>
  </initialization>
  </component>
</sdkExtension>

Finally, I updated the component.ztl with so that we can access the concatenated dimension in BIAL:


class com.sample.sapui5table.SAPUI5Table extends Component {
  /**
  Use to get Concatenated Dimension of row clicked
  */
  String getRowClicked() {*
  return this.rowClicked;
  *}
}

So, now bringing the component into DS, we can see that after binding some data and picking some columns (Column 1 being required, just like SAP's sample), we can see data:

You also so a 'On Row Click' even that you can write some BIAL script in.  Below is an example that will populate a Text label with the dimension value:

During runtime, we can see this in action:

As an added bonus, we can see some other native SAPUI5 Table functionality that you can leverage (rudimentary filtering and sorting):

As you can see, since DS SDK uses SAPUI5 under the hood, why not go ahead and leverage it instead of manually creating HTML tables by hand?

Resources:

SAPUI5 SDK - Demo Kit

SAPUI5 SDK - Table API Reference

Considerations:

DS 1.2 uses SAPUI5 1.12.7, so you'll want to find a copy of the API docs on SAP SWDC since the online API docs are a higher version, but most of the API works as a starting point of reference.

SAP has stated that they will offer a more "official" way to use and extend SAPUI5 components, but for now, this seems to work while we patiently wait.

Hope this helps!

42 Comments
Labels in this area