Child pages
  • Customizing the Web Client

Versions Compared


  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

The Servoy Web Client has a pure HTML & CSS based UI that runs in the Browser, while all the business logic is executed on the Application Server.

With the UI running in the browser and being pure HTML and CSS, it lends itself for customization. 

Customization of the Web Client is possible in a view different ways:

  • Modifying the Form HTML & CSS templates
  • Changing the "servoy_web_client_default.css" template
  • Interacting with the browser environment through non-editable HTMLAreas
  • Interacting with the browser environment through the WebClientUtils plugin

This chapter explains the above mentioned techniques.


Customizing the Form HTML & CSS templates

For each Form that is part of the designtime design of a Solution, Servoy generates both a HTML and CSS template dynamically. These templates are filled with data at runtime.

The generated templates can be customized and stored in a specific location on the Servoy Application Server, using a name identical to the dynamic generated template. If a template is available on disk, that template will be used at runtime, instead of the dynamicly genarated template.

Viewing the templates

The dynamically generated templates are available through the browser at {serverURL}/servoy-webclient/templates/default/{solutionName}/{formName}.[html/css] and viewing the source of the page. The templates can also be accessed via WEBDAV.

Modifying the templates

The source of the template can be modified any preferred tool. When modifying the the templates, care must be taken not to alter any of the identifiers used by Servoy to fill the template at runtime with data.

In case of a CSS template, these will be all the ID's used on the StyleClasses, for example the ID "form_frm_company" in the sample below:

Code Block
	border-style: none;
	min-width: 800px;
	min-height: 600px;
	position: absolute;
	top: 0px;
	left: 0px;
	right: 0px;
	bottom: 0px

In case of editing HTML templates, these are the "id" and "servoy:id" attributes on the nodes in the sample below:

Code Block
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ""> 
<!-- Servoy webclient page Copyright 2011 Servoy --> 
<html xmlns:servoy> 
  <title>dialog - Servoy</title> 
 <body id='servoy_page'> 
  <form id='servoy_dataform'> 
    <div servoy:id='servoywebform' id='form_dialog'> 
     <div id='sfw_form_dialog' style='position: absolute; height: 0px; right: 0px; left: 0px;'/>
     <div id='sfh_form_dialog' style='position: absolute; bottom: 0px; top: 0px; width: 0px;'/>
     <div servoy:id='View'> 
      <div servoy:id='sv_5636ffed_4465_43f0_97bb_23a7d800942f' id='sv_5636ffed_4465_43f0_97bb_23a7d800942f' class='formpart'> 
       <div servoy:id='sv_da70a6fe_39c8_445b_88bc_7aca5c1bb0b6' class='tabpanel' > 
        <div servoy:id='webform' style='overflow: auto;position: relative' class='webform' ></div>
       <div  style="white-space: nowrap;" servoy:id='sv_1e460f73_5cac_4396_815a_c09af002918e' class='label' ></div> 
       <div  style="white-space: nowrap;" servoy:id='sv_5eae2200_ae8d_4100_844b_4d825775f1d3' class='label' ></div> 
       <div servoy:id='sv_1399876f_ed4f_410e_a7e7_91839bd7390c_wrapper' id='sv_1399876f_ed4f_410e_a7e7_91839bd7390c_wrapper' >
        <button type='submit' servoy:id='sv_1399876f_ed4f_410e_a7e7_91839bd7390c' class='button' ></button>
       <div servoy:id='sv_8fb398c4_064f_4222_82b9_74f4fdc8410e_wrapper' id='sv_8fb398c4_064f_4222_82b9_74f4fdc8410e_wrapper' >
        <button type='submit' servoy:id='sv_8fb398c4_064f_4222_82b9_74f4fdc8410e' class='button' ></button>
       <div servoy:id='sv_5bdbe19a_0e8b_407d_855e_28c97dcade9e_wrapper' id='sv_5bdbe19a_0e8b_407d_855e_28c97dcade9e_wrapper' >
        <button type='submit' servoy:id='sv_5bdbe19a_0e8b_407d_855e_28c97dcade9e' class='button' ></button>

Any additions that are to end up in the Header section of the generated HMTL Markup of the Web Client can be placed within the  tags.

Inside the HTML Templates Servoy uses long UUID's as ID's, for example "sv_5636ffed_4465_43f0_97bb_23a7d800942f", sometimes postfixed with "_wrapper": these ID's match the UUID of the objects as available through the SolutionModel's API.  At runtime however, these ID's are replaced with dynamically generated short ID's.

(info)  The ID of the HTML node representing a Form or Element in the Web Client at runtime can be retrieved at runtime through the WebClientUtils plugin.

Storing modified templates

When modified, the templates need to be stored in the following location to be picked up by Servoy at runtime:

Code Block

Creating multiple sets of customizations

The '{subdir}' part of the location is the 'default' directory by default, but it is possible to create another subdirectory in the  {servoyInstall}/application_server/server/webapps/ROOT/servoy-webclient/templates/ directory for storing the modified templates and at runtime in the Solution tell Servoy to use this directory insetad of the default directory using the following code:

Code Block
application.setUIProperty(APP_WEB_PROPERTY.WEBCLIENT_TEMPLATES_DIR, 'customDirectoryName');

This mechanism allows for creating multiple variations of the templates, for example one variation per customer in a SaaS environment.

The pitfall of modifying HTML Templates

Modified templates become out of sync with the design of the Form as soon as the Form is altered in Servoy Developer. When this happens, the modified temaplte needs to be removed and the then  dynamicaly generated template needs to be modified and stored in the correct location again.

Changing the "servoy_web_client_default.css" template

Besides the Form HTML and CSS, there is also the "servoy_web_client_default.css" template. This template contains the default CSS used for styling the forms and elements in a Web Client. Modifying this template will result in changing the overall look of a Solution int he Web Client.

For an example customization of the "servoy_web_client_default.css" template see the Alternative CSS for Web Client project on ServoyForge .

(info)  For branding some of the generic web pages that are part of the Servoy environment and are utilized by the Web Client, see Branding.

Interacting with the browser environment through non-editable HTMLAreas

One of the standard UI widgets in Servoy in an HTMLArea. This widget provides one of the ways to interact with the browser environment, as it has some special behavior when set to not editable and used in the Web Client.

Foremost, the non-editable HTMLArea is meant to render the HTML string contained in the dataprovider attached to the HTMLArea.

The special behavior comes in when the HTML string contained in the dataprovider contains specific specific values for certain attributes on specific HTML tags:

  • Servoy media URL's (media:///.....) inside Style tags or attributes are rewritten so they can be resolved in the browser
  • Servoy media URL's used in the 'src' attribute of Style, Script and IMG tags are rewritten so they can be resolved in the browser 
  • Script, Style and Link tags automatically end up in the head section of the DOM in the browser
  • Event handlers that in the HTML start start with "javascript:", followed by a Servoy method identifier are rewritten to perform a callback to the server
  • An onload event handler on the body of the HTML is executed in the browser when the DOM is ready

(warning)   The HTML string in the dataprovider attached to the non-editable HTMLArea needs to be valid XHTML, as it needs to be parsed and processed in order to perform the above mentioned rewrites

Example 1

The following example renders the latest 100 tweets from the servoy twitter account in the non-editable HTMLArea.

The code snippet show a variable called 'html' being filled with a custom HTML string. The technique used here to create the HTML string is using an XML object, on which .toXMLString() is called to convert it into a String.

As the code of the initTweet function contains invalid characters for XML, the code is wrapped in a CDATA tag. The CData opening and closing tags are to be removed from the actual HTML string that is put in the 'html' variable for Servoy to be able to correctly parse and inject the HTML string into the Web Client's HTML markup. 

The tweet stream is initialized through the calling of the initTweets() function through the onload event on the body.

The required libraries for this example are stored in the Media Library of Servoy. 

(warning)  While storing the libraries in the Media Library is convenient for deployment of the libraries with a Solution, the contents of the Media Library is part of the Solution design and thus will be loaded into memory in each client. In case of the Smart Client this means that the libraries will also be downloaded, while they have no use in the Smart Client.

Code Block
var html = (<html>
  <script src="media:///jquery-1.6.2.min.js" type="text/javascript"></script>
  <!--JQuery Tweet plugin:>
  <script src="media:///jquery.tweet.js" type="text/javascript"></script>
  <style src="media:///jquery.tweet.css" media="all" rel="stylesheet" type="text/css"/>
  <script type='text/javascript'>
  function initTweets() {
     username: "servoy",
     avatar_size: 32,
     count: 100,
     loading_text: "Getting you the latests tweets right now...",
     refresh_interval: 60,
     template: '{avatar}{text}<span>{time} - {retweet_action} - {reply_action} - {favorite_action}</span>'
     }).bind("empty", function() { $(this).append("No matching tweets found"); });
 <body onload="initTweets()">
  <div class="tweet" style="width: 100%; height: 100%"></div>
</html>).toXMLString().replace(']]>', '').replace('<![CDATA[', '');

(warning)  While this example will work on a simple Form, there is a risk of it breaking. This example includes JQuery. Servoy itself also utilizes JQuery in certain scenario's. The logic of Servoy is as such that it will only conditionally include JQuery conditionally when required. When that happens when this html is also being shown, there can be a conflict between the 2 JQuery inclusions. This issue can be easily solved by excluding the JQuery library in the html of this example and forcing Servoy to include the JQuery library it ships using the WebClientUtils plugin. 

Example 2

This example shown the creation of a callback to the Web Client business logic that runs on the Server.

Inside the body a button is placed with a onclick event handler that is prefixed with "javascript:", followed by a global method called "myCoordinatesCallbackMethod" that should be defined in the Solution.

The call to "globals.myCoordinatesCallbackMethod()" in the onclick handler is setup to send 3 arguments into the callback: the first two are local, browser-side variables "x" and "y", while the third is a hardcoded false value.

The "browser:" prefix on the argument indicates that the value of a browser-side variable should be included in the callback.

The doCallback() function is a little helper function that can be called by browser-side logic to programmatically perform the click on the button.

Through the style attribute on the button, the button is made invisible to the user, while remaining programmatically clickable.

Code Block
var html = (<html>
   var x = 10;
   var y = 10;
   function doCallback() {
  <button id="myCoordinatesCallbackHandler" onclick="javascript:globals.myCoordinatesCallbackMethod(browser:x, browser:y, false)" style="visibility: hidden">&nbsp;</button>
</html>).toXMLString().replace(']]>', '').replace('<![CDATA[', '');

(warning)  When using the 'browser:' syntax to send back String values, the parameter needs to be double-quoted. Make sure to use single quotes to surround the overall event handler code:

Code Block

Example 3

Servoy hosts a Google Maps integration sample solution. For more information on this example see Google Maps.

Interacting with the browser environment through the WebClientUtils plugin

The WebClientUtils plugin is a plugin that is not part of the default distribution of Servoy, but is hosted on ServoyForge.

The plugin adds the following capabilities to the Servoy environment:

  • Allows to force inclusion of some of the JavaScript libraries Servoy ships with: Servoy by default conditionally includes them onto the Web Client markup only when they are needed. If custom clientside logic requires the library to be available, this can be done using the following code:
    Code Block
    For an overview of the version of each JavaScript library that is bundled with Servoy, check the Servoy stack info
  • Allows to execute custom JavaScript clientside in the browser, using the .execueClientSideJS(...) fucntion
  • Allows adding class attributes to the markup of elements, using .setExtraCssClass(element, classAttribute). The extra class can then be references in custom StyleSheets added to the markup
  • Allows for generating callback scripts through .addCallback(), which can then be included into the markup through a non-editable HTMLArea or be part of the code executed client-side using the .executeClientsideJS(...)
  • Allows for marking elements as rendered: this hooks deeply into Servoy mechanism for updating the Web Client markup when something changes in the UI. When some custom client-side code modifies the HTML Markup, this change will not automatically be synced back to the server-side running Web Client. when the developer implements the sync using a callback to the Server, any changes made to the UI in the callback method on the server, would normally result in Servoy performing an automatic update of the Web Client's UI in the browser again, because it recorded the changes made in the callback event. By calling the .setRendered(..) on the element(s) that were changed in the callback event in order to sync their state with their state in the browser, Servoy will ignore the updated made to the elements, thus not updated them again in the Web Client's UI.