Can't find what you are looking for? Try these pages!

Blog

Introduction to WebApp Styling

By Harm Wibier

This is the first in a series of blogs about styling DataFlex web and mobile applications. Styling, as used here, refers to defining the visual appearance of controls used within Web Framework Applications.

One of the major advantages of using the DataFlex WebApp Framework is that it eliminates the need to master all the techniques and technologies involved in the creation of web and mobile applications. In case of the styling, the framework does this by providing a set of pre-defined themes that provide great looks for your applications. So, without knowledge outside of DataFlex itself, one can write good looking web applications.

Personal taste, company design standards and functional requirements can be reasons to go outside of what the framework delivers by default. Customizing the default style of DataFlex web and mobile apps is done using Cascading Styles Sheets (CSS) – an industry standard used all over the web. This series of blogs will not be a CSS tutorial as there are already numerous excellent on-line resources available for that (for example, http://www.w3schools.com/css/). Rather, we will focus on using CSS within the DataFlex framework to accomplish custom results.

The framework itself uses CSS to define the default styles and for a big part of its functionality. For example, hiding controls is done with the pbRender and pbVisible properties that actually change the display and visibility CSS styles tags. Within the DataFlex Framework, these properties are mapped to inline CSS styles set directly on the so-called Document Object Model (or DOM, the HTML elements in memory) by the JavaScript classes. Some other properties like pbPromptButton are translated into a specific CSS Classname being added to DOM elements. The pbPromptButton property of cWebForm adds the "WebFrm_HasPrompt" classname to the DOM structure which makes sure that the prompt button is actually shown. The CSS rules for this classname are defined in the System.css and Theme.css include files, where System.css is responsible for the basic functionality of hiding / showing the button and Theme.css for the cosmetics of that button. There is only one System.css that is always used and there are multiple versions of Theme.css representing the actual themes.

System.css and Theme.css usually use the same selectors, and it is the order in which the selectors are included that determines which rules are applied. The Theme.css is always included after the System.css, so if the selectors are equal, the rules of the theme override those of the system. The third and last include file that affects styling is Application.css. This file is empty when creating a new workspace and this is where minor styling customizations and styles for extensions of the framework can be placed, especially when using one of the default themes, as it is good to keep small customizations separate to ease the process of migrating to a newer version of DataFlex.

If the customizations get too big then you should consider making your own theme. The process of making your own theme is simple: just copy one of the existing theme folders and rename it into the name of your new theme. The Df_ prefix is reserved for the standard themes and we do not guarantee that the studio will not overwrite your changes if the theme name starts with Df_ so, we suggest not using the Df_ prefix for your themes.

To be able to write CSS for Web Framework Applications you need to get familiar with the framework’s HTML structure for your application. Here’s how the framework HTML structure is created: The HTML is generated by the JavaScript classes of the framework, and usually has the same nested structure as the control objects have in the DataFlex code. The HTML generation is a process that is divided over the control class and its base classes. There is an important difference between controls (like cWebForm, cWebButton, ..) and containers (like cWebPanel, cWebView, ..).



<div class="WebControl WebForm Web_Enabled" data-dfobj="oVendor.oWebMainPanel.oVendorAddress" style="float: left; clear: left; margin-left: 0%; width: 100%;">
<div class="WebCon_Inner WebCon_LeftLabel">
<label for="_df_53" style="text-align: right;">Street:</label>
<div style="-webkit-user-select: text;">
<div class="WebFrm_Wrapper">
<span class="WebFrm_Prompt"></span>
<div class="WebFrm_PromptSpacer">
<input type="text" name="oVendorAddress" value="" id="_df_53" placeholder="" title="Street Address." class="dfData_Text" maxlength="30" style="-webkit-user-select: text;">
</div>
</div>
</div>
</div>
</div>

The example above shows the HTML structure for a cWebForm with all of the CSS classes and inline styles applied to it. The elements outside of the <div class="WebFrm_Wrapper" are all generated by the cWebBaseControl class and are the same for other controls (like cWebButton, cWebCheckbox). These elements are used to render the label (psLabel, peLabelPosition, ..) and for the control positioning (piColumnIndex and piColumnSpan). The positioning properties mainly translate into the inline styles applied on the outermost div element. Looking at the outermost div element, we see that controls always have the WebControl CSS class applied and Web_Enabled (or Web_Disabled) is available depending on pbEnabled.



<div class="WebContainer WebPanel Web_Enabled" data-dfobj="oDemoTreeView.oLeftPanel" tabindex="-1" style="position: absolute; top: 0px; left: 0px; bottom: 0px; width: 400px;">
<div class="WebCon_Sizer" style="min-height: 865px;">
<div class="WebCon_Content">
<!-- This is where HTML of controls inside the panel goes -->
<div style="clear: both;"></div>
</div>
</div>

<div class="WebPanel_DividerVertical" style="right: 0px;"></div>
</div>

The example above shows the HTML structure of a cWebPanel with all the CSS classes and inline styles applied to it. Instead of WebControl we now see the WebContainer class being applied to the outermost element. The only thing containers have in common is that they all can contain controls or panels. All different types of containers have their own logic for positioning themselves.

So the challenge of styling web framework applications is to get to know the HTML structures generated by the JavaScript controls. What can be done from CSS is limited as the framework determines the structure and the positioning of controls. Styling web framework applications should be seen as skinning or theming which is different from to what most web designers are used to doing.

Second blog in the series: CSS Classnames

Blog updated: November 11, 2016