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: 
Former Member

Hello,

I would like to share with you a method for implementing dynamic styles on any components, either standard or not, through 2 examples. It requires good scripting and CSS knowledge.

Pros:

  • No DOM hacking/modifications: No other component HTML code is modified
  • Only CSS, but very powerful:  Any part of the application can be accessed with the selectors
  • Dynamic: Can be controlled by the application
  • Compatible with IE and Chrome: Works like a charm in both

What do you need ? Rapid Prototyping Component from the SCN SDK Community Package For Design Studio !

These other components are optional:

  • Array: Only way to have a real global table in your application (except storing it in CSV String format)
  • Data Iterator: If you want to link the CSS to Datasource data

Don't hesitate to download the test application shown below here (Build for DS 1.6 SP2 P1)

Here's a quick demo with some comments:

PS: sorry for my french accent

Use-case 1: Custom Color Palette

I wanted to get a full color customizable color palette in DS. To do that, I used:

  • Buttons: up, down, +, delete etc ...
  • Array component: easy manipulation of the entries
  • Palette component to let the user choose the color

The last important feature would be to change the color of each list element:

Without the CSSWith CSS dynamically generatedCSS code

<style>

.colorList li:nth-child(1) * {background-color:#ff5d17 !important;}

.colorList li:nth-child(2) * {background-color:#ff8d00 !important;}

.colorList li:nth-child(3) * {background-color:#ffd141 !important;}

.colorList li:nth-child(4) * {background-color:#23b7ff !important;}

.colorList li:nth-child(5) * {background-color:#0092ff !important;}

</style>

It's actually quite easy to generate the CSS to get this display. Each entry of the list is a LI, and we just need to address each of the with its line number (using li:nth-child() selector) and apply the associated background color.

You can also use the attribute data-sap-ui-lvx-index the selector nth-child :smile:

HTML Code associated to the list:


<div id="LIST_COLORS_ddlb" data-sap-ui="LIST_COLORS_ddlb" tabindex="-1" class="sapUiLbx sapUiLbxFixed sapUiLbxStd zenControl zenTempFixForListBox colorList" style="width: 200px; height: 100%;">
   <ul id="LIST_COLORS_ddlb-list" tabindex="-1" role="listbox" aria-multiselectable="false" aria-activedescendant="__item3">
      <li id="__item0" data-sap-ui="__item0" data-sap-ui-lbx-index="0" tabindex="-1" class="sapUiLbxI" title="#ff5d17" role="option" aria-selected="false" aria-setsize="5" aria-posinset="1"><span class="sapUiLbxITxt" id="__item0-txt" style="text-align:left">#ff5d17</span></li>
      <li id="__item1" data-sap-ui="__item1" data-sap-ui-lbx-index="1" tabindex="-1" class="sapUiLbxI" title="#ff8d00" role="option" aria-selected="false" aria-setsize="5" aria-posinset="2"><span class="sapUiLbxITxt" id="__item1-txt" style="text-align:left">#ff8d00</span></li>
      <li id="__item2" data-sap-ui="__item2" data-sap-ui-lbx-index="2" tabindex="-1" class="sapUiLbxI" title="#ffd141" role="option" aria-selected="false" aria-setsize="5" aria-ponset="3"><span class="sapUiLbxITxt" id="__item2-txt" style="text-align:left">#ffd141</span></li>
      <li id="__item3" data-sap-ui="__item3" data-sap-ui-lbx-index="3" tabindex="0" class="sapUiLbxI sapUiLbxISel" title="#23b7ff" role="option" aria-selected="true" aria-setsize="5" aria-posinset="4"><span class="sapUiLbxITxt" id="__item3-txt" style="text-align:left">#23b7ff</span></li>
      <li id="__item4" data-sap-ui="__item4" data-sap-ui-lbx-index="4" tabindex="-1" class="sapUiLbxI" title="#0092ff" role="option" aria-selected="false" aria-setsize="5" aria-posinset="5"><span class="sapUiLbxITxt" id="__item4-txt" style="text-align:left">#0092ff</span></li>
   </ul>
</div>






I just added .colorList class to the list and called this script each time a modification is done:


var style = "<style>\n";
//Loop on the different colors in the list (stored in an array)
ARRAY_COLORS.getValuesAsSimpleStringArray().forEach(function(element, index) {
  var ind2 = index + 1; //CSS index starts at 1 when array starts at 0
  //Generate a CSS style for each list entry, using nth-child to refer to each line
  style = style + ".colorList li:nth-child(" + ind2 + ") * {background-color:" + element + " !important;} \n";
});
style = style + "</style>";
TA_GEN_CSS.setValue(style);
if (!CB_CSS_PALETTE.isChecked()) {
  style = "";
}
//Include the CSS style in the HTML
RAPID_PROT_COLORS_CSS.setHTML(style);






Use-case 2: Crosstab customizing with indicators

Just to demonstrate we can also work on standard components, I will show you how to change alter the style of a cross tab like that:

Normal CrosstabCustomized Crosstab

Again, the CSS is different from DOM hacking, therefore limits any serious issues.

The most difficult part is to get the working CSS, and I recommend testing it in Chrome or IE in debug before.

The first cell (Billed quantity) needs to be referenced by this path:

     .dynamicCT #CROSSTAB_1_dataArea tbody tr:nth-child(1) td:first-child div.sapzencrosstab-DataCellContentDiv


The TR corresponds to each of the lines (and the number will need to be dynamic), the TD corresponds to the columns, i.e. Billed quantity, and finally the div contains the measure value.


The algorithm is:

  • Loop at each line
    • Calculate %variance between Current Year and Last Year Billed quantity
    • if %variance is greater than threshold then:
      • If negative: display a red down arrow in front
      • If positive: display a green up arrow in front
    • Add after the measure value the %variance in parenthesis

Note: that Pixel based display must be activated to work.

Note 2: The script is at the end.

So, as a conclusion, only the CSS functionalities and your imagination can limit what you can do. Please do comment if you like it or if you have any questions ! :wink:


Thank you for reading.


And finally the script:


//Data Iterator: get all the rows
var rows = DATA_IT.getRows();
//Get the threshold from the Input Field
var thresh_u  = Convert.stringToFloat(IF_THRESH.getValue());
var thresh_d  = thresh_u * -1;
//Start the Style Markup
var content = "<style>\n";
//Hide PY billed qty
content = content + " .dynamicCT table.sapzencrosstab-ColumnHeaderArea * tr.sapzencrosstab-HeaderRow td:nth-child(3) { display: none}\n";
content = content + " .dynamicCT #CROSSTAB_1_dataArea tbody tr td:nth-child(3) { display: none}\n";
//Loop at each entry from the datasource
rows.forEach(function(element, index) {
//Get measure Billed quantity and Previous Year Billed Quantity
  var mes = element.getMeasureValue("BILLED_QUANTITY");
  var mes_ly = element.getMeasureValue("PREV_BILL");
//always add 1 to the array index because the CSS starts at 1. This index will bu used to address the correct line
  var index2 = index + 1;
  var diffpc = 0.0;
//calculate the difference in percentage
  if (mes_ly != 0) {
     diffpc = (mes - mes_ly) / mes_ly * 100;
     diffpc = MATH_1.round(diffpc);
  }
  var sign = "";
  if (diffpc < thresh_d) {
  //Percentage value is below -Threshold
  var id = ".dynamicCT #CROSSTAB_1_dataArea tbody tr:nth-child(" + index2 + ") td:first-child div.sapzencrosstab-DataCellContentDiv:before ";
    content = content + id + " \n{ content:url(http://www.exilim.eu/global/images/red-arrow-down.png);}\n";
  } else if (diffpc > thresh_u) {
  id = ".dynamicCT #CROSSTAB_1_dataArea tbody tr:nth-child(" + index2 + ") td:first-child div.sapzencrosstab-DataCellContentDiv:before ";
    content = content + id + " { content:url(https://upload.wikimedia.org/wikipedia/commons/4/48/Icons-mini-arrow_up.gif);}\n";
    sign = "+";
    }
    id = ".dynamicCT #CROSSTAB_1_dataArea tbody tr:nth-child(" + index2 + ") td:first-child div.sapzencrosstab-DataCellContentDiv:after ";
    content = content + id + " \n{ content:' (" + sign + diffpc  + "%)';}\n";
});
content = content + "</style>";
TA_GEN_CSS2.setValue(content);
if (!CB_CSS_CT.isChecked()) {
  content = "";
}
//Insert the HTML content in the page
RAPID_PROT_COLORS_CSS2.setHTML(content);






11 Comments
Labels in this area