- 02/04/2015 – Blog posted
- More Adaptive Layout Options?
- Panel-specific enhancements/Grid Support?
- Flow Layout?
Use Case #1
There was a recent/timely SCN topic thread (Jonas Duclos explaining a dilemma that exists today in Design Studio as it relates to Responsive/Adaptive layouts) posted by
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:
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:
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:
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:
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:
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’:
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’
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:
Moving on, let’s check out ‘Skinny’:
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’:
And finally, let’s check out ‘Cramped’:
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:
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 🙂
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:
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:
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!
- Responsive vs. Adaptive Design: What’s the Best Choice?
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.