Skip to Content
Author's profile photo Michael Howles

Design Studio 1.6 SDK – Component Layouter

Change Log

  • 02/04/2015 – Blog posted

Planned Enhancements

  • More Adaptive Layout Options?
  • Panel-specific enhancements/Grid Support?
  • Flow Layout?

Description

Use Case #1

There was a recent/timely SCN topic thread (Panel Component and Responsive Design) posted by Jonas Duclos explaining a dilemma that exists today in Design Studio as it relates to Responsive/Adaptive layouts

Specifically this part:

“My screen have to be split in 2. I want to have a top Panel and a bot Panel. (50%/50% size)

Then i want to have the possibility to hide the top Panel by clicking a button, in order to let the other panel take the full screen (Panel with a graph component).”

“I know the best practice is to use a Grid Layout (in my case with 2 rows with same dimension).

But how can i hide the top row and let the bot row take all the screen if i use a grid layout ? There is no way in Design Studio to change the height of Grid Layout’s Rows or Columns by scripting.”

As perhaps others have come to find, the Design Studio Grid Layout component can be very beneficial at times, but also frustrating at other times.  If you use the Grid Layout component, you are essentially trapped into using a Matrix Layout with a small amount of flexibility in terms of sizing only Rows at Design Time only, and then you really don’t have a lot of control over Column Widths without resorting to BIAL sizing math as a workaround, etc etc etc…

Use Case #2

What about times where you’d like to re-orient, re-position, or hide/show components based on either current browser dimensions, or device type?  Karol Kalisz in the past has provided us the popular Design Studio SDK: Client Information Component that provides you a lot of this information that you can leverage in BIAL scripting and eventing to perform a lot of this logic at the scripting level.  Or, in combination with his also popular Flow Layouter Component  (Responsive Layout with Flow Layouter SDK), achieve near-responsive layout functionality.  In addition, Karol’s done some very cool BIAL/ZTL work that I learned a lot from in his document here: Design Studio SDK: Component Manager (for dynamic component access)

I think these are all terrific components even present-day, however Karol’s approach does rely on a decent amount of BIAL scripting, which some may find a little daunting.  What if we were take take some of the pieces of this and offer design-time spin on it, what could we do?

Use Case #3

Percentage-based Width/Heights and Margins.  Enough said.

Component Layouter is Born

Taking queue from Karol’s ‘Flow Layouter’ and ‘Client Information’ and ‘Component Manager’, I present ‘Component Layouter’ πŸ™‚

Let’s start with a simple DS App layout:

/wp-content/uploads/2016/02/adapt1_881555.png

In the component outline under ‘Layout’, we see a Crosstab (not pictured), 2 Charts, and a Navigation Panel.  Pretty simple layout, and if we stop to consider how we’d take a responsive approach with delivered components to have things resize nicely, you could consider a Grid Layout, with 2 Rows of equal height, and 1 Column, and things would resize pretty decently…  But what about when this happens in that scenario:

/wp-content/uploads/2016/02/adapt2_881556.png

Suddenly, that useful navigation panel when real-estate is at a premium is no longer so useful.  We could certainly add a show/hide Navigation Panel button with some script commands somewhere, and that is definitely fine, but what if your browser window was wider than it was taller, and you’d really like those charts to show up side-by-side?  Maybe you don’t ever want the drag-and-drop unfriendly Navigation Panel to ever show up on something like a mobile device?

So how could we solve this with Component Layouter?

First, let me describe what Component Layouter is from an SDK perspective, it is a DIV handler component that is visible at Design Time, but not shown at Runtime.  Even with the introduction of invisible ‘Technical Components’ with 1.6 SDK, I could not make this one hidden, as the Additional Properties Sheet does not work with Technical Components (aside from one sneaky way of ‘tricking’ the APS to show up but not a feasible trick to ask of designers) – So for now, it must be a visible component.  See below:

/wp-content/uploads/2016/02/adapt3_881557.png

Pictured above, we can see the Component Layouter selected in blue, and more importantly the APS on the right.  Below is a larger excerpt, followed by a description:

/wp-content/uploads/2016/02/adapt4_881559.png

We have 4 profiles I have created by using the ‘New Profile’ button.  I have given each profile a descriptive name indicating the scenario.

  • ‘Default’ has a Minimum required Width of 600 and Minimum required Height of 400, meaning that it would not be applied at browser sizes below that.
  • ‘Short’ would accommodate heights below 400.
  • ‘Skinny’ would accommodate widths below 600 but not shorter in height than 400.
  • ‘Cramped’ would accommodate when width was below 600 AND height being below 400.

Note that widths and heights of -1 means ‘rules do not apply’ and are not checked.

Also, I am detecting popular Device types and OS based on browser agent information.  These have also optionally been incorporated into the profiles, if so wished to be used.  Below are the options:

/wp-content/uploads/2016/02/adapt5_881560.png

For this example, I’m leaving these set to ‘Any’ for all 4 profiles, but based on testing in Chrome with device emulation of an Android and iOS devices, this worked nicely.

Also of note in the APS screenshot above, you will see something called an ‘Item Filter’.  By default, no items are checkmarked and you must decide which components you wish to incorporate into your Component Layouter logic.  Why?  BI Apps become increasingly component-heavy, and I see no point in taking measurements of 60 components when you may only need to mess around with 5 of them, as an example.

Speaking of ‘messing around’ – I am NOT touching the browser DOM, as this has been said is a big no-no by SAP.  Any re-positioning of components that is being done, is all being done using ZTL/BIAL code to maintain browser and application state integrity.  I am also NOT making or hacking together my own container.  Everything is using as standard (as possible) SDK conventions.  That being said, I do perform some unobtrusive Rhino-JS inspections to pull out a list of Components in the canvas, as well as at runtime, inspecting width/height measurements of the browser window and Panel components so that the script layer can make correct determinations on sizes when it comes to percentages.  So speaking of percentages, let’s look at the details in the first profile ‘Default’:

/wp-content/uploads/2016/02/adapt6_881564.png

As you can see, 3 components are listed, Crosstab is not shown, as we’ve chosen to filter it out as we are not interested in resizing it.  What you can see here is I am saying I basically want the Navigation Panel to occupy 25% of the width of its container (in this case, the root of the application, but it works inside Panels, also).  I am also then saying I want the Left Margin of the 2 charts to begin at 25% of the window, essentially flush with the Navigation Panel.

Next, let’s look at ‘Short’

/wp-content/uploads/2016/02/adapt7_881565.png

What this is saying, is that when short is applied, make Chart 1’s width 62% and then move Chart 2 next to it and occupy it space to the right, so that they are now next to each other instead of on top of each other like so:

/wp-content/uploads/2016/02/adapt8_881566.png

Moving on, let’s check out ‘Skinny’:

/wp-content/uploads/2016/02/adapt9_881567.png

This basically is saying let’s hide the Navigation panel and stack the Charts on top of one another to occupy 50% space.  Note that Navigation Panel has ‘unchanged’ listed in its positions (which is the default properties for all fields) – This is useful when you only know you will be messing with visibility and not position/size, and vice-versa.  Just makes things a little more maintainable.  Below is the runtime example of ‘Skinny’:

/wp-content/uploads/2016/02/adapt10_881568.png

And finally, let’s check out ‘Cramped’:

/wp-content/uploads/2016/02/adapt11_881569.png

As you can see here, this basically hides everything but the Chart 1 and allows it to take up all available space.  Below is the (obvious) example:

/wp-content/uploads/2016/02/adapt12_881573.png

In summary, hopefully this serves as a useful example of how you could create an Adaptive UI without a single line of script that hopefully seems intuitive.  But what about more complex adaptive layouts that could not be achieved with these straightforward cases?  There’s an event for that πŸ™‚

/wp-content/uploads/2016/02/adapt13_881574.png

We have 3 items here.  ‘Monitor Resizes’ is what checks the browser for any resizes and then checks against the profiles to determine if it is time to switch.  You can disable this, if you wish.  By disabling, this means it is up to you the designer, to apply profile changes based on your own script logic, with a command such as:

/wp-content/uploads/2016/02/adapt14_881575.png

Pretty simple.  Next, I exposed an ‘On Profile Change’ event.  This fires if you are monitoring resizes.  Why would we need this event if we are managing component sizes in the profiles?  Because it’s not always so straightforward.  Imagine a case where it’s data selection or filter value-specific or whatever.  Maybe you are not managing ANY components in the Item Filter and thus your profiles have no components.  It is still useful to fire the profile event, and then perform your script logic which may be doing other complex logic.  So scripting definitely has its place here.

And finally, I have an ‘On Resize’ event which I may or may not leave in…  This event fires whenever the browser is resized and you can get a few properties of use:

/wp-content/uploads/2016/02/adapt15_881585.png

I feel like Karol’s ‘Client Information’ component already provides this and more, so this is a little redundant anyway, but it’s here in this sneak peak for now πŸ™‚

In closing, here is a video of the simple example at runtime:

Is this Responsive or is this Adaptive?

You know, I have no idea.  Maybe neither.  Or both.  I’m as confused as you are if you are asking.  Check these links out and decide for yourself!

What you have seen is nearly complete and should be available for download in the usual spot (details here: SCN Design Studio 1.6 SDK Components (ver 3.0)) by tomorrow.  Questions/Comments/Feedback always welcomed.

Assigned Tags

      23 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Hey Mike,

      That's awesome ! I achieved something similar using CSS and media queries ... Full CSS relative position. It was a bit tough.

      Your solution simplifies everything. I am so eager to test it.

      Great work, as always !

      Author's profile photo Michael Howles
      Michael Howles
      Blog Post Author

      Thanks, Franck πŸ™‚ - I went ahead and added to the stable and preview builds, go give it a shot.  There may be a few odd behaviors with resizing on some occasions when you have stuff nested in Panels in certain scenarios, but that's what testing is for is to make it better so give it a shot and let me know if it's headed in the right direction!

      Author's profile photo Former Member
      Former Member

      Hi Mike,

      I tried downloaded and imported it. It is not working in DS 1.6 after import. Can you please check?

      Thanks

      Veeraraghavan

      Author's profile photo Michael Howles
      Michael Howles
      Blog Post Author

      It is working for me.  What does 'not working' mean?  Can you try to download the latest and let me know?

      EDIT - I see what has happened I think, I've committed a correction and will get it bundled in next release.

      Bug fix for ComponentLayouter · org-scn-design-studio-community/sdkpackage@10f2e4b · GitHub

      EDIT 2: Fixed and updated in download link.

      Author's profile photo Former Member
      Former Member

      Hi Mike

      That would be a nice component. But I tried in Design Studio 1.6 and it does not work. Maybe I did something wrong although I followed your steps. How are the Top, bottom, left and right margin and width and height of the two charts when you paste it in? Or is there a bug in DS 1.6?

      Thanks for your help

      Author's profile photo Michael Howles
      Michael Howles
      Blog Post Author

      I think I would need more information when you say it is not working.  The examples and video in my post are working.  Maybe you can provide screenshots or details for me?

      EDIT - I see what has happened I think, I've committed a correction and will get it bundled in next release.

      Bug fix for ComponentLayouter · org-scn-design-studio-community/sdkpackage@10f2e4b · GitHub

      EDIT 2: Fixed and updated in download link.

      Author's profile photo Former Member
      Former Member

      Hey Mike Howles,

      I'm using the latest stable build and the "New Profile" button doesn't work in 1.6 SP01 Patch 2 - nothing happens when I click the button!

      I also receive the following error regularly - "TypeError: Unable to get property 'length' of undefined or null reference"

      Cheers,

      Dan

      Author's profile photo Michael Howles
      Michael Howles
      Blog Post Author

      I'll take a look.

      Author's profile photo Former Member
      Former Member

      I get exactly the same errors on the same DS version & patch.

      Regards

      Kruno

      Author's profile photo Michael Howles
      Michael Howles
      Blog Post Author

      I just tried what Daniel GROOM mentioned with SP1 Patch 2, and it works fine for me.

      Can you guys try:

      1. Clear IE cache and restart Design Studio
      2. Try with a new BI App with just something simple in it like a Button and see if you can click Add Profile, maybe there's a specific type of DS component that it does not like?

      Thanks, sorry for whatever is causing error.

      Author's profile photo Former Member
      Former Member

      It works fine when I select the Blank template, but fails if I use any other template.

      Author's profile photo Former Member
      Former Member

      The problem seems to be related to the TEXT_POOL technical component in

      basic layout.

      /wp-content/uploads/2016/04/compl1_927697.png

      If I remove TEXT_POOL it works, I can add new profile

      /wp-content/uploads/2016/04/compl2_927773.png

      Edit:

      The problem also manifest itself with some other Technical components, GLOBAL_SCRIPTS for example

      /wp-content/uploads/2016/04/compl3_927774.png

      Author's profile photo Former Member
      Former Member

      Thanks for the info Kruno, appreciate your debugging efforts on this!

      Author's profile photo Michael Howles
      Michael Howles
      Blog Post Author

      Thanks for hunting this one down, guys.  Either me or Karol can probably make Component Layouter ignore Text Pool so that it doesn't crash out on you in subsequent release.

      Author's profile photo Karol Kalisz
      Karol Kalisz

      hmm, I have debugged it. for quick solution - the loop ignores components with names

      * equal to "TEXT_POOL"

      * equal to "CONTEXT_MENU"

      * starting with "GLOBAL_SCRIPT"

      the third one is not optimal, as it means - all global scripts must be named "GLOBAL_SCRIPT*" and no components can be called so.

      root cause is difficult to find, those delivered technical components are not responding to the check if some methods are available (this is how we recognize if it is a component).

      new version will be produced (in 2 hours online)

      Karol

      Author's profile photo Karol Kalisz
      Karol Kalisz

      Hi,

      I have created quite simple example, see applications/SCN_LAYOUT-20160411184058.zip at master. you can import it in DS and press the first button - the other 4 buttons should move different directions.


      I suspect, something is wrongly configured in your all, perhaps you can export it (please some basic version) and share. Also, you should see the exception in error log, you can post it.


      Karol

      Author's profile photo Sanjeev Kumar
      Sanjeev Kumar

      Hi Mike,

      Great blog!  I already tried the Component Layouter and it works great in local mode.  Unfortunately nothing is showing up when I run it on BI platform.  I followed all the steps until restarting APS to install this component on BI platform.  Can you provide any clue what I might be missing?

      Regards

      Sanjeev.

      Author's profile photo Former Member
      Former Member

      Hi Mike,

      first of all great blog! I've got a challenge with the component layouter. My dashboard consists of several panels and each panel contains a chart and crosstab. Each panel is accessed by pressing a button. I've created one profile with your component layouter containing all the objects/panels and the initial panel works fine. However when I press the button to go to a different panel then it doesn't show me a crosstab and chart, only after I resize the browser screen they pop-up. Am I missing something or does the component layouter not support switching panels?

      Regards,

      Jeroen.

      Author's profile photo Michael Howles
      Michael Howles
      Blog Post Author

      Hey Jeroen, thanks for the feedback.

      Yes, indeed the Component Layouter only evaluates your profile rules when a resize occurs, however if you are performing panel switching, you can manually have it load your profile by using script such as:

      COMPONENTLAYOUTER_1.loadProfile("yourprofilename");

      This should make the Component Layouter do its thing manually (since presumably you are already doing script in your button, this should just be the one line of code)

      Author's profile photo Former Member
      Former Member

      Hi Mike,

      thanks for the reply. Yes, I've tried using that in my button script, but alas no luck, still only works after manually resizing the browser.

      Author's profile photo Michael Howles
      Michael Howles
      Blog Post Author

      Hey Jeroen,

      Can you try these 2 lines instead then?:

      COMPONENTLAYOUTER_1.loadProfile("somedummyprofilename");

      COMPONENTLAYOUTER_1.loadProfile("yourprofilename");

      Author's profile photo Former Member
      Former Member

      For now I put everything in the one panel (body) and implemented visibility (true/false) settings for each component in it. Then the component layouter works correctly. It seems that the layouter has issues when switching between panels or pages and you're using percentages for width/height etc.

      Kind regards,

      Jeroen.

      Author's profile photo Former Member
      Former Member

      Dear Mike,

      I used this component and found very impressive, but I am facing problem onΒ IPhone/IPad devices while switching among different profiles. For example, initially it load profile accurately but when I rotate the device profile change event is not being fired and no other profile gets loaded, instead my old profile get disturbed and components get scattered.

      On Android/ Windows devices its working fine.

      Your expert opinion is requested in this regard.

      Kind Regards,

      Imran