Date: Thu, 28 Mar 2024 22:08:08 +0000 (UTC) Message-ID: <485215073.10795.1711663688883@911f0a1bad02> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_10794_1493358174.1711663688883" ------=_Part_10794_1493358174.1711663688883 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
The Servoy Web Client has a pure HTML & CSS based UI that ru= ns in the Browser, while all the business logic is executed on the Applicat= ion Server.
=20With the UI running in the browser and being pure HTML and CSS, it lends= itself for customization.
=20Customization of the Web Client is possible in a view different ways:
=20This chapter explains the above mentioned techniques.
=20For each Form that is part of the designtime design of a Solution, Servo= y generates both a HTML and CSS template dynamically. These templates are f= illed with data at runtime.
=20The generated templates can be customized and stored in a specific locat= ion 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.
=20Viewing the templates
=20The dynamically generated templates are available through the browser at= {serverURL}/servoy-webclient/templates/default/{solutionName}/{formNam= e}.[html/css] and viewing the source of the page. The templates can al= so be accessed via WEBDAV.
=20Modifying the templates
=20The source of the template can be modified any preferred tool. When modi= fying the the templates, care must be taken not to alter any of the identif= iers used by Servoy to fill the template at runtime with data.
=20In case of a CSS template, these will be all the ID's used on the StyleC= lasses, for example the ID "form_frm_company" in the sample below:
=20#form_frm_= company { =09border-style: none; =09min-width: 800px; =09min-height: 600px; =09position: absolute; =09top: 0px; =09left: 0px; =09right: 0px; =09bottom: 0px }=20
In case of editing HTML templates, these are the "id" and "servoy:id" at= tributes on the nodes in the sample below:
=20<!DOCTY= PE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/= TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!-- Servoy webclient page Copyright 2011 Servoy --> <html xmlns:servoy> <head> <title>dialog - Servoy</title> <servoy:head> </servoy:head> </head> <body id=3D'servoy_page'> <form id=3D'servoy_dataform'> <servoy:panel> <div servoy:id=3D'servoywebform' id=3D'form_dialog'> <div id=3D'sfw_form_dialog' style=3D'position: absolute; height: 0p= x; right: 0px; left: 0px;'/> <div id=3D'sfh_form_dialog' style=3D'position: absolute; bottom: 0p= x; top: 0px; width: 0px;'/> <div servoy:id=3D'View'> <div servoy:id=3D'sv_5636ffed_4465_43f0_97bb_23a7d800942f' id=3D's= v_5636ffed_4465_43f0_97bb_23a7d800942f' class=3D'formpart'> <div servoy:id=3D'sv_da70a6fe_39c8_445b_88bc_7aca5c1bb0b6' class= =3D'tabpanel' > <div servoy:id=3D'webform' style=3D'overflow: auto;position: rel= ative' class=3D'webform' ></div> </div> <div style=3D"white-space: nowrap;" servoy:id=3D'sv_1e460f7= 3_5cac_4396_815a_c09af002918e' class=3D'label' ></div> <div style=3D"white-space: nowrap;" servoy:id=3D'sv_5eae220= 0_ae8d_4100_844b_4d825775f1d3' class=3D'label' ></div> <div servoy:id=3D'sv_1399876f_ed4f_410e_a7e7_91839bd7390c_wrapper= ' id=3D'sv_1399876f_ed4f_410e_a7e7_91839bd7390c_wrapper' > <button type=3D'submit' servoy:id=3D'sv_1399876f_ed4f_410e_a7e7_= 91839bd7390c' class=3D'button' ></button> </div> <div servoy:id=3D'sv_8fb398c4_064f_4222_82b9_74f4fdc8410e_wrapper= ' id=3D'sv_8fb398c4_064f_4222_82b9_74f4fdc8410e_wrapper' > <button type=3D'submit' servoy:id=3D'sv_8fb398c4_064f_4222_82b9_= 74f4fdc8410e' class=3D'button' ></button> </div> <div servoy:id=3D'sv_5bdbe19a_0e8b_407d_855e_28c97dcade9e_wrapper= ' id=3D'sv_5bdbe19a_0e8b_407d_855e_28c97dcade9e_wrapper' > <button type=3D'submit' servoy:id=3D'sv_5bdbe19a_0e8b_407d_855e_= 28c97dcade9e' class=3D'button' ></button> </div> </div> </div> </div> </servoy:panel> </form> </body> </html>=20
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.
= =20Inside the HTML Templates Servoy uses long UUID's as ID's, for example "= sv_5636ffed_4465_43f0_97bb_23a7d800942f", sometimes postfixed with "_wrappe= r": these ID's match the UUID of the objects as available through the Solut= ionModel's API. At runtime however, these ID's are replaced with dyna= mically generated short ID's.
=20The = ID of the HTML node representing a Form or Element in the Web Client at run= time can be retrieved at runtime through the WebClientUtils plugin.
=20Storing modified templates
=20When modified, the templates need to be stored in the following location= to be picked up by Servoy at runtime:
=20\{servoyIn= stall}/application_server/server/webapps/ROOT/servoy-webclient/templates/\{= subdir}/\{solutionName}/\{formName}.[html/css].=20
Creating multiple sets of customizations
=20The '{subdir}' part of the location is the 'default' directory by defaul= t, but it is possible to create another subdirectory in the {serv= oyInstall}/application_server/server/webapps/ROOT/servoy-webclient/template= s/ 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:
=20applicatio= n.setUIProperty(APP_WEB_PROPERTY.WEBCLIENT_TEMPLATES_DIR, 'customDirectoryN= ame');=20
This mechanism allows for creating multiple variations of the templates,= for example one variation per customer in a SaaS environment.
=20The pitfall of modifying HTML Templates
=20Modified templates become out of sync with the design of the Form as soo= n as the Form is altered in Servoy Developer. When this happens, the modifi= ed temaplte needs to be removed and the then dynamicaly generated tem= plate needs to be modified and stored in the correct location again.
=20Besides the Form HTML and CSS, there is also the "servoy_web_client_defa= ult.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.
=20For an example customization of the "servoy_web_client_default.css" temp= late see the Alternative CSS for Web Clie= nt project on ServoyForge .
=20For = branding some of the generic web pages that are part of the Servoy environm= ent and are utilized by the Web Client, see Branding.
=20One of the standard UI widgets in Servoy in an HTMLArea. This widget pro= vides one of the ways to interact with the browser environment, as it has s= ome special behavior when set to not editable and used in the Web Client.= p>=20
Foremost, the non-editable HTMLArea is meant to render the HTM= L string contained in the dataprovider attached to the HTMLArea.
=20The special behavior comes in when the HTML string contained in the data= provider contains specific specific values for certain attributes on specif= ic HTML tags:
=20The= HTML string in the dataprovider attached to the non-editable HTMLArea need= s to be valid XHTML, as it needs to be parsed and processed in order to per= form the above mentioned rewrites
=20Example 1
=20The following example renders the latest 100 tweets from the servoy twit= ter account in the non-editable HTMLArea.
=20The code snippet show a variable called 'html' being filled with a custo= m HTML string. The technique used here to create the HTML string is using a= n XML object, on which .toXMLString() is called to convert it into a String= .
=20As the code of the initTweet function contains invalid characters for XM= L, the code is wrapped in a CDATA tag. The CData opening and closing tags a= re to be removed from the actual HTML string that is put in the 'html' vari= able for Servoy to be able to correctly parse and inject the HTML string in= to the Web Client's HTML markup.
=20The tweet stream is initialized through the calling of the initTweets() = function through the onload event on the body.
=20The required libraries for this example are stored in the Media Library = of Servoy.
=20While sto= ring 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 th= e Solution design and thus will be loaded into memory in each client. In ca= se of the Smart Client this means that the libraries will also be downloade= d, while they have no use in the Smart Client.
=20var html = =3D (<html> <head> <script src=3D"media:///jquery-1.6.2.min.js" type=3D"text/javascr= ipt"></script> <!--JQuery Tweet plugin: http://tweet.seaofclouds.com/--> <script src=3D"media:///jquery.tweet.js" type=3D"text/javascript">&= lt;/script> <style src=3D"media:///jquery.tweet.css" media=3D"all" rel=3D"styleshe= et" type=3D"text/css"/> <script type=3D'text/javascript'> <![CDATA[ function initTweets() { $(".tweet").tweet({ 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} - {repl= y_action} - {favorite_action}</span>' }).bind("empty", function() { $(this).append("No matching tweets found= "); }); } ]]> </script> </head> <body onload=3D"initTweets()"> <div class=3D"tweet" style=3D"width: 100%; height: 100%"></div&g= t; </body> </html>).toXMLString().replace(']]>', '').replace('<![CDATA[', = '');=20
While thi= s 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 scen= ario's. The logic of Servoy is as such that it will only conditionally incl= ude 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 htm= l of this example and forcing Servoy to include the JQuery library it ships= using the WebClientUtils plugin.
=20Example 2
=20This example shown the creation of a callback to the Web Client business= logic that runs on the Server.
=20Inside the body a button is placed with a onclick event handler that is = prefixed with "javascript:", followed by a global method called "myCoordina= tesCallbackMethod" that should be defined in the Solution.
=20The call to "globals.myCoordinatesCallbackMethod()" in the onclick handl= er 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 v= alue.
=20The "browser:" prefix on the argument indicates that the value of a brow= ser-side variable should be included in the callback.
=20The doCallback() function is a little helper function that can be called= by browser-side logic to programmatically perform the click on t= he button.
=20Through the style attribute on the button, the button is made invisible = to the user, while remaining programmatically clickable.
=20var html = =3D (<html> <head> <script> <![CDATA[ var x =3D 10; var y =3D 10; function doCallback() { document.getElementById("myCoordinatesCallbackHandler").click() } ]]> </script> </head> <body> <button id=3D"myCoordinatesCallbackHandler" onclick=3D"javascript:glob= als.myCoordinatesCallbackMethod(browser:x, browser:y, false)" style=3D"visi= bility: hidden"> </button> </body> </html>).toXMLString().replace(']]>', '').replace('<![CDATA[', = '');=20
When usin= g the 'browser:' syntax to send back String values, the parameter = needs to be double-quoted. Make sure to use single quotes to surround the o= verall event handler code:
=20onclick=3D= 'javascript:globals.myZipCodeCallbackMethod(\"browser:zipcode\")';=20
Example 3
=20Servoy hosts a Google Maps integration sample solution. For more informa= tion on this example see Goog= le Maps.
=20The WebClientUtils plugin is a plugin = that is not part of the default distribution of Servoy, but is hosted on ServoyForge.
=20The plugin adds the following capabilities to the Servoy environment:
=20plugins.We= bClientUtils.addJsReference(SERVOY_WEB_RESOURCES.JQUERY)=20