https://www.lianja.com/doc/api.php?action=feedcontributions&user=Yvonne.milne&feedformat=atomLianjapedia - User contributions [en]2024-03-28T14:00:01ZUser contributionsMediaWiki 1.23.15https://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-27T15:35:29Z<p>Yvonne.milne: /* Overview */</p>
<hr />
<div>=See Also=<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
=Overview=<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja visually build forms] in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
* LianjaScript/VFP<br />
* Python<br />
* JavaScript<br />
* Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
=Sample App: example_timeclock=<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
[[{{ns:file}}:standalone_uipres.png|left|link={{filepath:standalone_uipres.png}}|UI Presentation Rules and Standalone Options]]<br />
<br clear=all><br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include library files. When the standalone app is run the library directory is set to the standalone App library directory.<br />
<br />
The following text files are used to specify which library files should be included:<br />
<br />
===dependencies.txt===<br />
This is generated automatically when the App is [[#Building_and_Testing_Standalone_Executables|built]] if the App contains any [[:Category:WebView Based Sections|WebView Based Sections]].<br />
<br />
For example, the 'Tabbed Form' (form2) App, includes the following sections:<br />
*[[ArticleView Section Attributes|ArticleView]]<br />
*[[CatalogView Section Attributes|CatalogView]]<br />
*[[CommentsView Section Attributes|CommentsView]]<br />
*[[CarouselView Section Attributes|CarouselView]]<br />
*[[Calendar Section Attributes|Calendar]]<br />
<br />
and its dependencies.txt is generated as:<br />
<pre>@articleview<br />
@catalogview<br />
@commentsview<br />
@carouselview<br />
@calendar</pre><br />
<br />
The '@sectiontype' format references the corresponding 'sectiontype-dependencies.txt' file in the library containing the names of any required files and directories, e.g. catalogview-dependencies.txt:<br />
<pre>bootstrap-3.3.4<br />
jquery-1.10.2<br />
catalogview.*</pre><br />
<br />
===includes.txt===<br />
The 'includes.txt' file is used to specify any additional files that should be included.<br />
<br />
As in 'dependencies.txt' these can be:<br />
* folder names<br />
* individual file names<br />
* wildcards (like catalogview.*)<br />
* @filename to include the contents of '@filename-dependencies.txt'<br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create an installer as a self-extracting exe file for the standalone App. This can be unzipped / installed on a target machine.<br />
<br />
==Standalone Login==<br />
From v9.5, checking the 'Standalone Login' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include the files required for enabling login.<br />
<br />
To require login for access to the App, set the [[Form]].requireslogin property to true:<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.requireslogin = 1<br />
</code><br />
<br />
The login page can optionally be customized using the [[Form]].parameters property, e.g.:<br />
<code lang="recital"><br />
oform.parameters = "login.caption=Factory Time Clock;";<br />
+ "login._background=darkred;";<br />
+ "login.backgroundimage=img/wallpapers/background.png;";<br />
+ "login.version=Time Clock Version 1.0;";<br />
+ "login.copyright=Copyright (c) (2024) LianjaDev. All Rights Reserved Worldwide."<br />
</code><br />
<br />
[[{{ns:file}}:standalone_login.png|left|link={{filepath:standalone_login.png}}|Standalone Login Page]]<br />
<br clear=all><br />
<br />
==Standalone Python modules==<br />
From v9.5, checking the 'Standalone Python modules' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) indicates that the standalone App requires Python modules in the App.<br />
<br />
==Standalone Data==<br />
From v9.5, specifying a comma separated list of databases in the 'Standalone Data' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will copy the databases into the standalone App directory. When the standalone app is run the data directory is set to the standalone App data directory.<br />
<br />
==Setup==<br />
From v9.5, if the file setup.prg (or setup.py or setup.js) is contained within the App it is executed before the standalone App is run. You can check to see if the App is running standalone using [[Lianja|Lianja.standalone]] and check the file path using [[Lianja|Lianja.standalonefilepath]].<br />
<br />
You would typically do nothing in setup if the App is not running standalone.<br />
<br />
<code lang="recital"><br />
// this is called when the app runs to setup databases, tables etc.<br />
if not Lianja.standalone<br />
return<br />
endif<br />
<br />
set debugout on<br />
debugout "running setup.prg"<br />
debugout "filepath: "+Lianja.standalonefilepath<br />
<br />
if not databaseExists("factory")<br />
debugout "database factory does not exist"<br />
create database factory<br />
try<br />
open database factory<br />
create table employees;<br />
(badgeno char(30),;<br />
firstname char(30),;<br />
lastname char(30),;<br />
photo blob)<br />
insert into employees (badgeno, firstname, lastname);<br />
values ("A1234", "John", "Doe")<br />
create table timeclock;<br />
(badgeno char(30),;<br />
clockin datetime,;<br />
clockout datetime,;<br />
clockinphoto blob,;<br />
clockoutphoto blob)<br />
catch<br />
debugout "An error occurred"<br />
endtry<br />
endif<br />
<br />
close database <br />
<br />
debugout "setup completed successfully"<br />
<br />
<br />
</code><br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
=Building and Testing Standalone Executables=<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar.<br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
Here showing the [[#Standalone Login|login page]]:<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
and after login and entering a badge number:<br />
[[{{ns:file}}:standalone_exampletimeclock3.png|800px|left|border|link={{filepath:standalone_exampletimeclock3.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Lianja Standalone App Debugger==<br />
From v9.5 standalone Apps can be debugged at runtime.<br />
<br />
''Coming Soon''<br />
<br />
=Deploying Standalone Executables=<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
==Pre-9.5 Deployment==<br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
==Post-9.5 Deployment==<br />
From v9.5 you can also choose to deploy your App in the following ways:<br />
* Zip - set the [[#Standalone Zip|Standalone Zip]] App setting to true<br />
* Self-extracting exe - set the [[#Standalone Exe|Standalone Exe]] App setting to true<br />
<br />
Additionally, using the [[#Standalone Lib|Standalone Lib]] and [[#Standalone Data|Standalone Data]] App settings allows any required library files and databases to be included in the deployment zip or exe.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]<br />
[[Category:Lianja v9.5]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-27T15:30:57Z<p>Yvonne.milne: /* Standalone Python modules */</p>
<hr />
<div>=See Also=<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
=Overview=<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja visually build forms] in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
=Sample App: example_timeclock=<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
[[{{ns:file}}:standalone_uipres.png|left|link={{filepath:standalone_uipres.png}}|UI Presentation Rules and Standalone Options]]<br />
<br clear=all><br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include library files. When the standalone app is run the library directory is set to the standalone App library directory.<br />
<br />
The following text files are used to specify which library files should be included:<br />
<br />
===dependencies.txt===<br />
This is generated automatically when the App is [[#Building_and_Testing_Standalone_Executables|built]] if the App contains any [[:Category:WebView Based Sections|WebView Based Sections]].<br />
<br />
For example, the 'Tabbed Form' (form2) App, includes the following sections:<br />
*[[ArticleView Section Attributes|ArticleView]]<br />
*[[CatalogView Section Attributes|CatalogView]]<br />
*[[CommentsView Section Attributes|CommentsView]]<br />
*[[CarouselView Section Attributes|CarouselView]]<br />
*[[Calendar Section Attributes|Calendar]]<br />
<br />
and its dependencies.txt is generated as:<br />
<pre>@articleview<br />
@catalogview<br />
@commentsview<br />
@carouselview<br />
@calendar</pre><br />
<br />
The '@sectiontype' format references the corresponding 'sectiontype-dependencies.txt' file in the library containing the names of any required files and directories, e.g. catalogview-dependencies.txt:<br />
<pre>bootstrap-3.3.4<br />
jquery-1.10.2<br />
catalogview.*</pre><br />
<br />
===includes.txt===<br />
The 'includes.txt' file is used to specify any additional files that should be included.<br />
<br />
As in 'dependencies.txt' these can be:<br />
* folder names<br />
* individual file names<br />
* wildcards (like catalogview.*)<br />
* @filename to include the contents of '@filename-dependencies.txt'<br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create an installer as a self-extracting exe file for the standalone App. This can be unzipped / installed on a target machine.<br />
<br />
==Standalone Login==<br />
From v9.5, checking the 'Standalone Login' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include the files required for enabling login.<br />
<br />
To require login for access to the App, set the [[Form]].requireslogin property to true:<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.requireslogin = 1<br />
</code><br />
<br />
The login page can optionally be customized using the [[Form]].parameters property, e.g.:<br />
<code lang="recital"><br />
oform.parameters = "login.caption=Factory Time Clock;";<br />
+ "login._background=darkred;";<br />
+ "login.backgroundimage=img/wallpapers/background.png;";<br />
+ "login.version=Time Clock Version 1.0;";<br />
+ "login.copyright=Copyright (c) (2024) LianjaDev. All Rights Reserved Worldwide."<br />
</code><br />
<br />
[[{{ns:file}}:standalone_login.png|left|link={{filepath:standalone_login.png}}|Standalone Login Page]]<br />
<br clear=all><br />
<br />
==Standalone Python modules==<br />
From v9.5, checking the 'Standalone Python modules' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) indicates that the standalone App requires Python modules in the App.<br />
<br />
==Standalone Data==<br />
From v9.5, specifying a comma separated list of databases in the 'Standalone Data' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will copy the databases into the standalone App directory. When the standalone app is run the data directory is set to the standalone App data directory.<br />
<br />
==Setup==<br />
From v9.5, if the file setup.prg (or setup.py or setup.js) is contained within the App it is executed before the standalone App is run. You can check to see if the App is running standalone using [[Lianja|Lianja.standalone]] and check the file path using [[Lianja|Lianja.standalonefilepath]].<br />
<br />
You would typically do nothing in setup if the App is not running standalone.<br />
<br />
<code lang="recital"><br />
// this is called when the app runs to setup databases, tables etc.<br />
if not Lianja.standalone<br />
return<br />
endif<br />
<br />
set debugout on<br />
debugout "running setup.prg"<br />
debugout "filepath: "+Lianja.standalonefilepath<br />
<br />
if not databaseExists("factory")<br />
debugout "database factory does not exist"<br />
create database factory<br />
try<br />
open database factory<br />
create table employees;<br />
(badgeno char(30),;<br />
firstname char(30),;<br />
lastname char(30),;<br />
photo blob)<br />
insert into employees (badgeno, firstname, lastname);<br />
values ("A1234", "John", "Doe")<br />
create table timeclock;<br />
(badgeno char(30),;<br />
clockin datetime,;<br />
clockout datetime,;<br />
clockinphoto blob,;<br />
clockoutphoto blob)<br />
catch<br />
debugout "An error occurred"<br />
endtry<br />
endif<br />
<br />
close database <br />
<br />
debugout "setup completed successfully"<br />
<br />
<br />
</code><br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
=Building and Testing Standalone Executables=<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar.<br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
Here showing the [[#Standalone Login|login page]]:<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
and after login and entering a badge number:<br />
[[{{ns:file}}:standalone_exampletimeclock3.png|800px|left|border|link={{filepath:standalone_exampletimeclock3.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Lianja Standalone App Debugger==<br />
From v9.5 standalone Apps can be debugged at runtime.<br />
<br />
''Coming Soon''<br />
<br />
=Deploying Standalone Executables=<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
==Pre-9.5 Deployment==<br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
==Post-9.5 Deployment==<br />
From v9.5 you can also choose to deploy your App in the following ways:<br />
* Zip - set the [[#Standalone Zip|Standalone Zip]] App setting to true<br />
* Self-extracting exe - set the [[#Standalone Exe|Standalone Exe]] App setting to true<br />
<br />
Additionally, using the [[#Standalone Lib|Standalone Lib]] and [[#Standalone Data|Standalone Data]] App settings allows any required library files and databases to be included in the deployment zip or exe.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]<br />
[[Category:Lianja v9.5]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-27T15:29:31Z<p>Yvonne.milne: /* Setup */</p>
<hr />
<div>=See Also=<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
=Overview=<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja visually build forms] in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
=Sample App: example_timeclock=<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
[[{{ns:file}}:standalone_uipres.png|left|link={{filepath:standalone_uipres.png}}|UI Presentation Rules and Standalone Options]]<br />
<br clear=all><br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include library files. When the standalone app is run the library directory is set to the standalone App library directory.<br />
<br />
The following text files are used to specify which library files should be included:<br />
<br />
===dependencies.txt===<br />
This is generated automatically when the App is [[#Building_and_Testing_Standalone_Executables|built]] if the App contains any [[:Category:WebView Based Sections|WebView Based Sections]].<br />
<br />
For example, the 'Tabbed Form' (form2) App, includes the following sections:<br />
*[[ArticleView Section Attributes|ArticleView]]<br />
*[[CatalogView Section Attributes|CatalogView]]<br />
*[[CommentsView Section Attributes|CommentsView]]<br />
*[[CarouselView Section Attributes|CarouselView]]<br />
*[[Calendar Section Attributes|Calendar]]<br />
<br />
and its dependencies.txt is generated as:<br />
<pre>@articleview<br />
@catalogview<br />
@commentsview<br />
@carouselview<br />
@calendar</pre><br />
<br />
The '@sectiontype' format references the corresponding 'sectiontype-dependencies.txt' file in the library containing the names of any required files and directories, e.g. catalogview-dependencies.txt:<br />
<pre>bootstrap-3.3.4<br />
jquery-1.10.2<br />
catalogview.*</pre><br />
<br />
===includes.txt===<br />
The 'includes.txt' file is used to specify any additional files that should be included.<br />
<br />
As in 'dependencies.txt' these can be:<br />
* folder names<br />
* individual file names<br />
* wildcards (like catalogview.*)<br />
* @filename to include the contents of '@filename-dependencies.txt'<br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create an installer as a self-extracting exe file for the standalone App. This can be unzipped / installed on a target machine.<br />
<br />
==Standalone Login==<br />
From v9.5, checking the 'Standalone Login' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include the files required for enabling login.<br />
<br />
To require login for access to the App, set the [[Form]].requireslogin property to true:<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.requireslogin = 1<br />
</code><br />
<br />
The login page can optionally be customized using the [[Form]].parameters property, e.g.:<br />
<code lang="recital"><br />
oform.parameters = "login.caption=Factory Time Clock;";<br />
+ "login._background=darkred;";<br />
+ "login.backgroundimage=img/wallpapers/background.png;";<br />
+ "login.version=Time Clock Version 1.0;";<br />
+ "login.copyright=Copyright (c) (2024) LianjaDev. All Rights Reserved Worldwide."<br />
</code><br />
<br />
[[{{ns:file}}:standalone_login.png|left|link={{filepath:standalone_login.png}}|Standalone Login Page]]<br />
<br clear=all><br />
<br />
==Standalone Python modules==<br />
From v9.5, checking the 'Standalone Python modules' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) indicates that the standalone App requires additional Python modules.<br />
<br />
==Standalone Data==<br />
From v9.5, specifying a comma separated list of databases in the 'Standalone Data' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will copy the databases into the standalone App directory. When the standalone app is run the data directory is set to the standalone App data directory.<br />
<br />
==Setup==<br />
From v9.5, if the file setup.prg (or setup.py or setup.js) is contained within the App it is executed before the standalone App is run. You can check to see if the App is running standalone using [[Lianja|Lianja.standalone]] and check the file path using [[Lianja|Lianja.standalonefilepath]].<br />
<br />
You would typically do nothing in setup if the App is not running standalone.<br />
<br />
<code lang="recital"><br />
// this is called when the app runs to setup databases, tables etc.<br />
if not Lianja.standalone<br />
return<br />
endif<br />
<br />
set debugout on<br />
debugout "running setup.prg"<br />
debugout "filepath: "+Lianja.standalonefilepath<br />
<br />
if not databaseExists("factory")<br />
debugout "database factory does not exist"<br />
create database factory<br />
try<br />
open database factory<br />
create table employees;<br />
(badgeno char(30),;<br />
firstname char(30),;<br />
lastname char(30),;<br />
photo blob)<br />
insert into employees (badgeno, firstname, lastname);<br />
values ("A1234", "John", "Doe")<br />
create table timeclock;<br />
(badgeno char(30),;<br />
clockin datetime,;<br />
clockout datetime,;<br />
clockinphoto blob,;<br />
clockoutphoto blob)<br />
catch<br />
debugout "An error occurred"<br />
endtry<br />
endif<br />
<br />
close database <br />
<br />
debugout "setup completed successfully"<br />
<br />
<br />
</code><br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
=Building and Testing Standalone Executables=<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar.<br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
Here showing the [[#Standalone Login|login page]]:<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
and after login and entering a badge number:<br />
[[{{ns:file}}:standalone_exampletimeclock3.png|800px|left|border|link={{filepath:standalone_exampletimeclock3.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Lianja Standalone App Debugger==<br />
From v9.5 standalone Apps can be debugged at runtime.<br />
<br />
''Coming Soon''<br />
<br />
=Deploying Standalone Executables=<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
==Pre-9.5 Deployment==<br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
==Post-9.5 Deployment==<br />
From v9.5 you can also choose to deploy your App in the following ways:<br />
* Zip - set the [[#Standalone Zip|Standalone Zip]] App setting to true<br />
* Self-extracting exe - set the [[#Standalone Exe|Standalone Exe]] App setting to true<br />
<br />
Additionally, using the [[#Standalone Lib|Standalone Lib]] and [[#Standalone Data|Standalone Data]] App settings allows any required library files and databases to be included in the deployment zip or exe.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]<br />
[[Category:Lianja v9.5]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-27T15:25:20Z<p>Yvonne.milne: /* Building and Testing Standalone Executables */</p>
<hr />
<div>=See Also=<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
=Overview=<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja visually build forms] in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
=Sample App: example_timeclock=<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
[[{{ns:file}}:standalone_uipres.png|left|link={{filepath:standalone_uipres.png}}|UI Presentation Rules and Standalone Options]]<br />
<br clear=all><br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include library files. When the standalone app is run the library directory is set to the standalone App library directory.<br />
<br />
The following text files are used to specify which library files should be included:<br />
<br />
===dependencies.txt===<br />
This is generated automatically when the App is [[#Building_and_Testing_Standalone_Executables|built]] if the App contains any [[:Category:WebView Based Sections|WebView Based Sections]].<br />
<br />
For example, the 'Tabbed Form' (form2) App, includes the following sections:<br />
*[[ArticleView Section Attributes|ArticleView]]<br />
*[[CatalogView Section Attributes|CatalogView]]<br />
*[[CommentsView Section Attributes|CommentsView]]<br />
*[[CarouselView Section Attributes|CarouselView]]<br />
*[[Calendar Section Attributes|Calendar]]<br />
<br />
and its dependencies.txt is generated as:<br />
<pre>@articleview<br />
@catalogview<br />
@commentsview<br />
@carouselview<br />
@calendar</pre><br />
<br />
The '@sectiontype' format references the corresponding 'sectiontype-dependencies.txt' file in the library containing the names of any required files and directories, e.g. catalogview-dependencies.txt:<br />
<pre>bootstrap-3.3.4<br />
jquery-1.10.2<br />
catalogview.*</pre><br />
<br />
===includes.txt===<br />
The 'includes.txt' file is used to specify any additional files that should be included.<br />
<br />
As in 'dependencies.txt' these can be:<br />
* folder names<br />
* individual file names<br />
* wildcards (like catalogview.*)<br />
* @filename to include the contents of '@filename-dependencies.txt'<br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create an installer as a self-extracting exe file for the standalone App. This can be unzipped / installed on a target machine.<br />
<br />
==Standalone Login==<br />
From v9.5, checking the 'Standalone Login' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include the files required for enabling login.<br />
<br />
To require login for access to the App, set the [[Form]].requireslogin property to true:<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.requireslogin = 1<br />
</code><br />
<br />
The login page can optionally be customized using the [[Form]].parameters property, e.g.:<br />
<code lang="recital"><br />
oform.parameters = "login.caption=Factory Time Clock;";<br />
+ "login._background=darkred;";<br />
+ "login.backgroundimage=img/wallpapers/background.png;";<br />
+ "login.version=Time Clock Version 1.0;";<br />
+ "login.copyright=Copyright (c) (2024) LianjaDev. All Rights Reserved Worldwide."<br />
</code><br />
<br />
[[{{ns:file}}:standalone_login.png|left|link={{filepath:standalone_login.png}}|Standalone Login Page]]<br />
<br clear=all><br />
<br />
==Standalone Python modules==<br />
From v9.5, checking the 'Standalone Python modules' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) indicates that the standalone App requires additional Python modules.<br />
<br />
==Standalone Data==<br />
From v9.5, specifying a comma separated list of databases in the 'Standalone Data' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will copy the databases into the standalone App directory. When the standalone app is run the data directory is set to the standalone App data directory.<br />
<br />
==Setup==<br />
From v9.5, if the file setup.prg (or setup.py or setup.js) is contained within the App it is executed before the standalone App is run. You can check to see if the App is running standalone using [[Lianja|Lianja.standalone]] and check the file path using [[Lianja|Lianja.standalonefilepath]].<br />
<br />
You would typically do nothing in setup if the App is not running standalone.<br />
<br />
<code lang="recital"><br />
if not Lianja.standalone<br />
return<br />
endif<br />
<br />
// e.g. to share data on a network <br />
set datadir to f:\lianja\data<br />
</code><br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
=Building and Testing Standalone Executables=<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar.<br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
Here showing the [[#Standalone Login|login page]]:<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
and after login and entering a badge number:<br />
[[{{ns:file}}:standalone_exampletimeclock3.png|800px|left|border|link={{filepath:standalone_exampletimeclock3.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Lianja Standalone App Debugger==<br />
From v9.5 standalone Apps can be debugged at runtime.<br />
<br />
''Coming Soon''<br />
<br />
=Deploying Standalone Executables=<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
==Pre-9.5 Deployment==<br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
==Post-9.5 Deployment==<br />
From v9.5 you can also choose to deploy your App in the following ways:<br />
* Zip - set the [[#Standalone Zip|Standalone Zip]] App setting to true<br />
* Self-extracting exe - set the [[#Standalone Exe|Standalone Exe]] App setting to true<br />
<br />
Additionally, using the [[#Standalone Lib|Standalone Lib]] and [[#Standalone Data|Standalone Data]] App settings allows any required library files and databases to be included in the deployment zip or exe.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]<br />
[[Category:Lianja v9.5]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/File:Standalone_exampletimeclock2.pngFile:Standalone exampletimeclock2.png2024-03-27T15:24:47Z<p>Yvonne.milne: Yvonne.milne uploaded a new version of &quot;File:Standalone exampletimeclock2.png&quot;</p>
<hr />
<div>Standalone Executables on Windows</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/File:Standalone_exampletimeclock3.pngFile:Standalone exampletimeclock3.png2024-03-27T15:20:51Z<p>Yvonne.milne: Standalone Executables on Windows</p>
<hr />
<div>Standalone Executables on Windows</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/File:Standalone_exampletimeclock2.pngFile:Standalone exampletimeclock2.png2024-03-27T15:20:19Z<p>Yvonne.milne: Yvonne.milne uploaded a new version of &quot;File:Standalone exampletimeclock2.png&quot;</p>
<hr />
<div>Standalone Executables on Windows</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/File:Standalone_exampletimeclock.pngFile:Standalone exampletimeclock.png2024-03-27T14:57:03Z<p>Yvonne.milne: Yvonne.milne uploaded a new version of &quot;File:Standalone exampletimeclock.png&quot;</p>
<hr />
<div>Standalone Executables on Windows</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/File:Standalone_scriptlang.pngFile:Standalone scriptlang.png2024-03-27T14:49:12Z<p>Yvonne.milne: Yvonne.milne uploaded a new version of &quot;File:Standalone scriptlang.png&quot;</p>
<hr />
<div>Standalone Executables on Windows</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-27T14:46:04Z<p>Yvonne.milne: /* Building Standalone Executables */</p>
<hr />
<div>=See Also=<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
=Overview=<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja visually build forms] in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
=Sample App: example_timeclock=<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
[[{{ns:file}}:standalone_uipres.png|left|link={{filepath:standalone_uipres.png}}|UI Presentation Rules and Standalone Options]]<br />
<br clear=all><br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include library files. When the standalone app is run the library directory is set to the standalone App library directory.<br />
<br />
The following text files are used to specify which library files should be included:<br />
<br />
===dependencies.txt===<br />
This is generated automatically when the App is [[#Building_and_Testing_Standalone_Executables|built]] if the App contains any [[:Category:WebView Based Sections|WebView Based Sections]].<br />
<br />
For example, the 'Tabbed Form' (form2) App, includes the following sections:<br />
*[[ArticleView Section Attributes|ArticleView]]<br />
*[[CatalogView Section Attributes|CatalogView]]<br />
*[[CommentsView Section Attributes|CommentsView]]<br />
*[[CarouselView Section Attributes|CarouselView]]<br />
*[[Calendar Section Attributes|Calendar]]<br />
<br />
and its dependencies.txt is generated as:<br />
<pre>@articleview<br />
@catalogview<br />
@commentsview<br />
@carouselview<br />
@calendar</pre><br />
<br />
The '@sectiontype' format references the corresponding 'sectiontype-dependencies.txt' file in the library containing the names of any required files and directories, e.g. catalogview-dependencies.txt:<br />
<pre>bootstrap-3.3.4<br />
jquery-1.10.2<br />
catalogview.*</pre><br />
<br />
===includes.txt===<br />
The 'includes.txt' file is used to specify any additional files that should be included.<br />
<br />
As in 'dependencies.txt' these can be:<br />
* folder names<br />
* individual file names<br />
* wildcards (like catalogview.*)<br />
* @filename to include the contents of '@filename-dependencies.txt'<br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create an installer as a self-extracting exe file for the standalone App. This can be unzipped / installed on a target machine.<br />
<br />
==Standalone Login==<br />
From v9.5, checking the 'Standalone Login' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include the files required for enabling login.<br />
<br />
To require login for access to the App, set the [[Form]].requireslogin property to true:<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.requireslogin = 1<br />
</code><br />
<br />
The login page can optionally be customized using the [[Form]].parameters property, e.g.:<br />
<code lang="recital"><br />
oform.parameters = "login.caption=Factory Time Clock;";<br />
+ "login._background=darkred;";<br />
+ "login.backgroundimage=img/wallpapers/background.png;";<br />
+ "login.version=Time Clock Version 1.0;";<br />
+ "login.copyright=Copyright (c) (2024) LianjaDev. All Rights Reserved Worldwide."<br />
</code><br />
<br />
[[{{ns:file}}:standalone_login.png|left|link={{filepath:standalone_login.png}}|Standalone Login Page]]<br />
<br clear=all><br />
<br />
==Standalone Python modules==<br />
From v9.5, checking the 'Standalone Python modules' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) indicates that the standalone App requires additional Python modules.<br />
<br />
==Standalone Data==<br />
From v9.5, specifying a comma separated list of databases in the 'Standalone Data' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will copy the databases into the standalone App directory. When the standalone app is run the data directory is set to the standalone App data directory.<br />
<br />
==Setup==<br />
From v9.5, if the file setup.prg (or setup.py or setup.js) is contained within the App it is executed before the standalone App is run. You can check to see if the App is running standalone using [[Lianja|Lianja.standalone]] and check the file path using [[Lianja|Lianja.standalonefilepath]].<br />
<br />
You would typically do nothing in setup if the App is not running standalone.<br />
<br />
<code lang="recital"><br />
if not Lianja.standalone<br />
return<br />
endif<br />
<br />
// e.g. to share data on a network <br />
set datadir to f:\lianja\data<br />
</code><br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
=Building and Testing Standalone Executables=<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar:<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Lianja Standalone App Debugger==<br />
From v9.5 standalone Apps can be debugged at runtime.<br />
<br />
''Coming Soon''<br />
<br />
=Deploying Standalone Executables=<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
==Pre-9.5 Deployment==<br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
==Post-9.5 Deployment==<br />
From v9.5 you can also choose to deploy your App in the following ways:<br />
* Zip - set the [[#Standalone Zip|Standalone Zip]] App setting to true<br />
* Self-extracting exe - set the [[#Standalone Exe|Standalone Exe]] App setting to true<br />
<br />
Additionally, using the [[#Standalone Lib|Standalone Lib]] and [[#Standalone Data|Standalone Data]] App settings allows any required library files and databases to be included in the deployment zip or exe.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]<br />
[[Category:Lianja v9.5]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/File:Standalone_login.pngFile:Standalone login.png2024-03-27T14:37:43Z<p>Yvonne.milne: Standalone Executables</p>
<hr />
<div>Standalone Executables</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/File:Standalone_uipres.pngFile:Standalone uipres.png2024-03-27T14:26:59Z<p>Yvonne.milne: Yvonne.milne uploaded a new version of &quot;File:Standalone uipres.png&quot;</p>
<hr />
<div>Standalone Executables on Windows</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-27T14:09:55Z<p>Yvonne.milne: /* Standalone Data */</p>
<hr />
<div>=See Also=<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
=Overview=<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja visually build forms] in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
=Sample App: example_timeclock=<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
[[{{ns:file}}:standalone_uipres.png|left|link={{filepath:standalone_uipres.png}}|UI Presentation Rules and Standalone Options]]<br />
<br clear=all><br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include library files. When the standalone app is run the library directory is set to the standalone App library directory.<br />
<br />
The following text files are used to specify which library files should be included:<br />
<br />
===dependencies.txt===<br />
This is generated automatically when the App is [[#Building_and_Testing_Standalone_Executables|built]] if the App contains any [[:Category:WebView Based Sections|WebView Based Sections]].<br />
<br />
For example, the 'Tabbed Form' (form2) App, includes the following sections:<br />
*[[ArticleView Section Attributes|ArticleView]]<br />
*[[CatalogView Section Attributes|CatalogView]]<br />
*[[CommentsView Section Attributes|CommentsView]]<br />
*[[CarouselView Section Attributes|CarouselView]]<br />
*[[Calendar Section Attributes|Calendar]]<br />
<br />
and its dependencies.txt is generated as:<br />
<pre>@articleview<br />
@catalogview<br />
@commentsview<br />
@carouselview<br />
@calendar</pre><br />
<br />
The '@sectiontype' format references the corresponding 'sectiontype-dependencies.txt' file in the library containing the names of any required files and directories, e.g. catalogview-dependencies.txt:<br />
<pre>bootstrap-3.3.4<br />
jquery-1.10.2<br />
catalogview.*</pre><br />
<br />
===includes.txt===<br />
The 'includes.txt' file is used to specify any additional files that should be included.<br />
<br />
As in 'dependencies.txt' these can be:<br />
* folder names<br />
* individual file names<br />
* wildcards (like catalogview.*)<br />
* @filename to include the contents of '@filename-dependencies.txt'<br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create an installer as a self-extracting exe file for the standalone App. This can be unzipped / installed on a target machine.<br />
<br />
==Standalone Login==<br />
<br />
<br />
==Standalone Python modules==<br />
<br />
==Standalone Data==<br />
From v9.5, specifying a comma separated list of databases in the 'Standalone Data' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will copy the databases into the standalone App directory. When the standalone app is run the data directory is set to the standalone App data directory.<br />
<br />
==Setup==<br />
From v9.5, if the file setup.prg (or setup.py or setup.js) is contained within the App it is executed before the standalone App is run. You can check to see if the App is running standalone using [[Lianja|Lianja.standalone]] and check the file path using [[Lianja|Lianja.standalonefilepath]].<br />
<br />
You would typically do nothing in setup if the App is not running standalone.<br />
<br />
<code lang="recital"><br />
if not Lianja.standalone<br />
return<br />
endif<br />
<br />
// e.g. to share data on a network <br />
set datadir to f:\lianja\data<br />
</code><br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
==Login==<br />
From v9.5 standalone Apps can require login.<br />
* [[Form]].requireslogin property<br />
* Fully customizable login form<br />
<br />
''Coming Soon''<br />
<br />
=Building and Testing Standalone Executables=<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar:<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Lianja Standalone App Debugger==<br />
From v9.5 standalone Apps can be debugged at runtime.<br />
<br />
''Coming Soon''<br />
<br />
=Deploying Standalone Executables=<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
==Pre-9.5 Deployment==<br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
==Post-9.5 Deployment==<br />
From v9.5 you can also choose to deploy your App in the following ways:<br />
* Zip - set the [[#Standalone Zip|Standalone Zip]] App setting to true<br />
* Self-extracting exe - set the [[#Standalone Exe|Standalone Exe]] App setting to true<br />
<br />
Additionally, using the [[#Standalone Lib|Standalone Lib]] and [[#Standalone Data|Standalone Data]] App settings allows any required library files and databases to be included in the deployment zip or exe.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]<br />
[[Category:Lianja v9.5]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/App_SettingsApp Settings2024-03-27T14:08:34Z<p>Yvonne.milne: /* Standalone Options */</p>
<hr />
<div>==Overview==<br />
Click the '''Settings''' icon in the ModeBar to open up the App Settings dialog. Select a setting category from the pulldown and/or use the scrollbar to browse the settings. With the settings grid selected, type a letter to jump to the first setting that starts with that letter. Typing the same letter again will move to the next setting starting with that letter.<br />
<br />
When you have finished editing the settings, click '''Done''' to save the changes and close the dialog or '''Cancel''' to close the dialog without saving.<br />
<br />
[[{{ns:file}}:open_app_settings.png|800px|border|left|link={{filepath:open_app_settings.png}}|Open App Settings]]<br />
<br clear=all><br />
<br />
Note: App Settings are selected in the [[Attributes]] tab when the [[App Inspector]] is open.<br />
<br />
[[{{ns:file}}:l5_settings.png|800px|border|left|link={{filepath:l5_settings.png}}|Select App Settings in App Inspector]]<br />
<br clear=all><br />
<br />
==Getting and Setting Attributes Programatically==<br />
The Lianja system object has desktop methods allowing App Settings to be queried and set programmatically:<br />
<br />
<pre>Lianja.getAttr(name)</pre><br />
<br />
<pre>Lianja.setAttr(name,value)</pre><br />
<br />
e.g.<br />
<br />
<code lang="recital"><br />
lIsPublished = Lianja.getAttr("apppublished")<br />
Lianja.setAttr("apppublished","true")<br />
</code><br />
<br />
See [[Custom Builders]] for details on intercepting the new App operation to allow it to be handled programmatically and for developer customizations to be applied.<br />
<br />
==General==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[General Settings#App Doc|App Doc]]||App Doc file. This html file will be included at the beginning of the [[App Doc]] when it is generated.<br />
|valign="top"|appdoc||valign="top"|Character<br />
|-<br />
|valign="top"|[[General Settings#Keep attribute versions|Keep attribute versions]]||Keep attribute versions in appname_appdoc.txt for diff comparison when the App is saved. From v6.3.<br />
|valign="top"|keepappdocversions||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Build mode|Build mode]]||The type of build for Web/Mobile Apps. Use Debug when testing and Release when deploying (Debug &#124; Release).<br />
|valign="top"|appbuildtype||valign="top"|Character<br />
|-<br />
|valign="top"|[[General Settings#Published|Published]]||App is published in the App Center (True &#124; False).<br />
|valign="top"|apppublished||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Use_wizards.2Fbuilders|Use wizards/builders]]||Use wizards/builders during development (True &#124; False).<br />
|valign="top"|usewizards||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Check for updates|Check for updates]]||Check for Lianja App Builder updates at startup (True &#124; False). From v5.2.<br />
|valign="top"|checkforupdates||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Event tracking|Event tracking]]||Trace App events in Web/Mobile Apps (True &#124; False). This is only effective in Debug mode.<br />
|valign="top"|appeventtracking||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Turn Password on|Turn Password on]]||Enter password when starting Lianja (True &#124; False).<br />
|valign="top"|&nbsp;||valign="top"|<br />
|-<br />
|valign="top"|[[General Settings#Password|Password]]||Password value.<br />
|valign="top"|&nbsp;||valign="top"|<br />
|-<br />
|valign="top"|[[General Settings#Confirm Password|Confirm Password]]||Confirm password value.<br />
|valign="top"|&nbsp;||valign="top"|<br />
|-<br />
|valign="top"|[[General Settings#Restore previous session on startup|Restore previous session on startup]]||valign="top"|Restore the previous session on startup. If checked, then the last App and editor files are reopened (True &#124; False).<br />
|valign="top"|&nbsp;||valign="top"|<br />
|-<br />
|valign="top"|[[General Settings#Login required|Login required]]||Authentication required to run App (True &#124; False).<br />
|valign="top"|apploginrequired||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Enable guest access|Enable guest access]]||Enable this App to be run as a guest without App Center login (True &#124; False).<br />
|valign="top"|appenableexternal||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Enable offline data|Enable offline data]]||Reserved for future use (True &#124; False).<br />
|valign="top"|appenableofflinedata||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Offline tables|Offline tables]]||Reserved for future use.<br />
|valign="top"|appofflinetables||valign="top"|Character<br />
|-<br />
|valign="top"|[[General Settings#Page libraries|Page libraries]]||The page libraries for this App. Comma-separate the filenames to specify more than one. From v9.1.4.<br />
|valign="top"|pagelibs||valign="top"|Character<br />
|-<br />
|valign="top"|[[General Settings#Database switcher list|Database switcher list]]||Comma separated list of databases that can be switched to.<br>From v6.3.<br />
|valign="top"|appdatabaseswitcherlist||valign="top"|Character<br />
|-<br />
|valign="top"|[[General Settings#Timelines Enabled|Timelines Enabled]]||Enable database timelines for sections that have timelines enabled (True &#124; False).<br />
|valign="top"|timelinesenabled||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Ask Before Deleting|Ask Before Deleting]]||Ask before deleting a record (True &#124; False).<br />
|valign="top"|confirmdeleterecord||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Add Form Section|Add Form Section]]||Always add a form section when creating a new blank page (True &#124; False).<br />
|valign="top"|addblankformsection||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Table information|Table information]]||Query for Table information in the data trees when an App is opened or a database is opened in the Data workspace<br>(True &#124; False).<br />
|valign="top"|&nbsp;||valign="top"|<br />
|-<br />
|valign="top"|[[General Settings#Deferred load|Deferred load]]||When this is checked all pages will be loaded with data only when they are first activated (speeds up App load time).<br>(True &#124; False).<br />
|valign="top"|deferredload||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Help provider homepage URL|Help provider homepage URL]]||Context sensitive help provider URL to use when editing.<br />
|valign="top"|helpproviderurl||valign="top"|Character<br />
|-<br />
|valign="top"|[[General Settings#Help provider search URL|Help provider search URL]]||Context sensitive help provider search URL to use when editing. Use {keyword} for item to search for.<br />
|valign="top"|helpprovidersearchurl||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==CSS theming==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[CSS#Client_Specific_UI_Theming|Desktop CSS style]]||Specify the global Desktop App CSS style for UI theming.<br>From v6.3.<br />
|valign="top"|cssstyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[CSS#Client_Specific_UI_Theming|Web CSS style]]||Specify the global Web App CSS style for UI theming. From v6.3.<br />
|valign="top"|cssstyle_web||Character<br />
|-<br />
|valign="top"|[[CSS#Client_Specific_UI_Theming|Tablet CSS style]]||Specify the global Tablet App CSS style for UI theming. From v6.3.<br />
|valign="top"|cssstyle_tablet||valign="top"|Character<br />
|-<br />
|valign="top"|[[CSS#Client_Specific_UI_Theming|Phone CSS style]]||Specify the global Phone App CSS style for UI theming. From v6.3.<br />
|valign="top"|cssstyle_phone||Character<br />
|-<br />
|}<br />
<br />
==Editor==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Editor Settings#Use External Editor|Use External Editor]]||Use External Editor for editing (True &#124; False).<br />
|valign="top"|useexternaleditor||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#External Editor|External Editor]]||The External Editor for editing.<br />
|valign="top"|externaleditor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Editor Settings#External Editor Extensions|External Editor Extensions]]||A comma separated list of file extensions that will be edited externally.<br />
|valign="top"|externaleditorextensions||valign="top"|Character<br />
|-<br />
|valign="top"|[[Editor Settings#Activate Completion|Activate Completion]]||Activate statement completion (Always &#124; Manually &#124; Never).<br />
|valign="top"|activatecompletion||valign="top"|Character<br />
|-<br />
|valign="top"|[[Editor Settings#Activate completion timeout|Activate completion timeout]]||Activate statement completion timeout.<br />
|valign="top"|activatecompletiontimeout||valign="top"|Int<br />
|-<br />
|valign="top"|[[Editor Settings#Enable Intellitips|Enable Intellitips]]||Enable Intellitips (True &#124; False).<br />
|valign="top"|enableintellitips||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Enable code snippets|Enable code snippets]]||Enable code snippets (True &#124; False).<br />
|valign="top"|enablecodesnippets||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Enable command syntax hints|Enable command syntax hints]]||Enable command syntax hints (True &#124; False).<br />
|valign="top"|enablesyntaxhints||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Enable function parameter hints|Enable function parameter hints]]||Enable function parameter hints (True &#124; False).<br />
|valign="top"|enableparameterhints||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Enable command parameter hints|Enable command parameter hints]]||valign="top"|Enable command window parameter hints (True &#124; False).<br />
|valign="top"|enableparametercommandhints||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Insert matching characters|Insert matching characters]]||Automatically insert matching characters (True &#124; False).<br />
|valign="top"|automaticallyaddmatchingcharacters||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Enable code folding|Enable code folding]]||Enable code folding (True &#124; False).<br />
|valign="top"|enablecodefolding||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Enable word highlighting|Enable word highlighting]]||Enable highlighting of words in file as typed (True &#124; False).<br />
|valign="top"|enablehighlightwords||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Enable smart indenting|Enable smart indenting]]||Enable smart indenting of code blocks (True &#124; False).<br />
|valign="top"|smartindent||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Enable object naming conventions|Enable object naming conventions]]||Enable object naming conventions to display property/method pick lists based on identifier prefixes (True &#124; False).<br />
|valign="top"|objectnamingconventions||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Refresh advanced panel|Refresh advanced panel]]||Always refresh the editor advanced panel when a file is edited<br>(True &#124; False).<br />
|valign="top"|refresheditoradvanced||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Fast syntax highlighting|Fast syntax highlighting]]||Fast syntax highlighting (True &#124; False).<br>Set to True by default. The syntax highlighter for LianjaScript is much more responsive in the [[Troubleshooter_Debugger_Tab|debugger]] when opening large files.<br>(From v9.5).<br />
|valign="top"|minimalsyntaxhighlighting||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Theme|Theme]]||The editor theme (Default &#124; Visual Studio Dark &#124; Visual Studio Light &#124; Eclipse &#124; Dreamweaver).<br />
|valign="top"|editortheme||valign="top"|Character<br />
|-<br />
|valign="top"|[[Editor Settings#Show Doc|Show Doc]]||Show the editor Doc when editing (True &#124; False).<br />
|valign="top"|editorhelp||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#App files search path|App files search path]]||A semi-colon (;) separated list of directories to search and refresh in the editor advanced panel when an App file is edited. (From v5.0).<br />
|valign="top"|appeditorsearchpath||valign="top"|Character<br />
|-<br />
|valign="top"|[[Editor Settings#Library files search path|Library files search path]]||A semi-colon (;) separated list of directories to search and refresh in the editor advanced panel when a Library file is edited. (From v5.0).<br />
|valign="top"|libeditorsearchpath||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Embedded HTTP Server==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Embedded_HTTP_Server#Listen_on|Listen on]]||The interface the HTTP server should listen for requests on<br />
|valign="top"|httpnodename||Character<br />
|-<br />
|valign="top"|[[Embedded_HTTP_Server#Port|Port]]||The port that the embedded HTTP server uses<br />
|valign="top"|httpport||Character<br />
|-<br />
|valign="top"|[[Embedded_HTTP_Server#Runtime_Port|Runtime Port]]||The port that the embedded HTTP server uses at runtime<br>(App Center).<br />
|valign="top"|runtimehttpport||valign="top"|Character<br />
|-<br />
|valign="top"|[[Embedded_HTTP_Server#API_key|API key]]||The API key that should be specified to invoke desktop web services.<br />
|valign="top"|httpapikey||Character<br />
|-<br />
|valign="top"|[[Embedded_HTTP_Server#Enable_services|Enable services]]||Enable embedded web services (True &#124; False)<br />
|valign="top"|httpenableservices||Boolean<br />
|-<br />
|}<br />
<br />
==Sessionstorage==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[SessionStorage in Lianja|Sessionstorage size]]||The size of the shared sessionstorage<br />
|valign="top"|sessionstoragesize||valign="top"|Int<br />
|-<br />
|valign="top"|[[SessionStorage in Lianja|Session data changed]]||The delegate procedure for the session data changed event<br />
|valign="top"|sessiondatachangedaction||Character<br />
|-<br />
|valign="top"|[[SessionStorage in Lianja|Session data changed interval]]||valign="top"|The interval in msecs that checks for session data changes will be made at runtime<br />
|valign="top"|sessiondatachangedinterval||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Directories==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Directories Settings#Data directory|Data directory]]||The database directory where your databases are located.<br />
|valign="top"|datadir||valign="top"|Character<br />
|-<br />
|valign="top"|[[Directories Settings#Apps directory|Apps directory]]||The apps directory where your apps are located.<br />
|valign="top"|appsdir||valign="top"|Character<br />
|-<br />
|valign="top"|[[Directories Settings#Library directory|Library directory]]||The library directory where your libraries are located.<br />
|valign="top"|libdir||valign="top"|Character<br />
|-<br />
|valign="top"|[[Directories Settings#Templates directory|Templates directory]]||The template directory where your templates are located.<br />
|valign="top"|templatesdir||valign="top"|Character<br />
|-<br />
|valign="top"|[[Directories Settings#Deployment directory|Deployment directory]]||The deployment directory. This should contain apps, data and library sub-directories. It can be on a network drive to provide shared App and Data access.<br />
|valign="top"|runtimerootdir||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Deployment==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[A Guide to Deploying Web Apps|Publisher]]||The way to publish the Apps (Copy &#124; SFTP &#124; Custom).<br />
|valign="top"|apppublisher||valign="top"|Character<br />
|-<br />
|valign="top"|[[A Guide to Deploying Web Apps|Publisher path]]||The optional full path of the publisher program, e.g. /usr/bin/rsync.<br />
|valign="top"|apppublisherpath||valign="top"|Character<br />
|-<br />
|valign="top"|[[A Guide to Deploying Web Apps|Publisher arguments]]||The optional arguments to the publisher program, e.g. -avc for rsync.<br />
|valign="top"|apppublisherarguments||valign="top"|Character<br />
|-<br />
|valign="top"|[[A Guide to Deploying Web Apps|Server]]||The server IP address or nodename where the App will be deployed, e.g. localhost or myserver.mydomain.com.<br />
|valign="top"|apppublisherserver||valign="top"|Character<br />
|-<br />
|valign="top"|[[A Guide to Deploying Web Apps|Directory]]||The root lianja directory on the LAN or server where the Apps will be deployed.<br />
|valign="top"|apppublisherdirectory||valign="top"|Character<br />
|-<br />
|valign="top"|[[Packaging Lianja Desktop Apps for Windows|Build an installer]]||Build an installer for Windows desktop deployment (True &#124; False).<br />
|valign="top"|&nbsp;||valign="top"|<br />
|-<br />
|valign="top"|[[A Guide to Deploying Web Apps|Username]]||The optional username to authenticate with the remote server.<br />
|valign="top"|apppublisherusername||valign="top"|Character<br />
|-<br />
|valign="top"|[[A Guide to Deploying Web Apps|Password]]||The optional password to authenticate with the remote server.<br />
|valign="top"|apppublisherpassword||valign="top"|Character<br />
|-<br />
|valign="top"|[[A Guide to Deploying Web Apps|Private key (.pem file)]]||The (optional) private key (.pem file) to authenticate with the remote server.<br />
|valign="top"|apppublisherpemfile||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==App Center Tile==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Author]]||The App author displayed in the App Center.<br />
|valign="top"|appauthor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Category]]||The category for the App displayed in the App Center.<br />
|valign="top"|appsidebarcategory||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Version]]||The version for the App displayed in the App Center.<br />
|valign="top"|appversion||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Caption]]||The caption for the App displayed in the App Center.<br />
|valign="top"|appsidebarcaption||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Icon]]||The icon for the App displayed in the App Center.<br />
|valign="top"|appsidebaricon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Description]]||The description for the App displayed in the App Center.<br />
|valign="top"|appdescription||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Background color]]||The background color for the App displayed in the App Center.<br />
|valign="top"|apptilebackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Tile size]]||The size of the tile in the App Center.<br />
|valign="top"|apptilesize||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Dynamic contents]]||The tile in the App Center contains dynamic contents only (True &#124; False).<br />
|valign="top"|apptiledynamiccontents||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Tile order]]||The category position for the tile in the App Center.<br />
|valign="top"|apptileorder||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Tile URL]]||The URL to invoke when this tile is clicked at runtime.<br />
|valign="top"|apptileurl||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Dynamic tile producer]]||The dynamic tile producer used to update the dynamic tile in the App Center. This can be a procedure or a URL.<br />
|valign="top"|timeraction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Dynamic tile timer interval]]||The timer interval in seconds to update the dynamic tile in the App Center.<br />
|valign="top"|timerinterval||valign="top"|Int<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Dynamic badge producer]]||The dynamic badge producer used to update the dynamic badge in the tile in the App Center. This can be a procedure or a URL.<br />
|valign="top"|countertimeraction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Dynamic badge timer interval]]||The timer interval in seconds to update the dynamic badge in the tile in the App Center.<br />
|valign="top"|countertimerinterval||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==General App Configuration==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Window Title|Window Title]]||The window title for this App.<br />
|valign="top"|apptitle||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Window Width|Window Width]]||The window width for this App.<br />
|valign="top"|appwidth||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Window Height|Window Height]]||The window height for this App.<br />
|valign="top"|appheight||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Maximize Window|Maximize Window]]||Maximize the window for this App (True &#124; False).<br />
|valign="top"|appmaximize||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Window Resizable|Window Resizable]]||Allow the user to resize the App window (True &#124; False).<br />
|valign="top"|appresizable||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Hide Header Bar|Hide Header Bar]]||Hide header bar at runtime (True &#124; False).<br />
|valign="top"|hideheaderbar||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Page_Menu#Show_navigation_history|Show navigation history]]||Show pages navigation history buttons in page header.<br />
|valign="top"|showbackbutton||valign="top"|Character<br />
|-<br />
|valign="top"|[[Page_Menu#Show_navigation_menu|Show navigation menu]]||Show pages navigation menu in page header (True &#124; False).<br />
|valign="top"|showpagesmenu||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Page_Menu#Show_Page_Center|Show Page Center]]||Show Page Center when navigation menu clicked (True &#124; False).<br />
|valign="top"|showpagecenter||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Disable VT requery when parentdatachanged|Disable VT requery when parentdatachanged]]||This will handle legacy VT usage prior to Lianja 6.3 (True &#124; False). From v6.3.<br />
|valign="top"|vtparentrequerydisabled||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Navigation menu caption|Navigation menu caption]]||Navigation menu caption text in the page header.<br />
|valign="top"|pagesmenucaption||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Hide header icons|Hide header icons]]||Hide the header icons in the page header bars (True &#124; False).<br />
|valign="top"|hideheadericons||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Desktop theme|Desktop theme]]||Desktop theme for this App (Default &#124; Android &#124; iOS &#124; Modern &#124; Modern2 &#124; ... (read from themes directory).<br />
|valign="top"|theme||valign="top"|Character<br />
|-<br />
|valign="top"|[[Help Attributes#Help table|Help table]]||Context sensitive help table for this App.<br />
|valign="top"|helptable||valign="top"|Character<br />
|-<br />
|valign="top"|[[MetaTypes|Meta types file]]||The Meta types file for this App.<br />
|valign="top"|metatypestable||valign="top"|Character<br />
|-<br />
|valign="top"|[[MetaTypes|Meta types library]]||The Meta types library for this App.<br />
|valign="top"|metatypeslib||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual Components|Component library]]||The Component library for this App. Components that are generated are saved here. (From v5.0).<br />
|valign="top"|componentlib||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual Components|Components]]||The Components needed for this App. Separate each with a ';' to specify more than one, e.g.<br> example_component.name;example_component.*. (From v5.0).<br />
|valign="top"|components||valign="top"|Character<br />
|-<br />
|valign="top"|[[CSS|CSS libraries]]||The CSS libraries for this App. Separate each filename with a ; to specify more than one.<br />
|valign="top"|csslibs||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Additional file path|Additional file path]]||A semi-colon (;) separated list of additional path locations to search for App specific files.<br />
|valign="top"|addinspath||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Autoload libraries|Autoload libraries]]||If True, then libraries are auto loaded if a file of the same name as the directory exists in the additional file paths (True &#124; False).<br />
|valign="top"|addinsautoload||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI States#UI states table|UI states table]]||UI states table for this App.<br />
|valign="top"|uistatestable||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI States#Initial UI state|Initial UI state]]||The initial UI state for this App. This will be applied to all pages, sections and fields/gadgets.<br />
|valign="top"|uistateinit||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Home page app|Home page app]]||The App to load when the Home icon is clicked.<br />
|valign="top"|homeapp||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Initial page|Initial page]]||The first page to view for this App at runtime.<br />
|valign="top"|firstpage||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#HTML editor|HTML editor]]||Choose the HTML editor to use in this App (Desktop &#124; Web &#124; Mobile).<br />
|valign="top"|htmleditor||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Runtime connection|Runtime connection]]||The connection string to use for 'local' virtual tables. This will be substituted when the App is deployed at runtime in the App Center or the Web/Mobile clients.<br />
|valign="top"|runtimeconnstr||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Runtime database|Runtime database]]||The database that will be substituted when the App is deployed at runtime in the App Center or the Web/Mobile clients.<br />
|valign="top"|runtimedatabase||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Include in HTML HEAD|Include in HTML HEAD]]||Include HTML file contents into the HTML5 Client.<br />
|valign="top"|includehtmlhead||valign="top"|Character<br />
|-<br />
|valign="top"|[[:Category:Progressive Web Apps|Enable as PWA]]||Enable as a Progressive Web App when generating web/mobile/tablet Apps.<br />
|valign="top"|pwa||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Automatic Language Translation#Enable user translate|Enable user translate]]||Enable user translation in web/mobile/tablet Apps. From v5.5.<br />
|valign="top"|enableusertranslation||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Automatic Language Translation#Enable text translator|Enable text translator]]||Enable text translation in web/mobile/tablet Apps. This enables dynamic language translation of captions in the UI. From v5.5.<br />
|valign="top"|enabletranslation||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Automatic Language Translation#Enable google translate|Enable google translate]]||Enable google translate in web/mobile/tablet Apps. This enables dynamic language translation of captions in the UI. From v5.5.<br />
|valign="top"|enablegoogletranslation||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Readonly fields backcolor|Readonly fields backcolor]]||The background color that readonly fields should be displayed in.<br />
|valign="top"|readonlybackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[CSS|App CSS style]]||Specify the global App CSS style for UI theming.<br />
|valign="top"|cssstyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Disable inline editing|Disable inline editing]]||Disable inline editing (True &#124; False).<br />
|valign="top"|disableinlineediting||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Console Workspace|Show PerfMeter in console]]||Show PerfMeter in the Console (True &#124; False).<br />
|valign="top"|consoleperfmeter||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Locale Configuration==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Locale Configuration Settings#Currency character|Currency character]]||The currency character to use for this App<br>(default $).<br />
|valign="top"|localecurrencycharacter||valign="top"|Character<br />
|-<br />
|valign="top"|[[Locale Configuration Settings#Separator character|Separator character]]||The separator character to use in number formatting for this App<br>(default ,).<br />
|valign="top"|localeseparatorcharacter||valign="top"|Character<br />
|-<br />
|valign="top"|[[Locale Configuration Settings#Point character|Point character]]||valign="top"|The point character to use in number formatting for this App<br>(default .).<br />
|valign="top"|localepointcharacter||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Web/Mobile App Configuration==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Browser|Browser]]||Browser to use for [[Deploying_to_Local_Directory#Preview_live_in_browser|Preview live in browser]]. From v9.1.5.<br />
|valign="top"|browser||valign="top"|Character<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Custom browser location|Custom browser location]]||Location of browser to use for [[Deploying_to_Local_Directory#Preview_live_in_browser|Preview live in browser]].<br>From v9.1.5.<br />
|valign="top"|custombrowser||valign="top"|Character<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Character encoding|Character encoding]]||Character encoding for Web/Mobile Apps<br>(utf-8 is recommended).<br />
|valign="top"|htmlencoding||valign="top"|Character<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Language locale|Language locale]]||Locale for Web/Mobile Apps (affects date picker and various captions).<br />
|valign="top"|htmllocale||valign="top"|Character<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Header icon type|Header icon type]]||Icon to be displayed in the page header bar in Web/Mobile<br>(Default &#124; Custom &#124; None).<br />
|valign="top"|webheadericon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Custom header icon|Custom header icon]]||Custom icon to be displayed in the page header bar in Web/Mobile.<br />
|valign="top"|customwebheadericon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Disable right click|Disable right click]]||Disable right click context menu in Web Apps (True &#124; False).<br />
|valign="top"|disablerightclick||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Disable success notifications|Disable success notifications]]||Disable success notifications in Web/Mobile apps<br>(True &#124; False). From v7.2.<br />
|valign="top"|disablesysmessages||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Enable animations|Enable animations]]||Enable animated section transitions in Web/Mobile Apps<br>(True &#124; False).<br />
|valign="top"|enableanimations||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Web Theme|Web Theme]]||Web theme for this App (Default &#124; AndroidBlackGreen &#124; AndroidBlackBlue &#124; AndroidBlackOrange &#124; AndroidBlackPurple &#124; AndroidBlackRed &#124; AndroidBlackWhite &#124; AndroidWhiteGreen &#124; AndroidWhiteBlue &#124; AndroidWhiteOrange &#124; AndroidWhitePurple &#124; AndroidWhiteRed &#124; iOS &#124; Modern).<br />
|valign="top"|webtheme||valign="top"|Character<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Mobile Theme|Mobile Theme]]||Mobile theme for this App (Default &#124; AndroidBlackGreen &#124; AndroidBlackBlue &#124; AndroidBlackOrange &#124; AndroidBlackPurple &#124; AndroidBlackRed &#124; AndroidBlackWhite &#124; AndroidWhiteGreen &#124; AndroidWhiteBlue &#124; AndroidWhiteOrange &#124; AndroidWhitePurple &#124; AndroidWhiteRed &#124; iOS &#124; Modern).<br />
|valign="top"|mobiletheme||valign="top"|Character<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Mini navigation panel|Mini navigation panel]]||Always show mini (phone) navigation panel on tablets<br>(True &#124; False).<br />
|valign="top"|showmininavigationpanel||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Page defaults==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Page_Appearance#Navigation_bar_type|Navigation bar type]]||Choose the appearance of the data navigation bar to use in this App (Flat &#124; Gradient).<br />
|valign="top"|navbartype||valign="top"|Character<br />
|-<br />
|valign="top"|[[Page_Appearance#Hide_navigation_bar_slider|Hide navigation bar slider]]||Hide navigation bar slider (True &#124; False).<br />
|valign="top"|hideslider||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Page_Appearance#Navigation_bar_CSS|Navigation bar CSS]]||Custom navigation bar CSS.<br />
|valign="top"|navbarcss||valign="top"|Character<br />
|-<br />
|valign="top"|[[Page_Menu#Page_menu|Page menu]]||Choose the appearance of the page navigation menu to use in this App (Menu &#124; Panel).<br />
|valign="top"|pagemenutype||valign="top"|Character<br />
|-<br />
|valign="top"|[[Page_Menu#Page menu theme|Page menu theme]]||Choose the page meu theme to use in this App (Dark &#124; Light).<br>From v9.0.<br />
|valign="top"|pagemenutheme||valign="top"|Character<br />
|-<br />
|valign="top"|[[Page_Menu#Page_menu_row_height|Page menu row height]]||The row height for the page menu items in this App.<br />
|valign="top"|pagemenurowheight||valign="top"|Character<br />
|-<br />
|valign="top"|[[Page_Menu#Page_menu_CSS|Page menu CSS]]||CSS for the page menu in this App.<br />
|valign="top"|pagemenucss||valign="top"|Character<br />
|-<br />
|valign="top"|[[Page_Menu#Additional page menuitems|Additional page menuitems]]||Additional menuitems (that can call [[Using the showdocument() function and Lianja.showDocument() method|showdocument()]] actions) for the page menu in this App. From v5.3.<br />
|valign="top"|custompagesmenuitems||valign="top"|Character<br />
|-<br />
|valign="top"|[[Left Sidebar|Left sidebar visible]]||Show left sidebar (True &#124; False).<br />
|valign="top"|pagedefault_leftsidebarvisible||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Right Sidebar|Right sidebar visible]]||Show right sidebar (True &#124; False).<br />
|valign="top"|pagedefault_rightsidebarvisible||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Page Header#Hide search box|Hide search box]]||Hide the search box in the page header bar (True &#124; False).<br />
|valign="top"|pagedefault_hidesearchbox||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Page Header#Hide notifications icon|Hide notifications icon]]||Hide the notifications icon in the page header bar (True &#124; False).<br />
|valign="top"|pagedefault_hidenotificationsicon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Page Header#Hide custom search icon|Hide search icon]]||Hide the custom search icon in the page header bar (True &#124; False).<br />
|valign="top"|pagedefault_hidecustomsearchicon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Page Header#Hide fullscreen icon|Hide fullscreen icon]]||Hide the fullscreen icon in the page header bar (True &#124; False).<br />
|valign="top"|pagedefault_hidefullscreenicon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Page Header#Hide share icon|Hide share icon]]||Hide the share icon in the page header bar (True &#124; False).<br />
|valign="top"|pagedefault_hideshareicon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Page Header#Hide home icon|Hide home icon]]||Hide the home icon in the page header bar (True &#124; False).<br />
|valign="top"|pagedefault_hidehomeicon||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Section defaults==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Data Attributes#Inherit dictionary rules|Inherit dictionary rules]]||Inherit the data dictionary rules (True &#124; False)<br />
|valign="top"|pagesectioninheritdictionary||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section_Header#App_Settings|Header type]]||Choose the appearance of the section headers to use in this App<br>(Flat &#124; Gradient).<br />
|valign="top"|pagesectionheadertype||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section_Header#App_Settings|Icon set]]||Choose the icon set to use for the section headers in this App<br>(Gradient &#124; Black &#124; White &#124; Blue &#124; Gray &#124; Darkgray).<br />
|valign="top"|pagesectionheadericonset||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section_Header#App_Settings|Header height]]||The header height for the section headers in this App.<br />
|valign="top"|pagesectionheaderheight||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section_Header#App_Settings|Header background color]]||The background color for the section headers in this App.<br />
|valign="top"|pagesectionheaderbackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section_Header#App_Settings|Header foreground color]]||The foreground color for the section headers in this App.<br />
|valign="top"|pagesectionheaderforecolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section_Header#App_Settings|Header font size]]||The font size for the section headers in this App.<br />
|valign="top"|pagesectionheaderfontsize||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section_Header#App_Settings|Header CSS]]||The CSS for the section headers in this App.<br />
|valign="top"|pagesectionheadercss||valign="top"|Character<br />
|-<br />
|valign="top"|[[CSS|Section CSS]]||The CSS for the sections in this App.<br />
|valign="top"|pagesectioncss||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Delegates==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Custom Delegates#Scripting Language|Scripting language]]||The default scripting language for custom code in this App (Recital &#124; Visual FoxPro &#124; Python &#124; JavaScript &#124; TypeScript &#124; Babel &#124; PHP).<br />
|valign="top"|scriptinglanguage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom Library|Custom library]]||The filename of the library containing code for event handlers and custom procedures/functions.<br />
|valign="top"|customlibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Hotkey|Hotkey]]||The delegate procedure for the Hotkey event.<br />
|valign="top"|hotkeyaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Init|Init]]||The delegate procedure for the Init event.<br />
|valign="top"|initaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Destroy|Destroy]]||The delegate procedure for the Destroy event.<br />
|valign="top"|destroyaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Load|Load]]||The delegate procedure for the Load event.<br />
|valign="top"|loadaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Ready|Ready]]||The delegate procedure for the Ready event.<br />
|valign="top"|readyaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Unload|Unload]]||The delegate procedure for the Unload event.<br />
|valign="top"|unloadaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Database changed|Database changed]]||The delegate procedure for the Database changed event.<br>From v6.3.<br />
|valign="top"|databasechangedaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#State Changed|State Changed]]||The delegate procedure for the State Changed event.<br />
|valign="top"|statechangedaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Text Translator|Text Translator]]||The delegate procedure for translating text messages.<br />
|valign="top"|texttranslatoraction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#File System Watcher|File System Watcher]]||The delegate procedure for watching for changes to directories and/or files.<br />
|valign="top"|watchaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Orientation Changed|Orientation Changed]]||The delegate procedure for the Orientation Changed event.<br>From v6.0.<br />
|valign="top"|orientationchangedaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Device Motion Changed|Device Motion Changed]]||The delegate procedure for the Device Motion Changed event.<br>From v6.0.<br />
|valign="top"|devicemotionchangedaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Connection State Changed|Connection State Changed]]||The delegate procedure for the Connection State Changed event.<br>From v6.0.<br />
|valign="top"|connectionchangedaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Inactive|Inactive]]||The delegate procedure for the Inactive event.<br />
|valign="top"|inactiveaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Inactive interval|Inactive interval]]||The inactive interval in seconds that the inactive delegate procedure will be called at runtime.<br />
|valign="top"|inactiveinterval||valign="top"|Int<br />
|-<br />
|valign="top"|[[Custom Delegates#Before preview|Before preview]]||The delegate procedure for the before preview event.<br>From v6.3.<br />
|valign="top"|beforepreviewaction||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Permissions and Roles==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Users and Roles#Available roles|Available roles]]||A comma separated list of roles that are available for the App<br />
|valign="top"|permavailable||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Admin roles]]||A comma separated list of roles that can perform admin operations on the App<br />
|valign="top"|permadmin||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Create roles]]||A comma separated list of roles that can perform create operations on data in the App<br />
|valign="top"|permcreate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Read roles]]||A comma separated list of roles that can read (and execute) the App<br />
|valign="top"|permread||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Update roles]]||A comma separated list of roles that can perform update operations on data in the App<br />
|valign="top"|permupdate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Delete roles]]||A comma separated list of roles that can perform delete operations on data in the App<br />
|valign="top"|permdelete||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Standalone Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Standalone_Executables_on_Windows#Standalone_Lib|Standalone Lib]]||Include library files in the standalone App directory<br>(True &#124; False). From v9.5.<br />
|valign="top"|standalonelib||Boolean<br />
|-<br />
|valign="top"|[[Standalone_Executables_on_Windows#Standalone_Zip|Standalone Zip]]||Create a zip file for the standalone App<br>(True &#124; False). From v9.5.<br />
|valign="top"|standalonezip||Boolean<br />
|-<br />
|valign="top"|[[Standalone_Executables_on_Windows#Standalone_Exe|Standalone Exe]]||Create an installer as a self-extracting exe file for the standalone App<br>(True &#124; False). From v9.5.<br />
|valign="top"|standaloneexe||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Standalone_Executables_on_Windows#Standalone_Login|Standalone Login]]||The standalone App requires login.<br>(True &#124; False). From v9.5.<br />
|valign="top"|standalonelogin||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Standalone_Executables_on_Windows#Standalone_Python_modules|Standalone Python modules]]||The standalone App requires Python modules.<br>(True &#124; False). From v9.5.<br />
|valign="top"|standalonepython||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Standalone_Executables_on_Windows#Standalone_Exe|Standalone Data]]||Include databases (comma separated list) in the standalone App directory<br>(True &#124; False). From v9.5.<br />
|valign="top"|standalonedata||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==UI Presentation Rules==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Standalone_Executables_on_Windows#Standalone|Standalone]]||Build this App as a Standalone app (True &#124; False).<br />
|valign="top"|standaloneui||Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Form|Form]]||Run this App as a Form (True &#124; False).<br />
|valign="top"|formui||Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Desktop|Desktop]]||Include this App in a Desktop client (True &#124; False).<br />
|valign="top"|desktopui||Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Web|Web]]||Include this App in a Web client (True &#124; False).<br />
|valign="top"|webui||Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Tablet|Tablet]]||Include this App in a Tablet client (True &#124; False).<br />
|valign="top"|mobileui||Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Phone|Phone]]||Include this App in a Phone client (True &#124; False).<br />
|valign="top"|phoneui||Boolean<br />
|-<br />
|}<br />
<br />
[[Category:Attributes|1 App]]<br />
[[Category:App Settings]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/FormForm2024-03-26T13:26:53Z<p>Yvonne.milne: /* Properties */</p>
<hr />
<div>Note: property, method and event names should be referred to in lowercase in case-sensitive scripting languages.<br />
<br />
====Description====<br />
[[{{ns:file}}:form.png|link={{filepath:form.png}}|Form]]<br />
<br />
Forms are standalone containers used to contain other containers and controls.<br />
<br />
====Properties====<br />
<br />
This class supports the [[:Category:Common_Properties|Common Properties]] plus the following:<br />
<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Property<br />
!Access (R/RW)<br />
!Value<br />
!width="50%"|Description<br />
|-<br />
|valign="top"|Accepted<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|When a form is being closed the beforeclose() event is dispatched to the object (any supported scripting language). You can validate the data in the form and reject the "close" operation by setting accepted to false, default is true.<br />
|-<br />
|valign="top"|Actionbar<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form has an actionbar.<br />
|-<br />
|valign="top"|AlwaysOnBottom<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form should always be on the bottom<br />
|-<br />
|AlwaysOnTop<br />
|RW<br />
|Boolean<br />
|Whether form should always be on top<br />
|-<br />
|valign="top"|AutoCenter<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|Whether form is autocentered<br />
|-<br />
|BufferMode<br />
|RW<br />
|Numeric<br />
|Buffer mode<br />
|-<br />
|Caption<br />
|RW<br />
|Character<br />
|Text displayed in caption<br />
|-<br />
|Closable<br />
|RW<br />
|Boolean<br />
|Whether form is closable<br />
|-<br />
|valign="top"|ControlCount<br />
|valign="top"|R<br />
|valign="top"|Numeric<br />
|Number of controls in form<br />
|-<br />
|valign="top"|CurrentX<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Current x coordinate for the next drawing method<br />
|-<br />
|valign="top"|CurrentY<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Current y coordinate for the next drawing method<br />
|-<br />
|valign="top"|DrawWidth<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Line width in pixels for draw operations<br />
|-<br />
|valign="top"|ExitOnClose<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether to exit session on closing form<br />
|-<br />
|valign="top"|FillColor<br />
|valign="top"|RW<br />
|valign="top"|Numeric or Character<br />
|valign="top"|Fill color<br />
|-<br />
|FillStyle<br />
|RW<br />
|Numeric<br />
|Fill style setting<br />
|-<br />
|valign="top"|KeyPreview<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether keypreview is enabled<br />
|-<br />
|valign="top"|MaxButton<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form has a maximize button<br />
|-<br />
|valign="top"|Menubar<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form has a menubar. From v8.0.<br />
|-<br />
|valign="top"|MenubarLayout<br />
|valign="top"|RW<br />
|valign="top"|Character<br />
|valign="top"|Menubar specification: "Opt1(Sub1,Sub2,Sub3),Opt2(Sub4,Sub5),...".<br>From v8.0.<br />
|-<br />
|valign="top"|Message<br />
|valign="top"|RW<br />
|valign="top"|Character<br />
|Text displayed in statusbar<br />
|-<br />
|valign="top"|MinButton<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form has a minimize button<br />
|-<br />
|valign="top"|MobileFullScreen<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether when the form is running on a phone, it is maximized into the phone viewport with its border removed.<br />
|-<br />
|valign="top"|MousePointer<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Mouse pointer: 0 = arrow, 1 = arrow, 2 = cross, 3 = I-beam, 5 = size, 6 = NE/SW, 7 = size N/S, 8 = size NW/SE, 9 = size W/E, 10 = up arrow, 12 = no drop, 15 = pointing hand<br />
|-<br />
|valign="top"|Picture<br />
|valign="top"|RW<br />
|valign="top"|Character<br />
|Filename of background image<br />
|-<br />
|valign="top"|requireslogin<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether a [[Standalone Executables on Windows|standalone App]] requires the user to log in. From v9.5.<br />
|-<br />
|valign="top"|Scrollbars<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Scrollbars: 0 = none, 1 = horizontal, 2 = vertical, 3 = both<br />
|-<br />
|valign="top"|ShowTips<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether tooltips are shown for controls in the form<br />
|-<br />
|valign="top"|Statusbar<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|Whether form has a statusbar<br />
|-<br />
|valign="top"|Titlebar<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form has a titlebar<br />
|-<br />
|valign="top"|Toolbar<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form has a toolbar. From v8.0.<br />
|-<br />
|valign="top"|ToolbarLayout<br />
|valign="top"|RW<br />
|valign="top"|Character<br />
|valign="top"|Toolbar specification: "icon@Caption,icon@Caption,...". From v8.0.<br />
|-<br />
|valign="top"|ToolbarPosition<br />
|valign="top"|RW<br />
|valign="top"|Character<br />
|valign="top"|Toolbar position: left &#124; right &#124; top &#124; bottom. From v8.0.<br />
|-<br />
|valign="top"|WindowState<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Window state: 0 = normal, 1 = minimized, 2 = maximized, 3 = fullscreen/kiosk<br />
|-<br />
|valign="top"|WindowType<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Window type: 0 = modeless, 1 = modal<br />
|-<br />
|}<br />
<br />
====Methods====<br />
<br />
This class supports the [[:Category:Common_Methods|Common Methods]] plus the following:<br />
<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Method<br />
!Args<br />
!width="50%"|Description<br />
|-<br />
|valign="top"|AddObject<br />
|valign="top"|existing as Object &#124; newobject as Character, class as Character<br />
|valign="top"|Add an existing object or a new object, in which case the object's class must also be specified<br />
|-<br />
|valign="top"|Box<br />
|valign="top"|x as Numeric, y as Numeric[, x2 as Numeric, y2 as Numeric]<br />
|valign="top"|Draw a box from currentx, currenty to x, y. If x2 and y2 are specified, draw a box from x, y to x2, y2<br />
|-<br />
|valign="top"|Circle<br />
|valign="top"|radius as Numeric[, x as Numeric, y as Numeric]<br />
|valign="top"|Draw a circle with the specified radius at currentx, currenty. If x and y are specified, draw the circle at x, y<br />
|-<br />
|valign="top"|Clear<br />
|valign="top"|None<br />
|valign="top"|Clear the form<br />
|-<br />
|valign="top"|Close<br />
|valign="top"|None<br />
|valign="top"|Close the form<br />
|-<br />
|valign="top"|Controls<br />
|valign="top"|control as Numeric<br />
|valign="top"|Return an object reference to the specified control within the form<br />
|-<br />
|valign="top"|debug<br />
|valign="top"|None<br />
|valign="top"|Start the [[Standalone_Executables_on_Windows#Lianja_Standalone_App_Debugger|Lianja Standalone App Debugger]]. From v9.5.<br />
|-<br />
|valign="top"|Draw<br />
|valign="top"|None<br />
|valign="top"|Repaint form<br />
|-<br />
|valign="top"|get<br />
|valign="top"|id as Character<br />
|valign="top"|Reference the form UI element with the specified id. Synonym of getElementByID().<br>From v8.0.<br />
|-<br />
|valign="top"|getElementByID<br />
|valign="top"|id as Character<br />
|valign="top"|Reference the form UI element with the specified id. Synonym of get(). From v8.0.<br />
|-<br />
|valign="top"|HideMessage<br />
|valign="top"|None<br />
|valign="top"|Hide any system message currently displayed in the form. From v7.0.<br />
|-<br />
|valign="top"|Line<br />
|valign="top"|x as Numeric, y as Numeric[, x2 as Numeric, y2 as Numeric]<br />
|valign="top"|Draw a line from currentx, currenty to x, y. If x2 and y2 are specified, draw a line from x, y to x2, y2<br />
|-<br />
|valign="top"|Print<br />
|valign="top"|text as Character<br />
|valign="top"|Print the specified text in the form<br />
|-<br />
|valign="top"|printObjectTree<br />
|valign="top"|None<br />
|valign="top"|Print the form object tree, example output:<pre>form::form [visible=0, height=700, width=700]<br />
mycontainer5::container [visible=0, height=480, width=640]<br />
myheader5::label [visible=0, height=40, width=156]<br />
grid5::grid [visible=0, height=192, width=256]</pre><br />
From v8.0.<br />
|-<br />
|valign="top"|Release<br />
|valign="top"|None<br />
|valign="top"|Release form<br />
|-<br />
|valign="top"|RemoveObject<br />
|valign="top"|existing as Object<br />
|valign="top"|Remove the specified object<br />
|-<br />
|valign="top"|Show<br />
|valign="top"|[WindowType as Numeric]<br />
|valign="top"|Show the form. WindowType 0 = modeless, 1 = modal<br />
|-<br />
|valign="top"|ShowDropDown<br />
|valign="top"|controlID as Character[, width as Numeric[, height as Numeric]]<br />
|valign="top"|Show the Form as a drop down from the specified controlID UI control. Optionally specify the width and height of the drop down. If these are not specified, the width will adjust to width of the controlID UI control and the height defaults to 250 pixels. The drop down can be closed by pressing the Esc key or issuing a form.close(). (From Lianja v3.3).<br />
|-<br />
|valign="top"|ShowErrorMessage<br />
|valign="top"|text as Character<br />
|valign="top"|Display the specified text in a red system message at the top of the form. From v7.0.<br />
|-<br />
|valign="top"|ShowInfoMessage<br />
|valign="top"|text as Character<br />
|valign="top"|Display the specified text in a blue system message at the top of the form. From v7.0.<br />
|-<br />
|valign="top"|ShowMessage<br />
|valign="top"|text as Character<br />
|valign="top"|Display the specified text in a blue system message at the top of the form. From v7.0.<br />
|-<br />
|valign="top"|ShowSuccessMessage<br />
|valign="top"|text as Character<br />
|valign="top"|Display the specified text in a green system message at the top of the form. From v7.0.<br />
|-<br />
|valign="top"|ShowWarningMessage<br />
|valign="top"|text as Character<br />
|valign="top"|Display the specified text in a blue system message at the top of the form. From v7.0.<br />
|-<br />
|valign="top"|suspend<br />
|valign="top"|None<br />
|valign="top"|Suspend execution of a standalone App when the [[Standalone_Executables_on_Windows#Lianja_Standalone_App_Debugger|Lianja Standalone App Debugger]] is active. From v9.5.<br />
|-<br />
|valign="top"|TextHeight<br />
|valign="top"|None<br />
|valign="top"|Return current text height setting in pixels<br />
|-<br />
|valign="top"|TextWidth<br />
|valign="top"|text as Character<br />
|valign="top"|Return pixels required to display specified text<br />
|-<br />
|}<br />
<br />
====Events====<br />
<br />
This class supports the [[:Category:Common_Events|Common Events]] plus the following:<br />
<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Event<br />
!Args<br />
!width="50%"|Description<br />
|-<br />
|valign="top"|actionbarclick<br />
|valign="top"|actioncaption as Character<br />
|valign="top"|Occurs when an icon in the form actionbar is clicked. From v8.0.<br />
|-<br />
|afterclose<br />
|None<br />
|Occurs after the form is closed.<br />
|-<br />
|beforeclose<br />
|None<br />
|Occurs when the form is being closed.<br />
|-<br />
|valign="top"|initform<br />
|valign="top"|None<br />
|valign="top"|Occurs when the form is initialized. From v8.0.<br />
|-<br />
|load<br />
|None<br />
|Occurs before the form is activated<br />
|-<br />
|valign="top"|menubarclick<br />
|valign="top"|menucaption as Character<br />
|valign="top"|Occurs when an option in the form menubar is clicked. From v8.0.<br />
|-<br />
|valign="top"|moved<br />
|valign="top"|x as Numeric, y as Numeric,<br>width as Numeric, height as Numeric<br />
|valign="top"|Occurs when the form is moved or resized. From v7.0.<br />
|-<br />
|valign="top"|toolbarclick<br />
|valign="top"|toolcaption as Character<br />
|valign="top"|Occurs when an icon in the form toolbar is clicked. From v8.0.<br />
|-<br />
|}<br />
<br />
[[Category:Documentation]]<br />
[[Category:Framework Classes]]<br />
[[Category:Lianja v8.0]]<br />
[[Category:Lianja v9.5]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-26T13:24:55Z<p>Yvonne.milne: /* Login */</p>
<hr />
<div>=See Also=<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
=Overview=<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja visually build forms] in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
=Sample App: example_timeclock=<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
[[{{ns:file}}:standalone_uipres.png|left|link={{filepath:standalone_uipres.png}}|UI Presentation Rules and Standalone Options]]<br />
<br clear=all><br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include library files. When the standalone app is run the library directory is set to the standalone App library directory.<br />
<br />
The following text files are used to specify which library files should be included:<br />
<br />
===dependencies.txt===<br />
This is generated automatically when the App is [[#Building_and_Testing_Standalone_Executables|built]] if the App contains any [[:Category:WebView Based Sections|WebView Based Sections]].<br />
<br />
For example, the 'Tabbed Form' (form2) App, includes the following sections:<br />
*[[ArticleView Section Attributes|ArticleView]]<br />
*[[CatalogView Section Attributes|CatalogView]]<br />
*[[CommentsView Section Attributes|CommentsView]]<br />
*[[CarouselView Section Attributes|CarouselView]]<br />
*[[Calendar Section Attributes|Calendar]]<br />
<br />
and its dependencies.txt is generated as:<br />
<pre>@articleview<br />
@catalogview<br />
@commentsview<br />
@carouselview<br />
@calendar</pre><br />
<br />
The '@sectiontype' format references the corresponding 'sectiontype-dependencies.txt' file in the library containing the names of any required files and directories, e.g. catalogview-dependencies.txt:<br />
<pre>bootstrap-3.3.4<br />
jquery-1.10.2<br />
catalogview.*</pre><br />
<br />
===includes.txt===<br />
The 'includes.txt' file is used to specify any additional files that should be included.<br />
<br />
As in 'dependencies.txt' these can be:<br />
* folder names<br />
* individual file names<br />
* wildcards (like catalogview.*)<br />
* @filename to include the contents of '@filename-dependencies.txt'<br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create an installer as a self-extracting exe file for the standalone App. This can be unzipped / installed on a target machine.<br />
<br />
==Standalone Data==<br />
From v9.5, specifying a comma separated list of databases in the 'Standalone Data' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will copy the databases into the standalone App directory. When the standalone app is run the data directory is set to the standalone App data directory.<br />
<br />
==Setup==<br />
From v9.5, if the file setup.prg (or setup.py or setup.js) is contained within the App it is executed before the standalone App is run. You can check to see if the App is running standalone using [[Lianja|Lianja.standalone]] and check the file path using [[Lianja|Lianja.standalonefilepath]].<br />
<br />
You would typically do nothing in setup if the App is not running standalone.<br />
<br />
<code lang="recital"><br />
if not Lianja.standalone<br />
return<br />
endif<br />
<br />
// e.g. to share data on a network <br />
set datadir to f:\lianja\data<br />
</code><br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
==Login==<br />
From v9.5 standalone Apps can require login.<br />
* [[Form]].requireslogin property<br />
* Fully customizable login form<br />
<br />
''Coming Soon''<br />
<br />
=Building and Testing Standalone Executables=<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar:<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Lianja Standalone App Debugger==<br />
From v9.5 standalone Apps can be debugged at runtime.<br />
<br />
''Coming Soon''<br />
<br />
=Deploying Standalone Executables=<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
==Pre-9.5 Deployment==<br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
==Post-9.5 Deployment==<br />
From v9.5 you can also choose to deploy your App in the following ways:<br />
* Zip - set the [[#Standalone Zip|Standalone Zip]] App setting to true<br />
* Self-extracting exe - set the [[#Standalone Exe|Standalone Exe]] App setting to true<br />
<br />
Additionally, using the [[#Standalone Lib|Standalone Lib]] and [[#Standalone Data|Standalone Data]] App settings allows any required library files and databases to be included in the deployment zip or exe.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]<br />
[[Category:Lianja v9.5]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-26T13:23:49Z<p>Yvonne.milne: /* Lianja Standalone App Debugger */</p>
<hr />
<div>=See Also=<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
=Overview=<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja visually build forms] in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
=Sample App: example_timeclock=<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
[[{{ns:file}}:standalone_uipres.png|left|link={{filepath:standalone_uipres.png}}|UI Presentation Rules and Standalone Options]]<br />
<br clear=all><br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include library files. When the standalone app is run the library directory is set to the standalone App library directory.<br />
<br />
The following text files are used to specify which library files should be included:<br />
<br />
===dependencies.txt===<br />
This is generated automatically when the App is [[#Building_and_Testing_Standalone_Executables|built]] if the App contains any [[:Category:WebView Based Sections|WebView Based Sections]].<br />
<br />
For example, the 'Tabbed Form' (form2) App, includes the following sections:<br />
*[[ArticleView Section Attributes|ArticleView]]<br />
*[[CatalogView Section Attributes|CatalogView]]<br />
*[[CommentsView Section Attributes|CommentsView]]<br />
*[[CarouselView Section Attributes|CarouselView]]<br />
*[[Calendar Section Attributes|Calendar]]<br />
<br />
and its dependencies.txt is generated as:<br />
<pre>@articleview<br />
@catalogview<br />
@commentsview<br />
@carouselview<br />
@calendar</pre><br />
<br />
The '@sectiontype' format references the corresponding 'sectiontype-dependencies.txt' file in the library containing the names of any required files and directories, e.g. catalogview-dependencies.txt:<br />
<pre>bootstrap-3.3.4<br />
jquery-1.10.2<br />
catalogview.*</pre><br />
<br />
===includes.txt===<br />
The 'includes.txt' file is used to specify any additional files that should be included.<br />
<br />
As in 'dependencies.txt' these can be:<br />
* folder names<br />
* individual file names<br />
* wildcards (like catalogview.*)<br />
* @filename to include the contents of '@filename-dependencies.txt'<br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create an installer as a self-extracting exe file for the standalone App. This can be unzipped / installed on a target machine.<br />
<br />
==Standalone Data==<br />
From v9.5, specifying a comma separated list of databases in the 'Standalone Data' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will copy the databases into the standalone App directory. When the standalone app is run the data directory is set to the standalone App data directory.<br />
<br />
==Setup==<br />
From v9.5, if the file setup.prg (or setup.py or setup.js) is contained within the App it is executed before the standalone App is run. You can check to see if the App is running standalone using [[Lianja|Lianja.standalone]] and check the file path using [[Lianja|Lianja.standalonefilepath]].<br />
<br />
You would typically do nothing in setup if the App is not running standalone.<br />
<br />
<code lang="recital"><br />
if not Lianja.standalone<br />
return<br />
endif<br />
<br />
// e.g. to share data on a network <br />
set datadir to f:\lianja\data<br />
</code><br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
==Login==<br />
''Coming Soon''<br />
<br />
=Building and Testing Standalone Executables=<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar:<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Lianja Standalone App Debugger==<br />
From v9.5 standalone Apps can be debugged at runtime.<br />
<br />
''Coming Soon''<br />
<br />
=Deploying Standalone Executables=<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
==Pre-9.5 Deployment==<br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
==Post-9.5 Deployment==<br />
From v9.5 you can also choose to deploy your App in the following ways:<br />
* Zip - set the [[#Standalone Zip|Standalone Zip]] App setting to true<br />
* Self-extracting exe - set the [[#Standalone Exe|Standalone Exe]] App setting to true<br />
<br />
Additionally, using the [[#Standalone Lib|Standalone Lib]] and [[#Standalone Data|Standalone Data]] App settings allows any required library files and databases to be included in the deployment zip or exe.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]<br />
[[Category:Lianja v9.5]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-26T13:23:22Z<p>Yvonne.milne: /* Script */</p>
<hr />
<div>=See Also=<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
=Overview=<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja visually build forms] in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
=Sample App: example_timeclock=<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
[[{{ns:file}}:standalone_uipres.png|left|link={{filepath:standalone_uipres.png}}|UI Presentation Rules and Standalone Options]]<br />
<br clear=all><br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include library files. When the standalone app is run the library directory is set to the standalone App library directory.<br />
<br />
The following text files are used to specify which library files should be included:<br />
<br />
===dependencies.txt===<br />
This is generated automatically when the App is [[#Building_and_Testing_Standalone_Executables|built]] if the App contains any [[:Category:WebView Based Sections|WebView Based Sections]].<br />
<br />
For example, the 'Tabbed Form' (form2) App, includes the following sections:<br />
*[[ArticleView Section Attributes|ArticleView]]<br />
*[[CatalogView Section Attributes|CatalogView]]<br />
*[[CommentsView Section Attributes|CommentsView]]<br />
*[[CarouselView Section Attributes|CarouselView]]<br />
*[[Calendar Section Attributes|Calendar]]<br />
<br />
and its dependencies.txt is generated as:<br />
<pre>@articleview<br />
@catalogview<br />
@commentsview<br />
@carouselview<br />
@calendar</pre><br />
<br />
The '@sectiontype' format references the corresponding 'sectiontype-dependencies.txt' file in the library containing the names of any required files and directories, e.g. catalogview-dependencies.txt:<br />
<pre>bootstrap-3.3.4<br />
jquery-1.10.2<br />
catalogview.*</pre><br />
<br />
===includes.txt===<br />
The 'includes.txt' file is used to specify any additional files that should be included.<br />
<br />
As in 'dependencies.txt' these can be:<br />
* folder names<br />
* individual file names<br />
* wildcards (like catalogview.*)<br />
* @filename to include the contents of '@filename-dependencies.txt'<br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create an installer as a self-extracting exe file for the standalone App. This can be unzipped / installed on a target machine.<br />
<br />
==Standalone Data==<br />
From v9.5, specifying a comma separated list of databases in the 'Standalone Data' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will copy the databases into the standalone App directory. When the standalone app is run the data directory is set to the standalone App data directory.<br />
<br />
==Setup==<br />
From v9.5, if the file setup.prg (or setup.py or setup.js) is contained within the App it is executed before the standalone App is run. You can check to see if the App is running standalone using [[Lianja|Lianja.standalone]] and check the file path using [[Lianja|Lianja.standalonefilepath]].<br />
<br />
You would typically do nothing in setup if the App is not running standalone.<br />
<br />
<code lang="recital"><br />
if not Lianja.standalone<br />
return<br />
endif<br />
<br />
// e.g. to share data on a network <br />
set datadir to f:\lianja\data<br />
</code><br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
==Login==<br />
''Coming Soon''<br />
<br />
=Building and Testing Standalone Executables=<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar:<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Lianja Standalone App Debugger==<br />
From v9.5 standalone Apps can be debugged at runtime.<br />
<br />
''Under construction''<br />
<br />
<br />
=Deploying Standalone Executables=<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
==Pre-9.5 Deployment==<br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
==Post-9.5 Deployment==<br />
From v9.5 you can also choose to deploy your App in the following ways:<br />
* Zip - set the [[#Standalone Zip|Standalone Zip]] App setting to true<br />
* Self-extracting exe - set the [[#Standalone Exe|Standalone Exe]] App setting to true<br />
<br />
Additionally, using the [[#Standalone Lib|Standalone Lib]] and [[#Standalone Data|Standalone Data]] App settings allows any required library files and databases to be included in the deployment zip or exe.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]<br />
[[Category:Lianja v9.5]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/FormForm2024-03-26T11:13:05Z<p>Yvonne.milne: /* Events */</p>
<hr />
<div>Note: property, method and event names should be referred to in lowercase in case-sensitive scripting languages.<br />
<br />
====Description====<br />
[[{{ns:file}}:form.png|link={{filepath:form.png}}|Form]]<br />
<br />
Forms are standalone containers used to contain other containers and controls.<br />
<br />
====Properties====<br />
<br />
This class supports the [[:Category:Common_Properties|Common Properties]] plus the following:<br />
<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Property<br />
!Access (R/RW)<br />
!Value<br />
!width="50%"|Description<br />
|-<br />
|valign="top"|Accepted<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|When a form is being closed the beforeclose() event is dispatched to the object (any supported scripting language). You can validate the data in the form and reject the "close" operation by setting accepted to false, default is true.<br />
|-<br />
|valign="top"|Actionbar<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form has an actionbar.<br />
|-<br />
|valign="top"|AlwaysOnBottom<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form should always be on the bottom<br />
|-<br />
|AlwaysOnTop<br />
|RW<br />
|Boolean<br />
|Whether form should always be on top<br />
|-<br />
|valign="top"|AutoCenter<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|Whether form is autocentered<br />
|-<br />
|BufferMode<br />
|RW<br />
|Numeric<br />
|Buffer mode<br />
|-<br />
|Caption<br />
|RW<br />
|Character<br />
|Text displayed in caption<br />
|-<br />
|Closable<br />
|RW<br />
|Boolean<br />
|Whether form is closable<br />
|-<br />
|valign="top"|ControlCount<br />
|valign="top"|R<br />
|valign="top"|Numeric<br />
|Number of controls in form<br />
|-<br />
|valign="top"|CurrentX<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Current x coordinate for the next drawing method<br />
|-<br />
|valign="top"|CurrentY<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Current y coordinate for the next drawing method<br />
|-<br />
|valign="top"|DrawWidth<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Line width in pixels for draw operations<br />
|-<br />
|valign="top"|ExitOnClose<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether to exit session on closing form<br />
|-<br />
|valign="top"|FillColor<br />
|valign="top"|RW<br />
|valign="top"|Numeric or Character<br />
|valign="top"|Fill color<br />
|-<br />
|FillStyle<br />
|RW<br />
|Numeric<br />
|Fill style setting<br />
|-<br />
|valign="top"|KeyPreview<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether keypreview is enabled<br />
|-<br />
|valign="top"|MaxButton<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form has a maximize button<br />
|-<br />
|valign="top"|Menubar<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form has a menubar. From v8.0.<br />
|-<br />
|valign="top"|MenubarLayout<br />
|valign="top"|RW<br />
|valign="top"|Character<br />
|valign="top"|Menubar specification: "Opt1(Sub1,Sub2,Sub3),Opt2(Sub4,Sub5),...".<br>From v8.0.<br />
|-<br />
|valign="top"|Message<br />
|valign="top"|RW<br />
|valign="top"|Character<br />
|Text displayed in statusbar<br />
|-<br />
|valign="top"|MinButton<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form has a minimize button<br />
|-<br />
|valign="top"|MobileFullScreen<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether when the form is running on a phone, it is maximized into the phone viewport with its border removed.<br />
|-<br />
|valign="top"|MousePointer<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Mouse pointer: 0 = arrow, 1 = arrow, 2 = cross, 3 = I-beam, 5 = size, 6 = NE/SW, 7 = size N/S, 8 = size NW/SE, 9 = size W/E, 10 = up arrow, 12 = no drop, 15 = pointing hand<br />
|-<br />
|valign="top"|Picture<br />
|valign="top"|RW<br />
|valign="top"|Character<br />
|Filename of background image<br />
|-<br />
|valign="top"|Scrollbars<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Scrollbars: 0 = none, 1 = horizontal, 2 = vertical, 3 = both<br />
|-<br />
|valign="top"|ShowTips<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether tooltips are shown for controls in the form<br />
|-<br />
|valign="top"|Statusbar<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|Whether form has a statusbar<br />
|-<br />
|valign="top"|Titlebar<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form has a titlebar<br />
|-<br />
|valign="top"|Toolbar<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form has a toolbar. From v8.0.<br />
|-<br />
|valign="top"|ToolbarLayout<br />
|valign="top"|RW<br />
|valign="top"|Character<br />
|valign="top"|Toolbar specification: "icon@Caption,icon@Caption,...". From v8.0.<br />
|-<br />
|valign="top"|ToolbarPosition<br />
|valign="top"|RW<br />
|valign="top"|Character<br />
|valign="top"|Toolbar position: left &#124; right &#124; top &#124; bottom. From v8.0.<br />
|-<br />
|valign="top"|WindowState<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Window state: 0 = normal, 1 = minimized, 2 = maximized, 3 = fullscreen/kiosk<br />
|-<br />
|valign="top"|WindowType<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Window type: 0 = modeless, 1 = modal<br />
|-<br />
|}<br />
<br />
====Methods====<br />
<br />
This class supports the [[:Category:Common_Methods|Common Methods]] plus the following:<br />
<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Method<br />
!Args<br />
!width="50%"|Description<br />
|-<br />
|valign="top"|AddObject<br />
|valign="top"|existing as Object &#124; newobject as Character, class as Character<br />
|valign="top"|Add an existing object or a new object, in which case the object's class must also be specified<br />
|-<br />
|valign="top"|Box<br />
|valign="top"|x as Numeric, y as Numeric[, x2 as Numeric, y2 as Numeric]<br />
|valign="top"|Draw a box from currentx, currenty to x, y. If x2 and y2 are specified, draw a box from x, y to x2, y2<br />
|-<br />
|valign="top"|Circle<br />
|valign="top"|radius as Numeric[, x as Numeric, y as Numeric]<br />
|valign="top"|Draw a circle with the specified radius at currentx, currenty. If x and y are specified, draw the circle at x, y<br />
|-<br />
|valign="top"|Clear<br />
|valign="top"|None<br />
|valign="top"|Clear the form<br />
|-<br />
|valign="top"|Close<br />
|valign="top"|None<br />
|valign="top"|Close the form<br />
|-<br />
|valign="top"|Controls<br />
|valign="top"|control as Numeric<br />
|valign="top"|Return an object reference to the specified control within the form<br />
|-<br />
|valign="top"|debug<br />
|valign="top"|None<br />
|valign="top"|Start the [[Standalone_Executables_on_Windows#Lianja_Standalone_App_Debugger|Lianja Standalone App Debugger]]. From v9.5.<br />
|-<br />
|valign="top"|Draw<br />
|valign="top"|None<br />
|valign="top"|Repaint form<br />
|-<br />
|valign="top"|get<br />
|valign="top"|id as Character<br />
|valign="top"|Reference the form UI element with the specified id. Synonym of getElementByID().<br>From v8.0.<br />
|-<br />
|valign="top"|getElementByID<br />
|valign="top"|id as Character<br />
|valign="top"|Reference the form UI element with the specified id. Synonym of get(). From v8.0.<br />
|-<br />
|valign="top"|HideMessage<br />
|valign="top"|None<br />
|valign="top"|Hide any system message currently displayed in the form. From v7.0.<br />
|-<br />
|valign="top"|Line<br />
|valign="top"|x as Numeric, y as Numeric[, x2 as Numeric, y2 as Numeric]<br />
|valign="top"|Draw a line from currentx, currenty to x, y. If x2 and y2 are specified, draw a line from x, y to x2, y2<br />
|-<br />
|valign="top"|Print<br />
|valign="top"|text as Character<br />
|valign="top"|Print the specified text in the form<br />
|-<br />
|valign="top"|printObjectTree<br />
|valign="top"|None<br />
|valign="top"|Print the form object tree, example output:<pre>form::form [visible=0, height=700, width=700]<br />
mycontainer5::container [visible=0, height=480, width=640]<br />
myheader5::label [visible=0, height=40, width=156]<br />
grid5::grid [visible=0, height=192, width=256]</pre><br />
From v8.0.<br />
|-<br />
|valign="top"|Release<br />
|valign="top"|None<br />
|valign="top"|Release form<br />
|-<br />
|valign="top"|RemoveObject<br />
|valign="top"|existing as Object<br />
|valign="top"|Remove the specified object<br />
|-<br />
|valign="top"|Show<br />
|valign="top"|[WindowType as Numeric]<br />
|valign="top"|Show the form. WindowType 0 = modeless, 1 = modal<br />
|-<br />
|valign="top"|ShowDropDown<br />
|valign="top"|controlID as Character[, width as Numeric[, height as Numeric]]<br />
|valign="top"|Show the Form as a drop down from the specified controlID UI control. Optionally specify the width and height of the drop down. If these are not specified, the width will adjust to width of the controlID UI control and the height defaults to 250 pixels. The drop down can be closed by pressing the Esc key or issuing a form.close(). (From Lianja v3.3).<br />
|-<br />
|valign="top"|ShowErrorMessage<br />
|valign="top"|text as Character<br />
|valign="top"|Display the specified text in a red system message at the top of the form. From v7.0.<br />
|-<br />
|valign="top"|ShowInfoMessage<br />
|valign="top"|text as Character<br />
|valign="top"|Display the specified text in a blue system message at the top of the form. From v7.0.<br />
|-<br />
|valign="top"|ShowMessage<br />
|valign="top"|text as Character<br />
|valign="top"|Display the specified text in a blue system message at the top of the form. From v7.0.<br />
|-<br />
|valign="top"|ShowSuccessMessage<br />
|valign="top"|text as Character<br />
|valign="top"|Display the specified text in a green system message at the top of the form. From v7.0.<br />
|-<br />
|valign="top"|ShowWarningMessage<br />
|valign="top"|text as Character<br />
|valign="top"|Display the specified text in a blue system message at the top of the form. From v7.0.<br />
|-<br />
|valign="top"|suspend<br />
|valign="top"|None<br />
|valign="top"|Suspend execution of a standalone App when the [[Standalone_Executables_on_Windows#Lianja_Standalone_App_Debugger|Lianja Standalone App Debugger]] is active. From v9.5.<br />
|-<br />
|valign="top"|TextHeight<br />
|valign="top"|None<br />
|valign="top"|Return current text height setting in pixels<br />
|-<br />
|valign="top"|TextWidth<br />
|valign="top"|text as Character<br />
|valign="top"|Return pixels required to display specified text<br />
|-<br />
|}<br />
<br />
====Events====<br />
<br />
This class supports the [[:Category:Common_Events|Common Events]] plus the following:<br />
<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Event<br />
!Args<br />
!width="50%"|Description<br />
|-<br />
|valign="top"|actionbarclick<br />
|valign="top"|actioncaption as Character<br />
|valign="top"|Occurs when an icon in the form actionbar is clicked. From v8.0.<br />
|-<br />
|afterclose<br />
|None<br />
|Occurs after the form is closed.<br />
|-<br />
|beforeclose<br />
|None<br />
|Occurs when the form is being closed.<br />
|-<br />
|valign="top"|initform<br />
|valign="top"|None<br />
|valign="top"|Occurs when the form is initialized. From v8.0.<br />
|-<br />
|load<br />
|None<br />
|Occurs before the form is activated<br />
|-<br />
|valign="top"|menubarclick<br />
|valign="top"|menucaption as Character<br />
|valign="top"|Occurs when an option in the form menubar is clicked. From v8.0.<br />
|-<br />
|valign="top"|moved<br />
|valign="top"|x as Numeric, y as Numeric,<br>width as Numeric, height as Numeric<br />
|valign="top"|Occurs when the form is moved or resized. From v7.0.<br />
|-<br />
|valign="top"|toolbarclick<br />
|valign="top"|toolcaption as Character<br />
|valign="top"|Occurs when an icon in the form toolbar is clicked. From v8.0.<br />
|-<br />
|}<br />
<br />
[[Category:Documentation]]<br />
[[Category:Framework Classes]]<br />
[[Category:Lianja v8.0]]<br />
[[Category:Lianja v9.5]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/FormForm2024-03-26T11:11:19Z<p>Yvonne.milne: /* Methods */</p>
<hr />
<div>Note: property, method and event names should be referred to in lowercase in case-sensitive scripting languages.<br />
<br />
====Description====<br />
[[{{ns:file}}:form.png|link={{filepath:form.png}}|Form]]<br />
<br />
Forms are standalone containers used to contain other containers and controls.<br />
<br />
====Properties====<br />
<br />
This class supports the [[:Category:Common_Properties|Common Properties]] plus the following:<br />
<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Property<br />
!Access (R/RW)<br />
!Value<br />
!width="50%"|Description<br />
|-<br />
|valign="top"|Accepted<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|When a form is being closed the beforeclose() event is dispatched to the object (any supported scripting language). You can validate the data in the form and reject the "close" operation by setting accepted to false, default is true.<br />
|-<br />
|valign="top"|Actionbar<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form has an actionbar.<br />
|-<br />
|valign="top"|AlwaysOnBottom<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form should always be on the bottom<br />
|-<br />
|AlwaysOnTop<br />
|RW<br />
|Boolean<br />
|Whether form should always be on top<br />
|-<br />
|valign="top"|AutoCenter<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|Whether form is autocentered<br />
|-<br />
|BufferMode<br />
|RW<br />
|Numeric<br />
|Buffer mode<br />
|-<br />
|Caption<br />
|RW<br />
|Character<br />
|Text displayed in caption<br />
|-<br />
|Closable<br />
|RW<br />
|Boolean<br />
|Whether form is closable<br />
|-<br />
|valign="top"|ControlCount<br />
|valign="top"|R<br />
|valign="top"|Numeric<br />
|Number of controls in form<br />
|-<br />
|valign="top"|CurrentX<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Current x coordinate for the next drawing method<br />
|-<br />
|valign="top"|CurrentY<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Current y coordinate for the next drawing method<br />
|-<br />
|valign="top"|DrawWidth<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Line width in pixels for draw operations<br />
|-<br />
|valign="top"|ExitOnClose<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether to exit session on closing form<br />
|-<br />
|valign="top"|FillColor<br />
|valign="top"|RW<br />
|valign="top"|Numeric or Character<br />
|valign="top"|Fill color<br />
|-<br />
|FillStyle<br />
|RW<br />
|Numeric<br />
|Fill style setting<br />
|-<br />
|valign="top"|KeyPreview<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether keypreview is enabled<br />
|-<br />
|valign="top"|MaxButton<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form has a maximize button<br />
|-<br />
|valign="top"|Menubar<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form has a menubar. From v8.0.<br />
|-<br />
|valign="top"|MenubarLayout<br />
|valign="top"|RW<br />
|valign="top"|Character<br />
|valign="top"|Menubar specification: "Opt1(Sub1,Sub2,Sub3),Opt2(Sub4,Sub5),...".<br>From v8.0.<br />
|-<br />
|valign="top"|Message<br />
|valign="top"|RW<br />
|valign="top"|Character<br />
|Text displayed in statusbar<br />
|-<br />
|valign="top"|MinButton<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form has a minimize button<br />
|-<br />
|valign="top"|MobileFullScreen<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether when the form is running on a phone, it is maximized into the phone viewport with its border removed.<br />
|-<br />
|valign="top"|MousePointer<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Mouse pointer: 0 = arrow, 1 = arrow, 2 = cross, 3 = I-beam, 5 = size, 6 = NE/SW, 7 = size N/S, 8 = size NW/SE, 9 = size W/E, 10 = up arrow, 12 = no drop, 15 = pointing hand<br />
|-<br />
|valign="top"|Picture<br />
|valign="top"|RW<br />
|valign="top"|Character<br />
|Filename of background image<br />
|-<br />
|valign="top"|Scrollbars<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Scrollbars: 0 = none, 1 = horizontal, 2 = vertical, 3 = both<br />
|-<br />
|valign="top"|ShowTips<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether tooltips are shown for controls in the form<br />
|-<br />
|valign="top"|Statusbar<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|Whether form has a statusbar<br />
|-<br />
|valign="top"|Titlebar<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form has a titlebar<br />
|-<br />
|valign="top"|Toolbar<br />
|valign="top"|RW<br />
|valign="top"|Boolean<br />
|valign="top"|Whether form has a toolbar. From v8.0.<br />
|-<br />
|valign="top"|ToolbarLayout<br />
|valign="top"|RW<br />
|valign="top"|Character<br />
|valign="top"|Toolbar specification: "icon@Caption,icon@Caption,...". From v8.0.<br />
|-<br />
|valign="top"|ToolbarPosition<br />
|valign="top"|RW<br />
|valign="top"|Character<br />
|valign="top"|Toolbar position: left &#124; right &#124; top &#124; bottom. From v8.0.<br />
|-<br />
|valign="top"|WindowState<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Window state: 0 = normal, 1 = minimized, 2 = maximized, 3 = fullscreen/kiosk<br />
|-<br />
|valign="top"|WindowType<br />
|valign="top"|RW<br />
|valign="top"|Numeric<br />
|valign="top"|Window type: 0 = modeless, 1 = modal<br />
|-<br />
|}<br />
<br />
====Methods====<br />
<br />
This class supports the [[:Category:Common_Methods|Common Methods]] plus the following:<br />
<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Method<br />
!Args<br />
!width="50%"|Description<br />
|-<br />
|valign="top"|AddObject<br />
|valign="top"|existing as Object &#124; newobject as Character, class as Character<br />
|valign="top"|Add an existing object or a new object, in which case the object's class must also be specified<br />
|-<br />
|valign="top"|Box<br />
|valign="top"|x as Numeric, y as Numeric[, x2 as Numeric, y2 as Numeric]<br />
|valign="top"|Draw a box from currentx, currenty to x, y. If x2 and y2 are specified, draw a box from x, y to x2, y2<br />
|-<br />
|valign="top"|Circle<br />
|valign="top"|radius as Numeric[, x as Numeric, y as Numeric]<br />
|valign="top"|Draw a circle with the specified radius at currentx, currenty. If x and y are specified, draw the circle at x, y<br />
|-<br />
|valign="top"|Clear<br />
|valign="top"|None<br />
|valign="top"|Clear the form<br />
|-<br />
|valign="top"|Close<br />
|valign="top"|None<br />
|valign="top"|Close the form<br />
|-<br />
|valign="top"|Controls<br />
|valign="top"|control as Numeric<br />
|valign="top"|Return an object reference to the specified control within the form<br />
|-<br />
|valign="top"|debug<br />
|valign="top"|None<br />
|valign="top"|Start the [[Standalone_Executables_on_Windows#Lianja_Standalone_App_Debugger|Lianja Standalone App Debugger]]. From v9.5.<br />
|-<br />
|valign="top"|Draw<br />
|valign="top"|None<br />
|valign="top"|Repaint form<br />
|-<br />
|valign="top"|get<br />
|valign="top"|id as Character<br />
|valign="top"|Reference the form UI element with the specified id. Synonym of getElementByID().<br>From v8.0.<br />
|-<br />
|valign="top"|getElementByID<br />
|valign="top"|id as Character<br />
|valign="top"|Reference the form UI element with the specified id. Synonym of get(). From v8.0.<br />
|-<br />
|valign="top"|HideMessage<br />
|valign="top"|None<br />
|valign="top"|Hide any system message currently displayed in the form. From v7.0.<br />
|-<br />
|valign="top"|Line<br />
|valign="top"|x as Numeric, y as Numeric[, x2 as Numeric, y2 as Numeric]<br />
|valign="top"|Draw a line from currentx, currenty to x, y. If x2 and y2 are specified, draw a line from x, y to x2, y2<br />
|-<br />
|valign="top"|Print<br />
|valign="top"|text as Character<br />
|valign="top"|Print the specified text in the form<br />
|-<br />
|valign="top"|printObjectTree<br />
|valign="top"|None<br />
|valign="top"|Print the form object tree, example output:<pre>form::form [visible=0, height=700, width=700]<br />
mycontainer5::container [visible=0, height=480, width=640]<br />
myheader5::label [visible=0, height=40, width=156]<br />
grid5::grid [visible=0, height=192, width=256]</pre><br />
From v8.0.<br />
|-<br />
|valign="top"|Release<br />
|valign="top"|None<br />
|valign="top"|Release form<br />
|-<br />
|valign="top"|RemoveObject<br />
|valign="top"|existing as Object<br />
|valign="top"|Remove the specified object<br />
|-<br />
|valign="top"|Show<br />
|valign="top"|[WindowType as Numeric]<br />
|valign="top"|Show the form. WindowType 0 = modeless, 1 = modal<br />
|-<br />
|valign="top"|ShowDropDown<br />
|valign="top"|controlID as Character[, width as Numeric[, height as Numeric]]<br />
|valign="top"|Show the Form as a drop down from the specified controlID UI control. Optionally specify the width and height of the drop down. If these are not specified, the width will adjust to width of the controlID UI control and the height defaults to 250 pixels. The drop down can be closed by pressing the Esc key or issuing a form.close(). (From Lianja v3.3).<br />
|-<br />
|valign="top"|ShowErrorMessage<br />
|valign="top"|text as Character<br />
|valign="top"|Display the specified text in a red system message at the top of the form. From v7.0.<br />
|-<br />
|valign="top"|ShowInfoMessage<br />
|valign="top"|text as Character<br />
|valign="top"|Display the specified text in a blue system message at the top of the form. From v7.0.<br />
|-<br />
|valign="top"|ShowMessage<br />
|valign="top"|text as Character<br />
|valign="top"|Display the specified text in a blue system message at the top of the form. From v7.0.<br />
|-<br />
|valign="top"|ShowSuccessMessage<br />
|valign="top"|text as Character<br />
|valign="top"|Display the specified text in a green system message at the top of the form. From v7.0.<br />
|-<br />
|valign="top"|ShowWarningMessage<br />
|valign="top"|text as Character<br />
|valign="top"|Display the specified text in a blue system message at the top of the form. From v7.0.<br />
|-<br />
|valign="top"|suspend<br />
|valign="top"|None<br />
|valign="top"|Suspend execution of a standalone App when the [[Standalone_Executables_on_Windows#Lianja_Standalone_App_Debugger|Lianja Standalone App Debugger]] is active. From v9.5.<br />
|-<br />
|valign="top"|TextHeight<br />
|valign="top"|None<br />
|valign="top"|Return current text height setting in pixels<br />
|-<br />
|valign="top"|TextWidth<br />
|valign="top"|text as Character<br />
|valign="top"|Return pixels required to display specified text<br />
|-<br />
|}<br />
<br />
====Events====<br />
<br />
This class supports the [[:Category:Common_Events|Common Events]] plus the following:<br />
<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Event<br />
!Args<br />
!width="50%"|Description<br />
|-<br />
|valign="top"|actionbarclick<br />
|valign="top"|actioncaption as Character<br />
|valign="top"|Occurs when an icon in the form actionbar is clicked. From v8.0.<br />
|-<br />
|afterclose<br />
|None<br />
|Occurs after the form is closed.<br />
|-<br />
|beforeclose<br />
|None<br />
|Occurs when the form is being closed.<br />
|-<br />
|valign="top"|initform<br />
|valign="top"|None<br />
|valign="top"|Occurs when the form is initialized. From v8.0.<br />
|-<br />
|load<br />
|None<br />
|Occurs before the form is activated<br />
|-<br />
|valign="top"|menubarclick<br />
|valign="top"|menucaption as Character<br />
|valign="top"|Occurs when an option in the form menubar is clicked. From v8.0.<br />
|-<br />
|valign="top"|moved<br />
|valign="top"|x as Numeric, y as Numeric,<br>width as Numeric, height as Numeric<br />
|valign="top"|Occurs when the form is moved or resized. From v7.0.<br />
|-<br />
|valign="top"|toolbarclick<br />
|valign="top"|toolcaption as Character<br />
|valign="top"|Occurs when an icon in the form toolbar is clicked. From v8.0.<br />
|-<br />
|}<br />
<br />
[[Category:Documentation]]<br />
[[Category:Framework Classes]]<br />
[[Category:Lianja v8.0]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-26T10:49:27Z<p>Yvonne.milne: /* Deploying Standalone Executables */</p>
<hr />
<div>=See Also=<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
=Overview=<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja visually build forms] in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
=Sample App: example_timeclock=<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
[[{{ns:file}}:standalone_uipres.png|left|link={{filepath:standalone_uipres.png}}|UI Presentation Rules and Standalone Options]]<br />
<br clear=all><br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include library files. When the standalone app is run the library directory is set to the standalone App library directory.<br />
<br />
The following text files are used to specify which library files should be included:<br />
<br />
===dependencies.txt===<br />
This is generated automatically when the App is [[#Building_and_Testing_Standalone_Executables|built]] if the App contains any [[:Category:WebView Based Sections|WebView Based Sections]].<br />
<br />
For example, the 'Tabbed Form' (form2) App, includes the following sections:<br />
*[[ArticleView Section Attributes|ArticleView]]<br />
*[[CatalogView Section Attributes|CatalogView]]<br />
*[[CommentsView Section Attributes|CommentsView]]<br />
*[[CarouselView Section Attributes|CarouselView]]<br />
*[[Calendar Section Attributes|Calendar]]<br />
<br />
and its dependencies.txt is generated as:<br />
<pre>@articleview<br />
@catalogview<br />
@commentsview<br />
@carouselview<br />
@calendar</pre><br />
<br />
The '@sectiontype' format references the corresponding 'sectiontype-dependencies.txt' file in the library containing the names of any required files and directories, e.g. catalogview-dependencies.txt:<br />
<pre>bootstrap-3.3.4<br />
jquery-1.10.2<br />
catalogview.*</pre><br />
<br />
===includes.txt===<br />
The 'includes.txt' file is used to specify any additional files that should be included.<br />
<br />
As in 'dependencies.txt' these can be:<br />
* folder names<br />
* individual file names<br />
* wildcards (like catalogview.*)<br />
* @filename to include the contents of '@filename-dependencies.txt'<br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create an installer as a self-extracting exe file for the standalone App. This can be unzipped / installed on a target machine.<br />
<br />
==Standalone Data==<br />
From v9.5, specifying a comma separated list of databases in the 'Standalone Data' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will copy the databases into the standalone App directory. When the standalone app is run the data directory is set to the standalone App data directory.<br />
<br />
==Setup==<br />
From v9.5, if the file setup.prg (or setup.py or setup.js) is contained within the App it is executed before the standalone App is run. You can check to see if the App is running standalone using [[Lianja|Lianja.standalone]] and check the file path using [[Lianja|Lianja.standalonefilepath]].<br />
<br />
You would typically do nothing in setup if the App is not running standalone.<br />
<br />
<code lang="recital"><br />
if not Lianja.standalone<br />
return<br />
endif<br />
<br />
// e.g. to share data on a network <br />
set datadir to f:\lianja\data<br />
</code><br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
=Building and Testing Standalone Executables=<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar:<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Lianja Standalone App Debugger==<br />
From v9.5 standalone Apps can be debugged at runtime.<br />
<br />
''Under construction''<br />
<br />
<br />
=Deploying Standalone Executables=<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
==Pre-9.5 Deployment==<br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
==Post-9.5 Deployment==<br />
From v9.5 you can also choose to deploy your App in the following ways:<br />
* Zip - set the [[#Standalone Zip|Standalone Zip]] App setting to true<br />
* Self-extracting exe - set the [[#Standalone Exe|Standalone Exe]] App setting to true<br />
<br />
Additionally, using the [[#Standalone Lib|Standalone Lib]] and [[#Standalone Data|Standalone Data]] App settings allows any required library files and databases to be included in the deployment zip or exe.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]<br />
[[Category:Lianja v9.5]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-26T10:41:49Z<p>Yvonne.milne: /* Deploying Standalone Executables */</p>
<hr />
<div>=See Also=<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
=Overview=<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja visually build forms] in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
=Sample App: example_timeclock=<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
[[{{ns:file}}:standalone_uipres.png|left|link={{filepath:standalone_uipres.png}}|UI Presentation Rules and Standalone Options]]<br />
<br clear=all><br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include library files. When the standalone app is run the library directory is set to the standalone App library directory.<br />
<br />
The following text files are used to specify which library files should be included:<br />
<br />
===dependencies.txt===<br />
This is generated automatically when the App is [[#Building_and_Testing_Standalone_Executables|built]] if the App contains any [[:Category:WebView Based Sections|WebView Based Sections]].<br />
<br />
For example, the 'Tabbed Form' (form2) App, includes the following sections:<br />
*[[ArticleView Section Attributes|ArticleView]]<br />
*[[CatalogView Section Attributes|CatalogView]]<br />
*[[CommentsView Section Attributes|CommentsView]]<br />
*[[CarouselView Section Attributes|CarouselView]]<br />
*[[Calendar Section Attributes|Calendar]]<br />
<br />
and its dependencies.txt is generated as:<br />
<pre>@articleview<br />
@catalogview<br />
@commentsview<br />
@carouselview<br />
@calendar</pre><br />
<br />
The '@sectiontype' format references the corresponding 'sectiontype-dependencies.txt' file in the library containing the names of any required files and directories, e.g. catalogview-dependencies.txt:<br />
<pre>bootstrap-3.3.4<br />
jquery-1.10.2<br />
catalogview.*</pre><br />
<br />
===includes.txt===<br />
The 'includes.txt' file is used to specify any additional files that should be included.<br />
<br />
As in 'dependencies.txt' these can be:<br />
* folder names<br />
* individual file names<br />
* wildcards (like catalogview.*)<br />
* @filename to include the contents of '@filename-dependencies.txt'<br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create an installer as a self-extracting exe file for the standalone App. This can be unzipped / installed on a target machine.<br />
<br />
==Standalone Data==<br />
From v9.5, specifying a comma separated list of databases in the 'Standalone Data' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will copy the databases into the standalone App directory. When the standalone app is run the data directory is set to the standalone App data directory.<br />
<br />
==Setup==<br />
From v9.5, if the file setup.prg (or setup.py or setup.js) is contained within the App it is executed before the standalone App is run. You can check to see if the App is running standalone using [[Lianja|Lianja.standalone]] and check the file path using [[Lianja|Lianja.standalonefilepath]].<br />
<br />
You would typically do nothing in setup if the App is not running standalone.<br />
<br />
<code lang="recital"><br />
if not Lianja.standalone<br />
return<br />
endif<br />
<br />
// e.g. to share data on a network <br />
set datadir to f:\lianja\data<br />
</code><br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
=Building and Testing Standalone Executables=<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar:<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Lianja Standalone App Debugger==<br />
From v9.5 standalone Apps can be debugged at runtime.<br />
<br />
''Under construction''<br />
<br />
<br />
=Deploying Standalone Executables=<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]<br />
[[Category:Lianja v9.5]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-26T10:39:55Z<p>Yvonne.milne: /* Building and Testing Standalone Executables */</p>
<hr />
<div>=See Also=<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
=Overview=<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja visually build forms] in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
=Sample App: example_timeclock=<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
[[{{ns:file}}:standalone_uipres.png|left|link={{filepath:standalone_uipres.png}}|UI Presentation Rules and Standalone Options]]<br />
<br clear=all><br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include library files. When the standalone app is run the library directory is set to the standalone App library directory.<br />
<br />
The following text files are used to specify which library files should be included:<br />
<br />
===dependencies.txt===<br />
This is generated automatically when the App is [[#Building_and_Testing_Standalone_Executables|built]] if the App contains any [[:Category:WebView Based Sections|WebView Based Sections]].<br />
<br />
For example, the 'Tabbed Form' (form2) App, includes the following sections:<br />
*[[ArticleView Section Attributes|ArticleView]]<br />
*[[CatalogView Section Attributes|CatalogView]]<br />
*[[CommentsView Section Attributes|CommentsView]]<br />
*[[CarouselView Section Attributes|CarouselView]]<br />
*[[Calendar Section Attributes|Calendar]]<br />
<br />
and its dependencies.txt is generated as:<br />
<pre>@articleview<br />
@catalogview<br />
@commentsview<br />
@carouselview<br />
@calendar</pre><br />
<br />
The '@sectiontype' format references the corresponding 'sectiontype-dependencies.txt' file in the library containing the names of any required files and directories, e.g. catalogview-dependencies.txt:<br />
<pre>bootstrap-3.3.4<br />
jquery-1.10.2<br />
catalogview.*</pre><br />
<br />
===includes.txt===<br />
The 'includes.txt' file is used to specify any additional files that should be included.<br />
<br />
As in 'dependencies.txt' these can be:<br />
* folder names<br />
* individual file names<br />
* wildcards (like catalogview.*)<br />
* @filename to include the contents of '@filename-dependencies.txt'<br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create an installer as a self-extracting exe file for the standalone App. This can be unzipped / installed on a target machine.<br />
<br />
==Standalone Data==<br />
From v9.5, specifying a comma separated list of databases in the 'Standalone Data' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will copy the databases into the standalone App directory. When the standalone app is run the data directory is set to the standalone App data directory.<br />
<br />
==Setup==<br />
From v9.5, if the file setup.prg (or setup.py or setup.js) is contained within the App it is executed before the standalone App is run. You can check to see if the App is running standalone using [[Lianja|Lianja.standalone]] and check the file path using [[Lianja|Lianja.standalonefilepath]].<br />
<br />
You would typically do nothing in setup if the App is not running standalone.<br />
<br />
<code lang="recital"><br />
if not Lianja.standalone<br />
return<br />
endif<br />
<br />
// e.g. to share data on a network <br />
set datadir to f:\lianja\data<br />
</code><br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
=Building and Testing Standalone Executables=<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar:<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Lianja Standalone App Debugger==<br />
From v9.5 standalone Apps can be debugged at runtime.<br />
<br />
''Under construction''<br />
<br />
<br />
=Deploying Standalone Executables=<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-25T11:13:52Z<p>Yvonne.milne: /* Standalone Data */</p>
<hr />
<div>=See Also=<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
=Overview=<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja visually build forms] in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
=Sample App: example_timeclock=<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
[[{{ns:file}}:standalone_uipres.png|left|link={{filepath:standalone_uipres.png}}|UI Presentation Rules and Standalone Options]]<br />
<br clear=all><br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include library files. When the standalone app is run the library directory is set to the standalone App library directory.<br />
<br />
The following text files are used to specify which library files should be included:<br />
<br />
===dependencies.txt===<br />
This is generated automatically when the App is [[#Building_and_Testing_Standalone_Executables|built]] if the App contains any [[:Category:WebView Based Sections|WebView Based Sections]].<br />
<br />
For example, the 'Tabbed Form' (form2) App, includes the following sections:<br />
*[[ArticleView Section Attributes|ArticleView]]<br />
*[[CatalogView Section Attributes|CatalogView]]<br />
*[[CommentsView Section Attributes|CommentsView]]<br />
*[[CarouselView Section Attributes|CarouselView]]<br />
*[[Calendar Section Attributes|Calendar]]<br />
<br />
and its dependencies.txt is generated as:<br />
<pre>@articleview<br />
@catalogview<br />
@commentsview<br />
@carouselview<br />
@calendar</pre><br />
<br />
The '@sectiontype' format references the corresponding 'sectiontype-dependencies.txt' file in the library containing the names of any required files and directories, e.g. catalogview-dependencies.txt:<br />
<pre>bootstrap-3.3.4<br />
jquery-1.10.2<br />
catalogview.*</pre><br />
<br />
===includes.txt===<br />
The 'includes.txt' file is used to specify any additional files that should be included.<br />
<br />
As in 'dependencies.txt' these can be:<br />
* folder names<br />
* individual file names<br />
* wildcards (like catalogview.*)<br />
* @filename to include the contents of '@filename-dependencies.txt'<br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create an installer as a self-extracting exe file for the standalone App. This can be unzipped / installed on a target machine.<br />
<br />
==Standalone Data==<br />
From v9.5, specifying a comma separated list of databases in the 'Standalone Data' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will copy the databases into the standalone App directory. When the standalone app is run the data directory is set to the standalone App data directory.<br />
<br />
==Setup==<br />
From v9.5, if the file setup.prg (or setup.py or setup.js) is contained within the App it is executed before the standalone App is run. You can check to see if the App is running standalone using [[Lianja|Lianja.standalone]] and check the file path using [[Lianja|Lianja.standalonefilepath]].<br />
<br />
You would typically do nothing in setup if the App is not running standalone.<br />
<br />
<code lang="recital"><br />
if not Lianja.standalone<br />
return<br />
endif<br />
<br />
// e.g. to share data on a network <br />
set datadir to f:\lianja\data<br />
</code><br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
=Building and Testing Standalone Executables=<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar:<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Deploying Standalone Executables==<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-22T14:17:08Z<p>Yvonne.milne: /* includes.txt */</p>
<hr />
<div>=See Also=<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
=Overview=<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja visually build forms] in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
=Sample App: example_timeclock=<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
[[{{ns:file}}:standalone_uipres.png|left|link={{filepath:standalone_uipres.png}}|UI Presentation Rules and Standalone Options]]<br />
<br clear=all><br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include library files. When the standalone app is run the library directory is set to the standalone App library directory.<br />
<br />
The following text files are used to specify which library files should be included:<br />
<br />
===dependencies.txt===<br />
This is generated automatically when the App is [[#Building_and_Testing_Standalone_Executables|built]] if the App contains any [[:Category:WebView Based Sections|WebView Based Sections]].<br />
<br />
For example, the 'Tabbed Form' (form2) App, includes the following sections:<br />
*[[ArticleView Section Attributes|ArticleView]]<br />
*[[CatalogView Section Attributes|CatalogView]]<br />
*[[CommentsView Section Attributes|CommentsView]]<br />
*[[CarouselView Section Attributes|CarouselView]]<br />
*[[Calendar Section Attributes|Calendar]]<br />
<br />
and its dependencies.txt is generated as:<br />
<pre>@articleview<br />
@catalogview<br />
@commentsview<br />
@carouselview<br />
@calendar</pre><br />
<br />
The '@sectiontype' format references the corresponding 'sectiontype-dependencies.txt' file in the library containing the names of any required files and directories, e.g. catalogview-dependencies.txt:<br />
<pre>bootstrap-3.3.4<br />
jquery-1.10.2<br />
catalogview.*</pre><br />
<br />
===includes.txt===<br />
The 'includes.txt' file is used to specify any additional files that should be included.<br />
<br />
As in 'dependencies.txt' these can be:<br />
* folder names<br />
* individual file names<br />
* wildcards (like catalogview.*)<br />
* @filename to include the contents of '@filename-dependencies.txt'<br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create an installer as a self-extracting exe file for the standalone App. This can be unzipped / installed on a target machine.<br />
<br />
==Standalone Data==<br />
From v9.5, specifying a list of databases in the 'Standalone Data' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will copy the databases into the standalone App directory. When the standalone app is run the data directory is set to the standalone App data directory.<br />
<br />
==Setup==<br />
From v9.5, if the file setup.prg (or setup.py or setup.js) is contained within the App it is executed before the standalone App is run. You can check to see if the App is running standalone using [[Lianja|Lianja.standalone]] and check the file path using [[Lianja|Lianja.standalonefilepath]].<br />
<br />
You would typically do nothing in setup if the App is not running standalone.<br />
<br />
<code lang="recital"><br />
if not Lianja.standalone<br />
return<br />
endif<br />
<br />
// e.g. to share data on a network <br />
set datadir to f:\lianja\data<br />
</code><br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
=Building and Testing Standalone Executables=<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar:<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Deploying Standalone Executables==<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-22T14:14:03Z<p>Yvonne.milne: /* Setup */</p>
<hr />
<div>=See Also=<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
=Overview=<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja visually build forms] in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
=Sample App: example_timeclock=<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
[[{{ns:file}}:standalone_uipres.png|left|link={{filepath:standalone_uipres.png}}|UI Presentation Rules and Standalone Options]]<br />
<br clear=all><br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include library files. When the standalone app is run the library directory is set to the standalone App library directory.<br />
<br />
The following text files are used to specify which library files should be included:<br />
<br />
===dependencies.txt===<br />
This is generated automatically when the App is [[#Building_and_Testing_Standalone_Executables|built]] if the App contains any [[:Category:WebView Based Sections|WebView Based Sections]].<br />
<br />
For example, the 'Tabbed Form' (form2) App, includes the following sections:<br />
*[[ArticleView Section Attributes|ArticleView]]<br />
*[[CatalogView Section Attributes|CatalogView]]<br />
*[[CommentsView Section Attributes|CommentsView]]<br />
*[[CarouselView Section Attributes|CarouselView]]<br />
*[[Calendar Section Attributes|Calendar]]<br />
<br />
and its dependencies.txt is generated as:<br />
<pre>@articleview<br />
@catalogview<br />
@commentsview<br />
@carouselview<br />
@calendar</pre><br />
<br />
The '@sectiontype' format references the corresponding 'sectiontype-dependencies.txt' file in the library containing the names of any required files and directories, e.g. catalogview-dependencies.txt:<br />
<pre>bootstrap-3.3.4<br />
jquery-1.10.2<br />
catalogview.*</pre><br />
<br />
===includes.txt===<br />
The 'includes.txt' file is used to specify any additional files that should be included.<br />
<br />
As in 'dependencies.txt' these can be:<br />
* folder names<br />
* individual file names<br />
* wildcards (like catalog.*)<br />
* @filename to include the contents of '@filename-dependencies.txt'<br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create an installer as a self-extracting exe file for the standalone App. This can be unzipped / installed on a target machine.<br />
<br />
==Standalone Data==<br />
From v9.5, specifying a list of databases in the 'Standalone Data' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will copy the databases into the standalone App directory. When the standalone app is run the data directory is set to the standalone App data directory.<br />
<br />
==Setup==<br />
From v9.5, if the file setup.prg (or setup.py or setup.js) is contained within the App it is executed before the standalone App is run. You can check to see if the App is running standalone using [[Lianja|Lianja.standalone]] and check the file path using [[Lianja|Lianja.standalonefilepath]].<br />
<br />
You would typically do nothing in setup if the App is not running standalone.<br />
<br />
<code lang="recital"><br />
if not Lianja.standalone<br />
return<br />
endif<br />
<br />
// e.g. to share data on a network <br />
set datadir to f:\lianja\data<br />
</code><br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
=Building and Testing Standalone Executables=<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar:<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Deploying Standalone Executables==<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-22T14:11:39Z<p>Yvonne.milne: /* Standalone Lib */</p>
<hr />
<div>=See Also=<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
=Overview=<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja visually build forms] in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
=Sample App: example_timeclock=<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
[[{{ns:file}}:standalone_uipres.png|left|link={{filepath:standalone_uipres.png}}|UI Presentation Rules and Standalone Options]]<br />
<br clear=all><br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include library files. When the standalone app is run the library directory is set to the standalone App library directory.<br />
<br />
The following text files are used to specify which library files should be included:<br />
<br />
===dependencies.txt===<br />
This is generated automatically when the App is [[#Building_and_Testing_Standalone_Executables|built]] if the App contains any [[:Category:WebView Based Sections|WebView Based Sections]].<br />
<br />
For example, the 'Tabbed Form' (form2) App, includes the following sections:<br />
*[[ArticleView Section Attributes|ArticleView]]<br />
*[[CatalogView Section Attributes|CatalogView]]<br />
*[[CommentsView Section Attributes|CommentsView]]<br />
*[[CarouselView Section Attributes|CarouselView]]<br />
*[[Calendar Section Attributes|Calendar]]<br />
<br />
and its dependencies.txt is generated as:<br />
<pre>@articleview<br />
@catalogview<br />
@commentsview<br />
@carouselview<br />
@calendar</pre><br />
<br />
The '@sectiontype' format references the corresponding 'sectiontype-dependencies.txt' file in the library containing the names of any required files and directories, e.g. catalogview-dependencies.txt:<br />
<pre>bootstrap-3.3.4<br />
jquery-1.10.2<br />
catalogview.*</pre><br />
<br />
===includes.txt===<br />
The 'includes.txt' file is used to specify any additional files that should be included.<br />
<br />
As in 'dependencies.txt' these can be:<br />
* folder names<br />
* individual file names<br />
* wildcards (like catalog.*)<br />
* @filename to include the contents of '@filename-dependencies.txt'<br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create an installer as a self-extracting exe file for the standalone App. This can be unzipped / installed on a target machine.<br />
<br />
==Standalone Data==<br />
From v9.5, specifying a list of databases in the 'Standalone Data' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will copy the databases into the standalone App directory. When the standalone app is run the data directory is set to the standalone App data directory.<br />
<br />
==Setup==<br />
From v9.5, if the file setup.prg /.dbo is contained within the App it is executed before the standalone App is executed. You can check to see if the App is running standalone using [[Lianja|Lianja.standalone]] and check the file path using [[Lianja|Lianja.standalonefilepath]].<br />
<br />
You would typically do nothing in setup if the App is not running standalone.<br />
<br />
<code lang="recital"><br />
if not Lianja.standalone<br />
return<br />
endif<br />
<br />
// e.g. to share data on a network <br />
set datadir to f:\lianja\data<br />
</code><br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
=Building and Testing Standalone Executables=<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar:<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Deploying Standalone Executables==<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Report_Section_AttributesReport Section Attributes2024-03-22T14:04:59Z<p>Yvonne.milne: /* UI Presentation Rules */</p>
<hr />
<div>=Overview=<br />
Report Sections are used to display tabular reports.<br />
{{DISPLAYTITLE:Report Section}}<br />
[[File:Report_section.png|middle|758px|link=]]<br />
<br />
You build Apps in Lianja App Builder visually using the [[:Category:Page_Builder|Page Builder]].<br />
<br />
If you have not yet done so please read [[Understanding_the_Lianja_App_Architecture|Understanding the Lianja Architecture]] and also [[Lianja_is_all_about_ART|Understanding ART]] to better understand this article.<br />
<br />
An App consists of pages. Pages are made up of Sections. Form sections are made up of FormItems. We call these collectively "UI Elements" or "Visual Elements".<br />
<br />
==Setting Attributes Declaratively==<br />
<br />
You adjust the appearance and behavior of each UI Element in the '''Attributes''' Tab of the [[:Category:App_Inspector|App Inspector]].<br />
<br />
[[{{ns:file}}:bm-attributes.png|800px|left|border|link={{filepath:bm-attributes.png}}|Attributes]]<br />
<br clear=all><br />
<br />
The attributes available consist of some common ones as well as some specific to the UI Element being inspected.<br />
<br />
==Getting and Setting Attributes Programmatically==<br />
The '''setAttribute(name, value)''' method can be used to set the value of an Attribute:<br />
<br />
<pre>Lianja.get("pageid.sectionid").setAttribute("title","Section1")</pre><br />
<br />
Note: on the desktop, the shortened form '''setAttr(name,value)''' is also available.<br />
<br />
The '''getAttribute(name)''' method can be used to get the value of an Attribute:<br />
<br />
<pre>cTitle = Lianja.get("pageid.sectionid").getAttribute("title")</pre><br />
<br />
Note: on the desktop, the shortened form '''getAttr(name)''' is also available.<br />
<br />
=See Also=<br />
[[Developing Quick Reports]], [[Report Options]]<br />
<br />
Demo Apps (included in the Lianja App Builder distribution):<br />
* Lianja Web UI Demo (example_webapp2)<br />
<br />
=Attributes=<br />
==Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Details Attributes#Name|Name]]||The name for this section (unique to the page)<br />
|valign="top"|id||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Full name|Full name]]||The full name for this section including its parent page, e.g. page1.section1<br />
|valign="top"|fullid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Alias name|Alias name]]||The alias name for this section<br />
|valign="top"|aliasid||Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Dashboard group]]||The dashboard section that this section belongs to. From v5.2.<br />
|valign="top"|horizontalgroup||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Horizontal stretch]]||The horizontal % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|horizontalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Vertical stretch]]||The vertical % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|verticalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#App Doc|App Doc]]||The App Doc file for this section. This will be included in the [[App Doc]] when it is generated.<br />
|valign="top"|appdoc||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#MetaData version|MetaData version]]||The MetaData version number. You can set this in the setupUI hook to prevent MetaData being applied multiple times.<br />
|valign="top"|metaDataVersion||valign="top"|Int<br />
|-<br />
|valign="top"|[[MetaTypes|Meta types]]||A comma separated list of metatype names<br />
|valign="top"|metatypes||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Custom Props|Custom Props]]||A ';' separated list of custom prop key pairs, e.g. name=barry;company=lianja<br>From v5.3.<br />
|valign="top"|customprops||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Type|Type]]||The type of section: report (readonly)<br />
|valign="top"|type||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Caption|Caption]]||The section caption displayed in the section header<br />
|valign="top"|title||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Database|Database]]||The database for this section<br />
|valign="top"|database||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Table|Table]]||The table for this section<br />
|valign="top"|table||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Height|Height]]||The section height<br />
|valign="top"|height||valign="top"|Int<br />
|-<br />
|valign="top"|[[Details Attributes#Fixed height|Fixed height]]||Fix the section height (True &#124; False)<br />
|valign="top"|fixedHeight||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Details Attributes#Auto layout percent|Auto layout percent]]||Auto layout percentage of page size. If set to 0, then all sections on a page are resized to an equal height<br />
|valign="top"|autoLayoutPercentage||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Appearance==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Appearance#Margin|Margin]]||Margin size around the section<br />
|valign="top"|margin||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Appearance#Add spacer at bottom|Add spacer at bottom]]||Add spacer at bottom of section (True &#124; False)<br />
|valign="top"|spacerVisible||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Header==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Hide header|Hide header]]||Hide section header at runtime(True &#124; False)<br />
|valign="top"|hideHeaderAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide actionbar|Hide actionbar]]||Hide actionbar when stacked section is activated at runtime<br>(True &#124; False)<br />
|valign="top"|hideActionBarAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header CSS style|Header CSS style]]||CSS style (separate attributes with ; or use app:/filename.css)<br />
|valign="top"|headerCssStyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header icon|Header icon]]||The image for the Header (png &#124; jpg &#124; gif).<br>Use app:/imagename.ext for app specific images.<br />
|valign="top"|headerIcon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient colors|Gradient colors]]||Render the Header background color as a gradient (True &#124; False)<br />
|valign="top"|headerGradient||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Gradients#Gradient type|Gradient type]]||Specify the gradient type<br />
|valign="top"|headerGradientType||valign="top"|Int<br />
|-<br />
|valign="top"|[[Gradients#Gradient start color|Gradient start color]]||Gradient start color<br />
|valign="top"|headerFromColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient end color|Gradient end color]]||Gradient end color<br />
|valign="top"|headerToColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show Print button|Show Print button]]||Show Print button in the section header (True &#124; False)<br />
|valign="top"|showPrintButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Edit button|Show Edit button]]||Show Edit button in the section header (True &#124; False)<br />
|valign="top"|showEditButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide custom search icon|Hide custom search icon]]||Hide the custom search icon (True &#124; False)<br />
|valign="top"|hideCustomSearchIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[QueryBuilder|Show custom search dialog]]||Show the custom search dialog when the custom search icon is clicked (True &#124; False)<br />
|valign="top"|showCustomSearchDialog||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[QueryBuilder|Show custom search dialog panel]]||Show the custom search dialog panel when the custom search icon is clicked (True &#124; False)<br />
|valign="top"|showCustomSearchDialogPanel||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show info tips icon|Show info tips icon]]||Show the info tips icon in the section header (True &#124; False)<br />
|valign="top"|showInfoTipsIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show help icon|Show help icon]]||Show the help icon in the section header (True &#124; False)<br />
|valign="top"|showHelpIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Help topic|Help topic]]||Help topic to display when the help icon is clicked in the section header<br />
|valign="top"|helpTopic||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Custom Header Style==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Use custom header style|Use custom header style]]||Use a custom header style (True &#124; False)<br />
|valign="top"|headercustomstyle||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header background color|Header background color]]||Header background color<br />
|valign="top"|headerbackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header foreground color|Header foreground color]]||Header foreground color<br />
|valign="top"|headerforecolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border|Header bottom border]]||Display the header bottom border (True &#124; False)<br />
|valign="top"|headerbottomborder||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border height|Header bottom border height]]||Height (in pixels) of the header bottom border (if displayed)<br />
|valign="top"|headerbottomborderheight||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border color|Header bottom border color]]||Header bottom border color<br />
|valign="top"|headerbottombordercolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show record count badge|Show record count badge]]||Show the record count badge in the section header (True &#124; False).<br />
|valign="top"|showreccount||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Visual Component Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Visual_Components#Component_library_3|Component library]]||This specifies the Component library where the component will be saved.<br />
|valign="top"|componentlib||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_name_2|Component name]]||Save as this component name whenever the section is saved.<br />
|valign="top"|componentname||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_author_2|Component author]]||The author of this component.<br />
|valign="top"|componentauthor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_version_2|Component version]]||The version of this component.<br />
|valign="top"|componentversion||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_description_2|Component description]]||The description of this component.<br />
|valign="top"|componentdescription||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_permissions_2|Component permissions]]||The permissions required for this component in Lianja Cloud App Builder.<br />
|valign="top"|componentpermissions||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_width_2|Component width]]||The width of this component when activated as a Form.<br />
|valign="top"|componentwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[Visual_Components#Component_height_2|Component height]]||The height of this component when activated as a Form.<br />
|valign="top"|componentheight||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Report Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Report Options#Report type|Report type]]||Select from a known report type (Tabular). Deprecated v5.0.<br />
|valign="top"|reportUrlType||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Report|Report]]||Select from a list of reports. From v5.0.<br />
|valign="top"|reportName||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Connstr|Connstr]]||The report data source connection string. From v5.0.<br />
|valign="top"|reportConnstr||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#SQL statement|SQL statement]]||A SQL statement. This can join multiple tables together and optionally include GROUP BY, ORDER BY and aggregate functions to display Crosstab queries. Use {} macros in the WHERE condition to relate parent->child sections. From v5.0.<br />
|valign="top"|sql||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Heading|Heading]]||The report heading<br />
|valign="top"|reportHeading||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Filter|Filter]]||The filter expression that restricts which records will be included in the report<br />
|valign="top"|reportFilter||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Fields|Fields]]||A comma separated list of field names or expressions. * selects all fields in the table.<br />
|valign="top"|reportFields||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Columns|Columns]]||A comma separated list of column positions from the fields selected<br>e.g. 2,4,7,1<br />
|valign="top"|reportColumns||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Subtotals|Subtotals]]||A comma separated list of column positions from the fields selected to subtotal on<br />
|valign="top"|reportSubtotals||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Column headings|Column headings]]||A comma separated list of report column headings<br />
|valign="top"|reportColumnHeadings||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Column alignments|Column alignments]]||A &#124; separated list of column alignments from the fields selected<br>e.g. left&#124;center&#124;right. From v5.0.<br />
|valign="top"|reportAlignments||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Column display masks|Column display masks]]||A &#124; separated list of column display masks from the fields selected<br>e.g. $&#124;99.999&#124;$. From v5.0.<br />
|valign="top"|reportDisplayMasks||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Column data mapping|Column data mapping]]||A &#124; separated list of custom data mapping for columns when displaying data. From v5.0.<br />
|valign="top"|reportDataMapping||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Column dynamic background|Column dynamic background]]||A &#124; separated list of expressions that provides dynamic cell color formatting <br>e.g. &#124;&#124;iif({}>10000,"lightgreen","")&#124;&#124;iif({}<1000,"pink","").<br>Note the use of {}, which is substituted with the current cell value.<br>From v5.0.<br />
|valign="top"|reportDynamicBackColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Column dynamic foreground|Column dynamic foreground]]||A &#124; separated list of expressions that provides dynamic cell color formatting <br>e.g. &#124;&#124;iif({}>10000,"white","")&#124;&#124;.<br>Note the use of {}, which is substituted with the current cell value.<br>From v5.0.<br />
|valign="top"|reportDynamicForeColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Group by|Group by]]||The field name or expression that data will be grouped by for subtotalling<br />
|valign="top"|reportGroupBy||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Group by list|Group by list]]||A &#124; separated choicelist of fields/expressions that an end user can group by. From v5.0.<br />
|valign="top"|reportGroupByList||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Sort by|Sort by]]||The field name or expression that data will be sorted by for subtotalling<br />
|valign="top"|reportSortBy||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Sort by list|Sort by list]]||A &#124; separated choicelist of fields/expressions that an end user can sort by. From v5.0.<br />
|valign="top"|reportSortByList||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Delegate argument|Delegate argument]]||An expressionto be evaluated and passed as an argument to the click and dblclick delegates. From v5.0.<br />
|valign="top"|reportKeyField||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Hyperlinks|Hyperlinks]]||A comma separated list of field names to render as hyperlinks for searching<br />
|valign="top"|reportHyperlinks||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Show grid lines|Show grid lines]]||Show grid lines for each row of the report (True &#124; False).<br />
|valign="top"|reportGridLines||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Report Options#Summary only|Summary only]]||Display report summary lines only (True &#124; False). From v5.0.<br />
|valign="top"|reportSummaryOnly||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Report Options#Sortable|Sortable]]||Whether report is sortable by clicking on column headers. Shift+Click to sort by multiple columns (True &#124; False). From v5.0.<br />
|valign="top"|reportSortable||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Report Options#Editable|Editable]]||Whether report is editable by end user (True &#124; False). From v5.0.<br />
|valign="top"|reportEditable||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Report Options#Enable custom SQL|Enable custom SQL]]||Whether custom SQL is enabled as a data source (True &#124; False).<br>From v5.0.<br />
|valign="top"|reportEnableSQL||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Report Options#Include memos|Include memos]]||Whether memo columns should be included in the report (True &#124; False). From v5.0.<br />
|valign="top"|reportIncludeMemos||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Report Options#Include images|Include images]]||Whether image columns should be included in the report (True &#124; False). From v5.0.<br />
|valign="top"|reportIncludeImages||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Report Options#Image width|Image width]]||The width of the images in pixels. From v5.0.<br />
|valign="top"|reportImageWidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[Report Options#Image height|Image height]]||The height of the images in pixels. From v5.0.<br />
|valign="top"|reportImageHeight||valign="top"|Int<br />
|-<br />
|valign="top"|[[Report Options#Selectable|Selectable]]||Whether report is selectable by end user and operates as a report viewer (True &#124; False). From v5.0.<br />
|valign="top"|reportSelectable||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Report Options#Needs filter|Needs filter]]||Whether report requires a filter (use [[QueryBuilder|Query Builder]]) (True &#124; False).<br>From v5.0.<br />
|valign="top"|reportNeedsFilter||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Report Options#Max records|Max records]]||The maximum number of records to be processed.<br>From v5.0.<br />
|valign="top"|reportMaxRecords||valign="top"|Int<br />
|-<br />
|valign="top"|[[Report Options#Paper size|Paper size]]||The paper size that the print will be printed on<br>(Letter &#124; 8.5x13 &#124; A4 &#124; Custom). From v5.0.<br />
|valign="top"|reportPaperSize||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Custom Paper size|Custom Paper size]]||The paper size that the print will be printed on e.g. 8.5x13.<br>From v5.0.<br />
|valign="top"|reportCustomPaperSize||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Rows per page|Rows per page]]||The number of rows to print in each page. From v5.0.<br />
|valign="top"|reportPageSize||valign="top"|Int<br />
|-<br />
|valign="top"|[[Report Options#Row height|Row height]]||The height of the rows in pixels. From v5.0.<br />
|valign="top"|reportRowHeight||valign="top"|Int<br />
|-<br />
|valign="top"|[[Report Options#Scale print size|Scale print size]]||The percentage by which to scale the report when printing in the web client. From v5.0.<br />
|valign="top"|reportZoomSize||valign="top"|Int<br />
|-<br />
|valign="top"|[[Report Options#Header height|Header height]]||The height of the page header in pixels when printing. From v5.0.<br />
|valign="top"|reportHeaderHeight||valign="top"|Int<br />
|-<br />
|valign="top"|[[Report Options#Header margin|Header margin]]||The height of the page header margin in pixels when printing. From v5.0.<br />
|valign="top"|reportHeaderMargin||valign="top"|Int<br />
|-<br />
|valign="top"|[[Report Options#Header image|Header image]]||The background image to display in the header. From v5.0.<br />
|valign="top"|reportHeaderImage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Left header image|Left header image]]||The left image to display in the header. From v5.0.<br />
|valign="top"|reportLeftHeaderImage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Left header image width|Left header image width]]||The width in pixels of the left image to display in the header. From v5.0.<br />
|valign="top"|reportLeftHeaderImageWidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[Report Options#Right header image|Right header image]]||The right image to display in the header. From v5.0.<br />
|valign="top"|reportRightHeaderImage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Right header image width|Right header image width]]||The width in pixels of the right image to display in the header. From v5.0.<br />
|valign="top"|reportRightHeaderImageWidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[Report Options#Footer height|Footer height]]||The height of the page footer in pixels when printing. From v5.0.<br />
|valign="top"|reportFooterHeight||valign="top"|Int<br />
|-<br />
|valign="top"|[[Report Options#Footer margin|Footer margin]]||The height of the page footer margin in pixels when printing. From v5.0.<br />
|valign="top"|reportFooterMargin||valign="top"|Int<br />
|-<br />
|valign="top"|[[Report Options#Footer image|Footer image]]||The background image to display in the footer. From v5.0.<br />
|valign="top"|reportFooterImage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Footer page numbers|Footer page numbers]]||Whether to show 'page n of count' in the footer (True &#124; False).<br>From v5.0.<br />
|valign="top"|reportShowPageNumbers||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Report Options#Footer date/time|Footer date/time]]||Whether to show date/time in the footer (True &#124; False). From v5.0.<br />
|valign="top"|reportShowDateTime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[CSS|CSS Stylesheet]]||You can override the CSS style for the report and style it yourself by specifying your own stylesheet. From v5.0.<br />
|valign="top"|reportStylesheet||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Delegate library|Delegate library]]||The name of a custom library containing the server-side report delegates. This should be a Lianja/VFP procedure library. From v5.0.<br />
|valign="top"|reportCustomLibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Other options|Other options]]||Other report options<br />
|valign="top"|reportOtherOptions||valign="top"|Character<br />
|-<br />
|valign="top"|[[Report Options#Pagination|Pagination]]||Paginate the rows displayed (True &#124; False). Deprecated v5.0.<br />
|valign="top"|reportPagination||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Report Options#Pagination size|Pagination size]]||The number of rows to paginate. Deprecated v5.0.<br />
|valign="top"|reportPageSize||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Related Data==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Related Data#Parent section name|Parent section name]]||Name of related parent section<br />
|valign="top"|parentid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Automatically relate|Automatically relate]]||Automatically relate the child section (True &#124; False). If this is unchecked then you need to manually relate it in the parentdatachanged delegate.<br />
|valign="top"|autoRelateChildSection||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Menu==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Menus#Visible|Visible]]||Section menu visible (True &#124; False)<br />
|valign="top"|sectionMenuVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Menus#Height|Height]]||Section menu height<br />
|valign="top"|sectionMenuHeight||Int<br />
|-<br />
|valign="top"|[[Section Menus#Background color|Background color]]||Section menu background color<br />
|valign="top"|sectionMenuBackColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Foreground color|Foreground color]]||Section menu foreground color<br />
|valign="top"|sectionMenuForeColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu panel|Custom menu panel]]||The .rsp or .jssp page used to create the custom menu panel. This page should generate dynamic HTML5/JavaScript.<br />
|valign="top"|customSectionMenuPanel||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu|Custom menu]]||Section menu contents<br />
|valign="top"|customSectionMenu||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom action|Custom action]]||Action to perform when a menu item is selected<br />
|valign="top"|sectionMenuAction||Character<br />
|-<br />
|}<br />
<br />
==Search Panel==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Search Panels#Visible|Visible]]||Section search panel visible (True &#124; False)<br />
|valign="top"|searchPanelVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Height|Height]]||Section search panel height<br />
|valign="top"|searchPanelHeight||Int<br />
|-<br />
|valign="top"|[[Section Search Panels#Background color|Background color]]||Section search panel background color<br />
|valign="top"|searchPanelBackColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Foreground color|Foreground color]]||Section search panel foreground color<br />
|valign="top"|searchPanelForeColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Auto create|Auto create]]||Automatically create search panel for all Section search fields<br />
|valign="top"|searchPanelAutoCreate||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Custom search panel|Custom search panel]]||The delegate used to create the custom search panel<br />
|valign="top"|searchPanelAction||Character<br />
|-<br />
|}<br />
<br />
==Subtitle==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Subtitles#Visible|Visible]]||Section subtitle visible (True &#124; False)<br />
|valign="top"|subtitleVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Subtitles#Caption|Caption]]||Section subtitle caption<br />
|valign="top"|subtitleCaption||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Height|Height]]||Section subtitle height<br />
|valign="top"|subtitleHeight||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#Background color|Background color]]||Section subtitle background color<br />
|valign="top"|subtitleBackColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Foreground color|Foreground color]]||Section subtitle foreground color<br />
|valign="top"|subtitleForeColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Font|Font]]||Section subtitle font<br />
|valign="top"|subtitleFont||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#CSS style|CSS style]]||CSS style<br />
|valign="top"|subtitleCssStyle||Character<br />
|-<br />
|}<br />
<br />
==Footer==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Footers#Visible|Visible]]||Section footer visible (True &#124; False)<br />
|valign="top"|footerVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Footers#Caption|Caption]]||Section footer caption<br />
|valign="top"|footerText||Character<br />
|-<br />
|valign="top"|[[Section Footers#Height|Height]]||Section footer height<br />
|valign="top"|footerHeight||Int<br />
|-<br />
|valign="top"|[[Section Footers#Background color|Background color]]||Section footer background color<br />
|valign="top"|footerBackColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#Foreground color|Foreground color]]||Section footer foreground color<br />
|valign="top"|footerForeColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#CSS style|CSS style]]||CSS style (separate attributes with ; or use app:/filename.css or specify CSS classes separated by spaces).<br />
|valign="top"|footercssstyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom menu|Custom menu]]||Section footer menu contents<br />
|valign="top"|customOptionsMenu||Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom action|Custom action]]||Action to perform when a footer menu item is selected<br />
|valign="top"|customOptionsMenuAction||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button CSS|Footer button CSS]]||Footer button CSS style<br />
|valign="top"|footerButtonCss||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button width|Footer button width]]||Footer button width<br />
|valign="top"|footerButtonWidth||Int<br />
|-<br />
|}<br />
<br />
==Behavior==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Report Options#Delegate Behavior|Delegate hyperlinks]]||Delegate hyperlinks in page to page and/or section (True &#124; False)<br />
|valign="top"|delegateHyperlinks||Boolean<br />
|-<br />
|valign="top"|[[Report Options#Delegate Behavior|Delegate page]]||Delegate page name to search (leave blank if current page)<br />
|valign="top"|delegateHyperlinksPage||Character<br />
|-<br />
|valign="top"|[[Report Options#Delegate Behavior|Delegate section]]||Delegate section name (leave blank if default searchkey section on page)<br />
|valign="top"|delegateHyperlinksSection||Character<br />
|-<br />
|valign="top"|[[Report Options#Delegate Behavior|Delegate script]]||Delegate script name (URL is passed as character string)<br />
|valign="top"|delegateHyperlinksScript||Character<br />
|-<br />
|}<br />
<br />
==Other Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Accordion Behavior#Hide form NavBar|Hide form NavBar]]||Hide form Navigation Bar at runtime if this section is in an Accordion Stack (True &#124; False)<br />
|valign="top"|hideFormNavBar||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Instant_Search#Hide_SearchBox|Hide SearchBox]]||Hide the Page Header Instant Search box when this section is selected in an Accordion Stack (True &#124; False). From v5.4.<br />
|valign="top"|hidesearchbox||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Appearance#Collapsable|Collapsable]]||The section is collapsible at runtime (True &#124; False)<br />
|valign="top"|collapsableAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Accordion Behavior#Exclude from accordion|Exclude from accordion]]||The section is excluded from accordion behavior at runtime (True &#124; False)<br />
|valign="top"|excludeAccordionAtRuntime||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Custom Delegates==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Custom Delegates#Scripting Language|Scripting language]]||The default scripting language for custom code in this section (Inherit &#124; Recital &#124; Visual FoxPro &#124; Python &#124; JavaScript &#124; PHP)<br />
|valign="top"|scriptingLanguage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom Library|Custom library]]||The filename of the library containing code for event handlers and custom procedures/functions<br />
|valign="top"|customLibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Print|Print]]||The delegate for the Print event.<br>This is called when you click the 'Print' icon.<br />
|valign="top"|printAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Expanded|Expanded]]||The delegate for the Expanded event<br />
|valign="top"|expandedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Collapsed|Collapsed]]||The delegate for the Collapsed event<br />
|valign="top"|collapsedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Hotkey|Hotkey]]||The delegate for the Hotkey event.<br />
|valign="top"|hotkeyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Click|Click]]||The delegate for the clicked event.<br />
|valign="top"|clickAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Double Click|Double Click]]||The delegate for the double clicked event.<br />
|valign="top"|dblclickAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Before Generate|Before Generate]]||The delegate for the Before Generate event. This should be a server-side script written in Lianja/VFP.<br />
|valign="top"|beforeGenerateAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#After Generate|After Generate]]||The delegate for the After Generate event. This should be a server-side script written in Lianja/VFP.<br />
|valign="top"|afterGenerateAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Cell Renderer|Cell Renderer]]||The delegate for the Cell Renderer event. This should be a server-side script written in Lianja/VFP. It is passed the name of the column as the first argument and the value as the second. It should output HTML using the [[?]] or [[ECHO|echo]] commands.<br />
|valign="top"|cellRendererAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Header Renderer|Header Renderer]]||The delegate for the Header Renderer event. This should be a server-side script written in Lianja/VFP. It is passed the name of the column as the first argument and the value as the second. It should output HTML using the [[?]] or [[ECHO|echo]] commands.<br />
|valign="top"|headerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Footer Renderer|Footer Renderer]]||The delegate for the Footer Renderer event. This should be a server-side script written in Lianja/VFP. It is passed the name of the column as the first argument and the value as the second. It should output HTML using the [[?]] or [[ECHO|echo]] commands.<br />
|valign="top"|footerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#After Data Changed|After Data Changed]]||The delegate for the DataChanged event (after data is read). From v5.0.<br />
|valign="top"|dataChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Before Group|Before Group]]||The delegate for the Before Group event. This should be a server-side script written in Lianja/VFP.<br />
|valign="top"|beforeGroupAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#After Group|After Group]]||The delegate for the After Group event. This should be a server-side script written in Lianja/VFP.<br />
|valign="top"|afterGroupAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Parent data changed|Parent data changed]]||The delegate for the ParentDataChanged event<br />
|valign="top"|parentDataChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Data Producer|Data Producer]]||The delegate for the DataProducer (used in Web Components).<br>From v6.1.<br />
|valign="top"|dataProducerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer|Timer]]||The delegate for the Timer event<br />
|valign="top"|timerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer interval|Timer interval]]||The timer interval in seconds that the Timer event will be called at runtime<br />
|valign="top"|timerInterval||valign="top"|Int<br />
|-<br />
|valign="top"|[[Custom Delegates#State Changed|State Changed]]||The delegate for the Statechanged event.<br />
|valign="top"|stateChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom footer menu|Custom footer menu]]||The delegate for the footer menu event<br />
|valign="top"|customMenuAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom search command|Custom search command]]||The delegate for the search event<br />
|valign="top"|customSearch||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom section menu|Custom section menu]]||The delegate for the section menu event<br />
|valign="top"|customSectionMenuAction||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Permissions and Roles==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Users and Roles|Create roles]]||A comma separated list of roles that can perform create operations on data in the section.<br />
|valign="top"|permcreate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Read roles]]||A comma separated list of roles that can read (and view) the section.<br />
|valign="top"|permRead||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Update roles]]||A comma separated list of roles that can perform update operations on data in the section.<br />
|valign="top"|permUpdate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Delete roles]]||A comma separated list of roles that can perform delete operations on data in the section.<br />
|valign="top"|permDelete||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==UI Presentation Rules==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Desktop|Desktop]]||Include this section in a Desktop client (True &#124; False).<br />
|valign="top"|desktopUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Web|Web]]||Include this section in a Web client (True &#124; False).<br />
|valign="top"|webUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Tablet|Tablet]]||Include this section in a Tablet client (True &#124; False).<br />
|valign="top"|tabletUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Phone|Phone]]||Include this section in a Phone client (True &#124; False).<br />
|valign="top"|mobileUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#UI States|UI States]]||UI states that affect this section. Specify multiple states as a comma separated list.<br />
|valign="top"|state||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Initial UI state|Initial UI state]]||The initial UI state for this section. This will be applied to the section and all its fields and gadgets.<br />
|valign="top"|uiStateInit||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Readonly when|Readonly when]]||Section is readonly at runtime if specified expression evaluates to true.<br />
|valign="top"|readonlyWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Visible when|Visible when]]||Section is visible at runtime if specified expression evaluates to true.<br />
|valign="top"|visibleWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Display orientation|Display orientation]]||Display depending on mobile device orientation for Tablets and Phones. (Always &#124; Portrait &#124; Landscape)<br />
|valign="top"|displayOrientation||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on change|Apply rules on change]]||Apply UI presentation rules (Visible when and Readonly when) when data is changed interactively or when navigating records (True &#124; False).<br />
|valign="top"|applyRulesOnChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on parent change|Apply rules on parent change]]||Apply section UI presentation rules (Visible when and Readonly when) when parent data is changed by navigating records (True &#124; False)<br />
|valign="top"|applyRulesOnParentChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Search Panel Responsive UI width breakpoint|Search Panel Responsive UI width breakpoint]]||The Search Panel responsive UI width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|searchpanelresponsivevisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Menu Responsive UI width breakpoint|Menu Responsive UI width breakpoint]]||valign="top"|The Menu responsive UI width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsivemenuwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI width breakpoint|Responsive UI width breakpoint]]||The section responsive UI visibility width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsivewidthvisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI height breakpoint|Responsive UI height breakpoint]]||The section responsive UI visibility height breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsiveheightvisibility||valign="top"|Int<br />
|-<br />
|}<br />
<br />
[[Category:Attributes|3 Report Section]]<br />
[[Category:Sections]]<br />
[[Category:WebView Based Sections]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/ChartView_Section_AttributesChartView Section Attributes2024-03-22T11:52:53Z<p>Yvonne.milne: /* UI Presentation Rules */</p>
<hr />
<div>{{DISPLAYTITLE:ChartView Section}}<br />
=Overview=<br />
ChartView Sections generate charts configured using developer specified parameters.<br />
<br />
Click the keyboard icon in the section header to open the '''Custom Web Component Parameters Editor''' and set the attributes.<br />
<br />
[[{{ns:file}}:chartview_section.png|800px|left|border|link={{filepath:chartview_section.png}}|ChartView Section]]<br />
<br clear=all><br />
<br />
You build Apps in Lianja App Builder visually using the [[:Category:Page_Builder|Page Builder]].<br />
<br />
If you have not yet done so please read [[Understanding_the_Lianja_App_Architecture|Understanding the Lianja Architecture]] and also [[Lianja_is_all_about_ART|Understanding ART]] to better understand this article.<br />
<br />
An App consists of pages. Pages are made up of Sections. Form sections are made up of FormItems. We call these collectively "UI Elements" or "Visual Elements".<br />
<br />
==Setting Attributes Declaratively==<br />
<br />
You adjust the appearance and behavior of each UI Element in the '''Attributes''' Tab of the [[:Category:App_Inspector|App Inspector]].<br />
<br />
[[{{ns:file}}:bm-attributes.png|800px|left|border|link={{filepath:bm-attributes.png}}|Attributes]]<br />
<br clear=all><br />
<br />
The attributes available consist of some common ones as well as some specific to the UI Element being inspected.<br />
<br />
==Getting and Setting Attributes Programmatically==<br />
The '''setAttribute(name, value)''' method can be used to set the value of an Attribute:<br />
<br />
<pre>Lianja.get("pageid.sectionid").setAttribute("title","Section1")</pre><br />
<br />
Note: on the desktop, the shortened form '''setAttr(name,value)''' is also available.<br />
<br />
The '''getAttribute(name)''' method can be used to get the value of an Attribute:<br />
<br />
<pre>cTitle = Lianja.get("pageid.sectionid").getAttribute("title")</pre><br />
<br />
Note: on the desktop, the shortened form '''getAttr(name)''' is also available.<br />
<br />
=See Also=<br />
[[:Category:Developing Custom WebViews|Developing Custom WebViews]], [[Using WebViewWidgets]], [[Webview Gadget Attributes]], [[Webview Section Attributes]]<br />
<br />
=Attributes=<br />
==Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Details Attributes#Name|Name]]||The name for this section (unique to the page)<br />
|valign="top"|id||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Full name|Full name]]||The full name for this section including its parent page, e.g. page1.section1<br />
|valign="top"|fullid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Alias name|Alias name]]||The alias name for this section<br />
|valign="top"|aliasid||Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Dashboard group]]||The dashboard section that this section belongs to.<br />
|valign="top"|horizontalgroup||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Horizontal stretch]]||The horizontal % stretch factor that this section should occupy.<br />
|valign="top"|horizontalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Vertical stretch]]||The vertical % stretch factor that this section should occupy.<br />
|valign="top"|verticalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#App Doc|App Doc]]||The App Doc file for this section. This will be included in the [[App Doc]] when it is generated.<br />
|valign="top"|appdoc||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#MetaData version|MetaData version]]||The MetaData version number. You can set this in the setupUI hook to prevent MetaData being applied multiple times.<br />
|valign="top"|metaDataVersion||valign="top"|Int<br />
|-<br />
|valign="top"|[[MetaTypes|Meta types]]||A comma separated list of metatype names<br />
|valign="top"|metatypes||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Custom Props|Custom Props]]||A ';' separated list of custom prop key pairs, e.g. name=barry;company=lianja<br />
|valign="top"|customprops||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Type|Type]]||The type of section: datalistview (readonly)<br />
|valign="top"|type||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Caption|Caption]]||The section caption displayed in the section header<br />
|valign="top"|title||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Database|Database]]||The database for this section<br />
|valign="top"|database||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Table|Table]]||The table for this section<br />
|valign="top"|table||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Height|Height]]||The section height<br />
|valign="top"|height||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Fixed height|Fixed height]]||Fix the section height (True &#124; False)<br />
|valign="top"|fixedHeight||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Details Attributes#Auto layout percent|Auto layout percent]]||Auto layout percentage of page size. If set to 0, then all sections on a page are resized to an equal height.<br />
|valign="top"|autoLayoutPercentage||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Appearance==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Appearance#Margin|Margin]]||Margin size around the section<br />
|valign="top"|margin||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Appearance#Add spacer at bottom|Add spacer at bottom]]||Add spacer at bottom of section (True &#124; False)<br />
|valign="top"|spacerVisible||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Header==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Hide header|Hide header]]||Hide section header at runtime(True &#124; False)<br />
|valign="top"|hideHeaderAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide actionbar|Hide actionbar]]||Hide actionbar when stacked section is activated at runtime<br>(True &#124; False)<br />
|valign="top"|hideActionBarAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header CSS style|Header CSS style]]||CSS style (separate attributes with ; or use app:/filename.css)<br />
|valign="top"|headerCssStyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header icon|Header icon]]||The image for the Header (png &#124; jpg &#124; gif).<br>Use app:/imagename.ext for app specific images.<br />
|valign="top"|headerIcon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient colors|Gradient colors]]||Render the Header background color as a gradient (True &#124; False)<br />
|valign="top"|headerGradient||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Gradients#Gradient type|Gradient type]]||Specify the gradient type<br />
|valign="top"|headerGradientType||valign="top"|Int<br />
|-<br />
|valign="top"|[[Gradients#Gradient start color|Gradient start color]]||Gradient start color<br />
|valign="top"|headerFromColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient end color|Gradient end color]]||Gradient end color<br />
|valign="top"|headerToColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show Print button|Show Print button]]||Show Print button in the section header (True &#124; False)<br />
|valign="top"|showPrintButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Edit button|Show Edit button]]||Show Edit button in the section header (True &#124; False)<br />
|valign="top"|showEditButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide custom search icon|Hide custom search icon]]||Hide the custom search icon (True &#124; False)<br />
|valign="top"|hideCustomSearchIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Custom search dialog|Show Custom search dialog]]||Show custom search dialog when custom search icon clicked (True &#124; False)<br />
|valign="top"|showcustomsearchdialog||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show custom search dialog panel|Show custom search dialog panel]]||Show custom search dialog panel when custom search icon clicked<br>(True &#124; False)<br />
|valign="top"|showcustomsearchdialogpanel||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show info tips icon|Show info tips icon]]||Show the info tips icon in the section header (True &#124; False)<br />
|valign="top"|showInfoTipsIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show help icon|Show help icon]]||Show the help icon in the section header (True &#124; False)<br />
|valign="top"|showHelpIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Help topic|Help topic]]||Help topic to display when the help icon is clicked in the section header<br />
|valign="top"|helpTopic||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Custom Header Style==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Use custom header style|Use custom header style]]||Use a custom header style (True &#124; False)<br />
|valign="top"|headercustomstyle||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header background color|Header background color]]||Header background color<br />
|valign="top"|headerbackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header foreground color|Header foreground color]]||Header foreground color<br />
|valign="top"|headerforecolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border|Header bottom border]]||Display the header bottom border (True &#124; False)<br />
|valign="top"|headerbottomborder||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border height|Header bottom border height]]||Height (in pixels) of the header bottom border (if displayed)<br />
|valign="top"|headerbottomborderheight||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border color|Header bottom border color]]||Header bottom border color<br />
|valign="top"|headerbottombordercolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show record count badge|Show record count badge]]||Show the record count badge in the section header (True &#124; False).<br />
|valign="top"|showreccount||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Visual Component Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Visual_Components#Component_library_3|Component library]]||This specifies the Component library where the component will be saved.<br />
|valign="top"|componentlib||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_name_2|Component name]]||Save as this component name whenever the section is saved.<br />
|valign="top"|componentname||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_author_2|Component author]]||The author of this component.<br />
|valign="top"|componentauthor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_version_2|Component version]]||The version of this component.<br />
|valign="top"|componentversion||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_description_2|Component description]]||The description of this component.<br />
|valign="top"|componentdescription||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_permissions_2|Component permissions]]||The permissions required for this component in Lianja Cloud App Builder.<br />
|valign="top"|componentpermissions||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_width_2|Component width]]||The width of this component when activated as a Form.<br />
|valign="top"|componentwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[Visual_Components#Component_height_2|Component height]]||The height of this component when activated as a Form.<br />
|valign="top"|componentheight||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Related Data==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Related Data#Parent section name|Parent section name]]||Name of related parent section<br />
|valign="top"|parentid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Automatically relate|Automatically relate]]||Automatically relate the child section (True &#124; False). If this is unchecked then you need to manually relate it in the parentdatachanged delegate.<br />
|valign="top"|autoRelateChildSection||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Related Data#Parent key|Parent key]]||Parent key<br />
|valign="top"|parentKeyExpr||Character<br />
|-<br />
|valign="top"|[[Related Data#Child key|Child key]]||Child key<br />
|valign="top"|childKeyExpr||Character<br />
|-<br />
|}<br />
<br />
==Menu==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Menus#Visible|Visible]]||Section menu visible (True &#124; False)<br />
|valign="top"|sectionMenuVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Menus#Height|Height]]||Section menu height<br />
|valign="top"|sectionMenuHeight||Int<br />
|-<br />
|valign="top"|[[Section Menus#Background color|Background color]]||Section menu background color<br />
|valign="top"|sectionMenuBackColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Foreground color|Foreground color]]||Section menu foreground color<br />
|valign="top"|sectionMenuForeColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu panel|Custom menu panel]]||The .rsp or .jssp page used to create the custom menu panel. This page should generate dynamic HTML5/JavaScript.<br />
|valign="top"|customSectionMenuPanel||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu|Custom menu]]||Section menu contents<br />
|valign="top"|customSectionMenu||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom action|Custom action]]||Action to perform when a menu item is selected<br />
|valign="top"|sectionMenuAction||Character<br />
|-<br />
|valign="top"|[[Section Menus#Context Menu|Context Menu]]||A comma separated list of menu items to popup when a user right clicks on the Section. Selecting an item calls the [[Custom_Delegates#Right_Click|rightclick]] delegate with the item text as an argument.<br />
|valign="top"|contextMenu||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Search Panel==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Search Panels#Visible|Visible]]||Section search panel visible (True &#124; False)<br />
|valign="top"|searchPanelVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Height|Height]]||Section search panel height<br />
|valign="top"|searchPanelHeight||Int<br />
|-<br />
|valign="top"|[[Section Search Panels#Background color|Background color]]||Section search panel background color<br />
|valign="top"|searchPanelBackColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Foreground color|Foreground color]]||Section search panel foreground color<br />
|valign="top"|searchPanelForeColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Auto create|Auto create]]||Automatically create search panel for all Section search fields<br />
|valign="top"|searchPanelAutoCreate||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Custom search panel|Custom search panel]]||The delegate used to create the custom search panel<br />
|valign="top"|searchPanelAction||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#WebView Search panel config|WebView Search panel config]]||A string to manually configure a WebView search panel.<br>caption:controlsource:datatype:width:decimals[:choicelist],...<br>the datatype can be C,N,D,T or L (character, numeric, date, datetime, logical).<br />
|valign="top"|searchpanelconfig||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Subtitle==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Subtitles#Visible|Visible]]||Section subtitle visible (True &#124; False)<br />
|valign="top"|subtitleVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Subtitles#Caption|Caption]]||Section subtitle caption<br />
|valign="top"|subtitleCaption||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Height|Height]]||Section subtitle height<br />
|valign="top"|subtitleHeight||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#Background color|Background color]]||Section subtitle background color<br />
|valign="top"|subtitleBackColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Foreground color|Foreground color]]||Section subtitle foreground color<br />
|valign="top"|subtitleForeColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Font|Font]]||Section subtitle font<br />
|valign="top"|subtitleFont||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#CSS style|CSS style]]||CSS style<br />
|valign="top"|subtitleCssStyle||Character<br />
|-<br />
|}<br />
<br />
==Footer==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Footers#Visible|Visible]]||Section footer visible (True &#124; False)<br />
|valign="top"|footerVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Footers#Caption|Caption]]||Section footer caption<br />
|valign="top"|footerText||Character<br />
|-<br />
|valign="top"|[[Section Footers#Height|Height]]||Section footer height<br />
|valign="top"|footerHeight||Int<br />
|-<br />
|valign="top"|[[Section Footers#Background color|Background color]]||Section footer background color<br />
|valign="top"|footerBackColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#Foreground color|Foreground color]]||Section footer foreground color<br />
|valign="top"|footerForeColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#CSS style|CSS style]]||CSS style (separate attributes with ; or use app:/filename.css or specify CSS classes separated by spaces).<br />
|valign="top"|footercssstyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom menu|Custom menu]]||Section footer menu contents<br />
|valign="top"|customOptionsMenu||Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom action|Custom action]]||Action to perform when a footer menu item is selected<br />
|valign="top"|customOptionsMenuAction||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button CSS|Footer button CSS]]||Footer button CSS style<br />
|valign="top"|footerButtonCss||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button width|Footer button width]]||Footer button width<br />
|valign="top"|footerButtonWidth||Int<br />
|-<br />
|}<br />
<br />
==Other Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Accordion Behavior#Hide form NavBar|Hide form NavBar]]||Hide form Navigation Bar at runtime if this section is in an Accordion Stack (True &#124; False)<br />
|valign="top"|hideFormNavBar||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Instant_Search#Hide_SearchBox|Hide SearchBox]]||Hide the Page Header Instant Search box when this section is selected in an Accordion Stack (True &#124; False).<br />
|valign="top"|hidesearchbox||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Appearance#Collapsable|Collapsable]]||The section is collapsible at runtime (True &#124; False)<br />
|valign="top"|collapsableAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Accordion Behavior#Exclude from accordion|Exclude from accordion]]||The section is excluded from accordion behavior at runtime (True &#124; False)<br />
|valign="top"|excludeAccordionAtRuntime||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Custom Delegates==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Custom Delegates#Scripting Language|Scripting language]]||The default scripting language for custom code in this section (Inherit &#124; Recital &#124; Visual FoxPro &#124; Python &#124; JavaScript &#124; PHP)<br />
|valign="top"|scriptingLanguage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom Library|Custom library]]||The filename of the library containing code for event handlers and custom procedures/functions<br />
|valign="top"|customLibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Print|Print]]||The delegate for the Print event. This is called when you click the 'Print' icon.<br />
|valign="top"|printAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Expanded|Expanded]]||The delegate for the Expanded event<br />
|valign="top"|expandedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Collapsed|Collapsed]]||The delegate for the Collapsed event<br />
|valign="top"|collapsedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Hotkey|Hotkey]]||The delegate for the Hotkey event.<br />
|valign="top"|hotkeyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Activate|Activate]]||The delegate for the Activate event<br />
|valign="top"|activateAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Deactivate|Deactivate]]||The delegate for the Deactivate event<br />
|valign="top"|deactivateAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Enabled When|Enabled When]]||The delegate for the EnabledWhen event<br />
|valign="top"|enabledWhenAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Visible When|Visible When]]||The delegate for the VisibleWhen event<br />
|valign="top"|visibleWhenAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Valid When|Valid When]]||The delegate for the ValidWhen event<br />
|valign="top"|validWhenAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Init|Init]]||The delegate for the Init event<br />
|valign="top"|initAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Destroy|Destroy]]||The delegate for the Destroy event<br />
|valign="top"|destroyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Load|Load]]||The delegate for the Load event<br />
|valign="top"|loadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Ready|Ready]]||The delegate for the Ready event<br />
|valign="top"|readyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Unload|Unload]]||The delegate for the Unload event<br />
|valign="top"|unloadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Change|Change]]||The delegate for the Change event<br />
|valign="top"|changedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Link Click|Link Click]]||The delegate for the Hyperlink/Button Click event. This is called with two arguments: functionname(controlsource,text)<br />
|valign="top"|linkClickAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Before Data Create|Before Data Create]]||The delegate for the BeforeCreate event<br />
|valign="top"|beforeCreateAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#After Data Create|After Data Create]]||The delegate for the AfterCreate event<br />
|valign="top"|afterCreateAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#After Data Changed|After Data Changed]]||The delegate for the dataChanged event (after data is read)<br />
|valign="top"|dataChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Before Data Update|Before Data Update]]||The delegate for the BeforeUpdate event<br />
|valign="top"|beforeUpdateAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#After Data Update|After Data Update]]||The delegate for the AfterUpdate event<br />
|valign="top"|afterUpdateAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Before Data Delete|Before Data Delete]]||The delegate for the BeforeDelete event<br />
|valign="top"|beforeDeleteAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#After Data Delete|After Data Delete]]||The delegate for the AfterDelete event<br />
|valign="top"|afterDeleteAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Before Refresh|Before Refresh action]]||The delegate for the BeforeRefresh event. From v6.2.<br />
|valign="top"|beforeRefreshAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Refresh|Refresh]]||The delegate for the Refresh event<br />
|valign="top"|refreshAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#After Refresh|After Refresh action]]||The delegate for the AfterRefresh event.<br />
|valign="top"|afterRefreshAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Before Edit|Before Edit]]||The delegate for the BeforeEdit event.<br />
|valign="top"|beforeEditAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#After Edit|After Edit]]||The delegate for the AfterEdit event.<br />
|valign="top"|afterEditAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Init Form Defaults|Init Form Defaults]]||The delegate for the InitFormDefaults event called when adding a new record.<br />
|valign="top"|initFormDefaults||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Parent data changed|Parent data changed]]||The delegate for the ParentDataChanged event<br />
|valign="top"|parentDataChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Dialog button delegate|Dialog button delegate]]||The delegate for the DialogButtonClicked event. If a dialogbutton on a Field has no delegate, the Section delegate will be called. If the section has no delegate, then the Page delegate will be called.<br />
|valign="top"|dialogButtonAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer|Timer]]||The delegate for the Timer event<br />
|valign="top"|timerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer interval|Timer interval]]||The timer interval in seconds that the Timer event will be called at runtime<br />
|valign="top"|timerInterval||valign="top"|Int<br />
|-<br />
|valign="top"|[[Custom Delegates#State Changed|State Changed]]||The delegate for the Statechanged event.<br />
|valign="top"|stateChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom footer menu|Custom footer menu]]||The delegate for the footer menu event<br />
|valign="top"|customMenuAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom search command|Custom search command]]||The delegate for the search event<br />
|valign="top"|customSearch||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom section menu|Custom section menu]]||The delegate for the section menu event<br />
|valign="top"|customSectionMenuAction||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Permissions and Roles==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Users and Roles|Create roles]]||A comma separated list of roles that can perform create operations on data in the section.<br />
|valign="top"|permcreate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Read roles]]||A comma separated list of roles that can read (and view) the section.<br />
|valign="top"|permRead||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Update roles]]||A comma separated list of roles that can perform update operations on data in the section.<br />
|valign="top"|permUpdate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Delete roles]]||A comma separated list of roles that can perform delete operations on data in the section.<br />
|valign="top"|permDelete||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==UI Presentation Rules==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Desktop|Desktop]]||Include this section in a Desktop client (True &#124; False).<br />
|valign="top"|desktopUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Web|Web]]||Include this section in a Web client (True &#124; False).<br />
|valign="top"|webUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Tablet|Tablet]]||Include this section in a Tablet client (True &#124; False).<br />
|valign="top"|tabletUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Phone|Phone]]||Include this section in a Phone client (True &#124; False).<br />
|valign="top"|mobileUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#UI States|UI States]]||UI states that affect this section. Specify multiple states as a comma separated list.<br />
|valign="top"|state||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Initial UI state|Initial UI state]]||The initial UI state for this section. This will be applied to the section and all its fields and gadgets.<br />
|valign="top"|uiStateInit||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Readonly when|Readonly when]]||Section is readonly at runtime if specified expression evaluates to true.<br />
|valign="top"|readonlyWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Visible when|Visible when]]||Section is visible at runtime if specified expression evaluates to true.<br />
|valign="top"|visibleWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Display orientation|Display orientation]]||Display depending on mobile device orientation for Tablets and Phones. (Always &#124; Portrait &#124; Landscape)<br />
|valign="top"|displayOrientation||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on change|Apply rules on change]]||Apply UI presentation rules (Visible when and Readonly when) when data is changed interactively or when navigating records (True &#124; False).<br />
|valign="top"|applyRulesOnChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on parent change|Apply rules on parent change]]||Apply section UI presentation rules (Visible when and Readonly when) when parent data is changed by navigating records (True &#124; False)<br />
|valign="top"|applyRulesOnParentChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Search Panel Responsive UI width breakpoint|Search Panel Responsive UI width breakpoint]]||The Search Panel responsive UI width breakpoint in Web/Mobile Apps.<br />
|valign="top"|searchpanelresponsivevisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Menu Responsive UI width breakpoint|Menu Responsive UI width breakpoint]]||valign="top"|The Menu responsive UI width breakpoint in Web/Mobile Apps.<br />
|valign="top"|responsivemenuwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI width breakpoint|Responsive UI width breakpoint]]||The section responsive UI visibility width breakpoint in Web/Mobile Apps.<br />
|valign="top"|responsivewidthvisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI height breakpoint|Responsive UI height breakpoint]]||The section responsive UI visibility height breakpoint in Web/Mobile Apps.<br />
|valign="top"|responsiveheightvisibility||valign="top"|Int<br />
|-<br />
|}<br />
<br />
[[Category:Attributes|3 Chartview Section]]<br />
[[Category:Sections]]<br />
[[Category:Lianja v6.1]]<br />
[[Category:WebView Based Sections]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Category:WebView_Based_SectionsCategory:WebView Based Sections2024-03-22T11:51:41Z<p>Yvonne.milne: Created page with "==See Also== Section Attributes, Using WebViewWidgets"</p>
<hr />
<div>==See Also==<br />
[[:Category:Attributes#Section_Attributes|Section Attributes]], [[Using WebViewWidgets]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/TreeView_Section_AttributesTreeView Section Attributes2024-03-22T11:49:06Z<p>Yvonne.milne: /* UI Presentation Rules */</p>
<hr />
<div>=Overview=<br />
TreeView Sections are data-bound tree grids that allow you to drill down through levels of hierarchical nodes.<br />
{{DISPLAYTITLE:TreeView Section}}<br />
[[File:treeview_section.png|middle|link=]]<br />
<br />
<br />
You build Apps in Lianja App Builder visually using the [[:Category:Page_Builder|Page Builder]].<br />
<br />
If you have not yet done so please read [[Understanding_the_Lianja_App_Architecture|Understanding the Lianja Architecture]] and also [[Lianja_is_all_about_ART|Understanding ART]] to better understand this article.<br />
<br />
An App consists of pages. Pages are made up of Sections. Form sections are made up of FormItems. We call these collectively "UI Elements" or "Visual Elements".<br />
<br />
==Setting Attributes Declaratively==<br />
<br />
You adjust the appearance and behavior of each UI Element in the '''Attributes''' Tab of the [[:Category:App_Inspector|App Inspector]].<br />
<br />
[[{{ns:file}}:bm-attributes.png|800px|left|border|link={{filepath:bm-attributes.png}}|Attributes]]<br />
<br clear=all><br />
<br />
The attributes available consist of some common ones as well as some specific to the UI Element being inspected.<br />
<br />
==Getting and Setting Attributes Programmatically==<br />
The '''setAttribute(name, value)''' method can be used to set the value of an Attribute:<br />
<br />
<pre>Lianja.get("pageid.sectionid").setAttribute("title","Section1")</pre><br />
<br />
Note: on the desktop, the shortened form '''setAttr(name,value)''' is also available.<br />
<br />
The '''getAttribute(name)''' method can be used to get the value of an Attribute:<br />
<br />
<pre>cTitle = Lianja.get("pageid.sectionid").getAttribute("title")</pre><br />
<br />
Note: on the desktop, the shortened form '''getAttr(name)''' is also available.<br />
<br />
=See Also=<br />
[[Treeview Gadget Attributes]], [[TreeView Options]]<br />
<br />
Demo Apps (included in the Lianja App Builder distribution):<br />
* Lianja TreeView Demo (example_treeview)<br />
<br />
=Attributes=<br />
==Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Details Attributes#Name|Name]]||The name for this section (unique to the page)<br />
|valign="top"|id||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Full name|Full name]]||The full name for this section including its parent page, e.g. page1.section1<br />
|valign="top"|fullid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Alias name|Alias name]]||The alias name for this section<br />
|valign="top"|aliasid||Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Dashboard group]]||The dashboard section that this section belongs to. From v5.2.<br />
|valign="top"|horizontalgroup||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Horizontal stretch]]||The horizontal % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|horizontalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Vertical stretch]]||The vertical % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|verticalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#App Doc|App Doc]]||The App Doc file for this section. This will be included in the [[App Doc]] when it is generated.<br />
|valign="top"|appdoc||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#MetaData version|MetaData version]]||The MetaData version number. You can set this in the setupUI hook to prevent MetaData being applied multiple times.<br />
|valign="top"|metaDataVersion||valign="top"|Int<br />
|-<br />
|valign="top"|[[MetaTypes|Meta types]]||A comma separated list of metatype names<br />
|valign="top"|metatypes||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Custom Props|Custom Props]]||A ';' separated list of custom prop key pairs, e.g. name=barry;company=lianja<br>From v5.3.<br />
|valign="top"|customprops||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Type|Type]]||The type of section: treeview (readonly)<br />
|valign="top"|type||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Caption|Caption]]||The section caption displayed in the section header<br />
|valign="top"|title||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Database|Database]]||The database for this section<br />
|valign="top"|database||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Table|Table]]||The table for this section<br />
|valign="top"|table||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Height|Height]]||The section height<br />
|valign="top"|height||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Fixed height|Fixed height]]||Fix the section height (True &#124; False)<br />
|valign="top"|fixedHeight||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Details Attributes#Auto layout percent|Auto layout percent]]||Auto layout percentage of page size. If set to 0, then all sections on a page are resized to an equal height.<br />
|valign="top"|autoLayoutPercentage||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Appearance==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Appearance#Margin|Margin]]||Margin size around the section<br />
|valign="top"|margin||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Appearance#Add spacer at bottom|Add spacer at bottom]]||Add spacer at bottom of section (True &#124; False)<br />
|valign="top"|spacerVisible||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Header==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Hide header|Hide header]]||Hide section header at runtime(True &#124; False)<br />
|valign="top"|hideHeaderAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide actionbar|Hide actionbar]]||Hide actionbar when stacked section is activated at runtime<br>(True &#124; False)<br />
|valign="top"|hideActionBarAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header icon|Header icon]]||The image for the Header (png &#124; jpg &#124; gif).<br>Use app:/imagename.ext for app specific images.<br />
|valign="top"|headerIcon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient colors|Gradient colors]]||Render the Header background color as a gradient (True &#124; False)<br />
|valign="top"|headerGradient||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Gradients#Gradient type|Gradient type]]||Specify the gradient type<br />
|valign="top"|headerGradientType||valign="top"|Int<br />
|-<br />
|valign="top"|[[Gradients#Gradient start color|Gradient start color]]||Gradient start color<br />
|valign="top"|headerFromColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient end color|Gradient end color]]||Gradient end color<br />
|valign="top"|headerToColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show Print button|Show Print button]]||Show Print button in the section header (True &#124; False)<br />
|valign="top"|showPrintButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Edit button|Show Edit button]]||Show Edit button in the section header (True &#124; False)<br />
|valign="top"|showEditButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide custom search icon|Hide custom search icon]]||Hide the custom search icon (True &#124; False)<br />
|valign="top"|hideCustomSearchIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Custom search dialog|Show Custom search dialog]]||Show custom search dialog when custom search icon clicked (True &#124; False)<br />
|valign="top"|showcustomsearchdialog||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show custom search dialog panel|Show custom search dialog panel]]||Show custom search dialog panel when custom search icon clicked<br>(True &#124; False)<br />
|valign="top"|showcustomsearchdialogpanel||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show info tips icon|Show info tips icon]]||Show the info tips icon in the section header (True &#124; False)<br />
|valign="top"|showInfoTipsIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show help icon|Show help icon]]||Show the help icon in the section header (True &#124; False)<br />
|valign="top"|showHelpIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Help topic|Help topic]]||Help topic to display when the help icon is clicked in the section header<br />
|valign="top"|helpTopic||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Custom Header Style==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Use custom header style|Use custom header style]]||Use a custom header style (True &#124; False)<br />
|valign="top"|headercustomstyle||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header background color|Header background color]]||Header background color<br />
|valign="top"|headerbackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header foreground color|Header foreground color]]||Header foreground color<br />
|valign="top"|headerforecolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border|Header bottom border]]||Display the header bottom border (True &#124; False)<br />
|valign="top"|headerbottomborder||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border height|Header bottom border height]]||Height (in pixels) of the header bottom border (if displayed)<br />
|valign="top"|headerbottomborderheight||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border color|Header bottom border color]]||Header bottom border color<br />
|valign="top"|headerbottombordercolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show record count badge|Show record count badge]]||Show the record count badge in the section header (True &#124; False).<br />
|valign="top"|showreccount||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Visual Component Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Visual_Components#Component_library_3|Component library]]||This specifies the Component library where the component will be saved.<br />
|valign="top"|componentlib||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_name_2|Component name]]||Save as this component name whenever the section is saved.<br />
|valign="top"|componentname||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_author_2|Component author]]||The author of this component.<br />
|valign="top"|componentauthor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_version_2|Component version]]||The version of this component.<br />
|valign="top"|componentversion||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_description_2|Component description]]||The description of this component.<br />
|valign="top"|componentdescription||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_permissions_2|Component permissions]]||The permissions required for this component in Lianja Cloud App Builder.<br />
|valign="top"|componentpermissions||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_width_2|Component width]]||The width of this component when activated as a Form.<br />
|valign="top"|componentwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[Visual_Components#Component_height_2|Component height]]||The height of this component when activated as a Form.<br />
|valign="top"|componentheight||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==TreeView Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[TreeView Options|Title]]||The name of the column containing the title to be displayed for each leaf node of the tree.<br />
|valign="top"|treeviewCaption||valign="top"|Character<br />
|-<br />
|valign="top"|[[TreeView Options|Key]]||The key expression to be associated with the tree node. This will be passed as the second argument to the click or dblclick delegates.<br />
|valign="top"|treeviewLink||valign="top"|Character<br />
|-<br />
|valign="top"|[[TreeView Options|Group By]]||A comma separated list of expressions that the tree will be organized by.<br />
|valign="top"|treeviewGroupBy||valign="top"|Character<br />
|-<br />
|valign="top"|[[TreeView Options|Filter]]||The filter expression that restricts which records will be included in the tree.<br />
|valign="top"|treeviewFilter||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Related Data==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Related Data#Parent section name|Parent section name]]||Name of related parent section<br />
|valign="top"|parentid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Automatically relate|Automatically relate]]||Automatically relate the child section (True &#124; False). If this is unchecked then you need to manually relate it in the parentdatachanged delegate.<br />
|valign="top"|autoRelateChildSection||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Menu==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Menus#Visible|Visible]]||Section menu visible (True &#124; False)<br />
|valign="top"|sectionMenuVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Menus#Height|Height]]||Section menu height<br />
|valign="top"|sectionMenuHeight||Int<br />
|-<br />
|valign="top"|[[Section Menus#Background color|Background color]]||Section menu background color<br />
|valign="top"|sectionMenuBackColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Foreground color|Foreground color]]||Section menu foreground color<br />
|valign="top"|sectionMenuForeColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu panel|Custom menu panel]]||The .rsp or .jssp page used to create the custom menu panel. This page should generate dynamic HTML5/JavaScript.<br />
|valign="top"|customSectionMenuPanel||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu|Custom menu]]||Section menu contents<br />
|valign="top"|customSectionMenu||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom action|Custom action]]||Action to perform when a menu item is selected<br />
|valign="top"|sectionMenuAction||Character<br />
|-<br />
|}<br />
<br />
==Search Panel==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Search Panels#Visible|Visible]]||Section search panel visible (True &#124; False)<br />
|valign="top"|searchPanelVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Height|Height]]||Section search panel height<br />
|valign="top"|searchPanelHeight||Int<br />
|-<br />
|valign="top"|[[Section Search Panels#Background color|Background color]]||Section search panel background color<br />
|valign="top"|searchPanelBackColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Foreground color|Foreground color]]||Section search panel foreground color<br />
|valign="top"|searchPanelForeColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Auto create|Auto create]]||Automatically create search panel for all Section search fields<br />
|valign="top"|searchPanelAutoCreate||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Custom search panel|Custom search panel]]||The delegate used to create the custom search panel<br />
|valign="top"|searchPanelAction||Character<br />
|-<br />
|}<br />
<br />
==Subtitle==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Subtitles#Visible|Visible]]||Section subtitle visible (True &#124; False)<br />
|valign="top"|subtitleVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Subtitles#Caption|Caption]]||Section subtitle caption<br />
|valign="top"|subtitleCaption||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Height|Height]]||Section subtitle height<br />
|valign="top"|subtitleHeight||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#Background color|Background color]]||Section subtitle background color<br />
|valign="top"|subtitleBackColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Foreground color|Foreground color]]||Section subtitle foreground color<br />
|valign="top"|subtitleForeColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Font|Font]]||Section subtitle font<br />
|valign="top"|subtitleFont||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#CSS style|CSS style]]||CSS style<br />
|valign="top"|subtitleCssStyle||Character<br />
|-<br />
|}<br />
<br />
==Footer==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Footers#Visible|Visible]]||Section footer visible (True &#124; False)<br />
|valign="top"|footerVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Footers#Caption|Caption]]||Section footer caption<br />
|valign="top"|footerText||Character<br />
|-<br />
|valign="top"|[[Section Footers#Height|Height]]||Section footer height<br />
|valign="top"|footerHeight||Int<br />
|-<br />
|valign="top"|[[Section Footers#Background color|Background color]]||Section footer background color<br />
|valign="top"|footerBackColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#Foreground color|Foreground color]]||Section footer foreground color<br />
|valign="top"|footerForeColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#CSS style|CSS style]]||CSS style (separate attributes with ; or use app:/filename.css or specify CSS classes separated by spaces).<br />
|valign="top"|footercssstyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom menu|Custom menu]]||Section footer menu contents<br />
|valign="top"|customOptionsMenu||Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom action|Custom action]]||Action to perform when a footer menu item is selected<br />
|valign="top"|customOptionsMenuAction||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button CSS|Footer button CSS]]||Footer button CSS style<br />
|valign="top"|footerButtonCss||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button width|Footer button width]]||Footer button width<br />
|valign="top"|footerButtonWidth||Int<br />
|-<br />
|}<br />
<br />
==Other Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Accordion Behavior#Hide form NavBar|Hide form NavBar]]||Hide form Navigation Bar at runtime if this section is in an Accordion Stack (True &#124; False)<br />
|valign="top"|hideFormNavBar||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Instant_Search#Hide_SearchBox|Hide SearchBox]]||Hide the Page Header Instant Search box when this section is selected in an Accordion Stack (True &#124; False). From v5.4.<br />
|valign="top"|hidesearchbox||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Appearance#Collapsable|Collapsable]]||The section is collapsible at runtime (True &#124; False)<br />
|valign="top"|collapsableAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Accordion Behavior#Exclude from accordion|Exclude from accordion]]||The section is excluded from accordion behavior at runtime (True &#124; False)<br />
|valign="top"|excludeAccordionAtRuntime||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Custom Delegates==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Custom Delegates#Scripting Language|Scripting language]]||The default scripting language for custom code in this section (Inherit &#124; Recital &#124; Visual FoxPro &#124; Python &#124; JavaScript &#124; PHP)<br />
|valign="top"|scriptingLanguage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom Library|Custom library]]||The filename of the library containing code for event handlers and custom procedures/functions<br />
|valign="top"|customLibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Print|Print]]||The delegate for the Print event.<br>This is called when you click the 'Print' icon.<br />
|valign="top"|printAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Expanded|Expanded]]||The delegate for the Expanded event<br />
|valign="top"|expandedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Collapsed|Collapsed]]||The delegate for the Collapsed event<br />
|valign="top"|collapsedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Hotkey|Hotkey]]||The delegate for the Hotkey event.<br />
|valign="top"|hotkeyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Init|Init]]||The delegate for the Init event<br />
|valign="top"|initAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Destroy|Destroy]]||The delegate for the Destroy event<br />
|valign="top"|destroyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Load|Load]]||The delegate for the Load event<br />
|valign="top"|loadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Ready|Ready]]||The delegate for the Ready event<br />
|valign="top"|readyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Unload|Unload]]||The delegate for the Unload event<br />
|valign="top"|unloadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Click|Click]]||The delegate for the Click event<br />
|valign="top"|clickAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Double Click|Double Click]]||The delegate for the Double Clicked event<br />
|valign="top"|dblClickAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Parent data changed|Parent data changed]]||The delegate for the ParentDataChanged event<br />
|valign="top"|parentDataChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Data Producer|Data Producer]]||The delegate for the DataProducer (used in Web Components).<br>From v6.1.<br />
|valign="top"|dataProducerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer|Timer]]||The delegate for the Timer event<br />
|valign="top"|timerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer interval|Timer interval]]||The timer interval in seconds that the Timer event will be called at runtime<br />
|valign="top"|timerInterval||valign="top"|Int<br />
|-<br />
|valign="top"|[[Custom Delegates#State Changed|State Changed]]||The delegate for the Statechanged event.<br />
|valign="top"|stateChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom footer menu|Custom footer menu]]||The delegate for the footer menu event<br />
|valign="top"|customMenuAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom search command|Custom search command]]||The delegate for the search event<br />
|valign="top"|customSearch||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom section menu|Custom section menu]]||The delegate for the section menu event<br />
|valign="top"|customSectionMenuAction||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Permissions and Roles==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Users and Roles|Create roles]]||A comma separated list of roles that can perform create operations on data in the section.<br />
|valign="top"|permcreate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Read roles]]||A comma separated list of roles that can read (and view) the section.<br />
|valign="top"|permRead||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Update roles]]||A comma separated list of roles that can perform update operations on data in the section.<br />
|valign="top"|permUpdate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Delete roles]]||A comma separated list of roles that can perform delete operations on data in the section.<br />
|valign="top"|permDelete||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==UI Presentation Rules==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Desktop|Desktop]]||Include this section in a Desktop client (True &#124; False).<br />
|valign="top"|desktopUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Web|Web]]||Include this section in a Web client (True &#124; False).<br />
|valign="top"|webUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Tablet|Tablet]]||Include this section in a Tablet client (True &#124; False).<br />
|valign="top"|tabletUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Phone|Phone]]||Include this section in a Phone client (True &#124; False).<br />
|valign="top"|mobileUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#UI States|UI States]]||UI states that affect this section. Specify multiple states as a comma separated list.<br />
|valign="top"|state||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Initial UI state|Initial UI state]]||The initial UI state for this section. This will be applied to the section and all its fields and gadgets.<br />
|valign="top"|uiStateInit||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Readonly when|Readonly when]]||Section is readonly at runtime if specified expression evaluates to true.<br />
|valign="top"|readonlyWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Visible when|Visible when]]||Section is visible at runtime if specified expression evaluates to true.<br />
|valign="top"|visibleWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Display orientation|Display orientation]]||Display depending on mobile device orientation for Tablets and Phones. (Always &#124; Portrait &#124; Landscape)<br />
|valign="top"|displayOrientation||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on change|Apply rules on change]]||Apply UI presentation rules (Visible when and Readonly when) when data is changed interactively or when navigating records (True &#124; False).<br />
|valign="top"|applyRulesOnChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on parent change|Apply rules on parent change]]||Apply section UI presentation rules (Visible when and Readonly when) when parent data is changed by navigating records (True &#124; False)<br />
|valign="top"|applyRulesOnParentChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Search Panel Responsive UI width breakpoint|Search Panel Responsive UI width breakpoint]]||The Search Panel responsive UI width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|searchpanelresponsivevisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Menu Responsive UI width breakpoint|Menu Responsive UI width breakpoint]]||valign="top"|The Menu responsive UI width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsivemenuwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI width breakpoint|Responsive UI width breakpoint]]||The section responsive UI visibility width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsivewidthvisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI height breakpoint|Responsive UI height breakpoint]]||The section responsive UI visibility height breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsiveheightvisibility||valign="top"|Int<br />
|-<br />
|}<br />
<br />
[[Category:Attributes|3 TreeView Section]]<br />
[[Category:Sections]]<br />
[[Category:WebView Based Sections]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/SignatureView_Section_AttributesSignatureView Section Attributes2024-03-22T11:48:02Z<p>Yvonne.milne: /* UI Presentation Rules */</p>
<hr />
<div>{{DISPLAYTITLE:SignatureView Section}}<br />
=Overview=<br />
SignatureView Sections are used for signature capture in touch enabled web/mobile Apps.<br />
<br />
[[{{ns:file}}:signatureview_browser2.png|800px|left|border|link={{filepath:signatureview_browser2.png}}|example_signatureview]]<br />
<br clear=all><br />
<br />
You build Apps in Lianja App Builder visually using the [[:Category:Page_Builder|Page Builder]].<br />
<br />
If you have not yet done so please read [[Understanding_the_Lianja_App_Architecture|Understanding the Lianja Architecture]] and also [[Lianja_is_all_about_ART|Understanding ART]] to better understand this article.<br />
<br />
An App consists of pages. Pages are made up of Sections. Form sections are made up of FormItems. We call these collectively "UI Elements" or "Visual Elements".<br />
<br />
==Setting Attributes Declaratively==<br />
<br />
You adjust the appearance and behavior of each UI Element in the '''Attributes''' Tab of the [[:Category:App_Inspector|App Inspector]].<br />
<br />
[[{{ns:file}}:bm-attributes.png|800px|left|border|link={{filepath:bm-attributes.png}}|Attributes]]<br />
<br clear=all><br />
<br />
The attributes available consist of some common ones as well as some specific to the UI Element being inspected.<br />
<br />
==Getting and Setting Attributes Programmatically==<br />
The '''setAttribute(name, value)''' method can be used to set the value of an Attribute:<br />
<br />
<pre>Lianja.get("pageid.sectionid").setAttribute("title","Section1")</pre><br />
<br />
Note: on the desktop, the shortened form '''setAttr(name,value)''' is also available.<br />
<br />
The '''getAttribute(name)''' method can be used to get the value of an Attribute:<br />
<br />
<pre>cTitle = Lianja.get("pageid.sectionid").getAttribute("title")</pre><br />
<br />
Note: on the desktop, the shortened form '''getAttr(name)''' is also available.<br />
<br />
=See Also=<br />
[[SignatureView Options]]<br />
<br />
Demo Apps (included in the Lianja App Builder distribution):<br />
* SignatureView (example_signatureview)<br />
<br />
=Attributes=<br />
==Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Details Attributes#Name|Name]]||The name for this section (unique to the page)<br />
|valign="top"|id||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Full name|Full name]]||The full name for this section including its parent page, e.g. page1.section1<br />
|valign="top"|fullid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Alias name|Alias name]]||The alias name for this section<br />
|valign="top"|aliasid||Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Dashboard group]]||The dashboard section that this section belongs to.<br />
|valign="top"|horizontalgroup||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Horizontal stretch]]||The horizontal % stretch factor that this section should occupy.<br />
|valign="top"|horizontalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Vertical stretch]]||The vertical % stretch factor that this section should occupy.<br />
|valign="top"|verticalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#App Doc|App Doc]]||The App Doc file for this section. This will be included in the [[App Doc]] when it is generated.<br />
|valign="top"|appdoc||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#MetaData version|MetaData version]]||The MetaData version number. You can set this in the setupUI hook to prevent MetaData being applied multiple times.<br />
|valign="top"|metaDataVersion||valign="top"|Int<br />
|-<br />
|valign="top"|[[MetaTypes|Meta types]]||A comma separated list of metatype names<br />
|valign="top"|metatypes||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Custom Props|Custom Props]]||A ';' separated list of custom prop key pairs, e.g. name=barry;company=lianja<br />
|valign="top"|customprops||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Type|Type]]||The type of section: panelview (readonly)<br />
|valign="top"|type||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Caption|Caption]]||The section caption displayed in the section header<br />
|valign="top"|title||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Height|Height]]||The section height<br />
|valign="top"|height||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Fixed height|Fixed height]]||Fix the section height (True &#124; False)<br />
|valign="top"|fixedHeight||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Details Attributes#Auto layout percent|Auto layout percent]]||Auto layout percentage of page size. If set to 0, then all sections on a page are resized to an equal height.<br />
|valign="top"|autoLayoutPercentage||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Appearance==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Appearance#Margin|Margin]]||Margin size around the section<br />
|valign="top"|margin||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Appearance#Add spacer at bottom|Add spacer at bottom]]||Add spacer at bottom of section (True &#124; False)<br />
|valign="top"|spacerVisible||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Header==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Hide header|Hide header]]||Hide section header at runtime(True &#124; False)<br />
|valign="top"|hideHeaderAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide actionbar|Hide actionbar]]||Hide actionbar when stacked section is activated at runtime<br>(True &#124; False)<br />
|valign="top"|hideActionBarAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header CSS style|Header CSS style]]||CSS style (separate attributes with ; or use app:/filename.css)<br />
|valign="top"|headerCssStyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header icon|Header icon]]||The image for the Header (png &#124; jpg &#124; gif).<br>Use app:/imagename.ext for app specific images.<br />
|valign="top"|headerIcon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient colors|Gradient colors]]||Render the Header background color as a gradient (True &#124; False)<br />
|valign="top"|headerGradient||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Gradients#Gradient type|Gradient type]]||Specify the gradient type<br />
|valign="top"|headerGradientType||valign="top"|Int<br />
|-<br />
|valign="top"|[[Gradients#Gradient start color|Gradient start color]]||Gradient start color<br />
|valign="top"|headerFromColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient end color|Gradient end color]]||Gradient end color<br />
|valign="top"|headerToColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show Print button|Show Print button]]||Show Print button in the section header (True &#124; False)<br />
|valign="top"|showPrintButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Edit button|Show Edit button]]||Show Edit button in the section header (True &#124; False)<br />
|valign="top"|showEditButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide custom search icon|Hide custom search icon]]||Hide the custom search icon (True &#124; False)<br />
|valign="top"|hideCustomSearchIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Custom search dialog|Show Custom search dialog]]||Show custom search dialog when custom search icon clicked (True &#124; False)<br />
|valign="top"|showcustomsearchdialog||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show custom search dialog panel|Show custom search dialog panel]]||Show custom search dialog panel when custom search icon clicked<br>(True &#124; False)<br />
|valign="top"|showcustomsearchdialogpanel||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show info tips icon|Show info tips icon]]||Show the info tips icon in the section header (True &#124; False)<br />
|valign="top"|showInfoTipsIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show help icon|Show help icon]]||Show the help icon in the section header (True &#124; False)<br />
|valign="top"|showHelpIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Help topic|Help topic]]||Help topic to display when the help icon is clicked in the section header<br />
|valign="top"|helpTopic||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Custom Header Style==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Use custom header style|Use custom header style]]||Use a custom header style (True &#124; False)<br />
|valign="top"|headercustomstyle||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header background color|Header background color]]||Header background color<br />
|valign="top"|headerbackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header foreground color|Header foreground color]]||Header foreground color<br />
|valign="top"|headerforecolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border|Header bottom border]]||Display the header bottom border (True &#124; False)<br />
|valign="top"|headerbottomborder||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border height|Header bottom border height]]||Height (in pixels) of the header bottom border (if displayed)<br />
|valign="top"|headerbottomborderheight||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border color|Header bottom border color]]||Header bottom border color<br />
|valign="top"|headerbottombordercolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show record count badge|Show record count badge]]||Show the record count badge in the section header (True &#124; False).<br />
|valign="top"|showreccount||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Visual Component Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Visual_Components#Component_library_3|Component library]]||This specifies the Component library where the component will be saved.<br />
|valign="top"|componentlib||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_name_2|Component name]]||Save as this component name whenever the section is saved.<br />
|valign="top"|componentname||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_author_2|Component author]]||The author of this component.<br />
|valign="top"|componentauthor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_version_2|Component version]]||The version of this component.<br />
|valign="top"|componentversion||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_description_2|Component description]]||The description of this component.<br />
|valign="top"|componentdescription||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_permissions_2|Component permissions]]||The permissions required for this component in Lianja Cloud App Builder.<br />
|valign="top"|componentpermissions||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_width_2|Component width]]||The width of this component when activated as a Form.<br />
|valign="top"|componentwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[Visual_Components#Component_height_2|Component height]]||The height of this component when activated as a Form.<br />
|valign="top"|componentheight||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==SignatureView Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[SignatureView Options#Database|Database]]||The database for this section.<br />
|valign="top"|database||valign="top"|Character<br />
|-<br />
|valign="top"|[[SignatureView Options#Table|Table]]||The table for this section.<br />
|valign="top"|table||valign="top"|Character<br />
|-<br />
|valign="top"|[[SignatureView Options#Filter|Filter]]||The filter expression.<br />
|valign="top"|reportfilter||valign="top"|Character<br />
|-<br />
|valign="top"|[[SignatureView Options#Image column|Image column]]||The name of the column in the data-bound table containing signature images.<br />
|valign="top"|carouselimagecolumn||valign="top"|Character<br />
|-<br />
|valign="top"|[[SignatureView Options#Keyfield|Keyfield]]||The name of the column that the keyfield expression will be inserted into when a signature image is added.<br />
|valign="top"|carouselkeyfield||valign="top"|Character<br />
|-<br />
|valign="top"|[[SignatureView Options#Keyfield expression|Keyfield expression]]||The keyfield value that will be inserted when a signature image is added. Use {expr} to insert dynamic values.<br />
|valign="top"|carouselkeyfieldvalue||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Related Data==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Related Data#Parent section name|Parent section name]]||Name of related parent section<br />
|valign="top"|parentid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Automatically relate|Automatically relate]]||Automatically relate the child section (True &#124; False). If this is unchecked then you need to manually relate it in the parentdatachanged delegate.<br />
|valign="top"|autoRelateChildSection||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Related Data#Parent key|Parent key]]||Parent key<br />
|valign="top"|parentKeyExpr||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Child key|Child key]]||Child key<br />
|valign="top"|childKeyExpr||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Menu==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Menus#Visible|Visible]]||Section menu visible (True &#124; False)<br />
|valign="top"|sectionMenuVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Menus#Height|Height]]||Section menu height<br />
|valign="top"|sectionMenuHeight||Int<br />
|-<br />
|valign="top"|[[Section Menus#Background color|Background color]]||Section menu background color<br />
|valign="top"|sectionMenuBackColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Foreground color|Foreground color]]||Section menu foreground color<br />
|valign="top"|sectionMenuForeColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu panel|Custom menu panel]]||The .rsp or .jssp page used to create the custom menu panel. This page should generate dynamic HTML5/JavaScript.<br />
|valign="top"|customSectionMenuPanel||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu|Custom menu]]||Section menu contents<br />
|valign="top"|customSectionMenu||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom action|Custom action]]||Action to perform when a menu item is selected<br />
|valign="top"|sectionMenuAction||Character<br />
|-<br />
|}<br />
<br />
==Search Panel==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Search Panels#Visible|Visible]]||Section search panel visible (True &#124; False)<br />
|valign="top"|searchPanelVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Height|Height]]||Section search panel height<br />
|valign="top"|searchPanelHeight||Int<br />
|-<br />
|valign="top"|[[Section Search Panels#Background color|Background color]]||Section search panel background color<br />
|valign="top"|searchPanelBackColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Foreground color|Foreground color]]||Section search panel foreground color<br />
|valign="top"|searchPanelForeColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Auto create|Auto create]]||Automatically create search panel for all Section search fields<br />
|valign="top"|searchPanelAutoCreate||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Custom search panel|Custom search panel]]||The delegate used to create the custom search panel<br />
|valign="top"|searchPanelAction||Character<br />
|-<br />
|}<br />
<br />
==Subtitle==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Subtitles#Visible|Visible]]||Section subtitle visible (True &#124; False)<br />
|valign="top"|subtitleVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Subtitles#Caption|Caption]]||Section subtitle caption<br />
|valign="top"|subtitleCaption||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Height|Height]]||Section subtitle height<br />
|valign="top"|subtitleHeight||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#Background color|Background color]]||Section subtitle background color<br />
|valign="top"|subtitleBackColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Foreground color|Foreground color]]||Section subtitle foreground color<br />
|valign="top"|subtitleForeColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Font|Font]]||Section subtitle font<br />
|valign="top"|subtitleFont||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#CSS style|CSS style]]||CSS style<br />
|valign="top"|subtitleCssStyle||Character<br />
|-<br />
|}<br />
<br />
==Footer==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Footers#Visible|Visible]]||Section footer visible (True &#124; False)<br />
|valign="top"|footerVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Footers#Caption|Caption]]||Section footer caption<br />
|valign="top"|footerText||Character<br />
|-<br />
|valign="top"|[[Section Footers#Height|Height]]||Section footer height<br />
|valign="top"|footerHeight||Int<br />
|-<br />
|valign="top"|[[Section Footers#Background color|Background color]]||Section footer background color<br />
|valign="top"|footerBackColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#Foreground color|Foreground color]]||Section footer foreground color<br />
|valign="top"|footerForeColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#CSS style|CSS style]]||CSS style (separate attributes with ; or use app:/filename.css or specify CSS classes separated by spaces).<br />
|valign="top"|footercssstyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom menu|Custom menu]]||Section footer menu contents<br />
|valign="top"|customOptionsMenu||Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom action|Custom action]]||Action to perform when a footer menu item is selected<br />
|valign="top"|customOptionsMenuAction||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button CSS|Footer button CSS]]||Footer button CSS style<br />
|valign="top"|footerButtonCss||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button width|Footer button width]]||Footer button width<br />
|valign="top"|footerButtonWidth||Int<br />
|-<br />
|}<br />
<br />
==Other Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Accordion Behavior#Hide form NavBar|Hide form NavBar]]||Hide form Navigation Bar at runtime if this section is in an Accordion Stack (True &#124; False)<br />
|valign="top"|hideFormNavBar||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Instant_Search#Hide_SearchBox|Hide SearchBox]]||Hide the Page Header Instant Search box when this section is selected in an Accordion Stack (True &#124; False).<br />
|valign="top"|hidesearchbox||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Appearance#Collapsable|Collapsable]]||The section is collapsible at runtime (True &#124; False)<br />
|valign="top"|collapsableAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Accordion Behavior#Exclude from accordion|Exclude from accordion]]||The section is excluded from accordion behavior at runtime (True &#124; False)<br />
|valign="top"|excludeAccordionAtRuntime||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Custom Delegates==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Custom Delegates#Scripting Language|Scripting language]]||The default scripting language for custom code in this section (Inherit &#124; Recital &#124; Visual FoxPro &#124; Python &#124; JavaScript &#124; PHP)<br />
|valign="top"|scriptingLanguage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom Library|Custom library]]||The filename of the library containing code for event handlers and custom procedures/functions<br />
|valign="top"|customLibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Print|Print]]||The delegate for the Print event.<br>This is called when you click the 'Print' icon.<br />
|valign="top"|printAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Expanded|Expanded]]||The delegate for the Expanded event<br />
|valign="top"|expandedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Collapsed|Collapsed]]||The delegate for the Collapsed event<br />
|valign="top"|collapsedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Hotkey|Hotkey]]||The delegate for the Hotkey event.<br />
|valign="top"|hotkeyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Init|Init]]||The delegate for the Init event<br />
|valign="top"|initAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Destroy|Destroy]]||The delegate for the Destroy event<br />
|valign="top"|destroyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Load|Load]]||The delegate for the Load event<br />
|valign="top"|loadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Ready|Ready]]||The delegate for the Ready event<br />
|valign="top"|readyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Unload|Unload]]||The delegate for the Unload event<br />
|valign="top"|unloadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Parent data changed|Parent data changed]]||The delegate for the ParentDataChanged event<br />
|valign="top"|parentDataChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Data Producer|Data Producer]]||The delegate for the DataProducer (used in Web Components).<br />
|valign="top"|dataProducerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer|Timer]]||The delegate for the Timer event<br />
|valign="top"|timerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer interval|Timer interval]]||The timer interval in seconds that the Timer event will be called at runtime<br />
|valign="top"|timerInterval||valign="top"|Int<br />
|-<br />
|valign="top"|[[Custom Delegates#State Changed|State Changed]]||The delegate for the Statechanged event.<br />
|valign="top"|stateChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom footer menu|Custom footer menu]]||The delegate for the footer menu event<br />
|valign="top"|customMenuAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom search command|Custom search command]]||The delegate for the search event<br />
|valign="top"|customSearch||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom section menu|Custom section menu]]||The delegate for the section menu event<br />
|valign="top"|customSectionMenuAction||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Permissions and Roles==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Users and Roles|Create roles]]||A comma separated list of roles that can perform create operations on data in the section.<br />
|valign="top"|permcreate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Read roles]]||A comma separated list of roles that can read (and view) the section.<br />
|valign="top"|permRead||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Update roles]]||A comma separated list of roles that can perform update operations on data in the section.<br />
|valign="top"|permUpdate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Delete roles]]||A comma separated list of roles that can perform delete operations on data in the section.<br />
|valign="top"|permDelete||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==UI Presentation Rules==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Desktop|Desktop]]||Include this section in a Desktop client (True &#124; False).<br />
|valign="top"|desktopUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Web|Web]]||Include this section in a Web client (True &#124; False).<br />
|valign="top"|webUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Tablet|Tablet]]||Include this section in a Tablet client (True &#124; False).<br />
|valign="top"|tabletUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Phone|Phone]]||Include this section in a Phone client (True &#124; False).<br />
|valign="top"|mobileUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#UI States|UI States]]||UI states that affect this section. Specify multiple states as a comma separated list.<br />
|valign="top"|state||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Initial UI state|Initial UI state]]||The initial UI state for this section. This will be applied to the section and all its fields and gadgets.<br />
|valign="top"|uiStateInit||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Readonly when|Readonly when]]||Section is readonly at runtime if specified expression evaluates to true.<br />
|valign="top"|readonlyWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Visible when|Visible when]]||Section is visible at runtime if specified expression evaluates to true.<br />
|valign="top"|visibleWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Display orientation|Display orientation]]||Display depending on mobile device orientation for Tablets and Phones. (Always &#124; Portrait &#124; Landscape)<br />
|valign="top"|displayOrientation||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on change|Apply rules on change]]||Apply UI presentation rules (Visible when and Readonly when) when data is changed interactively or when navigating records (True &#124; False).<br />
|valign="top"|applyRulesOnChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on parent change|Apply rules on parent change]]||Apply section UI presentation rules (Visible when and Readonly when) when parent data is changed by navigating records (True &#124; False)<br />
|valign="top"|applyRulesOnParentChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Search Panel Responsive UI width breakpoint|Search Panel Responsive UI width breakpoint]]||The Search Panel responsive UI width breakpoint in Web/Mobile Apps.<br />
|valign="top"|searchpanelresponsivevisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Menu Responsive UI width breakpoint|Menu Responsive UI width breakpoint]]||valign="top"|The Menu responsive UI width breakpoint in Web/Mobile Apps.<br />
|valign="top"|responsivemenuwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI width breakpoint|Responsive UI width breakpoint]]||The section responsive UI visibility width breakpoint in Web/Mobile Apps.<br />
|valign="top"|responsivewidthvisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI height breakpoint|Responsive UI height breakpoint]]||The section responsive UI visibility height breakpoint in Web/Mobile Apps.<br />
|valign="top"|responsiveheightvisibility||valign="top"|Int<br />
|-<br />
|}<br />
<br />
[[Category:Attributes|3 PanelView Section]]<br />
[[Category:Sections]]<br />
[[Category:Lianja v9.5]]<br />
[[Category:WebView Based Sections]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/PanelView_Section_AttributesPanelView Section Attributes2024-03-22T11:46:56Z<p>Yvonne.milne: /* UI Presentation Rules */</p>
<hr />
<div>=Overview=<br />
PanelView sections are similar to CarouselView Sections, but instead of displaying a carousel of images, they allow you to display panels containing dynamic WebView content using Visual FoxPro Server Pages (.rsp) or JavaScript Server Pages (.jssp).<br />
{{DISPLAYTITLE:PanelView Section}}<br />
[[File:PanelView_section.png|middle|758px|link=]]<br />
<br />
You build Apps in Lianja App Builder visually using the [[:Category:Page_Builder|Page Builder]].<br />
<br />
If you have not yet done so please read [[Understanding_the_Lianja_App_Architecture|Understanding the Lianja Architecture]] and also [[Lianja_is_all_about_ART|Understanding ART]] to better understand this article.<br />
<br />
An App consists of pages. Pages are made up of Sections. Form sections are made up of FormItems. We call these collectively "UI Elements" or "Visual Elements".<br />
<br />
==Setting Attributes Declaratively==<br />
<br />
You adjust the appearance and behavior of each UI Element in the '''Attributes''' Tab of the [[:Category:App_Inspector|App Inspector]].<br />
<br />
[[{{ns:file}}:bm-attributes.png|800px|left|border|link={{filepath:bm-attributes.png}}|Attributes]]<br />
<br clear=all><br />
<br />
The attributes available consist of some common ones as well as some specific to the UI Element being inspected.<br />
<br />
==Getting and Setting Attributes Programmatically==<br />
The '''setAttribute(name, value)''' method can be used to set the value of an Attribute:<br />
<br />
<pre>Lianja.get("pageid.sectionid").setAttribute("title","Section1")</pre><br />
<br />
Note: on the desktop, the shortened form '''setAttr(name,value)''' is also available.<br />
<br />
The '''getAttribute(name)''' method can be used to get the value of an Attribute:<br />
<br />
<pre>cTitle = Lianja.get("pageid.sectionid").getAttribute("title")</pre><br />
<br />
Note: on the desktop, the shortened form '''getAttr(name)''' is also available.<br />
<br />
=See Also=<br />
[[PanelView Options]]<br />
<br />
Demo Apps (included in the Lianja App Builder distribution):<br />
* Lianja PanelView Demo (example_panelview)<br />
<br />
=Attributes=<br />
==Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Details Attributes#Name|Name]]||The name for this section (unique to the page)<br />
|valign="top"|id||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Full name|Full name]]||The full name for this section including its parent page, e.g. page1.section1<br />
|valign="top"|fullid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Alias name|Alias name]]||The alias name for this section<br />
|valign="top"|aliasid||Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Dashboard group]]||The dashboard section that this section belongs to. From v5.2.<br />
|valign="top"|horizontalgroup||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Horizontal stretch]]||The horizontal % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|horizontalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Vertical stretch]]||The vertical % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|verticalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#App Doc|App Doc]]||The App Doc file for this section. This will be included in the [[App Doc]] when it is generated.<br />
|valign="top"|appdoc||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#MetaData version|MetaData version]]||The MetaData version number. You can set this in the setupUI hook to prevent MetaData being applied multiple times.<br />
|valign="top"|metaDataVersion||valign="top"|Int<br />
|-<br />
|valign="top"|[[MetaTypes|Meta types]]||A comma separated list of metatype names<br />
|valign="top"|metatypes||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Custom Props|Custom Props]]||A ';' separated list of custom prop key pairs, e.g. name=barry;company=lianja<br>From v5.3.<br />
|valign="top"|customprops||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Type|Type]]||The type of section: panelview (readonly)<br />
|valign="top"|type||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Caption|Caption]]||The section caption displayed in the section header<br />
|valign="top"|title||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Height|Height]]||The section height<br />
|valign="top"|height||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Fixed height|Fixed height]]||Fix the section height (True &#124; False)<br />
|valign="top"|fixedHeight||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Details Attributes#Auto layout percent|Auto layout percent]]||Auto layout percentage of page size. If set to 0, then all sections on a page are resized to an equal height.<br />
|valign="top"|autoLayoutPercentage||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Appearance==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Appearance#Margin|Margin]]||Margin size around the section<br />
|valign="top"|margin||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Appearance#Add spacer at bottom|Add spacer at bottom]]||Add spacer at bottom of section (True &#124; False)<br />
|valign="top"|spacerVisible||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Header==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Hide header|Hide header]]||Hide section header at runtime(True &#124; False)<br />
|valign="top"|hideHeaderAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide actionbar|Hide actionbar]]||Hide actionbar when stacked section is activated at runtime<br>(True &#124; False)<br />
|valign="top"|hideActionBarAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header icon|Header icon]]||The image for the Header (png &#124; jpg &#124; gif).<br>Use app:/imagename.ext for app specific images.<br />
|valign="top"|headerIcon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient colors|Gradient colors]]||Render the Header background color as a gradient (True &#124; False)<br />
|valign="top"|headerGradient||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Gradients#Gradient type|Gradient type]]||Specify the gradient type<br />
|valign="top"|headerGradientType||valign="top"|Int<br />
|-<br />
|valign="top"|[[Gradients#Gradient start color|Gradient start color]]||Gradient start color<br />
|valign="top"|headerFromColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient end color|Gradient end color]]||Gradient end color<br />
|valign="top"|headerToColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show Print button|Show Print button]]||Show Print button in the section header (True &#124; False)<br />
|valign="top"|showPrintButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Edit button|Show Edit button]]||Show Edit button in the section header (True &#124; False)<br />
|valign="top"|showEditButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide custom search icon|Hide custom search icon]]||Hide the custom search icon (True &#124; False)<br />
|valign="top"|hideCustomSearchIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Custom search dialog|Show Custom search dialog]]||Show custom search dialog when custom search icon clicked (True &#124; False)<br />
|valign="top"|showcustomsearchdialog||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show custom search dialog panel|Show custom search dialog panel]]||Show custom search dialog panel when custom search icon clicked<br>(True &#124; False)<br />
|valign="top"|showcustomsearchdialogpanel||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show info tips icon|Show info tips icon]]||Show the info tips icon in the section header (True &#124; False)<br />
|valign="top"|showInfoTipsIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show help icon|Show help icon]]||Show the help icon in the section header (True &#124; False)<br />
|valign="top"|showHelpIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Help topic|Help topic]]||Help topic to display when the help icon is clicked in the section header<br />
|valign="top"|helpTopic||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Custom Header Style==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Use custom header style|Use custom header style]]||Use a custom header style (True &#124; False)<br />
|valign="top"|headercustomstyle||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header background color|Header background color]]||Header background color<br />
|valign="top"|headerbackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header foreground color|Header foreground color]]||Header foreground color<br />
|valign="top"|headerforecolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border|Header bottom border]]||Display the header bottom border (True &#124; False)<br />
|valign="top"|headerbottomborder||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border height|Header bottom border height]]||Height (in pixels) of the header bottom border (if displayed)<br />
|valign="top"|headerbottomborderheight||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border color|Header bottom border color]]||Header bottom border color<br />
|valign="top"|headerbottombordercolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show record count badge|Show record count badge]]||Show the record count badge in the section header (True &#124; False).<br />
|valign="top"|showreccount||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Visual Component Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Visual_Components#Component_library_3|Component library]]||This specifies the Component library where the component will be saved.<br />
|valign="top"|componentlib||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_name_2|Component name]]||Save as this component name whenever the section is saved.<br />
|valign="top"|componentname||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_author_2|Component author]]||The author of this component.<br />
|valign="top"|componentauthor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_version_2|Component version]]||The version of this component.<br />
|valign="top"|componentversion||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_description_2|Component description]]||The description of this component.<br />
|valign="top"|componentdescription||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_permissions_2|Component permissions]]||The permissions required for this component in Lianja Cloud App Builder.<br />
|valign="top"|componentpermissions||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_width_2|Component width]]||The width of this component when activated as a Form.<br />
|valign="top"|componentwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[Visual_Components#Component_height_2|Component height]]||The height of this component when activated as a Form.<br />
|valign="top"|componentheight||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==PanelView Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[PanelView Options#Menu|Menu]]||The menu to embed at the top of the PanelView section. This is a comma separated list.<br />
|valign="top"|panelMenu||valign="top"|Character<br />
|-<br />
|valign="top"|[[PanelView Options#Panels|Panels]]||A comma separated list of .rsp or .jssp pages to be displayed as carousel panels.<br />
|valign="top"|panelList||valign="top"|Character<br />
|-<br />
|valign="top"|[[PanelView Options#Captions|Captions]]||A comma separated list of captions to be displayed in the carousel panels.<br />
|valign="top"|panelCaptions||valign="top"|Character<br />
|-<br />
|valign="top"|[[PanelView Options#Sub captions|Sub captions]]||A comma separated list of sub captions to be displayed in the carousel panels.<br />
|valign="top"|panelSubCaptions||valign="top"|Character<br />
|-<br />
|valign="top"|[[PanelView Options#Show controls|Show controls]]||Show the carousel left and right selection controls (True &#124; False).<br />
|valign="top"|panelControls||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[PanelView Options#Show indicators|Show indicators]]||Show the carousel panel indicators (True &#124; False).<br />
|valign="top"|panelIndicators||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[PanelView Options#Auto select|Auto select]]||Automatically select the panel corresponding to the ordinal position of the menuitem (True &#124; False).<br />
|valign="top"|panelAutoSelect||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[PanelView Options#Auto refresh|Auto refresh]]||Automatically refresh the panel contents as they are selected (True &#124; False).<br />
|valign="top"|panelAutoRefresh||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[PanelView Options#Cycle interval|Cycle interval]]||The interval in seconds to cycle through the panels. 0 (default) specifies no cycling.<br />
|valign="top"|panellInterval||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Related Data==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Related Data#Parent section name|Parent section name]]||Name of related parent section<br />
|valign="top"|parentid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Automatically relate|Automatically relate]]||Automatically relate the child section (True &#124; False). If this is unchecked then you need to manually relate it in the parentdatachanged delegate.<br />
|valign="top"|autoRelateChildSection||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Related Data#Parent key|Parent key]]||Parent key<br />
|valign="top"|parentKeyExpr||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Child key|Child key]]||Child key<br />
|valign="top"|childKeyExpr||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Menu==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Menus#Visible|Visible]]||Section menu visible (True &#124; False)<br />
|valign="top"|sectionMenuVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Menus#Height|Height]]||Section menu height<br />
|valign="top"|sectionMenuHeight||Int<br />
|-<br />
|valign="top"|[[Section Menus#Background color|Background color]]||Section menu background color<br />
|valign="top"|sectionMenuBackColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Foreground color|Foreground color]]||Section menu foreground color<br />
|valign="top"|sectionMenuForeColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu panel|Custom menu panel]]||The .rsp or .jssp page used to create the custom menu panel. This page should generate dynamic HTML5/JavaScript.<br />
|valign="top"|customSectionMenuPanel||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu|Custom menu]]||Section menu contents<br />
|valign="top"|customSectionMenu||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom action|Custom action]]||Action to perform when a menu item is selected<br />
|valign="top"|sectionMenuAction||Character<br />
|-<br />
|}<br />
<br />
==Search Panel==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Search Panels#Visible|Visible]]||Section search panel visible (True &#124; False)<br />
|valign="top"|searchPanelVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Height|Height]]||Section search panel height<br />
|valign="top"|searchPanelHeight||Int<br />
|-<br />
|valign="top"|[[Section Search Panels#Background color|Background color]]||Section search panel background color<br />
|valign="top"|searchPanelBackColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Foreground color|Foreground color]]||Section search panel foreground color<br />
|valign="top"|searchPanelForeColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Auto create|Auto create]]||Automatically create search panel for all Section search fields<br />
|valign="top"|searchPanelAutoCreate||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Custom search panel|Custom search panel]]||The delegate used to create the custom search panel<br />
|valign="top"|searchPanelAction||Character<br />
|-<br />
|}<br />
<br />
==Subtitle==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Subtitles#Visible|Visible]]||Section subtitle visible (True &#124; False)<br />
|valign="top"|subtitleVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Subtitles#Caption|Caption]]||Section subtitle caption<br />
|valign="top"|subtitleCaption||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Height|Height]]||Section subtitle height<br />
|valign="top"|subtitleHeight||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#Background color|Background color]]||Section subtitle background color<br />
|valign="top"|subtitleBackColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Foreground color|Foreground color]]||Section subtitle foreground color<br />
|valign="top"|subtitleForeColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Font|Font]]||Section subtitle font<br />
|valign="top"|subtitleFont||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#CSS style|CSS style]]||CSS style<br />
|valign="top"|subtitleCssStyle||Character<br />
|-<br />
|}<br />
<br />
==Footer==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Footers#Visible|Visible]]||Section footer visible (True &#124; False)<br />
|valign="top"|footerVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Footers#Caption|Caption]]||Section footer caption<br />
|valign="top"|footerText||Character<br />
|-<br />
|valign="top"|[[Section Footers#Height|Height]]||Section footer height<br />
|valign="top"|footerHeight||Int<br />
|-<br />
|valign="top"|[[Section Footers#Background color|Background color]]||Section footer background color<br />
|valign="top"|footerBackColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#Foreground color|Foreground color]]||Section footer foreground color<br />
|valign="top"|footerForeColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#CSS style|CSS style]]||CSS style (separate attributes with ; or use app:/filename.css or specify CSS classes separated by spaces).<br />
|valign="top"|footercssstyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom menu|Custom menu]]||Section footer menu contents<br />
|valign="top"|customOptionsMenu||Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom action|Custom action]]||Action to perform when a footer menu item is selected<br />
|valign="top"|customOptionsMenuAction||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button CSS|Footer button CSS]]||Footer button CSS style<br />
|valign="top"|footerButtonCss||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button width|Footer button width]]||Footer button width<br />
|valign="top"|footerButtonWidth||Int<br />
|-<br />
|}<br />
<br />
==Other Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Accordion Behavior#Hide form NavBar|Hide form NavBar]]||Hide form Navigation Bar at runtime if this section is in an Accordion Stack (True &#124; False)<br />
|valign="top"|hideFormNavBar||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Instant_Search#Hide_SearchBox|Hide SearchBox]]||Hide the Page Header Instant Search box when this section is selected in an Accordion Stack (True &#124; False). From v5.4.<br />
|valign="top"|hidesearchbox||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Appearance#Collapsable|Collapsable]]||The section is collapsible at runtime (True &#124; False)<br />
|valign="top"|collapsableAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Accordion Behavior#Exclude from accordion|Exclude from accordion]]||The section is excluded from accordion behavior at runtime (True &#124; False)<br />
|valign="top"|excludeAccordionAtRuntime||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Custom Delegates==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Custom Delegates#Scripting Language|Scripting language]]||The default scripting language for custom code in this section (Inherit &#124; Recital &#124; Visual FoxPro &#124; Python &#124; JavaScript &#124; PHP)<br />
|valign="top"|scriptingLanguage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom Library|Custom library]]||The filename of the library containing code for event handlers and custom procedures/functions<br />
|valign="top"|customLibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Print|Print]]||The delegate for the Print event.<br>This is called when you click the 'Print' icon.<br />
|valign="top"|printAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Expanded|Expanded]]||The delegate for the Expanded event<br />
|valign="top"|expandedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Collapsed|Collapsed]]||The delegate for the Collapsed event<br />
|valign="top"|collapsedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Hotkey|Hotkey]]||The delegate for the Hotkey event.<br />
|valign="top"|hotkeyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Init|Init]]||The delegate for the Init event<br />
|valign="top"|initAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Destroy|Destroy]]||The delegate for the Destroy event<br />
|valign="top"|destroyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Load|Load]]||The delegate for the Load event<br />
|valign="top"|loadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Ready|Ready]]||The delegate for the Ready event<br />
|valign="top"|readyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Unload|Unload]]||The delegate for the Unload event<br />
|valign="top"|unloadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Parent data changed|Parent data changed]]||The delegate for the ParentDataChanged event<br />
|valign="top"|parentDataChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Data Producer|Data Producer]]||The delegate for the DataProducer (used in Web Components).<br>From v6.1.<br />
|valign="top"|dataProducerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer|Timer]]||The delegate for the Timer event<br />
|valign="top"|timerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer interval|Timer interval]]||The timer interval in seconds that the Timer event will be called at runtime<br />
|valign="top"|timerInterval||valign="top"|Int<br />
|-<br />
|valign="top"|[[Custom Delegates#State Changed|State Changed]]||The delegate for the Statechanged event.<br />
|valign="top"|stateChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom footer menu|Custom footer menu]]||The delegate for the footer menu event<br />
|valign="top"|customMenuAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom search command|Custom search command]]||The delegate for the search event<br />
|valign="top"|customSearch||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom section menu|Custom section menu]]||The delegate for the section menu event<br />
|valign="top"|customSectionMenuAction||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Permissions and Roles==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Users and Roles|Create roles]]||A comma separated list of roles that can perform create operations on data in the section.<br />
|valign="top"|permcreate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Read roles]]||A comma separated list of roles that can read (and view) the section.<br />
|valign="top"|permRead||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Update roles]]||A comma separated list of roles that can perform update operations on data in the section.<br />
|valign="top"|permUpdate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Delete roles]]||A comma separated list of roles that can perform delete operations on data in the section.<br />
|valign="top"|permDelete||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==UI Presentation Rules==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Desktop|Desktop]]||Include this section in a Desktop client (True &#124; False).<br />
|valign="top"|desktopUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Web|Web]]||Include this section in a Web client (True &#124; False).<br />
|valign="top"|webUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Tablet|Tablet]]||Include this section in a Tablet client (True &#124; False).<br />
|valign="top"|tabletUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Phone|Phone]]||Include this section in a Phone client (True &#124; False).<br />
|valign="top"|mobileUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#UI States|UI States]]||UI states that affect this section. Specify multiple states as a comma separated list.<br />
|valign="top"|state||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Initial UI state|Initial UI state]]||The initial UI state for this section. This will be applied to the section and all its fields and gadgets.<br />
|valign="top"|uiStateInit||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Readonly when|Readonly when]]||Section is readonly at runtime if specified expression evaluates to true.<br />
|valign="top"|readonlyWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Visible when|Visible when]]||Section is visible at runtime if specified expression evaluates to true.<br />
|valign="top"|visibleWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Display orientation|Display orientation]]||Display depending on mobile device orientation for Tablets and Phones. (Always &#124; Portrait &#124; Landscape)<br />
|valign="top"|displayOrientation||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on change|Apply rules on change]]||Apply UI presentation rules (Visible when and Readonly when) when data is changed interactively or when navigating records (True &#124; False).<br />
|valign="top"|applyRulesOnChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on parent change|Apply rules on parent change]]||Apply section UI presentation rules (Visible when and Readonly when) when parent data is changed by navigating records (True &#124; False)<br />
|valign="top"|applyRulesOnParentChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Search Panel Responsive UI width breakpoint|Search Panel Responsive UI width breakpoint]]||The Search Panel responsive UI width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|searchpanelresponsivevisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Menu Responsive UI width breakpoint|Menu Responsive UI width breakpoint]]||valign="top"|The Menu responsive UI width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsivemenuwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI width breakpoint|Responsive UI width breakpoint]]||The section responsive UI visibility width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsivewidthvisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI height breakpoint|Responsive UI height breakpoint]]||The section responsive UI visibility height breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsiveheightvisibility||valign="top"|Int<br />
|-<br />
|}<br />
<br />
[[Category:Attributes|3 PanelView Section]]<br />
[[Category:Sections]]<br />
[[Category:WebView Based Sections]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Org_Chart_Section_AttributesOrg Chart Section Attributes2024-03-22T11:46:26Z<p>Yvonne.milne: /* UI Presentation Rules */</p>
<hr />
<div>=Overview=<br />
OrgChart Sections are used to display an organization chart with clickable nodes.<br />
{{DISPLAYTITLE:OrgChart Section}}<br />
[[File:OrgChart_section.png|middle|758px|link=]]<br />
<br />
You build Apps in Lianja App Builder visually using the [[:Category:Page_Builder|Page Builder]].<br />
<br />
If you have not yet done so please read [[Understanding_the_Lianja_App_Architecture|Understanding the Lianja Architecture]] and also [[Lianja_is_all_about_ART|Understanding ART]] to better understand this article.<br />
<br />
An App consists of pages. Pages are made up of Sections. Form sections are made up of FormItems. We call these collectively "UI Elements" or "Visual Elements".<br />
<br />
==Setting Attributes Declaratively==<br />
<br />
You adjust the appearance and behavior of each UI Element in the '''Attributes''' Tab of the [[:Category:App_Inspector|App Inspector]].<br />
<br />
[[{{ns:file}}:bm-attributes.png|800px|left|border|link={{filepath:bm-attributes.png}}|Attributes]]<br />
<br clear=all><br />
<br />
The attributes available consist of some common ones as well as some specific to the UI Element being inspected.<br />
<br />
==Getting and Setting Attributes Programmatically==<br />
The '''setAttribute(name, value)''' method can be used to set the value of an Attribute:<br />
<br />
<pre>Lianja.get("pageid.sectionid").setAttribute("title","Section1")</pre><br />
<br />
Note: on the desktop, the shortened form '''setAttr(name,value)''' is also available.<br />
<br />
The '''getAttribute(name)''' method can be used to get the value of an Attribute:<br />
<br />
<pre>cTitle = Lianja.get("pageid.sectionid").getAttribute("title")</pre><br />
<br />
Note: on the desktop, the shortened form '''getAttr(name)''' is also available.<br />
<br />
=See Also=<br />
[[Org Chart Options]]<br />
<br />
Demo Apps (included in the Lianja App Builder distribution):<br />
* Lianja Org Chart Demo (example_orgchart)<br />
<br />
=Attributes=<br />
==Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Details Attributes#Name|Name]]||The name for this section (unique to the page)<br />
|valign="top"|id||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Full name|Full name]]||The full name for this section including its parent page, e.g. page1.section1<br />
|valign="top"|fullid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Alias name|Alias name]]||The alias name for this section<br />
|valign="top"|aliasid||Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Dashboard group]]||The dashboard section that this section belongs to. From v5.2.<br />
|valign="top"|horizontalgroup||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Horizontal stretch]]||The horizontal % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|horizontalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Vertical stretch]]||The vertical % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|verticalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#App Doc|App Doc]]||The App Doc file for this section. This will be included in the [[App Doc]] when it is generated.<br />
|valign="top"|appdoc||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#MetaData version|MetaData version]]||The MetaData version number. You can set this in the setupUI hook to prevent MetaData being applied multiple times.<br />
|valign="top"|metaDataVersion||valign="top"|Int<br />
|-<br />
|valign="top"|[[MetaTypes|Meta types]]||A comma separated list of metatype names<br />
|valign="top"|metatypes||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Custom Props|Custom Props]]||A ';' separated list of custom prop key pairs, e.g. name=barry;company=lianja<br>From v5.3.<br />
|valign="top"|customprops||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Type|Type]]||The type of section: orgchart (readonly)<br />
|valign="top"|type||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Caption|Caption]]||The section caption displayed in the section header<br />
|valign="top"|title||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Database|Database]]||The database for this section<br />
|valign="top"|database||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Table|Table]]||The table for this section<br />
|valign="top"|table||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Height|Height]]||The section height<br />
|valign="top"|height||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Fixed height|Fixed height]]||Fix the section height (True &#124; False)<br />
|valign="top"|fixedHeight||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Details Attributes#Auto layout percent|Auto layout percent]]||Auto layout percentage of page size. If set to 0, then all sections on a page are resized to an equal height.<br />
|valign="top"|autoLayoutPercentage||valign="top"|Int<br />
|-<br />
|valign="top"|[[Details Attributes#Readonly|Readonly]]||Section is readonly (True &#124; False)<br />
|valign="top"|readOnly||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Appearance==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Appearance#Margin|Margin]]||Margin size around the section<br />
|valign="top"|margin||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Appearance#Add spacer at bottom|Add spacer at bottom]]||Add spacer at bottom of section (True &#124; False)<br />
|valign="top"|spacerVisible||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Header==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Hide header|Hide header]]||Hide section header at runtime (True &#124; False)<br />
|valign="top"|hideHeaderAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide actionbar|Hide actionbar]]||Hide actionbar when stacked section is activated at runtime<br>(True &#124; False)<br />
|valign="top"|hideActionBarAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header icon|Header icon]]||The image for the Header (png &#124; jpg &#124; gif).<br>Use app:/imagename.ext for app specific images.<br />
|valign="top"|headerIcon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient colors|Gradient colors]]||Render the Header background color as a gradient (True &#124; False)<br />
|valign="top"|headerGradient||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Gradients#Gradient type|Gradient type]]||Specify the gradient type<br />
|valign="top"|headerGradientType||valign="top"|Int<br />
|-<br />
|valign="top"|[[Gradients#Gradient start color|Gradient start color]]||Gradient start color<br />
|valign="top"|headerFromColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient end color|Gradient end color]]||Gradient end color<br />
|valign="top"|headerToColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show Print button|Show Print button]]||Show Print button in the section header (True &#124; False)<br />
|valign="top"|showPrintButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Edit button|Show Edit button]]||Show Edit button in the section header (True &#124; False)<br />
|valign="top"|showEditButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide custom search icon|Hide custom search icon]]||Hide the custom search icon (True &#124; False)<br />
|valign="top"|hideCustomSearchIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Custom search dialog|Show Custom search dialog]]||Show custom search dialog when custom search icon clicked (True &#124; False)<br />
|valign="top"|showcustomsearchdialog||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show custom search dialog panel|Show custom search dialog panel]]||Show custom search dialog panel when custom search icon clicked<br>(True &#124; False)<br />
|valign="top"|showcustomsearchdialogpanel||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show info tips icon|Show info tips icon]]||Show the info tips icon in the section header (True &#124; False)<br />
|valign="top"|showInfoTipsIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show help icon|Show help icon]]||Show the help icon in the section header (True &#124; False)<br />
|valign="top"|showHelpIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Help topic|Help topic]]||Help topic to display when the help icon is clicked in the section header<br />
|valign="top"|helpTopic||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Custom Header Style==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Use custom header style|Use custom header style]]||Use a custom header style (True &#124; False)<br />
|valign="top"|headercustomstyle||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header background color|Header background color]]||Header background color<br />
|valign="top"|headerbackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header foreground color|Header foreground color]]||Header foreground color<br />
|valign="top"|headerforecolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border|Header bottom border]]||Display the header bottom border (True &#124; False)<br />
|valign="top"|headerbottomborder||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border height|Header bottom border height]]||Height (in pixels) of the header bottom border (if displayed)<br />
|valign="top"|headerbottomborderheight||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border color|Header bottom border color]]||Header bottom border color<br />
|valign="top"|headerbottombordercolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show record count badge|Show record count badge]]||Show the record count badge in the section header (True &#124; False).<br />
|valign="top"|showreccount||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Visual Component Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Visual_Components#Component_library_3|Component library]]||This specifies the Component library where the component will be saved.<br />
|valign="top"|componentlib||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_name_2|Component name]]||Save as this component name whenever the section is saved.<br />
|valign="top"|componentname||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_author_2|Component author]]||The author of this component.<br />
|valign="top"|componentauthor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_version_2|Component version]]||The version of this component.<br />
|valign="top"|componentversion||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_description_2|Component description]]||The description of this component.<br />
|valign="top"|componentdescription||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_permissions_2|Component permissions]]||The permissions required for this component in Lianja Cloud App Builder.<br />
|valign="top"|componentpermissions||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_width_2|Component width]]||The width of this component when activated as a Form.<br />
|valign="top"|componentwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[Visual_Components#Component_height_2|Component height]]||The height of this component when activated as a Form.<br />
|valign="top"|componentheight||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Org Chart Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Org Chart Options#Child ID column|Child ID column]]||The column name for the Child ID column (this must be numeric).<br />
|valign="top"|orgchartIdColumn||valign="top"|Character<br />
|-<br />
|valign="top"|[[Org Chart Options#Parent ID column|Parent ID column]]||The column name for the Parent ID column (this must be numeric).<br />
|valign="top"|orgchartParentIdColumn||valign="top"|Character<br />
|-<br />
|valign="top"|[[Org Chart Options#Caption expression|Caption expression]]||An expression that will be evaluated and displayed as the node caption (may contain HTML).<br />
|valign="top"|orgchartCaption||valign="top"|Character<br />
|-<br />
|valign="top"|[[Org Chart Options#Details expression|Details expression]]||An expression that will be evaluated and displayed as the node details beneath the caption (may contain HTML).<br />
|valign="top"|orgchartDetails||valign="top"|Character<br />
|-<br />
|valign="top"|[[Org Chart Options#Child key column|Child key column]]||The column that will be passed to the Click and DblClick delegates as an argument.<br />
|valign="top"|orgchartKeyColumn||valign="top"|Character<br />
|-<br />
|valign="top"|[[Org Chart Options#Node width|Node width]]||The display width of the nodes.<br />
|valign="top"|orgchartNodeWidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[Org Chart Options#Node height|Node height]]||The display height of the nodes.<br />
|valign="top"|orgchartNodeHeight||valign="top"|Int<br />
|-<br />
|valign="top"|[[Org Chart Options#Dynamic node backcolor|Dynamic node backcolor]]||Delegate to return the background color of the node for the current record being processed.<br />
|valign="top"|orgchartBackColorDelegate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Org Chart Options#Dynamic node forecolor|Dynamic node forecolor]]||Delegate to return the foreground color of the node for the current record being processed.<br />
|valign="top"|orgchartForeColorDelegate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Org Chart Options#Custom delegate library|Custom delegate library]]||Custom library containing the dynamic color delegates<br />
|valign="top"|orgchartCustomLibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[Org Chart Options#Filter|Filter]]||The filter expression that restricts which records will be included in the Org Chart<br />
|valign="top"|orgchartCalendarFilter||valign="top"|Character<br />
|-<br />
|valign="top"|[[Org Chart Options#Other options|Other options]]||Other custom Org Chart options, e.g. name=value&name2=value2<br />
|valign="top"|orgchartCalendarOtherOptions||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Related Data==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Related Data#Parent section name|Parent section name]]||Name of related parent section<br />
|valign="top"|parentid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Automatically relate|Automatically relate]]||Automatically relate the child section (True &#124; False). If this is unchecked then you need to manually relate it in the parentdatachanged delegate.<br />
|valign="top"|autoRelateChildSection||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Related Data#Parent key|Parent key]]||Parent key<br />
|valign="top"|parentKeyExpr||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Child key|Child key]]||Child key<br />
|valign="top"|childKeyExpr||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Menu==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Menus#Visible|Visible]]||Section menu visible (True &#124; False)<br />
|valign="top"|sectionMenuVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Menus#Height|Height]]||Section menu height<br />
|valign="top"|sectionMenuHeight||Int<br />
|-<br />
|valign="top"|[[Section Menus#Background color|Background color]]||Section menu background color<br />
|valign="top"|sectionMenuBackColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Foreground color|Foreground color]]||Section menu foreground color<br />
|valign="top"|sectionMenuForeColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu panel|Custom menu panel]]||The .rsp or .jssp page used to create the custom menu panel. This page should generate dynamic HTML5/JavaScript.<br />
|valign="top"|customSectionMenuPanel||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu|Custom menu]]||Section menu contents<br />
|valign="top"|customSectionMenu||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom action|Custom action]]||Action to perform when a menu item is selected<br />
|valign="top"|sectionMenuAction||Character<br />
|-<br />
|}<br />
<br />
==Search Panel==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Search Panels#Visible|Visible]]||Section search panel visible (True &#124; False)<br />
|valign="top"|searchPanelVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Height|Height]]||Section search panel height<br />
|valign="top"|searchPanelHeight||Int<br />
|-<br />
|valign="top"|[[Section Search Panels#Background color|Background color]]||Section search panel background color<br />
|valign="top"|searchPanelBackColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Foreground color|Foreground color]]||Section search panel foreground color<br />
|valign="top"|searchPanelForeColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Auto create|Auto create]]||Automatically create search panel for all Section search fields<br />
|valign="top"|searchPanelAutoCreate||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Custom search panel|Custom search panel]]||The delegate used to create the custom search panel<br />
|valign="top"|searchPanelAction||Character<br />
|-<br />
|}<br />
<br />
==Subtitle==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Subtitles#Visible|Visible]]||Section subtitle visible (True &#124; False)<br />
|valign="top"|subtitleVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Subtitles#Caption|Caption]]||Section subtitle caption<br />
|valign="top"|subtitleCaption||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Height|Height]]||Section subtitle height<br />
|valign="top"|subtitleHeight||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#Background color|Background color]]||Section subtitle background color<br />
|valign="top"|subtitleBackColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Foreground color|Foreground color]]||Section subtitle foreground color<br />
|valign="top"|subtitleForeColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Font|Font]]||Section subtitle font<br />
|valign="top"|subtitleFont||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#CSS style|CSS style]]||CSS style<br />
|valign="top"|subtitleCssStyle||Character<br />
|-<br />
|}<br />
<br />
==Footer==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Footers#Visible|Visible]]||Section footer visible (True &#124; False)<br />
|valign="top"|footerVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Footers#Caption|Caption]]||Section footer caption<br />
|valign="top"|footerText||Character<br />
|-<br />
|valign="top"|[[Section Footers#Height|Height]]||Section footer height<br />
|valign="top"|footerHeight||Int<br />
|-<br />
|valign="top"|[[Section Footers#Background color|Background color]]||Section footer background color<br />
|valign="top"|footerBackColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#Foreground color|Foreground color]]||Section footer foreground color<br />
|valign="top"|footerForeColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#CSS style|CSS style]]||CSS style (separate attributes with ; or use app:/filename.css or specify CSS classes separated by spaces).<br />
|valign="top"|footercssstyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom menu|Custom menu]]||Section footer menu contents<br />
|valign="top"|customOptionsMenu||Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom action|Custom action]]||Action to perform when a footer menu item is selected<br />
|valign="top"|customOptionsMenuAction||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button CSS|Footer button CSS]]||Footer button CSS style<br />
|valign="top"|footerButtonCss||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button width|Footer button width]]||Footer button width<br />
|valign="top"|footerButtonWidth||Int<br />
|-<br />
|}<br />
<br />
==Other Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Accordion Behavior#Hide form NavBar|Hide form NavBar]]||Hide form Navigation Bar at runtime if this section is in an Accordion Stack (True &#124; False)<br />
|valign="top"|hideFormNavBar||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Instant_Search#Hide_SearchBox|Hide SearchBox]]||Hide the Page Header Instant Search box when this section is selected in an Accordion Stack (True &#124; False). From v5.4.<br />
|valign="top"|hidesearchbox||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Appearance#Collapsable|Collapsable]]||The section is collapsible at runtime (True &#124; False)<br />
|valign="top"|collapsableAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Accordion Behavior#Exclude from accordion|Exclude from accordion]]||The section is excluded from accordion behavior at runtime (True &#124; False)<br />
|valign="top"|excludeAccordionAtRuntime||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Custom Delegates==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Custom Delegates#Scripting Language|Scripting language]]||The default scripting language for custom code in this section (Inherit &#124; Recital &#124; Visual FoxPro &#124; Python &#124; JavaScript &#124; PHP)<br />
|valign="top"|scriptingLanguage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom Library|Custom library]]||The filename of the library containing code for event handlers and custom procedures/functions<br />
|valign="top"|customLibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Print|Print]]||The delegate for the Print event.<br>This is called when you click the 'Print' icon.<br />
|valign="top"|printAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Expanded|Expanded]]||The delegate for the Expanded event<br />
|valign="top"|expandedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Collapsed|Collapsed]]||The delegate for the Collapsed event<br />
|valign="top"|collapsedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Hotkey|Hotkey]]||The delegate for the Hotkey event.<br />
|valign="top"|hotkeyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Init|Init]]||The delegate for the Init event<br />
|valign="top"|initAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Destroy|Destroy]]||The delegate for the Destroy event<br />
|valign="top"|destroyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Load|Load]]||The delegate for the Load event<br />
|valign="top"|loadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Ready|Ready]]||The delegate for the Ready event<br />
|valign="top"|readyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Unload|Unload]]||The delegate for the Unload event<br />
|valign="top"|unloadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Click|Click]]||The delegate for the Click event<br />
|valign="top"|clickAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Double Click|Double Click]]||The delegate for the Double Clicked event<br />
|valign="top"|dblClickAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Parent data changed|Parent data changed]]||The delegate for the ParentDataChanged event<br />
|valign="top"|parentDataChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Data Producer|Data Producer]]||The delegate for the DataProducer (used in Web Components).<br>From v6.1.<br />
|valign="top"|dataProducerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer|Timer]]||The delegate for the Timer event<br />
|valign="top"|timerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer interval|Timer interval]]||The timer interval in seconds that the Timer event will be called at runtime<br />
|valign="top"|timerInterval||valign="top"|Int<br />
|-<br />
|valign="top"|[[Custom Delegates#State Changed|State Changed]]||The delegate for the Statechanged event.<br />
|valign="top"|stateChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom footer menu|Custom footer menu]]||The delegate for the footer menu event<br />
|valign="top"|customMenuAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom search command|Custom search command]]||The delegate for the search event<br />
|valign="top"|customSearch||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom section menu|Custom section menu]]||The delegate for the section menu event<br />
|valign="top"|customSectionMenuAction||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Permissions and Roles==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Users and Roles|Create roles]]||A comma separated list of roles that can perform create operations on data in the section.<br />
|valign="top"|permcreate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Read roles]]||A comma separated list of roles that can read (and view) the section.<br />
|valign="top"|permRead||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Update roles]]||A comma separated list of roles that can perform update operations on data in the section.<br />
|valign="top"|permUpdate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Delete roles]]||A comma separated list of roles that can perform delete operations on data in the section.<br />
|valign="top"|permDelete||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==UI Presentation Rules==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Desktop|Desktop]]||Include this section in a Desktop client (True &#124; False).<br />
|valign="top"|desktopUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Web|Web]]||Include this section in a Web client (True &#124; False).<br />
|valign="top"|webUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Tablet|Tablet]]||Include this section in a Tablet client (True &#124; False).<br />
|valign="top"|tabletUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Phone|Phone]]||Include this section in a Phone client (True &#124; False).<br />
|valign="top"|mobileUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#UI States|UI States]]||UI states that affect this section. Specify multiple states as a comma separated list.<br />
|valign="top"|state||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Initial UI state|Initial UI state]]||The initial UI state for this section. This will be applied to the section and all its fields and gadgets.<br />
|valign="top"|uiStateInit||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Readonly when|Readonly when]]||Section is readonly at runtime if specified expression evaluates to true.<br />
|valign="top"|readonlyWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Visible when|Visible when]]||Section is visible at runtime if specified expression evaluates to true.<br />
|valign="top"|visibleWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Display orientation|Display orientation]]||Display depending on mobile device orientation for Tablets and Phones. (Always &#124; Portrait &#124; Landscape)<br />
|valign="top"|displayOrientation||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on change|Apply rules on change]]||Apply UI presentation rules (Visible when and Readonly when) when data is changed interactively or when navigating records (True &#124; False).<br />
|valign="top"|applyRulesOnChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on parent change|Apply rules on parent change]]||Apply section UI presentation rules (Visible when and Readonly when) when parent data is changed by navigating records (True &#124; False)<br />
|valign="top"|applyRulesOnParentChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Search Panel Responsive UI width breakpoint|Search Panel Responsive UI width breakpoint]]||The Search Panel responsive UI width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|searchpanelresponsivevisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Menu Responsive UI width breakpoint|Menu Responsive UI width breakpoint]]||valign="top"|The Menu responsive UI width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsivemenuwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI width breakpoint|Responsive UI width breakpoint]]||The section responsive UI visibility width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsivewidthvisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI height breakpoint|Responsive UI height breakpoint]]||The section responsive UI visibility height breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsiveheightvisibility||valign="top"|Int<br />
|-<br />
|}<br />
<br />
[[Category:Attributes|3 Org Chart Section]]<br />
[[Category:Sections]]<br />
[[Category:WebView Based Sections]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/GalleryView_Section_AttributesGalleryView Section Attributes2024-03-22T11:46:04Z<p>Yvonne.milne: /* UI Presentation Rules */</p>
<hr />
<div>=Overview=<br />
GalleryView Sections are used to display a gallery of Tiles. Clicking on a Tile automatically displays a full-section Content panel.<br />
{{DISPLAYTITLE:GalleryView Section}}<br />
[[File:GalleryView_section.png|middle|758px|link=]]<br />
<br />
You build Apps in Lianja App Builder visually using the [[:Category:Page_Builder|Page Builder]].<br />
<br />
If you have not yet done so please read [[Understanding_the_Lianja_App_Architecture|Understanding the Lianja Architecture]] and also [[Lianja_is_all_about_ART|Understanding ART]] to better understand this article.<br />
<br />
An App consists of pages. Pages are made up of Sections. Form sections are made up of FormItems. We call these collectively "UI Elements" or "Visual Elements".<br />
<br />
==Setting Attributes Declaratively==<br />
<br />
You adjust the appearance and behavior of each UI Element in the '''Attributes''' Tab of the [[:Category:App_Inspector|App Inspector]].<br />
<br />
[[{{ns:file}}:bm-attributes.png|800px|left|border|link={{filepath:bm-attributes.png}}|Attributes]]<br />
<br clear=all><br />
<br />
The attributes available consist of some common ones as well as some specific to the UI Element being inspected.<br />
<br />
==Getting and Setting Attributes Programmatically==<br />
The '''setAttribute(name, value)''' method can be used to set the value of an Attribute:<br />
<br />
<pre>Lianja.get("pageid.sectionid").setAttribute("title","Section1")</pre><br />
<br />
Note: on the desktop, the shortened form '''setAttr(name,value)''' is also available.<br />
<br />
The '''getAttribute(name)''' method can be used to get the value of an Attribute:<br />
<br />
<pre>cTitle = Lianja.get("pageid.sectionid").getAttribute("title")</pre><br />
<br />
Note: on the desktop, the shortened form '''getAttr(name)''' is also available.<br />
<br />
=See Also=<br />
[[GalleryView Options]]<br />
<br />
Demo Apps (included in the Lianja App Builder distribution):<br />
* Lianja Galleryview Demo (example_galleryview)<br />
<br />
=Attributes=<br />
==Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Details Attributes#Name|Name]]||The name for this section (unique to the page)<br />
|valign="top"|id||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Full name|Full name]]||The full name for this section including its parent page, e.g. page1.section1<br />
|valign="top"|fullid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Alias name|Alias name]]||The alias name for this section<br />
|valign="top"|aliasid||Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Dashboard group]]||The dashboard section that this section belongs to. From v5.2.<br />
|valign="top"|horizontalgroup||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Horizontal stretch]]||The horizontal % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|horizontalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Vertical stretch]]||The vertical % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|verticalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#App Doc|App Doc]]||The App Doc file for this section. This will be included in the [[App Doc]] when it is generated.<br />
|valign="top"|appdoc||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#MetaData version|MetaData version]]||The MetaData version number. You can set this in the setupUI hook to prevent MetaData being applied multiple times.<br />
|valign="top"|metaDataVersion||valign="top"|Int<br />
|-<br />
|valign="top"|[[MetaTypes|Meta types]]||A comma separated list of metatype names<br />
|valign="top"|metatypes||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Custom Props|Custom Props]]||A ';' separated list of custom prop key pairs, e.g. name=barry;company=lianja<br>From v5.3.<br />
|valign="top"|customprops||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Type|Type]]||The type of section: galleryview (readonly)<br />
|valign="top"|type||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Caption|Caption]]||The section caption displayed in the section header<br />
|valign="top"|title||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Database|Database]]||The database for this section<br />
|valign="top"|database||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Table|Table]]||The table for this section<br />
|valign="top"|table||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Height|Height]]||The section height<br />
|valign="top"|height||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Fixed height|Fixed height]]||Fix the section height (True &#124; False)<br />
|valign="top"|fixedHeight||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Details Attributes#Auto layout percent|Auto layout percent]]||Auto layout percentage of page size. If set to 0, then all sections on a page are resized to an equal height.<br />
|valign="top"|autoLayoutPercentage||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Appearance==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Appearance#Margin|Margin]]||Margin size around the section<br />
|valign="top"|margin||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Appearance#Add spacer at bottom|Add spacer at bottom]]||Add spacer at bottom of section (True &#124; False)<br />
|valign="top"|spacerVisible||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Header==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Hide header|Hide header]]||Hide section header at runtime(True &#124; False)<br />
|valign="top"|hideHeaderAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide actionbar|Hide actionbar]]||Hide actionbar when stacked section is activated at runtime<br>(True &#124; False)<br />
|valign="top"|hideActionBarAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header icon|Header icon]]||The image for the Header (png &#124; jpg &#124; gif).<br>Use app:/imagename.ext for app specific images.<br />
|valign="top"|headerIcon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient colors|Gradient colors]]||Render the Header background color as a gradient (True &#124; False)<br />
|valign="top"|headerGradient||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Gradients#Gradient type|Gradient type]]||Specify the gradient type<br />
|valign="top"|headerGradientType||valign="top"|Int<br />
|-<br />
|valign="top"|[[Gradients#Gradient start color|Gradient start color]]||Gradient start color<br />
|valign="top"|headerFromColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient end color|Gradient end color]]||Gradient end color<br />
|valign="top"|headerToColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show Print button|Show Print button]]||Show Print button in the section header (True &#124; False)<br />
|valign="top"|showPrintButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Edit button|Show Edit button]]||Show Edit button in the section header (True &#124; False)<br />
|valign="top"|showEditButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide custom search icon|Hide custom search icon]]||Hide the custom search icon (True &#124; False)<br />
|valign="top"|hideCustomSearchIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Custom search dialog|Show Custom search dialog]]||Show custom search dialog when custom search icon clicked (True &#124; False)<br />
|valign="top"|showcustomsearchdialog||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show custom search dialog panel|Show custom search dialog panel]]||Show custom search dialog panel when custom search icon clicked<br>(True &#124; False)<br />
|valign="top"|showcustomsearchdialogpanel||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show info tips icon|Show info tips icon]]||Show the info tips icon in the section header (True &#124; False)<br />
|valign="top"|showInfoTipsIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show help icon|Show help icon]]||Show the help icon in the section header (True &#124; False)<br />
|valign="top"|showHelpIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Help topic|Help topic]]||Help topic to display when the help icon is clicked in the section header<br />
|valign="top"|helpTopic||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Custom Header Style==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Use custom header style|Use custom header style]]||Use a custom header style (True &#124; False)<br />
|valign="top"|headercustomstyle||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header background color|Header background color]]||Header background color<br />
|valign="top"|headerbackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header foreground color|Header foreground color]]||Header foreground color<br />
|valign="top"|headerforecolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border|Header bottom border]]||Display the header bottom border (True &#124; False)<br />
|valign="top"|headerbottomborder||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border height|Header bottom border height]]||Height (in pixels) of the header bottom border (if displayed)<br />
|valign="top"|headerbottomborderheight||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border color|Header bottom border color]]||Header bottom border color<br />
|valign="top"|headerbottombordercolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show record count badge|Show record count badge]]||Show the record count badge in the section header (True &#124; False).<br />
|valign="top"|showreccount||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Visual Component Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Visual_Components#Component_library_3|Component library]]||This specifies the Component library where the component will be saved.<br />
|valign="top"|componentlib||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_name_2|Component name]]||Save as this component name whenever the section is saved.<br />
|valign="top"|componentname||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_author_2|Component author]]||The author of this component.<br />
|valign="top"|componentauthor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_version_2|Component version]]||The version of this component.<br />
|valign="top"|componentversion||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_description_2|Component description]]||The description of this component.<br />
|valign="top"|componentdescription||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_permissions_2|Component permissions]]||The permissions required for this component in Lianja Cloud App Builder.<br />
|valign="top"|componentpermissions||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_width_2|Component width]]||The width of this component when activated as a Form.<br />
|valign="top"|componentwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[Visual_Components#Component_height_2|Component height]]||The height of this component when activated as a Form.<br />
|valign="top"|componentheight||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==GalleryView Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[GalleryView Options#Tile caption|Tile caption]]||The name of the column in the table (or expression) containing the caption for each tile<br />
|valign="top"|galleryviewCaption||valign="top"|Character<br />
|-<br />
|valign="top"|[[GalleryView Options#Tile category|Tile category]]||The name of the column in the table (or expression) containing the category caption for each tile<br />
|valign="top"|galleryViewSubCaption||valign="top"|Character<br />
|-<br />
|valign="top"|[[GalleryView Options#Content title|Content title]]||The content title as an expression<br />
|valign="top"|galleryviewHeading||valign="top"|Character<br />
|-<br />
|valign="top"|[[GalleryView Options#Content details|Content details]]||The name of the column in the table containing the content (typically a varchar/memo)<br />
|valign="top"|galleryviewDetails||valign="top"|Character<br />
|-<br />
|valign="top"|[[GalleryView Options#Custom library|Custom library]]||Custom library containing the Tile producer and Content producer delegates<br />
|valign="top"|galleryviewCustomLibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[GalleryView Options#Tile producer|Tile producer]]||Delegate to call to render a custom tile. <br>This should just output the HTML<br />
|valign="top"|galleryviewTileDelegate||valign="top"|Character<br />
|-<br />
|valign="top"|[[GalleryView Options#Content producer|Content producer]]||Delegate to call to render the content.<br>This should just output the HTML<br />
|valign="top"|galleryviewContentDelegate||valign="top"|Character<br />
|-<br />
|valign="top"|[[GalleryView Options#Filter|Filter]]||The filter expression that restricts which records will be included<br />
|valign="top"|galleryViewFilter||valign="top"|Character<br />
|-<br />
|valign="top"|[[GalleryView Options#Order by|Order by]]||The orderby expression for the data in the GalleryView<br />
|valign="top"|galleryViewOrderBy||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Related Data==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Related Data#Parent section name|Parent section name]]||Name of related parent section<br />
|valign="top"|parentid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Automatically relate|Automatically relate]]||Automatically relate the child section (True &#124; False). If this is unchecked then you need to manually relate it in the parentdatachanged delegate.<br />
|valign="top"|autoRelateChildSection||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Menu==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Menus#Visible|Visible]]||Section menu visible (True &#124; False)<br />
|valign="top"|sectionMenuVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Menus#Height|Height]]||Section menu height<br />
|valign="top"|sectionMenuHeight||Int<br />
|-<br />
|valign="top"|[[Section Menus#Background color|Background color]]||Section menu background color<br />
|valign="top"|sectionMenuBackColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Foreground color|Foreground color]]||Section menu foreground color<br />
|valign="top"|sectionMenuForeColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu panel|Custom menu panel]]||The .rsp or .jssp page used to create the custom menu panel. This page should generate dynamic HTML5/JavaScript.<br />
|valign="top"|customSectionMenuPanel||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu|Custom menu]]||Section menu contents<br />
|valign="top"|customSectionMenu||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom action|Custom action]]||Action to perform when a menu item is selected<br />
|valign="top"|sectionMenuAction||Character<br />
|-<br />
|}<br />
<br />
==Search Panel==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Search Panels#Visible|Visible]]||Section search panel visible (True &#124; False)<br />
|valign="top"|searchPanelVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Height|Height]]||Section search panel height<br />
|valign="top"|searchPanelHeight||Int<br />
|-<br />
|valign="top"|[[Section Search Panels#Background color|Background color]]||Section search panel background color<br />
|valign="top"|searchPanelBackColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Foreground color|Foreground color]]||Section search panel foreground color<br />
|valign="top"|searchPanelForeColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Auto create|Auto create]]||Automatically create search panel for all Section search fields<br />
|valign="top"|searchPanelAutoCreate||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Custom search panel|Custom search panel]]||The delegate used to create the custom search panel<br />
|valign="top"|searchPanelAction||Character<br />
|-<br />
|}<br />
<br />
==Subtitle==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Subtitles#Visible|Visible]]||Section subtitle visible (True &#124; False)<br />
|valign="top"|subtitleVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Subtitles#Caption|Caption]]||Section subtitle caption<br />
|valign="top"|subtitleCaption||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Height|Height]]||Section subtitle height<br />
|valign="top"|subtitleHeight||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#Background color|Background color]]||Section subtitle background color<br />
|valign="top"|subtitleBackColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Foreground color|Foreground color]]||Section subtitle foreground color<br />
|valign="top"|subtitleForeColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Font|Font]]||Section subtitle font<br />
|valign="top"|subtitleFont||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#CSS style|CSS style]]||CSS style<br />
|valign="top"|subtitleCssStyle||Character<br />
|-<br />
|}<br />
<br />
==Footer==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Footers#Visible|Visible]]||Section footer visible (True &#124; False)<br />
|valign="top"|footerVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Footers#Caption|Caption]]||Section footer caption<br />
|valign="top"|footerText||Character<br />
|-<br />
|valign="top"|[[Section Footers#Height|Height]]||Section footer height<br />
|valign="top"|footerHeight||Int<br />
|-<br />
|valign="top"|[[Section Footers#Background color|Background color]]||Section footer background color<br />
|valign="top"|footerBackColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#Foreground color|Foreground color]]||Section footer foreground color<br />
|valign="top"|footerForeColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#CSS style|CSS style]]||CSS style (separate attributes with ; or use app:/filename.css or specify CSS classes separated by spaces).<br />
|valign="top"|footercssstyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom menu|Custom menu]]||Section footer menu contents<br />
|valign="top"|customOptionsMenu||Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom action|Custom action]]||Action to perform when a footer menu item is selected<br />
|valign="top"|customOptionsMenuAction||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button CSS|Footer button CSS]]||Footer button CSS style<br />
|valign="top"|footerButtonCss||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button width|Footer button width]]||Footer button width<br />
|valign="top"|footerButtonWidth||Int<br />
|-<br />
|}<br />
<br />
==Other Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Accordion Behavior#Hide form NavBar|Hide form NavBar]]||Hide form Navigation Bar at runtime if this section is in an Accordion Stack (True &#124; False)<br />
|valign="top"|hideFormNavBar||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Instant_Search#Hide_SearchBox|Hide SearchBox]]||Hide the Page Header Instant Search box when this section is selected in an Accordion Stack (True &#124; False). From v5.4.<br />
|valign="top"|hidesearchbox||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Appearance#Collapsable|Collapsable]]||The section is collapsible at runtime (True &#124; False)<br />
|valign="top"|collapsableAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Accordion Behavior#Exclude from accordion|Exclude from accordion]]||The section is excluded from accordion behavior at runtime (True &#124; False)<br />
|valign="top"|excludeAccordionAtRuntime||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Custom Delegates==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Custom Delegates#Scripting Language|Scripting language]]||The default scripting language for custom code in this section (Inherit &#124; Recital &#124; Visual FoxPro &#124; Python &#124; JavaScript &#124; PHP)<br />
|valign="top"|scriptingLanguage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom Library|Custom library]]||The filename of the library containing code for event handlers and custom procedures/functions<br />
|valign="top"|customLibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Print|Print]]||The delegate for the Print event.<br>This is called when you click the 'Print' icon.<br />
|valign="top"|printAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Expanded|Expanded]]||The delegate for the Expanded event<br />
|valign="top"|expandedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Collapsed|Collapsed]]||The delegate for the Collapsed event<br />
|valign="top"|collapsedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Hotkey|Hotkey]]||The delegate for the Hotkey event.<br />
|valign="top"|hotkeyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Init|Init]]||The delegate for the Init event<br />
|valign="top"|initAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Destroy|Destroy]]||The delegate for the Destroy event<br />
|valign="top"|destroyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Load|Load]]||The delegate for the Load event<br />
|valign="top"|loadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Ready|Ready]]||The delegate for the Ready event<br />
|valign="top"|readyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Unload|Unload]]||The delegate for the Unload event<br />
|valign="top"|unloadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Parent data changed|Parent data changed]]||The delegate for the ParentDataChanged event<br />
|valign="top"|parentDataChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Data Producer|Data Producer]]||The delegate for the DataProducer (used in Web Components).<br>From v6.1.<br />
|valign="top"|dataproduceraction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer|Timer]]||The delegate for the Timer event<br />
|valign="top"|timerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer interval|Timer interval]]||The timer interval in seconds that the Timer event will be called at runtime<br />
|valign="top"|timerInterval||valign="top"|Int<br />
|-<br />
|valign="top"|[[Custom Delegates#State Changed|State Changed]]||The delegate for the Statechanged event.<br />
|valign="top"|stateChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom footer menu|Custom footer menu]]||The delegate for the footer menu event<br />
|valign="top"|customMenuAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom search command|Custom search command]]||The delegate for the search event<br />
|valign="top"|customSearch||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom section menu|Custom section menu]]||The delegate for the section menu event<br />
|valign="top"|customSectionMenuAction||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Permissions and Roles==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Users and Roles|Create roles]]||A comma separated list of roles that can perform create operations on data in the section.<br />
|valign="top"|permcreate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Read roles]]||A comma separated list of roles that can read (and view) the section.<br />
|valign="top"|permRead||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Update roles]]||A comma separated list of roles that can perform update operations on data in the section.<br />
|valign="top"|permUpdate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Delete roles]]||A comma separated list of roles that can perform delete operations on data in the section.<br />
|valign="top"|permDelete||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==UI Presentation Rules==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Desktop|Desktop]]||Include this section in a Desktop client (True &#124; False).<br />
|valign="top"|desktopUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Web|Web]]||Include this section in a Web client (True &#124; False).<br />
|valign="top"|webUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Tablet|Tablet]]||Include this section in a Tablet client (True &#124; False).<br />
|valign="top"|tabletUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Phone|Phone]]||Include this section in a Phone client (True &#124; False).<br />
|valign="top"|mobileUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#UI States|UI States]]||UI states that affect this section. Specify multiple states as a comma separated list.<br />
|valign="top"|state||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Initial UI state|Initial UI state]]||The initial UI state for this section. This will be applied to the section and all its fields and gadgets.<br />
|valign="top"|uiStateInit||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Readonly when|Readonly when]]||Section is readonly at runtime if specified expression evaluates to true.<br />
|valign="top"|readonlyWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Visible when|Visible when]]||Section is visible at runtime if specified expression evaluates to true.<br />
|valign="top"|visibleWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Display orientation|Display orientation]]||Display depending on mobile device orientation for Tablets and Phones. (Always &#124; Portrait &#124; Landscape)<br />
|valign="top"|displayOrientation||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on change|Apply rules on change]]||Apply UI presentation rules (Visible when and Readonly when) when data is changed interactively or when navigating records (True &#124; False).<br />
|valign="top"|applyRulesOnChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on parent change|Apply rules on parent change]]||Apply section UI presentation rules (Visible when and Readonly when) when parent data is changed by navigating records (True &#124; False)<br />
|valign="top"|applyRulesOnParentChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Search Panel Responsive UI width breakpoint|Search Panel Responsive UI width breakpoint]]||The Search Panel responsive UI width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|searchpanelresponsivevisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Menu Responsive UI width breakpoint|Menu Responsive UI width breakpoint]]||valign="top"|The Menu responsive UI width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsivemenuwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI width breakpoint|Responsive UI width breakpoint]]||The section responsive UI visibility width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsivewidthvisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI height breakpoint|Responsive UI height breakpoint]]||The section responsive UI visibility height breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsiveheightvisibility||valign="top"|Int<br />
|-<br />
|}<br />
<br />
[[Category:Attributes|3 GalleryView Section]]<br />
[[Category:Lianja v2.0]]<br />
[[Category:Sections]]<br />
[[Category:WebView Based Sections]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/DocumentView_Section_AttributesDocumentView Section Attributes2024-03-22T11:45:35Z<p>Yvonne.milne: /* UI Presentation Rules */</p>
<hr />
<div>=Overview=<br />
DocumentView Sections are used to view pdf documents. DocumentView Sections include tools for printing, downloading, searching, zooming and navigating the document displayed without having to install any plugins.<br />
{{DISPLAYTITLE:DocumentView Section}}<br />
[[File:DocumentView_section.png|middle|758px|link=]]<br />
<br />
You build Apps in Lianja App Builder visually using the [[:Category:Page_Builder|Page Builder]].<br />
<br />
If you have not yet done so please read [[Understanding_the_Lianja_App_Architecture|Understanding the Lianja Architecture]] and also [[Lianja_is_all_about_ART|Understanding ART]] to better understand this article.<br />
<br />
An App consists of pages. Pages are made up of Sections. Form sections are made up of FormItems. We call these collectively "UI Elements" or "Visual Elements".<br />
<br />
==Setting Attributes Declaratively==<br />
<br />
You adjust the appearance and behavior of each UI Element in the '''Attributes''' Tab of the [[:Category:App_Inspector|App Inspector]].<br />
<br />
[[{{ns:file}}:bm-attributes.png|800px|left|border|link={{filepath:bm-attributes.png}}|Attributes]]<br />
<br clear=all><br />
<br />
The attributes available consist of some common ones as well as some specific to the UI Element being inspected.<br />
<br />
==Getting and Setting Attributes Programmatically==<br />
The '''setAttribute(name, value)''' method can be used to set the value of an Attribute:<br />
<br />
<pre>Lianja.get("pageid.sectionid").setAttribute("title","Section1")</pre><br />
<br />
Note: on the desktop, the shortened form '''setAttr(name,value)''' is also available.<br />
<br />
The '''getAttribute(name)''' method can be used to get the value of an Attribute:<br />
<br />
<pre>cTitle = Lianja.get("pageid.sectionid").getAttribute("title")</pre><br />
<br />
Note: on the desktop, the shortened form '''getAttr(name)''' is also available.<br />
<br />
==See Also==<br />
[[DocumentView Options]]<br />
<br />
Demo Apps (included in the Lianja App Builder distribution):<br />
* Lianja DocumentView Demo (example_docview)<br />
<br />
=Attributes=<br />
==Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Details Attributes#Name|Name]]||The name for this section (unique to the page)<br />
|valign="top"|id||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Full name|Full name]]||The full name for this section including its parent page, e.g. page1.section1<br />
|valign="top"|fullid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Alias name|Alias name]]||The alias name for this section<br />
|valign="top"|aliasid||Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Dashboard group]]||The dashboard section that this section belongs to. From v5.2.<br />
|valign="top"|horizontalgroup||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Horizontal stretch]]||The horizontal % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|horizontalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Vertical stretch]]||The vertical % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|verticalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#App Doc|App Doc]]||The App Doc file for this section. This will be included in the [[App Doc]] when it is generated.<br />
|valign="top"|appdoc||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#MetaData version|MetaData version]]||The MetaData version number. You can set this in the setupUI hook to prevent MetaData being applied multiple times.<br />
|valign="top"|metaDataVersion||valign="top"|Int<br />
|-<br />
|valign="top"|[[MetaTypes|Meta types]]||A comma separated list of metatype names<br />
|valign="top"|metatypes||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Custom Props|Custom Props]]||A ';' separated list of custom prop key pairs, e.g. name=barry;company=lianja<br>From v5.3.<br />
|valign="top"|customprops||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Type|Type]]||The type of section: documentview (readonly)<br />
|valign="top"|type||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Caption|Caption]]||The section caption displayed in the section header<br />
|valign="top"|title||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Height|Height]]||The section height<br />
|valign="top"|height||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Fixed height|Fixed height]]||Fix the section height (True &#124; False)<br />
|valign="top"|fixedHeight||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Details Attributes#Auto layout percent|Auto layout percent]]||Auto layout percentage of page size. If set to 0, then all sections on a page are resized to an equal height.<br />
|valign="top"|autoLayoutPercentage||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Appearance==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Appearance#Margin|Margin]]||Margin size around the section<br />
|valign="top"|margin||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Appearance#Add spacer at bottom|Add spacer at bottom]]||Add spacer at bottom of section (True &#124; False)<br />
|valign="top"|spacerVisible||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Header==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Hide header|Hide header]]||Hide section header at runtime(True &#124; False)<br />
|valign="top"|hideHeaderAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide actionbar|Hide actionbar]]||Hide actionbar when stacked section is activated at runtime<br>(True &#124; False)<br />
|valign="top"|hideActionBarAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header CSS style|Header CSS style]]||CSS style (separate attributes with ; or use app:/filename.css)<br />
|valign="top"|headerCssStyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header icon|Header icon]]||The image for the Header (png &#124; jpg &#124; gif).<br>Use app:/imagename.ext for app specific images.<br />
|valign="top"|headerIcon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient colors|Gradient colors]]||Render the Header background color as a gradient (True &#124; False)<br />
|valign="top"|headerGradient||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Gradients#Gradient type|Gradient type]]||Specify the gradient type<br />
|valign="top"|headerGradientType||valign="top"|Int<br />
|-<br />
|valign="top"|[[Gradients#Gradient start color|Gradient start color]]||Gradient start color<br />
|valign="top"|headerFromColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient end color|Gradient end color]]||Gradient end color<br />
|valign="top"|headerToColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show Print button|Show Print button]]||Show Print button in the section header (True &#124; False)<br />
|valign="top"|showPrintButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Edit button|Show Edit button]]||Show Edit button in the section header (True &#124; False)<br />
|valign="top"|showEditButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide custom search icon|Hide custom search icon]]||Hide the custom search icon (True &#124; False)<br />
|valign="top"|hideCustomSearchIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Custom search dialog|Show Custom search dialog]]||Show custom search dialog when custom search icon clicked (True &#124; False)<br />
|valign="top"|showcustomsearchdialog||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show custom search dialog panel|Show custom search dialog panel]]||Show custom search dialog panel when custom search icon clicked<br>(True &#124; False)<br />
|valign="top"|showcustomsearchdialogpanel||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show info tips icon|Show info tips icon]]||Show the info tips icon in the section header (True &#124; False)<br />
|valign="top"|showInfoTipsIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show help icon|Show help icon]]||Show the help icon in the section header (True &#124; False)<br />
|valign="top"|showHelpIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Help topic|Help topic]]||Help topic to display when the help icon is clicked in the section header<br />
|valign="top"|helpTopic||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Custom Header Style==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Use custom header style|Use custom header style]]||Use a custom header style (True &#124; False)<br />
|valign="top"|headercustomstyle||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header background color|Header background color]]||Header background color<br />
|valign="top"|headerbackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header foreground color|Header foreground color]]||Header foreground color<br />
|valign="top"|headerforecolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border|Header bottom border]]||Display the header bottom border (True &#124; False)<br />
|valign="top"|headerbottomborder||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border height|Header bottom border height]]||Height (in pixels) of the header bottom border (if displayed)<br />
|valign="top"|headerbottomborderheight||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border color|Header bottom border color]]||Header bottom border color<br />
|valign="top"|headerbottombordercolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show record count badge|Show record count badge]]||Show the record count badge in the section header (True &#124; False).<br />
|valign="top"|showreccount||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Visual Component Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Visual_Components#Component_library_3|Component library]]||This specifies the Component library where the component will be saved.<br />
|valign="top"|componentlib||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_name_2|Component name]]||Save as this component name whenever the section is saved.<br />
|valign="top"|componentname||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_author_2|Component author]]||The author of this component.<br />
|valign="top"|componentauthor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_version_2|Component version]]||The version of this component.<br />
|valign="top"|componentversion||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_description_2|Component description]]||The description of this component.<br />
|valign="top"|componentdescription||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_permissions_2|Component permissions]]||The permissions required for this component in Lianja Cloud App Builder.<br />
|valign="top"|componentpermissions||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_width_2|Component width]]||The width of this component when activated as a Form.<br />
|valign="top"|componentwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[Visual_Components#Component_height_2|Component height]]||The height of this component when activated as a Form.<br />
|valign="top"|componentheight||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==DocumentView Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[DocumentView Options#File|File]]||The PDF file to be displayed. This may contain {...} macros.<br />
|valign="top"|DocumentViewFileName||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Related Data==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Related Data#Parent section name|Parent section name]]||Name of related parent section<br />
|valign="top"|parentid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Automatically relate|Automatically relate]]||Automatically relate the child section (True &#124; False). If this is unchecked then you need to manually relate it in the parentdatachanged delegate.<br />
|valign="top"|autoRelateChildSection||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Menu==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Menus#Visible|Visible]]||Section menu visible (True &#124; False)<br />
|valign="top"|sectionMenuVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Menus#Height|Height]]||Section menu height<br />
|valign="top"|sectionMenuHeight||Int<br />
|-<br />
|valign="top"|[[Section Menus#Background color|Background color]]||Section menu background color<br />
|valign="top"|sectionMenuBackColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Foreground color|Foreground color]]||Section menu foreground color<br />
|valign="top"|sectionMenuForeColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu panel|Custom menu panel]]||The .rsp or .jssp page used to create the custom menu panel. This page should generate dynamic HTML5/JavaScript.<br />
|valign="top"|customSectionMenuPanel||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu|Custom menu]]||Section menu contents<br />
|valign="top"|customSectionMenu||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom action|Custom action]]||Action to perform when a menu item is selected<br />
|valign="top"|sectionMenuAction||Character<br />
|-<br />
|}<br />
<br />
==Search Panel==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Search Panels#Visible|Visible]]||Section search panel visible (True &#124; False)<br />
|valign="top"|searchPanelVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Height|Height]]||Section search panel height<br />
|valign="top"|searchPanelHeight||Int<br />
|-<br />
|valign="top"|[[Section Search Panels#Background color|Background color]]||Section search panel background color<br />
|valign="top"|searchPanelBackColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Foreground color|Foreground color]]||Section search panel foreground color<br />
|valign="top"|searchPanelForeColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Auto create|Auto create]]||Automatically create search panel for all Section search fields<br />
|valign="top"|searchPanelAutoCreate||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Custom search panel|Custom search panel]]||The delegate used to create the custom search panel<br />
|valign="top"|searchPanelAction||Character<br />
|-<br />
|}<br />
<br />
==Subtitle==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Subtitles#Visible|Visible]]||Section subtitle visible (True &#124; False)<br />
|valign="top"|subtitleVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Subtitles#Caption|Caption]]||Section subtitle caption<br />
|valign="top"|subtitleCaption||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Height|Height]]||Section subtitle height<br />
|valign="top"|subtitleHeight||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#Background color|Background color]]||Section subtitle background color<br />
|valign="top"|subtitleBackColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Foreground color|Foreground color]]||Section subtitle foreground color<br />
|valign="top"|subtitleForeColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Font|Font]]||Section subtitle font<br />
|valign="top"|subtitleFont||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#CSS style|CSS style]]||CSS style<br />
|valign="top"|subtitleCssStyle||Character<br />
|-<br />
|}<br />
<br />
==Footer==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Footers#Visible|Visible]]||Section footer visible (True &#124; False)<br />
|valign="top"|footerVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Footers#Caption|Caption]]||Section footer caption<br />
|valign="top"|footerText||Character<br />
|-<br />
|valign="top"|[[Section Footers#Height|Height]]||Section footer height<br />
|valign="top"|footerHeight||Int<br />
|-<br />
|valign="top"|[[Section Footers#Background color|Background color]]||Section footer background color<br />
|valign="top"|footerBackColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#Foreground color|Foreground color]]||Section footer foreground color<br />
|valign="top"|footerForeColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#CSS style|CSS style]]||CSS style (separate attributes with ; or use app:/filename.css or specify CSS classes separated by spaces).<br />
|valign="top"|footercssstyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom menu|Custom menu]]||Section footer menu contents<br />
|valign="top"|customOptionsMenu||Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom action|Custom action]]||Action to perform when a footer menu item is selected<br />
|valign="top"|customOptionsMenuAction||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button CSS|Footer button CSS]]||Footer button CSS style<br />
|valign="top"|footerButtonCss||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button width|Footer button width]]||Footer button width<br />
|valign="top"|footerButtonWidth||Int<br />
|-<br />
|}<br />
<br />
==Other Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Accordion Behavior#Hide form NavBar|Hide form NavBar]]||Hide form Navigation Bar at runtime if this section is in an Accordion Stack (True &#124; False)<br />
|valign="top"|hideFormNavBar||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Instant_Search#Hide_SearchBox|Hide SearchBox]]||Hide the Page Header Instant Search box when this section is selected in an Accordion Stack (True &#124; False). From v5.4.<br />
|valign="top"|hidesearchbox||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Appearance#Collapsable|Collapsable]]||The section is collapsible at runtime (True &#124; False)<br />
|valign="top"|collapsableAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Accordion Behavior#Exclude from accordion|Exclude from accordion]]||The section is excluded from accordion behavior at runtime (True &#124; False)<br />
|valign="top"|excludeAccordionAtRuntime||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Custom Delegates==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Custom Delegates#Scripting Language|Scripting language]]||The default scripting language for custom code in this section (Inherit &#124; Recital &#124; Visual FoxPro &#124; Python &#124; JavaScript &#124; PHP)<br />
|valign="top"|scriptingLanguage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom Library|Custom library]]||The filename of the library containing code for event handlers and custom procedures/functions<br />
|valign="top"|customLibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Print|Print]]||The delegate for the Print event.<br>This is called when you click the 'Print' icon.<br />
|valign="top"|printAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Expanded|Expanded]]||The delegate for the Expanded event<br />
|valign="top"|expandedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Collapsed|Collapsed]]||The delegate for the Collapsed event<br />
|valign="top"|collapsedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Hotkey|Hotkey]]||The delegate for the Hotkey event.<br />
|valign="top"|hotkeyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Parent data changed|Parent data changed]]||The delegate for the ParentDataChanged event<br />
|valign="top"|parentDataChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Data Producer|Data Producer]]||The delegate for the DataProducer (used in Web Components).<br>From v6.1.<br />
|valign="top"|dataproduceraction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer|Timer]]||The delegate for the Timer event<br />
|valign="top"|timerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer interval|Timer interval]]||The timer interval in seconds that the Timer event will be called at runtime<br />
|valign="top"|timerInterval||valign="top"|Int<br />
|-<br />
|valign="top"|[[Custom Delegates#State Changed|State Changed]]||The delegate for the Statechanged event.<br />
|valign="top"|stateChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom footer menu|Custom footer menu]]||The delegate for the footer menu event<br />
|valign="top"|customMenuAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom search command|Custom search command]]||The delegate for the search event<br />
|valign="top"|customSearch||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom section menu|Custom section menu]]||The delegate for the section menu event<br />
|valign="top"|customSectionMenuAction||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Permissions and Roles==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Users and Roles|Create roles]]||A comma separated list of roles that can perform create operations on data in the section.<br />
|valign="top"|permcreate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Read roles]]||A comma separated list of roles that can read (and view) the section.<br />
|valign="top"|permRead||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Update roles]]||A comma separated list of roles that can perform update operations on data in the section.<br />
|valign="top"|permUpdate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Delete roles]]||A comma separated list of roles that can perform delete operations on data in the section.<br />
|valign="top"|permDelete||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==UI Presentation Rules==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Desktop|Desktop]]||Include this section in a Desktop client (True &#124; False).<br />
|valign="top"|desktopUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Web|Web]]||Include this section in a Web client (True &#124; False).<br />
|valign="top"|webUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Tablet|Tablet]]||Include this section in a Tablet client (True &#124; False).<br />
|valign="top"|tabletUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Phone|Phone]]||Include this section in a Phone client (True &#124; False).<br />
|valign="top"|mobileUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#UI States|UI States]]||UI states that affect this section. Specify multiple states as a comma separated list.<br />
|valign="top"|state||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Initial UI state|Initial UI state]]||The initial UI state for this section. This will be applied to the section and all its fields and gadgets.<br />
|valign="top"|uiStateInit||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Readonly when|Readonly when]]||Section is readonly at runtime if specified expression evaluates to true.<br />
|valign="top"|readonlyWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Visible when|Visible when]]||Section is visible at runtime if specified expression evaluates to true.<br />
|valign="top"|visibleWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Display orientation|Display orientation]]||Display depending on mobile device orientation for Tablets and Phones. (Always &#124; Portrait &#124; Landscape)<br />
|valign="top"|displayOrientation||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on change|Apply rules on change]]||Apply UI presentation rules (Visible when and Readonly when) when data is changed interactively or when navigating records (True &#124; False).<br />
|valign="top"|applyRulesOnChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on parent change|Apply rules on parent change]]||Apply section UI presentation rules (Visible when and Readonly when) when parent data is changed by navigating records (True &#124; False)<br />
|valign="top"|applyRulesOnParentChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Search Panel Responsive UI width breakpoint|Search Panel Responsive UI width breakpoint]]||The Search Panel responsive UI width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|searchpanelresponsivevisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Menu Responsive UI width breakpoint|Menu Responsive UI width breakpoint]]||valign="top"|The Menu responsive UI width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsivemenuwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI width breakpoint|Responsive UI width breakpoint]]||The section responsive UI visibility width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsivewidthvisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI height breakpoint|Responsive UI height breakpoint]]||The section responsive UI visibility height breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsiveheightvisibility||valign="top"|Int<br />
|-<br />
|}<br />
<br />
[[Category:Attributes|3 DocumentView Section]]<br />
[[Category:Lianja v2.0]]<br />
[[Category:Sections]]<br />
[[Category:WebView Based Sections]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/DatalistView_Section_AttributesDatalistView Section Attributes2024-03-22T11:45:16Z<p>Yvonne.milne: /* UI Presentation Rules */</p>
<hr />
<div>{{DISPLAYTITLE:DatalistView Section}}<br />
=Overview=<br />
DatalistView Sections are used to display a bootstrap styled list of data records with clickable rows.<br />
<br />
[[{{ns:file}}:datalistview_section.png|800px|left|border|link={{filepath:datalistview_section.png}}|DatalistView Section]]<br />
<br clear=all><br />
<br />
You build Apps in Lianja App Builder visually using the [[:Category:Page_Builder|Page Builder]].<br />
<br />
If you have not yet done so please read [[Understanding_the_Lianja_App_Architecture|Understanding the Lianja Architecture]] and also [[Lianja_is_all_about_ART|Understanding ART]] to better understand this article.<br />
<br />
An App consists of pages. Pages are made up of Sections. Form sections are made up of FormItems. We call these collectively "UI Elements" or "Visual Elements".<br />
<br />
==Setting Attributes Declaratively==<br />
<br />
You adjust the appearance and behavior of each UI Element in the '''Attributes''' Tab of the [[:Category:App_Inspector|App Inspector]].<br />
<br />
[[{{ns:file}}:bm-attributes.png|800px|left|border|link={{filepath:bm-attributes.png}}|Attributes]]<br />
<br clear=all><br />
<br />
The attributes available consist of some common ones as well as some specific to the UI Element being inspected.<br />
<br />
==Getting and Setting Attributes Programmatically==<br />
The '''setAttribute(name, value)''' method can be used to set the value of an Attribute:<br />
<br />
<pre>Lianja.get("pageid.sectionid").setAttribute("title","Section1")</pre><br />
<br />
Note: on the desktop, the shortened form '''setAttr(name,value)''' is also available.<br />
<br />
The '''getAttribute(name)''' method can be used to get the value of an Attribute:<br />
<br />
<pre>cTitle = Lianja.get("pageid.sectionid").getAttribute("title")</pre><br />
<br />
Note: on the desktop, the shortened form '''getAttr(name)''' is also available.<br />
<br />
=See Also=<br />
[[:Category:Developing Custom WebViews|Developing Custom WebViews]], [[Using WebViewWidgets]], [[Webview Gadget Attributes]], [[Webview Section Attributes]]<br />
<br />
=Attributes=<br />
==Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Details Attributes#Name|Name]]||The name for this section (unique to the page)<br />
|valign="top"|id||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Full name|Full name]]||The full name for this section including its parent page, e.g. page1.section1<br />
|valign="top"|fullid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Alias name|Alias name]]||The alias name for this section<br />
|valign="top"|aliasid||Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Dashboard group]]||The dashboard section that this section belongs to.<br />
|valign="top"|horizontalgroup||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Horizontal stretch]]||The horizontal % stretch factor that this section should occupy.<br />
|valign="top"|horizontalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Vertical stretch]]||The vertical % stretch factor that this section should occupy.<br />
|valign="top"|verticalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#App Doc|App Doc]]||The App Doc file for this section. This will be included in the [[App Doc]] when it is generated.<br />
|valign="top"|appdoc||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#MetaData version|MetaData version]]||The MetaData version number. You can set this in the setupUI hook to prevent MetaData being applied multiple times.<br />
|valign="top"|metaDataVersion||valign="top"|Int<br />
|-<br />
|valign="top"|[[MetaTypes|Meta types]]||A comma separated list of metatype names<br />
|valign="top"|metatypes||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Custom Props|Custom Props]]||A ';' separated list of custom prop key pairs, e.g. name=barry;company=lianja<br />
|valign="top"|customprops||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Type|Type]]||The type of section: datalistview (readonly)<br />
|valign="top"|type||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Caption|Caption]]||The section caption displayed in the section header<br />
|valign="top"|title||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Database|Database]]||The database for this section<br />
|valign="top"|database||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Table|Table]]||The table for this section<br />
|valign="top"|table||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Height|Height]]||The section height<br />
|valign="top"|height||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Fixed height|Fixed height]]||Fix the section height (True &#124; False)<br />
|valign="top"|fixedHeight||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Details Attributes#Auto layout percent|Auto layout percent]]||Auto layout percentage of page size. If set to 0, then all sections on a page are resized to an equal height.<br />
|valign="top"|autoLayoutPercentage||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Appearance==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Appearance#Margin|Margin]]||Margin size around the section<br />
|valign="top"|margin||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Appearance#Add spacer at bottom|Add spacer at bottom]]||Add spacer at bottom of section (True &#124; False)<br />
|valign="top"|spacerVisible||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Header==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Hide header|Hide header]]||Hide section header at runtime(True &#124; False)<br />
|valign="top"|hideHeaderAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide actionbar|Hide actionbar]]||Hide actionbar when stacked section is activated at runtime<br>(True &#124; False)<br />
|valign="top"|hideActionBarAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header CSS style|Header CSS style]]||CSS style (separate attributes with ; or use app:/filename.css)<br />
|valign="top"|headerCssStyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header icon|Header icon]]||The image for the Header (png &#124; jpg &#124; gif).<br>Use app:/imagename.ext for app specific images.<br />
|valign="top"|headerIcon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient colors|Gradient colors]]||Render the Header background color as a gradient (True &#124; False)<br />
|valign="top"|headerGradient||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Gradients#Gradient type|Gradient type]]||Specify the gradient type<br />
|valign="top"|headerGradientType||valign="top"|Int<br />
|-<br />
|valign="top"|[[Gradients#Gradient start color|Gradient start color]]||Gradient start color<br />
|valign="top"|headerFromColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient end color|Gradient end color]]||Gradient end color<br />
|valign="top"|headerToColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show Print button|Show Print button]]||Show Print button in the section header (True &#124; False)<br />
|valign="top"|showPrintButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Edit button|Show Edit button]]||Show Edit button in the section header (True &#124; False)<br />
|valign="top"|showEditButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide custom search icon|Hide custom search icon]]||Hide the custom search icon (True &#124; False)<br />
|valign="top"|hideCustomSearchIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Custom search dialog|Show Custom search dialog]]||Show custom search dialog when custom search icon clicked (True &#124; False)<br />
|valign="top"|showcustomsearchdialog||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show custom search dialog panel|Show custom search dialog panel]]||Show custom search dialog panel when custom search icon clicked<br>(True &#124; False)<br />
|valign="top"|showcustomsearchdialogpanel||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show info tips icon|Show info tips icon]]||Show the info tips icon in the section header (True &#124; False)<br />
|valign="top"|showInfoTipsIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show help icon|Show help icon]]||Show the help icon in the section header (True &#124; False)<br />
|valign="top"|showHelpIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Help topic|Help topic]]||Help topic to display when the help icon is clicked in the section header<br />
|valign="top"|helpTopic||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Custom Header Style==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Use custom header style|Use custom header style]]||Use a custom header style (True &#124; False)<br />
|valign="top"|headercustomstyle||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header background color|Header background color]]||Header background color<br />
|valign="top"|headerbackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header foreground color|Header foreground color]]||Header foreground color<br />
|valign="top"|headerforecolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border|Header bottom border]]||Display the header bottom border (True &#124; False)<br />
|valign="top"|headerbottomborder||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border height|Header bottom border height]]||Height (in pixels) of the header bottom border (if displayed)<br />
|valign="top"|headerbottomborderheight||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border color|Header bottom border color]]||Header bottom border color<br />
|valign="top"|headerbottombordercolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show record count badge|Show record count badge]]||Show the record count badge in the section header (True &#124; False).<br />
|valign="top"|showreccount||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Visual Component Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Visual_Components#Component_library_3|Component library]]||This specifies the Component library where the component will be saved.<br />
|valign="top"|componentlib||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_name_2|Component name]]||Save as this component name whenever the section is saved.<br />
|valign="top"|componentname||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_author_2|Component author]]||The author of this component.<br />
|valign="top"|componentauthor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_version_2|Component version]]||The version of this component.<br />
|valign="top"|componentversion||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_description_2|Component description]]||The description of this component.<br />
|valign="top"|componentdescription||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_permissions_2|Component permissions]]||The permissions required for this component in Lianja Cloud App Builder.<br />
|valign="top"|componentpermissions||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_width_2|Component width]]||The width of this component when activated as a Form.<br />
|valign="top"|componentwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[Visual_Components#Component_height_2|Component height]]||The height of this component when activated as a Form.<br />
|valign="top"|componentheight||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Related Data==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Related Data#Parent section name|Parent section name]]||Name of related parent section<br />
|valign="top"|parentid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Automatically relate|Automatically relate]]||Automatically relate the child section (True &#124; False). If this is unchecked then you need to manually relate it in the parentdatachanged delegate.<br />
|valign="top"|autoRelateChildSection||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Related Data#Parent key|Parent key]]||Parent key<br />
|valign="top"|parentKeyExpr||Character<br />
|-<br />
|valign="top"|[[Related Data#Child key|Child key]]||Child key<br />
|valign="top"|childKeyExpr||Character<br />
|-<br />
|}<br />
<br />
==Menu==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Menus#Visible|Visible]]||Section menu visible (True &#124; False)<br />
|valign="top"|sectionMenuVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Menus#Height|Height]]||Section menu height<br />
|valign="top"|sectionMenuHeight||Int<br />
|-<br />
|valign="top"|[[Section Menus#Background color|Background color]]||Section menu background color<br />
|valign="top"|sectionMenuBackColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Foreground color|Foreground color]]||Section menu foreground color<br />
|valign="top"|sectionMenuForeColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu panel|Custom menu panel]]||The .rsp or .jssp page used to create the custom menu panel. This page should generate dynamic HTML5/JavaScript.<br />
|valign="top"|customSectionMenuPanel||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu|Custom menu]]||Section menu contents<br />
|valign="top"|customSectionMenu||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom action|Custom action]]||Action to perform when a menu item is selected<br />
|valign="top"|sectionMenuAction||Character<br />
|-<br />
|valign="top"|[[Section Menus#Context Menu|Context Menu]]||A comma separated list of menu items to popup when a user right clicks on the Section. Selecting an item calls the [[Custom_Delegates#Right_Click|rightclick]] delegate with the item text as an argument.<br />
|valign="top"|contextMenu||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Search Panel==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Search Panels#Visible|Visible]]||Section search panel visible (True &#124; False)<br />
|valign="top"|searchPanelVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Height|Height]]||Section search panel height<br />
|valign="top"|searchPanelHeight||Int<br />
|-<br />
|valign="top"|[[Section Search Panels#Background color|Background color]]||Section search panel background color<br />
|valign="top"|searchPanelBackColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Foreground color|Foreground color]]||Section search panel foreground color<br />
|valign="top"|searchPanelForeColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Auto create|Auto create]]||Automatically create search panel for all Section search fields<br />
|valign="top"|searchPanelAutoCreate||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Custom search panel|Custom search panel]]||The delegate used to create the custom search panel<br />
|valign="top"|searchPanelAction||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#WebView Search panel config|WebView Search panel config]]||A string to manually configure a WebView search panel.<br>caption:controlsource:datatype:width:decimals[:choicelist],...<br>the datatype can be C,N,D,T or L (character, numeric, date, datetime, logical).<br />
|valign="top"|searchpanelconfig||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Subtitle==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Subtitles#Visible|Visible]]||Section subtitle visible (True &#124; False)<br />
|valign="top"|subtitleVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Subtitles#Caption|Caption]]||Section subtitle caption<br />
|valign="top"|subtitleCaption||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Height|Height]]||Section subtitle height<br />
|valign="top"|subtitleHeight||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#Background color|Background color]]||Section subtitle background color<br />
|valign="top"|subtitleBackColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Foreground color|Foreground color]]||Section subtitle foreground color<br />
|valign="top"|subtitleForeColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Font|Font]]||Section subtitle font<br />
|valign="top"|subtitleFont||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#CSS style|CSS style]]||CSS style<br />
|valign="top"|subtitleCssStyle||Character<br />
|-<br />
|}<br />
<br />
==Footer==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Footers#Visible|Visible]]||Section footer visible (True &#124; False)<br />
|valign="top"|footerVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Footers#Caption|Caption]]||Section footer caption<br />
|valign="top"|footerText||Character<br />
|-<br />
|valign="top"|[[Section Footers#Height|Height]]||Section footer height<br />
|valign="top"|footerHeight||Int<br />
|-<br />
|valign="top"|[[Section Footers#Background color|Background color]]||Section footer background color<br />
|valign="top"|footerBackColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#Foreground color|Foreground color]]||Section footer foreground color<br />
|valign="top"|footerForeColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#CSS style|CSS style]]||CSS style (separate attributes with ; or use app:/filename.css or specify CSS classes separated by spaces).<br />
|valign="top"|footercssstyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom menu|Custom menu]]||Section footer menu contents<br />
|valign="top"|customOptionsMenu||Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom action|Custom action]]||Action to perform when a footer menu item is selected<br />
|valign="top"|customOptionsMenuAction||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button CSS|Footer button CSS]]||Footer button CSS style<br />
|valign="top"|footerButtonCss||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button width|Footer button width]]||Footer button width<br />
|valign="top"|footerButtonWidth||Int<br />
|-<br />
|}<br />
<br />
==Other Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Accordion Behavior#Hide form NavBar|Hide form NavBar]]||Hide form Navigation Bar at runtime if this section is in an Accordion Stack (True &#124; False)<br />
|valign="top"|hideFormNavBar||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Instant_Search#Hide_SearchBox|Hide SearchBox]]||Hide the Page Header Instant Search box when this section is selected in an Accordion Stack (True &#124; False).<br />
|valign="top"|hidesearchbox||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Appearance#Collapsable|Collapsable]]||The section is collapsible at runtime (True &#124; False)<br />
|valign="top"|collapsableAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Accordion Behavior#Exclude from accordion|Exclude from accordion]]||The section is excluded from accordion behavior at runtime (True &#124; False)<br />
|valign="top"|excludeAccordionAtRuntime||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Custom Delegates==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Custom Delegates#Scripting Language|Scripting language]]||The default scripting language for custom code in this section (Inherit &#124; Recital &#124; Visual FoxPro &#124; Python &#124; JavaScript &#124; PHP)<br />
|valign="top"|scriptingLanguage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom Library|Custom library]]||The filename of the library containing code for event handlers and custom procedures/functions<br />
|valign="top"|customLibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Print|Print]]||The delegate for the Print event.<br>This is called when you click the 'Print' icon.<br />
|valign="top"|printAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Expanded|Expanded]]||The delegate for the Expanded event<br />
|valign="top"|expandedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Collapsed|Collapsed]]||The delegate for the Collapsed event<br />
|valign="top"|collapsedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Hotkey|Hotkey]]||The delegate for the Hotkey event.<br />
|valign="top"|hotkeyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Activate|Activate]]||The delegate for the Activate event<br />
|valign="top"|activateAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Deactivate|Deactivate]]||The delegate for the Deactivate event<br />
|valign="top"|deactivateAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Enabled When|Enabled When]]||The delegate for the EnabledWhen event<br />
|valign="top"|enabledWhenAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Visible When|Visible When]]||The delegate for the VisibleWhen event<br />
|valign="top"|visibleWhenAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Valid When|Valid When]]||The delegate for the ValidWhen event<br />
|valign="top"|validWhenAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Init|Init]]||The delegate for the Init event<br />
|valign="top"|initAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Destroy|Destroy]]||The delegate for the Destroy event<br />
|valign="top"|destroyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Load|Load]]||The delegate for the Load event<br />
|valign="top"|loadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Ready|Ready]]||The delegate for the Ready event<br />
|valign="top"|readyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Unload|Unload]]||The delegate for the Unload event<br />
|valign="top"|unloadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Change|Change]]||The delegate for the Change event<br />
|valign="top"|changedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Link Click|Link Click]]||The delegate for the Hyperlink/Button Click event. This is called with two arguments: functionname(controlsource,text)<br />
|valign="top"|linkClickAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Before Data Create|Before Data Create]]||The delegate for the BeforeCreate event<br />
|valign="top"|beforeCreateAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#After Data Create|After Data Create]]||The delegate for the AfterCreate event<br />
|valign="top"|afterCreateAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#After Data Changed|After Data Changed]]||The delegate for the dataChanged event (after data is read)<br />
|valign="top"|dataChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Before Data Update|Before Data Update]]||The delegate for the BeforeUpdate event<br />
|valign="top"|beforeUpdateAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#After Data Update|After Data Update]]||The delegate for the AfterUpdate event<br />
|valign="top"|afterUpdateAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Before Data Delete|Before Data Delete]]||The delegate for the BeforeDelete event<br />
|valign="top"|beforeDeleteAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#After Data Delete|After Data Delete]]||The delegate for the AfterDelete event<br />
|valign="top"|afterDeleteAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Before Refresh|Before Refresh action]]||The delegate for the BeforeRefresh event. From v6.2.<br />
|valign="top"|beforeRefreshAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Refresh|Refresh]]||The delegate for the Refresh event<br />
|valign="top"|refreshAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#After Refresh|After Refresh action]]||The delegate for the AfterRefresh event.<br />
|valign="top"|afterRefreshAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Before Edit|Before Edit]]||The delegate for the BeforeEdit event.<br />
|valign="top"|beforeEditAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#After Edit|After Edit]]||The delegate for the AfterEdit event.<br />
|valign="top"|afterEditAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Init Form Defaults|Init Form Defaults]]||The delegate for the InitFormDefaults event called when adding a new record.<br />
|valign="top"|initFormDefaults||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Parent data changed|Parent data changed]]||The delegate for the ParentDataChanged event<br />
|valign="top"|parentDataChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Dialog button delegate|Dialog button delegate]]||The delegate for the DialogButtonClicked event. If a dialogbutton on a Field has no delegate, the Section delegate will be called. If the section has no delegate, then the Page delegate will be called.<br />
|valign="top"|dialogButtonAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Right Click|Right Click]]||The delegate for the Right Clicked event<br />
|valign="top"|rightClickAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Data Producer|Data Producer]]||The delegate for the DataProducer (used in Web Components).<br />
|valign="top"|dataproduceraction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer|Timer]]||The delegate for the Timer event<br />
|valign="top"|timerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer interval|Timer interval]]||The timer interval in seconds that the Timer event will be called at runtime<br />
|valign="top"|timerInterval||valign="top"|Int<br />
|-<br />
|valign="top"|[[Custom Delegates#State Changed|State Changed]]||The delegate for the Statechanged event.<br />
|valign="top"|stateChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom footer menu|Custom footer menu]]||The delegate for the footer menu event<br />
|valign="top"|customMenuAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom search command|Custom search command]]||The delegate for the search event<br />
|valign="top"|customSearch||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom section menu|Custom section menu]]||The delegate for the section menu event<br />
|valign="top"|customSectionMenuAction||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Permissions and Roles==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Users and Roles|Create roles]]||A comma separated list of roles that can perform create operations on data in the section.<br />
|valign="top"|permcreate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Read roles]]||A comma separated list of roles that can read (and view) the section.<br />
|valign="top"|permRead||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Update roles]]||A comma separated list of roles that can perform update operations on data in the section.<br />
|valign="top"|permUpdate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Delete roles]]||A comma separated list of roles that can perform delete operations on data in the section.<br />
|valign="top"|permDelete||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==UI Presentation Rules==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Desktop|Desktop]]||Include this section in a Desktop client (True &#124; False).<br />
|valign="top"|desktopUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Web|Web]]||Include this section in a Web client (True &#124; False).<br />
|valign="top"|webUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Tablet|Tablet]]||Include this section in a Tablet client (True &#124; False).<br />
|valign="top"|tabletUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Phone|Phone]]||Include this section in a Phone client (True &#124; False).<br />
|valign="top"|mobileUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#UI States|UI States]]||UI states that affect this section. Specify multiple states as a comma separated list.<br />
|valign="top"|state||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Initial UI state|Initial UI state]]||The initial UI state for this section. This will be applied to the section and all its fields and gadgets.<br />
|valign="top"|uiStateInit||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Readonly when|Readonly when]]||Section is readonly at runtime if specified expression evaluates to true.<br />
|valign="top"|readonlyWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Visible when|Visible when]]||Section is visible at runtime if specified expression evaluates to true.<br />
|valign="top"|visibleWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Display orientation|Display orientation]]||Display depending on mobile device orientation for Tablets and Phones. (Always &#124; Portrait &#124; Landscape)<br />
|valign="top"|displayOrientation||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on change|Apply rules on change]]||Apply UI presentation rules (Visible when and Readonly when) when data is changed interactively or when navigating records (True &#124; False).<br />
|valign="top"|applyRulesOnChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on parent change|Apply rules on parent change]]||Apply section UI presentation rules (Visible when and Readonly when) when parent data is changed by navigating records (True &#124; False)<br />
|valign="top"|applyRulesOnParentChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Search Panel Responsive UI width breakpoint|Search Panel Responsive UI width breakpoint]]||The Search Panel responsive UI width breakpoint in Web/Mobile Apps.<br />
|valign="top"|searchpanelresponsivevisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Menu Responsive UI width breakpoint|Menu Responsive UI width breakpoint]]||valign="top"|The Menu responsive UI width breakpoint in Web/Mobile Apps.<br />
|valign="top"|responsivemenuwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI width breakpoint|Responsive UI width breakpoint]]||The section responsive UI visibility width breakpoint in Web/Mobile Apps.<br />
|valign="top"|responsivewidthvisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI height breakpoint|Responsive UI height breakpoint]]||The section responsive UI visibility height breakpoint in Web/Mobile Apps.<br />
|valign="top"|responsiveheightvisibility||valign="top"|Int<br />
|-<br />
|}<br />
<br />
[[Category:Attributes|3 Datalistview Section]]<br />
[[Category:Sections]]<br />
[[Category:Lianja v6.1]]<br />
[[Category:WebView Based Sections]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/CommentsView_Section_AttributesCommentsView Section Attributes2024-03-22T11:44:48Z<p>Yvonne.milne: /* UI Presentation Rules */</p>
<hr />
<div>=Overview=<br />
CommentsView Sections are used for social interaction within business Apps. Users can collaborate directly inside the App with access to the entire conversation history. The CommentsView is typically related to a parent record e.g. a customer or an employee record. As you navigate between records the threaded conversation history associated with that record is displayed.<br />
{{DISPLAYTITLE:CommentsView Section}}<br />
[[File:CommentsView_section.png|middle|758px|link=]]<br />
<br />
You build Apps in Lianja App Builder visually using the [[:Category:Page_Builder|Page Builder]].<br />
<br />
If you have not yet done so please read [[Understanding_the_Lianja_App_Architecture|Understanding the Lianja Architecture]] and also [[Lianja_is_all_about_ART|Understanding ART]] to better understand this article.<br />
<br />
An App consists of pages. Pages are made up of Sections. Form sections are made up of FormItems. We call these collectively "UI Elements" or "Visual Elements".<br />
<br />
==Setting Attributes Declaratively==<br />
<br />
You adjust the appearance and behavior of each UI Element in the '''Attributes''' Tab of the [[:Category:App_Inspector|App Inspector]].<br />
<br />
[[{{ns:file}}:bm-attributes.png|800px|left|border|link={{filepath:bm-attributes.png}}|Attributes]]<br />
<br clear=all><br />
<br />
The attributes available consist of some common ones as well as some specific to the UI Element being inspected.<br />
<br />
==Getting and Setting Attributes Programmatically==<br />
The '''setAttribute(name, value)''' method can be used to set the value of an Attribute:<br />
<br />
<pre>Lianja.get("pageid.sectionid").setAttribute("title","Section1")</pre><br />
<br />
Note: on the desktop, the shortened form '''setAttr(name,value)''' is also available.<br />
<br />
The '''getAttribute(name)''' method can be used to get the value of an Attribute:<br />
<br />
<pre>cTitle = Lianja.get("pageid.sectionid").getAttribute("title")</pre><br />
<br />
Note: on the desktop, the shortened form '''getAttr(name)''' is also available.<br />
<br />
=See Also=<br />
[[CommentsView Options]]<br />
<br />
Demo Apps (included in the Lianja App Builder distribution):<br />
* Lianja CommentsView Demo (example_commentsview)<br />
<br />
=Attributes=<br />
==Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Details Attributes#Name|Name]]||The name for this section (unique to the page)<br />
|valign="top"|id||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Full name|Full name]]||The full name for this section including its parent page, e.g. page1.section1<br />
|valign="top"|fullid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Alias name|Alias name]]||The alias name for this section<br />
|valign="top"|aliasid||Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Dashboard group]]||The dashboard section that this section belongs to. From v5.2.<br />
|valign="top"|horizontalgroup||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Horizontal stretch]]||The horizontal % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|horizontalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Vertical stretch]]||The vertical % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|verticalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#App Doc|App Doc]]||The App Doc file for this section. This will be included in the [[App Doc]] when it is generated.<br />
|valign="top"|appdoc||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#MetaData version|MetaData version]]||The MetaData version number. You can set this in the setupUI hook to prevent MetaData being applied multiple times.<br />
|valign="top"|metaDataVersion||valign="top"|Int<br />
|-<br />
|valign="top"|[[MetaTypes|Meta types]]||A comma separated list of metatype names<br />
|valign="top"|metatypes||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Custom Props|Custom Props]]||A ';' separated list of custom prop key pairs, e.g. name=barry;company=lianja<br>From v5.3.<br />
|valign="top"|customprops||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Type|Type]]||The type of section: commentsview (readonly)<br />
|valign="top"|type||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Caption|Caption]]||The section caption displayed in the section header<br />
|valign="top"|title||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Database|Database]]||The database for this section<br />
|valign="top"|database||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Table|Table]]||The table for this section<br />
|valign="top"|table||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Height|Height]]||The section height<br />
|valign="top"|height||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Fixed height|Fixed height]]||Fix the section height (True &#124; False)<br />
|valign="top"|fixedHeight||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Details Attributes#Auto layout percent|Auto layout percent]]||Auto layout percentage of page size. If set to 0, then all sections on a page are resized to an equal height.<br />
|valign="top"|autoLayoutPercentage||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Appearance==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Appearance#Margin|Margin]]||Margin size around the section<br />
|valign="top"|margin||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Appearance#Add spacer at bottom|Add spacer at bottom]]||Add spacer at bottom of section (True &#124; False)<br />
|valign="top"|spacerVisible||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Header==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Hide header|Hide header]]||Hide section header at runtime(True &#124; False)<br />
|valign="top"|hideHeaderAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide actionbar|Hide actionbar]]||Hide actionbar when stacked section is activated at runtime<br>(True &#124; False)<br />
|valign="top"|hideActionBarAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header icon|Header icon]]||The image for the Header (png &#124; jpg &#124; gif).<br>Use app:/imagename.ext for app specific images.<br />
|valign="top"|headerIcon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient colors|Gradient colors]]||Render the Header background color as a gradient (True &#124; False)<br />
|valign="top"|headerGradient||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Gradients#Gradient type|Gradient type]]||Specify the gradient type<br />
|valign="top"|headerGradientType||valign="top"|Int<br />
|-<br />
|valign="top"|[[Gradients#Gradient start color|Gradient start color]]||Gradient start color<br />
|valign="top"|headerFromColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient end color|Gradient end color]]||Gradient end color<br />
|valign="top"|headerToColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show Print button|Show Print button]]||Show Print button in the section header (True &#124; False)<br />
|valign="top"|showPrintButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Edit button|Show Edit button]]||Show Edit button in the section header (True &#124; False)<br />
|valign="top"|showEditButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide custom search icon|Hide custom search icon]]||Hide the custom search icon (True &#124; False)<br />
|valign="top"|hideCustomSearchIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Custom search dialog|Show Custom search dialog]]||Show custom search dialog when custom search icon clicked (True &#124; False)<br />
|valign="top"|showcustomsearchdialog||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show custom search dialog panel|Show custom search dialog panel]]||Show custom search dialog panel when custom search icon clicked<br>(True &#124; False)<br />
|valign="top"|showcustomsearchdialogpanel||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show info tips icon|Show info tips icon]]||Show the info tips icon in the section header (True &#124; False)<br />
|valign="top"|showInfoTipsIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show help icon|Show help icon]]||Show the help icon in the section header (True &#124; False)<br />
|valign="top"|showHelpIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Help topic|Help topic]]||Help topic to display when the help icon is clicked in the section header<br />
|valign="top"|helpTopic||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Custom Header Style==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Use custom header style|Use custom header style]]||Use a custom header style (True &#124; False)<br />
|valign="top"|headercustomstyle||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header background color|Header background color]]||Header background color<br />
|valign="top"|headerbackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header foreground color|Header foreground color]]||Header foreground color<br />
|valign="top"|headerforecolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border|Header bottom border]]||Display the header bottom border (True &#124; False)<br />
|valign="top"|headerbottomborder||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border height|Header bottom border height]]||Height (in pixels) of the header bottom border (if displayed)<br />
|valign="top"|headerbottomborderheight||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border color|Header bottom border color]]||Header bottom border color<br />
|valign="top"|headerbottombordercolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show record count badge|Show record count badge]]||Show the record count badge in the section header (True &#124; False).<br />
|valign="top"|showreccount||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Visual Component Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Visual_Components#Component_library_3|Component library]]||This specifies the Component library where the component will be saved.<br />
|valign="top"|componentlib||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_name_2|Component name]]||Save as this component name whenever the section is saved.<br />
|valign="top"|componentname||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_author_2|Component author]]||The author of this component.<br />
|valign="top"|componentauthor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_version_2|Component version]]||The version of this component.<br />
|valign="top"|componentversion||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_description_2|Component description]]||The description of this component.<br />
|valign="top"|componentdescription||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_permissions_2|Component permissions]]||The permissions required for this component in Lianja Cloud App Builder.<br />
|valign="top"|componentpermissions||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_width_2|Component width]]||The width of this component when activated as a Form.<br />
|valign="top"|componentwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[Visual_Components#Component_height_2|Component height]]||The height of this component when activated as a Form.<br />
|valign="top"|componentheight||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==CommentsView Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[CommentsView Options#Caption|Caption]]||The caption to be displayed in the CommentsView header. This may contain {...} macros<br />
|valign="top"|CommentsViewCaption||valign="top"|Character<br />
|-<br />
|valign="top"|[[CommentsView Options#Topics|Topics]]||A comma separated list of topics displayed in the CommentsView header and used to filter comments.<br />
|valign="top"|CommentsViewSubCaption||valign="top"|Character<br />
|-<br />
|valign="top"|[[CommentsView Options#Category|Category]]||The category assigned to new comments.<br />
|valign="top"|CommentsViewCaptionLink||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Related Data==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Related Data#Parent section name|Parent section name]]||Name of related parent section<br />
|valign="top"|parentid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Automatically relate|Automatically relate]]||Automatically relate the child section (True &#124; False). If this is unchecked then you need to manually relate it in the parentdatachanged delegate.<br />
|valign="top"|autoRelateChildSection||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Related Data#Parent key|Parent key]]||Parent key<br />
|valign="top"|parentKeyExpr||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Child key|Child key]]||Child key<br />
|valign="top"|childKeyExpr||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Menu==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Menus#Visible|Visible]]||Section menu visible (True &#124; False)<br />
|valign="top"|sectionMenuVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Menus#Height|Height]]||Section menu height<br />
|valign="top"|sectionMenuHeight||Int<br />
|-<br />
|valign="top"|[[Section Menus#Background color|Background color]]||Section menu background color<br />
|valign="top"|sectionMenuBackColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Foreground color|Foreground color]]||Section menu foreground color<br />
|valign="top"|sectionMenuForeColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu panel|Custom menu panel]]||The .rsp or .jssp page used to create the custom menu panel. This page should generate dynamic HTML5/JavaScript.<br />
|valign="top"|customSectionMenuPanel||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu|Custom menu]]||Section menu contents<br />
|valign="top"|customSectionMenu||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom action|Custom action]]||Action to perform when a menu item is selected<br />
|valign="top"|sectionMenuAction||Character<br />
|-<br />
|}<br />
<br />
==Search Panel==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Search Panels#Visible|Visible]]||Section search panel visible (True &#124; False)<br />
|valign="top"|searchPanelVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Height|Height]]||Section search panel height<br />
|valign="top"|searchPanelHeight||Int<br />
|-<br />
|valign="top"|[[Section Search Panels#Background color|Background color]]||Section search panel background color<br />
|valign="top"|searchPanelBackColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Foreground color|Foreground color]]||Section search panel foreground color<br />
|valign="top"|searchPanelForeColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Auto create|Auto create]]||Automatically create search panel for all Section search fields<br />
|valign="top"|searchPanelAutoCreate||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Custom search panel|Custom search panel]]||The delegate used to create the custom search panel<br />
|valign="top"|searchPanelAction||Character<br />
|-<br />
|}<br />
<br />
==Subtitle==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Subtitles#Visible|Visible]]||Section subtitle visible (True &#124; False)<br />
|valign="top"|subtitleVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Subtitles#Caption|Caption]]||Section subtitle caption<br />
|valign="top"|subtitleCaption||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Height|Height]]||Section subtitle height<br />
|valign="top"|subtitleHeight||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#Background color|Background color]]||Section subtitle background color<br />
|valign="top"|subtitleBackColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Foreground color|Foreground color]]||Section subtitle foreground color<br />
|valign="top"|subtitleForeColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Font|Font]]||Section subtitle font<br />
|valign="top"|subtitleFont||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#CSS style|CSS style]]||CSS style<br />
|valign="top"|subtitleCssStyle||Character<br />
|-<br />
|}<br />
<br />
==Footer==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Footers#Visible|Visible]]||Section footer visible (True &#124; False)<br />
|valign="top"|footerVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Footers#Caption|Caption]]||Section footer caption<br />
|valign="top"|footerText||Character<br />
|-<br />
|valign="top"|[[Section Footers#Height|Height]]||Section footer height<br />
|valign="top"|footerHeight||Int<br />
|-<br />
|valign="top"|[[Section Footers#Background color|Background color]]||Section footer background color<br />
|valign="top"|footerBackColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#Foreground color|Foreground color]]||Section footer foreground color<br />
|valign="top"|footerForeColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#CSS style|CSS style]]||CSS style (separate attributes with ; or use app:/filename.css or specify CSS classes separated by spaces).<br />
|valign="top"|footercssstyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom menu|Custom menu]]||Section footer menu contents<br />
|valign="top"|customOptionsMenu||Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom action|Custom action]]||Action to perform when a footer menu item is selected<br />
|valign="top"|customOptionsMenuAction||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button CSS|Footer button CSS]]||Footer button CSS style<br />
|valign="top"|footerButtonCss||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button width|Footer button width]]||Footer button width<br />
|valign="top"|footerButtonWidth||Int<br />
|-<br />
|}<br />
<br />
==Other Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Accordion Behavior#Hide form NavBar|Hide form NavBar]]||Hide form Navigation Bar at runtime if this section is in an Accordion Stack (True &#124; False)<br />
|valign="top"|hideFormNavBar||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Instant_Search#Hide_SearchBox|Hide SearchBox]]||Hide the Page Header Instant Search box when this section is selected in an Accordion Stack (True &#124; False). From v5.4.<br />
|valign="top"|hidesearchbox||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Appearance#Collapsable|Collapsable]]||The section is collapsible at runtime (True &#124; False)<br />
|valign="top"|collapsableAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Accordion Behavior#Exclude from accordion|Exclude from accordion]]||The section is excluded from accordion behavior at runtime (True &#124; False)<br />
|valign="top"|excludeAccordionAtRuntime||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Custom Delegates==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Custom Delegates#Scripting Language|Scripting language]]||The default scripting language for custom code in this section (Inherit &#124; Recital &#124; Visual FoxPro &#124; Python &#124; JavaScript &#124; PHP)<br />
|valign="top"|scriptingLanguage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom Library|Custom library]]||The filename of the library containing code for event handlers and custom procedures/functions<br />
|valign="top"|customLibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Print|Print]]||The delegate for the Print event.<br>This is called when you click the 'Print' icon.<br />
|valign="top"|printAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Expanded|Expanded]]||The delegate for the Expanded event<br />
|valign="top"|expandedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Collapsed|Collapsed]]||The delegate for the Collapsed event<br />
|valign="top"|collapsedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Hotkey|Hotkey]]||The delegate for the Hotkey event.<br />
|valign="top"|hotkeyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Init|Init]]||The delegate for the Init event<br />
|valign="top"|initAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Destroy|Destroy]]||The delegate for the Destroy event<br />
|valign="top"|destroyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Load|Load]]||The delegate for the Load event<br />
|valign="top"|loadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Ready|Ready]]||The delegate for the Ready event<br />
|valign="top"|readyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Unload|Unload]]||The delegate for the Unload event<br />
|valign="top"|unloadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Parent data changed|Parent data changed]]||The delegate for the ParentDataChanged event<br />
|valign="top"|parentDataChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Data Producer|Data Producer]]||The delegate for the DataProducer (used in Web Components).<br>From v6.1.<br />
|valign="top"|dataproduceraction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer|Timer]]||The delegate for the Timer event<br />
|valign="top"|timerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer interval|Timer interval]]||The timer interval in seconds that the Timer event will be called at runtime<br />
|valign="top"|timerInterval||valign="top"|Int<br />
|-<br />
|valign="top"|[[Custom Delegates#State Changed|State Changed]]||The delegate for the Statechanged event.<br />
|valign="top"|stateChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom footer menu|Custom footer menu]]||The delegate for the footer menu event<br />
|valign="top"|customMenuAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom search command|Custom search command]]||The delegate for the search event<br />
|valign="top"|customSearch||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom section menu|Custom section menu]]||The delegate for the section menu event<br />
|valign="top"|customSectionMenuAction||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Permissions and Roles==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Users and Roles|Create roles]]||A comma separated list of roles that can perform create operations on data in the section.<br />
|valign="top"|permcreate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Read roles]]||A comma separated list of roles that can read (and view) the section.<br />
|valign="top"|permRead||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Update roles]]||A comma separated list of roles that can perform update operations on data in the section.<br />
|valign="top"|permUpdate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Delete roles]]||A comma separated list of roles that can perform delete operations on data in the section.<br />
|valign="top"|permDelete||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==UI Presentation Rules==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Desktop|Desktop]]||Include this section in a Desktop client (True &#124; False).<br />
|valign="top"|desktopUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Web|Web]]||Include this section in a Web client (True &#124; False).<br />
|valign="top"|webUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Tablet|Tablet]]||Include this section in a Tablet client (True &#124; False).<br />
|valign="top"|tabletUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Phone|Phone]]||Include this section in a Phone client (True &#124; False).<br />
|valign="top"|mobileUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#UI States|UI States]]||UI states that affect this section. Specify multiple states as a comma separated list.<br />
|valign="top"|state||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Initial UI state|Initial UI state]]||The initial UI state for this section. This will be applied to the section and all its fields and gadgets.<br />
|valign="top"|uiStateInit||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Readonly when|Readonly when]]||Section is readonly at runtime if specified expression evaluates to true.<br />
|valign="top"|readonlyWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Visible when|Visible when]]||Section is visible at runtime if specified expression evaluates to true.<br />
|valign="top"|visibleWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Display orientation|Display orientation]]||Display depending on mobile device orientation for Tablets and Phones. (Always &#124; Portrait &#124; Landscape)<br />
|valign="top"|displayOrientation||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on change|Apply rules on change]]||Apply UI presentation rules (Visible when and Readonly when) when data is changed interactively or when navigating records (True &#124; False).<br />
|valign="top"|applyRulesOnChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on parent change|Apply rules on parent change]]||Apply section UI presentation rules (Visible when and Readonly when) when parent data is changed by navigating records (True &#124; False)<br />
|valign="top"|applyRulesOnParentChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Search Panel Responsive UI width breakpoint|Search Panel Responsive UI width breakpoint]]||The Search Panel responsive UI width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|searchpanelresponsivevisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Menu Responsive UI width breakpoint|Menu Responsive UI width breakpoint]]||valign="top"|The Menu responsive UI width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsivemenuwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI width breakpoint|Responsive UI width breakpoint]]||The section responsive UI visibility width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsivewidthvisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI height breakpoint|Responsive UI height breakpoint]]||The section responsive UI visibility height breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsiveheightvisibility||valign="top"|Int<br />
|-<br />
|}<br />
<br />
[[Category:Attributes|3 CommentsView Section]]<br />
[[Category:Lianja v2.0]]<br />
[[Category:Sections]]<br />
[[Category:WebView Based Sections]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/CatalogView_Section_AttributesCatalogView Section Attributes2024-03-22T11:44:12Z<p>Yvonne.milne: /* UI Presentation Rules */</p>
<hr />
<div>=Overview=<br />
CatalogView Sections are data bound WebViews that display a catalog of items. Each page provides a table of cells comprising an image, a caption, a sub caption, some details and optional links to drill down to additional information about the selected catalog item.<br />
{{DISPLAYTITLE:CatalogView Section}}<br />
[[File:CatalogView_section.png|middle|758px|link=]]<br />
<br />
You build Apps in Lianja App Builder visually using the [[:Category:Page_Builder|Page Builder]].<br />
<br />
If you have not yet done so please read [[Understanding_the_Lianja_App_Architecture|Understanding the Lianja Architecture]] and also [[Lianja_is_all_about_ART|Understanding ART]] to better understand this article.<br />
<br />
An App consists of pages. Pages are made up of Sections. Form sections are made up of FormItems. We call these collectively "UI Elements" or "Visual Elements".<br />
<br />
==Setting Attributes Declaratively==<br />
<br />
You adjust the appearance and behavior of each UI Element in the '''Attributes''' Tab of the [[:Category:App_Inspector|App Inspector]].<br />
<br />
[[{{ns:file}}:bm-attributes.png|800px|left|border|link={{filepath:bm-attributes.png}}|Attributes]]<br />
<br clear=all><br />
<br />
The attributes available consist of some common ones as well as some specific to the UI Element being inspected.<br />
<br />
==Getting and Setting Attributes Programmatically==<br />
The '''setAttribute(name, value)''' method can be used to set the value of an Attribute:<br />
<br />
<pre>Lianja.get("pageid.sectionid").setAttribute("title","Section1")</pre><br />
<br />
Note: on the desktop, the shortened form '''setAttr(name,value)''' is also available.<br />
<br />
The '''getAttribute(name)''' method can be used to get the value of an Attribute:<br />
<br />
<pre>cTitle = Lianja.get("pageid.sectionid").getAttribute("title")</pre><br />
<br />
Note: on the desktop, the shortened form '''getAttr(name)''' is also available.<br />
<br />
=See Also=<br />
[[CatalogView Options]], [[CatalogView Sections (Video)]]<br />
<br />
Demo Apps (included in the Lianja App Builder distribution):<br />
* CatalogView App (example_catalogview)<br />
* Lianja Tablet Web UI Demo (example_webapp1)<br />
<br />
=Attributes=<br />
==Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Details Attributes#Name|Name]]||The name for this section (unique to the page)<br />
|valign="top"|id||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Full name|Full name]]||The full name for this section including its parent page, e.g. page1.section1<br />
|valign="top"|fullid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Alias name|Alias name]]||The alias name for this section<br />
|valign="top"|aliasid||Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Dashboard group]]||The dashboard section that this section belongs to. From v5.2.<br />
|valign="top"|horizontalgroup||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Horizontal stretch]]||The horizontal % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|horizontalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Vertical stretch]]||The vertical % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|verticalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#App Doc|App Doc]]||The App Doc file for this section. This will be included in the [[App Doc]] when it is generated.<br />
|valign="top"|appdoc||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#MetaData version|MetaData version]]||The MetaData version number. You can set this in the setupUI hook to prevent MetaData being applied multiple times.<br />
|valign="top"|metaDataVersion||valign="top"|Int<br />
|-<br />
|valign="top"|[[MetaTypes|Meta types]]||A comma separated list of metatype names<br />
|valign="top"|metatypes||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Custom Props|Custom Props]]||A ';' separated list of custom prop key pairs, e.g. name=barry;company=lianja<br>From v5.3.<br />
|valign="top"|customprops||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Type|Type]]||The type of section: catalogview (readonly)<br />
|valign="top"|type||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Caption|Caption]]||The section caption displayed in the section header<br />
|valign="top"|title||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Database|Database]]||The database for this section<br />
|valign="top"|database||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Table|Table]]||The table for this section<br />
|valign="top"|table||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Height|Height]]||The section height<br />
|valign="top"|height||valign="top"|Int<br />
|-<br />
|valign="top"|[[Details Attributes#Fixed height|Fixed height]]||Fix the section height (True &#124; False)<br />
|valign="top"|fixedHeight||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Details Attributes#Auto layout percent|Auto layout percent]]||Auto layout percentage of page size. If set to 0, then all sections on a page are resized to an equal height<br />
|valign="top"|autoLayoutPercentage||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Appearance==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Appearance#Margin|Margin]]||Margin size around the section<br />
|valign="top"|margin||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Appearance#Add spacer at bottom|Add spacer at bottom]]||Add spacer at bottom of section (True &#124; False)<br />
|valign="top"|spacerVisible||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Header==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Hide header|Hide header]]||Hide section header at runtime(True &#124; False)<br />
|valign="top"|hideHeaderAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide actionbar|Hide actionbar]]||Hide actionbar when stacked section is activated at runtime<br>(True &#124; False)<br />
|valign="top"|hideActionBarAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header icon|Header icon]]||The image for the Header (png &#124; jpg &#124; gif).<br>Use app:/imagename.ext for app specific images.<br />
|valign="top"|headerIcon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient colors|Gradient colors]]||Render the Header background color as a gradient (True &#124; False)<br />
|valign="top"|headerGradient||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Gradients#Gradient type|Gradient type]]||Specify the gradient type<br />
|valign="top"|headerGradientType||valign="top"|Int<br />
|-<br />
|valign="top"|[[Gradients#Gradient start color|Gradient start color]]||Gradient start color<br />
|valign="top"|headerFromColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient end color|Gradient end color]]||Gradient end color<br />
|valign="top"|headerToColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show Print button|Show Print button]]||Show Print button in the section header (True &#124; False)<br />
|valign="top"|showPrintButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Edit button|Show Edit button]]||Show Edit button in the section header (True &#124; False)<br />
|valign="top"|showEditButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide custom search icon|Hide custom search icon]]||Hide the custom search icon (True &#124; False)<br />
|valign="top"|hideCustomSearchIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Custom search dialog|Show Custom search dialog]]||Show custom search dialog when custom search icon clicked (True &#124; False)<br />
|valign="top"|showcustomsearchdialog||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show custom search dialog panel|Show custom search dialog panel]]||Show custom search dialog panel when custom search icon clicked<br>(True &#124; False)<br />
|valign="top"|showcustomsearchdialogpanel||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show info tips icon|Show info tips icon]]||Show the info tips icon in the section header (True &#124; False)<br />
|valign="top"|showInfoTipsIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show help icon|Show help icon]]||Show the help icon in the section header (True &#124; False)<br />
|valign="top"|showHelpIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Help topic|Help topic]]||Help topic to display when the help icon is clicked in the section header<br />
|valign="top"|helpTopic||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Custom Header Style==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Use custom header style|Use custom header style]]||Use a custom header style (True &#124; False)<br />
|valign="top"|headercustomstyle||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header background color|Header background color]]||Header background color<br />
|valign="top"|headerbackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header foreground color|Header foreground color]]||Header foreground color<br />
|valign="top"|headerforecolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border|Header bottom border]]||Display the header bottom border (True &#124; False)<br />
|valign="top"|headerbottomborder||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border height|Header bottom border height]]||Height (in pixels) of the header bottom border (if displayed)<br />
|valign="top"|headerbottomborderheight||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border color|Header bottom border color]]||Header bottom border color<br />
|valign="top"|headerbottombordercolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show record count badge|Show record count badge]]||Show the record count badge in the section header (True &#124; False).<br />
|valign="top"|showreccount||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Visual Component Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Visual_Components#Component_library_3|Component library]]||This specifies the Component library where the component will be saved.<br />
|valign="top"|componentlib||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_name_2|Component name]]||Save as this component name whenever the section is saved.<br />
|valign="top"|componentname||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_author_2|Component author]]||The author of this component.<br />
|valign="top"|componentauthor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_version_2|Component version]]||The version of this component.<br />
|valign="top"|componentversion||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_description_2|Component description]]||The description of this component.<br />
|valign="top"|componentdescription||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_permissions_2|Component permissions]]||The permissions required for this component in Lianja Cloud App Builder.<br />
|valign="top"|componentpermissions||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_width_2|Component width]]||The width of this component when activated as a Form.<br />
|valign="top"|componentwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[Visual_Components#Component_height_2|Component height]]||The height of this component when activated as a Form.<br />
|valign="top"|componentheight||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==CatalogView Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[CatalogView Options#Heading Attribute|Heading]]||The Catalogview heading. This defaults to none, which causes the heading to not be displayed<br />
|valign="top"|catalogViewHeading||valign="top"|Character<br />
|-<br />
|valign="top"|[[CatalogView Options#Cell Attributes|Cell width]]||The width of each cell (this is a percentage that the cell will used in the display area). This defaults to 100%<br />
|valign="top"|catalogViewCellWidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[CatalogView Options#Cell Attributes|Cell height]]||The height of the cell in pixels. This defaults to just take up the space that is required to display the cell<br />
|valign="top"|catalogViewCellHeight||valign="top"|Int<br />
|-<br />
|valign="top"|[[CatalogView Options#Cell Attributes|Columns across]]||The number of columns to display across the page<br />
|valign="top"|catalogViewTableColumns||valign="top"|Int<br />
|-<br />
|valign="top"|[[CatalogView Options#Image Attributes|Image]]||The name of the (blob/object) column in the table containing the image for each cell<br />
|valign="top"|catalogViewImage||valign="top"|Character<br />
|-<br />
|valign="top"|[[CatalogView Options#Image Attributes|Image width]]||The width of the image in pixels<br />
|valign="top"|catalogViewImageWidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[CatalogView Options#Image Attributes|Image height]]||The height of the image in pixels<br />
|valign="top"|catalogViewImageHeight||valign="top"|Int<br />
|-<br />
|valign="top"|[[CatalogView Options#Caption Attributes|Caption]]||The name of the (character) column in the table containing the caption for each cell<br />
|valign="top"|catalogViewCaption||valign="top"|Character<br />
|-<br />
|valign="top"|[[CatalogView Options#Caption Attributes|Caption delegate]]||The inline delegate to invoke when the caption is clicked.<br />
|valign="top"|catalogViewCaptionLink||valign="top"|Character<br />
|-<br />
|valign="top"|[[CatalogView Options#Caption Attributes|Caption link searchkey]]||The search key expression to be postfixed to the caption delegate when it is invoked<br />
|valign="top"|catalogViewLink||valign="top"|Character<br />
|-<br />
|valign="top"|[[CatalogView Options#Sub Caption Attribute|Sub caption]]||The name of the (character) column in the table containing the sub-caption for each cell<br />
|valign="top"|catalogViewSubCaption||valign="top"|Character<br />
|-<br />
|valign="top"|[[CatalogView Options#Details Attributes|Details]]||The name of the (memo/varchar) column in the table containing the details for each cell<br />
|valign="top"|catalogViewDetails||valign="top"|Character<br />
|-<br />
|valign="top"|[[CatalogView Options#Details Attributes|Read more]]||Show the 'Read more' link (True &#124; False)<br />
|valign="top"|catalogViewReadmore||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[CatalogView Options#Details Attributes|Details height]]||Maximum height of details to display if 'Read more' is specified<br />
|valign="top"|catalogViewReadmoreSize||valign="top"|Int<br />
|-<br />
|valign="top"|[[CatalogView Options#Details Attributes|Read more delegate]]||The inline delegate to invoke when the 'Read more' link is clicked. Alternatively, the 'Click' delegate can be used.<br />
|valign="top"|catalogViewReadmoreLink||valign="top"|Character<br />
|-<br />
|valign="top"|[[CatalogView Options#Details Attributes|Read more link searchkey]]||The search key expression to be postfixed to the 'Read more' delegate when it is invoked<br />
|valign="top"|catalogViewReadmoreSearchkey||valign="top"|Character<br />
|-<br />
|valign="top"|[[CatalogView Options#Order by and Filter Attributes|Order by]]||The orderby expression for the data in the Catalogview<br />
|valign="top"|catalogViewOrderby||valign="top"|Character<br />
|-<br />
|valign="top"|[[CatalogView Options#Order by and Filter Attributes|Filter]]||The filter expression that restricts which records will be included in the Catalogview<br />
|valign="top"|catalogViewFilter||valign="top"|Character<br />
|-<br />
|valign="top"|[[CatalogView Options#Pagination Attributes|Pagination]]||Paginate the rows displayed (True &#124; False)<br />
|valign="top"|catalogViewPagination||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[CatalogView Options#Pagination Attributes|Pagination size]]||The number of rows to paginate<br />
|valign="top"|catalogViewPaginationSize||valign="top"|Int<br />
|-<br />
|valign="top"|[[CatalogView Options#Show grid lines|Show grid lines]]||Show grid lines to separate each row (True &#124; False)<br />
|valign="top"|catalogViewGridLines||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[CatalogView Options#Extension Attributes|CSS Stylesheet]]||You can override the CSS style for the table containing the cells and the style of the cells themselves by specifying your own stylesheet.<br />
|valign="top"|catalogViewStylesheet||valign="top"|Character<br />
|-<br />
|valign="top"|[[CatalogView Options#Extension Attributes|Other options]]||Other Catalogview options<br />
|valign="top"|catalogViewOtherOptions||valign="top"|Character<br />
|-<br />
|valign="top"|[[CatalogView Options#Extension Attributes|Custom library]]||Custom library containing the Tile producer delegate.<br />
|valign="top"|catalogviewCustomLibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[CatalogView Options#Extension Attributes|Tile producer]]||Delegate to call to render a custom tile. This should just output the HTML.<br />
|valign="top"|catalogViewTileDelegate||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Related Data==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Related Data#Parent section name|Parent section name]]||Name of related parent section<br />
|valign="top"|parentid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Automatically relate|Automatically relate]]||Automatically relate the child section (True &#124; False). If this is unchecked then you need to manually relate it in the parentdatachanged delegate.<br />
|valign="top"|autoRelateChildSection||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Menu==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Menus#Visible|Visible]]||Section menu visible (True &#124; False)<br />
|valign="top"|sectionMenuVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Menus#Height|Height]]||Section menu height<br />
|valign="top"|sectionMenuHeight||Int<br />
|-<br />
|valign="top"|[[Section Menus#Background color|Background color]]||Section menu background color<br />
|valign="top"|sectionMenuBackColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Foreground color|Foreground color]]||Section menu foreground color<br />
|valign="top"|sectionMenuForeColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu panel|Custom menu panel]]||The .rsp or .jssp page used to create the custom menu panel. This page should generate dynamic HTML5/JavaScript.<br />
|valign="top"|customSectionMenuPanel||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu|Custom menu]]||Section menu contents<br />
|valign="top"|customSectionMenu||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom action|Custom action]]||Action to perform when a menu item is selected<br />
|valign="top"|sectionMenuAction||Character<br />
|-<br />
|}<br />
<br />
==Search Panel==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Search Panels#Visible|Visible]]||Section search panel visible (True &#124; False)<br />
|valign="top"|searchPanelVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Height|Height]]||Section search panel height<br />
|valign="top"|searchPanelHeight||Int<br />
|-<br />
|valign="top"|[[Section Search Panels#Background color|Background color]]||Section search panel background color<br />
|valign="top"|searchPanelBackColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Foreground color|Foreground color]]||Section search panel foreground color<br />
|valign="top"|searchPanelForeColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Auto create|Auto create]]||Automatically create search panel for all Section search fields<br />
|valign="top"|searchPanelAutoCreate||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Custom search panel|Custom search panel]]||The delegate used to create the custom search panel<br />
|valign="top"|searchPanelAction||Character<br />
|-<br />
|}<br />
<br />
==Subtitle==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Subtitles#Visible|Visible]]||Section subtitle visible (True &#124; False)<br />
|valign="top"|subtitleVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Subtitles#Caption|Caption]]||Section subtitle caption<br />
|valign="top"|subtitleCaption||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Height|Height]]||Section subtitle height<br />
|valign="top"|subtitleHeight||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#Background color|Background color]]||Section subtitle background color<br />
|valign="top"|subtitleBackColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Foreground color|Foreground color]]||Section subtitle foreground color<br />
|valign="top"|subtitleForeColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Font|Font]]||Section subtitle font<br />
|valign="top"|subtitleFont||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#CSS style|CSS style]]||CSS style<br />
|valign="top"|subtitleCssStyle||Character<br />
|-<br />
|}<br />
<br />
==Footer==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Footers#Visible|Visible]]||Section footer visible (True &#124; False)<br />
|valign="top"|footerVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Footers#Caption|Caption]]||Section footer caption<br />
|valign="top"|footerText||Character<br />
|-<br />
|valign="top"|[[Section Footers#Height|Height]]||Section footer height<br />
|valign="top"|footerHeight||Int<br />
|-<br />
|valign="top"|[[Section Footers#Background color|Background color]]||Section footer background color<br />
|valign="top"|footerBackColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#Foreground color|Foreground color]]||Section footer foreground color<br />
|valign="top"|footerForeColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#CSS style|CSS style]]||CSS style (separate attributes with ; or use app:/filename.css or specify CSS classes separated by spaces).<br />
|valign="top"|footercssstyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom menu|Custom menu]]||Section footer menu contents<br />
|valign="top"|customOptionsMenu||Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom action|Custom action]]||Action to perform when a footer menu item is selected<br />
|valign="top"|customOptionsMenuAction||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button CSS|Footer button CSS]]||Footer button CSS style<br />
|valign="top"|footerButtonCss||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button width|Footer button width]]||Footer button width<br />
|valign="top"|footerButtonWidth||Int<br />
|-<br />
|}<br />
<br />
==Other Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Accordion Behavior#Hide form NavBar|Hide form NavBar]]||Hide form Navigation Bar at runtime if this section is in an Accordion Stack (True &#124; False)<br />
|valign="top"|hideFormNavBar||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Instant_Search#Hide_SearchBox|Hide SearchBox]]||Hide the Page Header Instant Search box when this section is selected in an Accordion Stack (True &#124; False). From v5.4.<br />
|valign="top"|hidesearchbox||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Appearance#Collapsable|Collapsable]]||The section is collapsible at runtime (True &#124; False)<br />
|valign="top"|collapsableAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Accordion Behavior#Exclude from accordion|Exclude from accordion]]||The section is excluded from accordion behavior at runtime (True &#124; False)<br />
|valign="top"|excludeAccordionAtRuntime||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Custom Delegates==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Custom Delegates#Scripting Language|Scripting language]]||The default scripting language for custom code in this section (Inherit &#124; Recital &#124; Visual FoxPro &#124; Python &#124; JavaScript &#124; PHP)<br />
|valign="top"|scriptingLanguage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom Library|Custom library]]||The filename of the library containing code for event handlers and custom procedures/functions<br />
|valign="top"|customLibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Print|Print]]||The delegate for the Print event.<br>This is called when you click the 'Print' icon.<br />
|valign="top"|printAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Expanded|Expanded]]||The delegate for the Expanded event<br />
|valign="top"|expandedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Collapsed|Collapsed]]||The delegate for the Collapsed event<br />
|valign="top"|collapsedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Hotkey|Hotkey]]||The delegate for the Hotkey event.<br />
|valign="top"|hotkeyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Init|Init]]||The delegate for the Init event<br />
|valign="top"|initAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Destroy|Destroy]]||The delegate for the Destroy event<br />
|valign="top"|destroyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Load|Load]]||The delegate for the Load event<br />
|valign="top"|loadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Ready|Ready]]||The delegate for the Ready event<br />
|valign="top"|readyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Unload|Unload]]||The delegate for the Unload event<br />
|valign="top"|unloadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Click|Click]]||The delegate for the Clicked event<br />
|valign="top"|clickAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Double Click|Double Click]]||The delegate for the Double Clicked event<br />
|valign="top"|dblClickAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Parent data changed|Parent data changed]]||The delegate for the ParentDataChanged event<br />
|valign="top"|parentDataChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Data Producer|Data Producer]]||The delegate for the DataProducer (used in Web Components).<br>From v6.1.<br />
|valign="top"|dataproduceraction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer|Timer]]||The delegate for the Timer event<br />
|valign="top"|timerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer interval|Timer interval]]||The timer interval in seconds that the Timer event will be called at runtime<br />
|valign="top"|timerInterval||valign="top"|Int<br />
|-<br />
|valign="top"|[[Custom Delegates#State Changed|State Changed]]||The delegate for the Statechanged event.<br />
|valign="top"|stateChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom footer menu|Custom footer menu]]||The delegate for the footer menu event<br />
|valign="top"|customMenuAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom search command|Custom search command]]||The delegate for the search event<br />
|valign="top"|customSearch||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom section menu|Custom section menu]]||The delegate for the section menu event<br />
|valign="top"|customSectionMenuAction||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Permissions and Roles==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Users and Roles|Create roles]]||A comma separated list of roles that can perform create operations on data in the section.<br />
|valign="top"|permcreate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Read roles]]||A comma separated list of roles that can read (and view) the section.<br />
|valign="top"|permRead||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Update roles]]||A comma separated list of roles that can perform update operations on data in the section.<br />
|valign="top"|permUpdate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Delete roles]]||A comma separated list of roles that can perform delete operations on data in the section.<br />
|valign="top"|permDelete||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==UI Presentation Rules==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Desktop|Desktop]]||Include this section in a Desktop client (True &#124; False).<br />
|valign="top"|desktopUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Web|Web]]||Include this section in a Web client (True &#124; False).<br />
|valign="top"|webUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Tablet|Tablet]]||Include this section in a Tablet client (True &#124; False).<br />
|valign="top"|tabletUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Phone|Phone]]||Include this section in a Phone client (True &#124; False).<br />
|valign="top"|mobileUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#UI States|UI States]]||UI states that affect this section. Specify multiple states as a comma separated list.<br />
|valign="top"|state||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Initial UI state|Initial UI state]]||The initial UI state for this section. This will be applied to the section and all its fields and gadgets.<br />
|valign="top"|uiStateInit||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Readonly when|Readonly when]]||Section is readonly at runtime if specified expression evaluates to true.<br />
|valign="top"|readonlyWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Visible when|Visible when]]||Section is visible at runtime if specified expression evaluates to true.<br />
|valign="top"|visibleWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Display orientation|Display orientation]]||Display depending on mobile device orientation for Tablets and Phones. (Always &#124; Portrait &#124; Landscape)<br />
|valign="top"|displayOrientation||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on change|Apply rules on change]]||Apply UI presentation rules (Visible when and Readonly when) when data is changed interactively or when navigating records (True &#124; False).<br />
|valign="top"|applyRulesOnChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on parent change|Apply rules on parent change]]||Apply section UI presentation rules (Visible when and Readonly when) when parent data is changed by navigating records (True &#124; False)<br />
|valign="top"|applyRulesOnParentChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Search Panel Responsive UI width breakpoint|Search Panel Responsive UI width breakpoint]]||The Search Panel responsive UI width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|searchpanelresponsivevisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Menu Responsive UI width breakpoint|Menu Responsive UI width breakpoint]]||valign="top"|The Menu responsive UI width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsivemenuwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI width breakpoint|Responsive UI width breakpoint]]||The section responsive UI visibility width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsivewidthvisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI height breakpoint|Responsive UI height breakpoint]]||The section responsive UI visibility height breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsiveheightvisibility||valign="top"|Int<br />
|-<br />
|}<br />
<br />
[[Category:Attributes|3 Catalogview Section]]<br />
[[Category:Sections]]<br />
[[Category:WebView Based Sections]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/CarouselView_Section_AttributesCarouselView Section Attributes2024-03-22T11:43:50Z<p>Yvonne.milne: /* UI Presentation Rules */</p>
<hr />
<div>=Overview=<br />
CarouselView Sections display a series of full-section images along with their captions. Images can scroll automatically or using on-screen controls. They are ideal as welcome pages.<br />
{{DISPLAYTITLE:CarouselView Section}}<br />
[[File:carouselview_section.png|middle|link={{filepath:carouselview.png}}]]<br />
<br />
You build Apps in Lianja App Builder visually using the [[:Category:Page_Builder|Page Builder]].<br />
<br />
If you have not yet done so please read [[Understanding_the_Lianja_App_Architecture|Understanding the Lianja Architecture]] and also [[Lianja_is_all_about_ART|Understanding ART]] to better understand this article.<br />
<br />
An App consists of pages. Pages are made up of Sections. Form sections are made up of FormItems. We call these collectively "UI Elements" or "Visual Elements".<br />
<br />
==Setting Attributes Declaratively==<br />
<br />
You adjust the appearance and behavior of each UI Element in the '''Attributes''' Tab of the [[:Category:App_Inspector|App Inspector]].<br />
<br />
[[{{ns:file}}:bm-attributes.png|800px|left|border|link={{filepath:bm-attributes.png}}|Attributes]]<br />
<br clear=all><br />
<br />
The attributes available consist of some common ones as well as some specific to the UI Element being inspected.<br />
<br />
==Getting and Setting Attributes Programmatically==<br />
The '''setAttribute(name, value)''' method can be used to set the value of an Attribute:<br />
<br />
<pre>Lianja.get("pageid.sectionid").setAttribute("title","Section1")</pre><br />
<br />
Note: on the desktop, the shortened form '''setAttr(name,value)''' is also available.<br />
<br />
The '''getAttribute(name)''' method can be used to get the value of an Attribute:<br />
<br />
<pre>cTitle = Lianja.get("pageid.sectionid").getAttribute("title")</pre><br />
<br />
Note: on the desktop, the shortened form '''getAttr(name)''' is also available.<br />
<br />
=See Also=<br />
[[CarouselView Options]]<br />
<br />
=Attributes=<br />
==Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Details Attributes#Name|Name]]||The name for this section (unique to the page)<br />
|valign="top"|id||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Full name|Full name]]||The full name for this section including its parent page, e.g. page1.section1<br />
|valign="top"|fullid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Alias name|Alias name]]||The alias name for this section<br />
|valign="top"|aliasid||Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Dashboard group]]||The dashboard section that this section belongs to. From v5.2.<br />
|valign="top"|horizontalgroup||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Horizontal stretch]]||The horizontal % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|horizontalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Vertical stretch]]||The vertical % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|verticalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#App Doc|App Doc]]||The App Doc file for this section. This will be included in the [[App Doc]] when it is generated.<br />
|valign="top"|appdoc||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#MetaData version|MetaData version]]||The MetaData version number. You can set this in the setupUI hook to prevent MetaData being applied multiple times.<br />
|valign="top"|metaDataVersion||valign="top"|Int<br />
|-<br />
|valign="top"|[[MetaTypes|Meta types]]||A comma separated list of metatype names<br />
|valign="top"|metatypes||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Custom Props|Custom Props]]||A ';' separated list of custom prop key pairs, e.g. name=barry;company=lianja<br>From v5.3.<br />
|valign="top"|customprops||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Type|Type]]||The type of section: carouselview (readonly)<br />
|valign="top"|type||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Caption|Caption]]||The section caption displayed in the section header<br />
|valign="top"|title||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Height|Height]]||The section height<br />
|valign="top"|height||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Fixed height|Fixed height]]||Fix the section height (True &#124; False)<br />
|valign="top"|fixedHeight||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Details Attributes#Auto layout percent|Auto layout percent]]||Auto layout percentage of page size. If set to 0, then all sections on a page are resized to an equal height.<br />
|valign="top"|autoLayoutPercentage||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Appearance==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Appearance#Margin|Margin]]||Margin size around the section<br />
|valign="top"|margin||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Appearance#Add spacer at bottom|Add spacer at bottom]]||Add spacer at bottom of section (True &#124; False)<br />
|valign="top"|spacerVisible||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Header==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Hide header|Hide header]]||Hide section header at runtime(True &#124; False)<br />
|valign="top"|hideHeaderAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide actionbar|Hide actionbar]]||Hide actionbar when stacked section is activated at runtime<br>(True &#124; False)<br />
|valign="top"|hideActionBarAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header icon|Header icon]]||The image for the Header (png &#124; jpg &#124; gif).<br>Use app:/imagename.ext for app specific images.<br />
|valign="top"|headerIcon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient colors|Gradient colors]]||Render the Header background color as a gradient (True &#124; False)<br />
|valign="top"|headerGradient||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Gradients#Gradient type|Gradient type]]||Specify the gradient type<br />
|valign="top"|headerGradientType||valign="top"|Int<br />
|-<br />
|valign="top"|[[Gradients#Gradient start color|Gradient start color]]||Gradient start color<br />
|valign="top"|headerFromColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient end color|Gradient end color]]||Gradient end color<br />
|valign="top"|headerToColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show Print button|Show Print button]]||Show Print button in the section header (True &#124; False)<br />
|valign="top"|showPrintButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Edit button|Show Edit button]]||Show Edit button in the section header (True &#124; False)<br />
|valign="top"|showEditButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide custom search icon|Hide custom search icon]]||Hide the custom search icon (True &#124; False)<br />
|valign="top"|hideCustomSearchIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Custom search dialog|Show Custom search dialog]]||Show custom search dialog when custom search icon clicked (True &#124; False)<br />
|valign="top"|showcustomsearchdialog||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show custom search dialog panel|Show custom search dialog panel]]||Show custom search dialog panel when custom search icon clicked<br>(True &#124; False)<br />
|valign="top"|showcustomsearchdialogpanel||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show info tips icon|Show info tips icon]]||Show the info tips icon in the section header (True &#124; False)<br />
|valign="top"|showInfoTipsIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show help icon|Show help icon]]||Show the help icon in the section header (True &#124; False)<br />
|valign="top"|showHelpIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Help topic|Help topic]]||Help topic to display when the help icon is clicked in the section header<br />
|valign="top"|helpTopic||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Custom Header Style==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Use custom header style|Use custom header style]]||Use a custom header style (True &#124; False)<br />
|valign="top"|headercustomstyle||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header background color|Header background color]]||Header background color<br />
|valign="top"|headerbackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header foreground color|Header foreground color]]||Header foreground color<br />
|valign="top"|headerforecolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border|Header bottom border]]||Display the header bottom border (True &#124; False)<br />
|valign="top"|headerbottomborder||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border height|Header bottom border height]]||Height (in pixels) of the header bottom border (if displayed)<br />
|valign="top"|headerbottomborderheight||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border color|Header bottom border color]]||Header bottom border color<br />
|valign="top"|headerbottombordercolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show record count badge|Show record count badge]]||Show the record count badge in the section header (True &#124; False).<br />
|valign="top"|showreccount||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Visual Component Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Visual_Components#Component_library_3|Component library]]||This specifies the Component library where the component will be saved.<br />
|valign="top"|componentlib||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_name_2|Component name]]||Save as this component name whenever the section is saved.<br />
|valign="top"|componentname||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_author_2|Component author]]||The author of this component.<br />
|valign="top"|componentauthor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_version_2|Component version]]||The version of this component.<br />
|valign="top"|componentversion||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_description_2|Component description]]||The description of this component.<br />
|valign="top"|componentdescription||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_permissions_2|Component permissions]]||The permissions required for this component in Lianja Cloud App Builder.<br />
|valign="top"|componentpermissions||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_width_2|Component width]]||The width of this component when activated as a Form.<br />
|valign="top"|componentwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[Visual_Components#Component_height_2|Component height]]||The height of this component when activated as a Form.<br />
|valign="top"|componentheight||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==CarouselView Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[CarouselView Options|Menu]]||The menu to embed at the top of the CarouselView section. This is a comma separated list that may contain submenus.<br />
|valign="top"|carouselMenu||valign="top"|Character<br />
|-<br />
|valign="top"|[[CarouselView Options|Images]]||A comma separated list of images to be displayed as a carousel.<br />
|valign="top"|carouselImageList||valign="top"|Character<br />
|-<br />
|valign="top"|[[CarouselView Options|Captions]]||A comma separated list of captions to be displayed in the carousel images.<br />
|valign="top"|CarouselViewCaption||valign="top"|Character<br />
|-<br />
|valign="top"|[[CarouselView Options|Sub captions]]||A comma separated list of sub captions to be displayed in the carousel images.<br />
|valign="top"|CarouselViewSubCaption||valign="top"|Character<br />
|-<br />
|valign="top"|[[CarouselView Options|Show controls]]||Show the carousel left and right selection controls (True &#124; False).<br />
|valign="top"|carouselControls||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[CarouselView Options|Show indicators]]||Show the carousel panel indicators (True &#124; False).<br />
|valign="top"|carouselIndicators||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[CarouselView Options|Cycle interval]]||The interval in seconds to cycle through the images. 0 (default) specifies no cycling.<br />
|valign="top"|carouselInterval||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Related Data==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Related Data#Parent section name|Parent section name]]||Name of related parent section<br />
|valign="top"|parentid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Automatically relate|Automatically relate]]||Automatically relate the child section (True &#124; False). If this is unchecked then you need to manually relate it in the parentdatachanged delegate.<br />
|valign="top"|autoRelateChildSection||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Related Data#Parent key|Parent key]]||Parent key<br />
|valign="top"|parentKeyExpr||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Child key|Child key]]||Child key<br />
|valign="top"|childKeyExpr||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Menu==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Menus#Visible|Visible]]||Section menu visible (True &#124; False)<br />
|valign="top"|sectionMenuVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Menus#Height|Height]]||Section menu height<br />
|valign="top"|sectionMenuHeight||Int<br />
|-<br />
|valign="top"|[[Section Menus#Background color|Background color]]||Section menu background color<br />
|valign="top"|sectionMenuBackColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Foreground color|Foreground color]]||Section menu foreground color<br />
|valign="top"|sectionMenuForeColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu panel|Custom menu panel]]||The .rsp or .jssp page used to create the custom menu panel. This page should generate dynamic HTML5/JavaScript.<br />
|valign="top"|customSectionMenuPanel||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu|Custom menu]]||Section menu contents<br />
|valign="top"|customSectionMenu||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom action|Custom action]]||Action to perform when a menu item is selected<br />
|valign="top"|sectionMenuAction||Character<br />
|-<br />
|}<br />
<br />
==Search Panel==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Search Panels#Visible|Visible]]||Section search panel visible (True &#124; False)<br />
|valign="top"|searchPanelVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Height|Height]]||Section search panel height<br />
|valign="top"|searchPanelHeight||Int<br />
|-<br />
|valign="top"|[[Section Search Panels#Background color|Background color]]||Section search panel background color<br />
|valign="top"|searchPanelBackColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Foreground color|Foreground color]]||Section search panel foreground color<br />
|valign="top"|searchPanelForeColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Auto create|Auto create]]||Automatically create search panel for all Section search fields<br />
|valign="top"|searchPanelAutoCreate||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Custom search panel|Custom search panel]]||The delegate used to create the custom search panel<br />
|valign="top"|searchPanelAction||Character<br />
|-<br />
|}<br />
<br />
==Subtitle==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Subtitles#Visible|Visible]]||Section subtitle visible (True &#124; False)<br />
|valign="top"|subtitleVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Subtitles#Caption|Caption]]||Section subtitle caption<br />
|valign="top"|subtitleCaption||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Height|Height]]||Section subtitle height<br />
|valign="top"|subtitleHeight||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#Background color|Background color]]||Section subtitle background color<br />
|valign="top"|subtitleBackColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Foreground color|Foreground color]]||Section subtitle foreground color<br />
|valign="top"|subtitleForeColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Font|Font]]||Section subtitle font<br />
|valign="top"|subtitleFont||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#CSS style|CSS style]]||CSS style<br />
|valign="top"|subtitleCssStyle||Character<br />
|-<br />
|}<br />
<br />
==Footer==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Footers#Visible|Visible]]||Section footer visible (True &#124; False)<br />
|valign="top"|footerVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Footers#Caption|Caption]]||Section footer caption<br />
|valign="top"|footerText||Character<br />
|-<br />
|valign="top"|[[Section Footers#Height|Height]]||Section footer height<br />
|valign="top"|footerHeight||Int<br />
|-<br />
|valign="top"|[[Section Footers#Background color|Background color]]||Section footer background color<br />
|valign="top"|footerBackColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#Foreground color|Foreground color]]||Section footer foreground color<br />
|valign="top"|footerForeColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#CSS style|CSS style]]||CSS style (separate attributes with ; or use app:/filename.css or specify CSS classes separated by spaces).<br />
|valign="top"|footercssstyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom menu|Custom menu]]||Section footer menu contents<br />
|valign="top"|customOptionsMenu||Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom action|Custom action]]||Action to perform when a footer menu item is selected<br />
|valign="top"|customOptionsMenuAction||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button CSS|Footer button CSS]]||Footer button CSS style<br />
|valign="top"|footerButtonCss||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button width|Footer button width]]||Footer button width<br />
|valign="top"|footerButtonWidth||Int<br />
|-<br />
|}<br />
<br />
==Other Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Accordion Behavior#Hide form NavBar|Hide form NavBar]]||Hide form Navigation Bar at runtime if this section is in an Accordion Stack (True &#124; False)<br />
|valign="top"|hideFormNavBar||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Instant_Search#Hide_SearchBox|Hide SearchBox]]||Hide the Page Header Instant Search box when this section is selected in an Accordion Stack (True &#124; False). From v5.4.<br />
|valign="top"|hidesearchbox||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Appearance#Collapsable|Collapsable]]||The section is collapsible at runtime (True &#124; False)<br />
|valign="top"|collapsableAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Accordion Behavior#Exclude from accordion|Exclude from accordion]]||The section is excluded from accordion behavior at runtime (True &#124; False)<br />
|valign="top"|excludeAccordionAtRuntime||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Custom Delegates==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Custom Delegates#Scripting Language|Scripting language]]||The default scripting language for custom code in this section (Inherit &#124; Recital &#124; Visual FoxPro &#124; Python &#124; JavaScript &#124; PHP)<br />
|valign="top"|scriptingLanguage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom Library|Custom library]]||The filename of the library containing code for event handlers and custom procedures/functions<br />
|valign="top"|customLibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Print|Print]]||The delegate for the Print event.<br>This is called when you click the 'Print' icon.<br />
|valign="top"|printAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Expanded|Expanded]]||The delegate for the Expanded event<br />
|valign="top"|expandedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Collapsed|Collapsed]]||The delegate for the Collapsed event<br />
|valign="top"|collapsedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Hotkey|Hotkey]]||The delegate for the Hotkey event.<br />
|valign="top"|hotkeyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Init|Init]]||The delegate for the Init event<br />
|valign="top"|initAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Destroy|Destroy]]||The delegate for the Destroy event<br />
|valign="top"|destroyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Load|Load]]||The delegate for the Load event<br />
|valign="top"|loadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Ready|Ready]]||The delegate for the Ready event<br />
|valign="top"|readyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Unload|Unload]]||The delegate for the Unload event<br />
|valign="top"|unloadAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Parent data changed|Parent data changed]]||The delegate for the ParentDataChanged event<br />
|valign="top"|parentDataChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Data Producer|Data Producer]]||The delegate for the DataProducer (used in Web Components).<br>From v6.1.<br />
|valign="top"|dataproduceraction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer|Timer]]||The delegate for the Timer event<br />
|valign="top"|timerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer interval|Timer interval]]||The timer interval in seconds that the Timer event will be called at runtime<br />
|valign="top"|timerInterval||valign="top"|Int<br />
|-<br />
|valign="top"|[[Custom Delegates#State Changed|State Changed]]||The delegate for the Statechanged event.<br />
|valign="top"|stateChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom footer menu|Custom footer menu]]||The delegate for the footer menu event<br />
|valign="top"|customMenuAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom search command|Custom search command]]||The delegate for the search event<br />
|valign="top"|customSearch||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom section menu|Custom section menu]]||The delegate for the section menu event<br />
|valign="top"|customSectionMenuAction||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Permissions and Roles==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Users and Roles|Create roles]]||A comma separated list of roles that can perform create operations on data in the section.<br />
|valign="top"|permcreate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Read roles]]||A comma separated list of roles that can read (and view) the section.<br />
|valign="top"|permRead||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Update roles]]||A comma separated list of roles that can perform update operations on data in the section.<br />
|valign="top"|permUpdate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Delete roles]]||A comma separated list of roles that can perform delete operations on data in the section.<br />
|valign="top"|permDelete||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==UI Presentation Rules==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Desktop|Desktop]]||Include this section in a Desktop client (True &#124; False).<br />
|valign="top"|desktopUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Web|Web]]||Include this section in a Web client (True &#124; False).<br />
|valign="top"|webUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Tablet|Tablet]]||Include this section in a Tablet client (True &#124; False).<br />
|valign="top"|tabletUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Phone|Phone]]||Include this section in a Phone client (True &#124; False).<br />
|valign="top"|mobileUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#UI States|UI States]]||UI states that affect this section. Specify multiple states as a comma separated list.<br />
|valign="top"|state||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Initial UI state|Initial UI state]]||The initial UI state for this section. This will be applied to the section and all its fields and gadgets.<br />
|valign="top"|uiStateInit||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Readonly when|Readonly when]]||Section is readonly at runtime if specified expression evaluates to true.<br />
|valign="top"|readonlyWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Visible when|Visible when]]||Section is visible at runtime if specified expression evaluates to true.<br />
|valign="top"|visibleWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Display orientation|Display orientation]]||Display depending on mobile device orientation for Tablets and Phones. (Always &#124; Portrait &#124; Landscape)<br />
|valign="top"|displayOrientation||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on change|Apply rules on change]]||Apply UI presentation rules (Visible when and Readonly when) when data is changed interactively or when navigating records (True &#124; False).<br />
|valign="top"|applyRulesOnChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on parent change|Apply rules on parent change]]||Apply section UI presentation rules (Visible when and Readonly when) when parent data is changed by navigating records (True &#124; False)<br />
|valign="top"|applyRulesOnParentChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Search Panel Responsive UI width breakpoint|Search Panel Responsive UI width breakpoint]]||The Search Panel responsive UI width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|searchpanelresponsivevisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Menu Responsive UI width breakpoint|Menu Responsive UI width breakpoint]]||valign="top"|The Menu responsive UI width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsivemenuwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI width breakpoint|Responsive UI width breakpoint]]||The section responsive UI visibility width breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsivewidthvisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI height breakpoint|Responsive UI height breakpoint]]||The section responsive UI visibility height breakpoint in Web/Mobile Apps. From v5.4.<br />
|valign="top"|responsiveheightvisibility||valign="top"|Int<br />
|-<br />
|}<br />
<br />
[[Category:Attributes|3 CarouselView Section]]<br />
[[Category:Sections]]<br />
[[Category:WebView Based Sections]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Calendar_Section_AttributesCalendar Section Attributes2024-03-22T11:43:24Z<p>Yvonne.milne: /* UI Presentation Rules */</p>
<hr />
<div>=Overview=<br />
Calendar Sections provide a calendar interface to allow for the creation, display, update and deletion of appointments and other time planner events.<br />
{{DISPLAYTITLE:Calendar Section}}<br />
[[{{ns:file}}:l95_lianja_mobiledemo_cale.png|800px|left|border|link={{filepath:l95_lianja_mobiledemo_cale.png}}|lianja_mobiledemo]]<br />
<br clear=all><br />
<br />
You build Apps in Lianja App Builder visually using the [[:Category:Page_Builder|Page Builder]].<br />
<br />
If you have not yet done so please read [[Understanding_the_Lianja_App_Architecture|Understanding the Lianja Architecture]] and also [[Lianja_is_all_about_ART|Understanding ART]] to better understand this article.<br />
<br />
An App consists of pages. Pages are made up of Sections. Form sections are made up of FormItems. We call these collectively "UI Elements" or "Visual Elements".<br />
<br />
==Setting Attributes Declaratively==<br />
<br />
You adjust the appearance and behavior of each UI Element in the '''Attributes''' Tab of the [[:Category:App_Inspector|App Inspector]].<br />
<br />
[[{{ns:file}}:bm-attributes.png|800px|left|border|link={{filepath:bm-attributes.png}}|Attributes]]<br />
<br clear=all><br />
<br />
The attributes available consist of some common ones as well as some specific to the UI Element being inspected.<br />
<br />
==Getting and Setting Attributes Programmatically==<br />
The '''setAttribute(name, value)''' method can be used to set the value of an Attribute:<br />
<br />
<pre>Lianja.get("pageid.sectionid").setAttribute("title","Section1")</pre><br />
<br />
Note: on the desktop, the shortened form '''setAttr(name,value)''' is also available.<br />
<br />
The '''getAttribute(name)''' method can be used to get the value of an Attribute:<br />
<br />
<pre>cTitle = Lianja.get("pageid.sectionid").getAttribute("title")</pre><br />
<br />
Note: on the desktop, the shortened form '''getAttr(name)''' is also available.<br />
<br />
=See Also=<br />
[[Calendar Options]]<br />
<br />
Demo Apps (included in the Lianja App Builder distribution):<br />
* Lianja Demo (lianjademo)<br />
* Lianja Web UI Calendar Demo (example_webapp4)<br />
<br />
=Attributes=<br />
==Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Details Attributes#Name|Name]]||The name for this section (unique to the page)<br />
|valign="top"|id||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Full name|Full name]]||The full name for this section including its parent page, e.g. page1.section1<br />
|valign="top"|fullid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Alias name|Alias name]]||The alias name for this section<br />
|valign="top"|aliasid||Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Dashboard group]]||The dashboard section that this section belongs to. From v5.2.<br />
|valign="top"|horizontalgroup||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Horizontal stretch]]||The horizontal % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|horizontalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Vertical stretch]]||The vertical % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|verticalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#App Doc|App Doc]]||The App Doc file for this section. This will be included in the [[App Doc]] when it is generated.<br />
|valign="top"|appdoc||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#MetaData version|MetaData version]]||The MetaData version number. You can set this in the setupUI hook to prevent MetaData being applied multiple times.<br />
|valign="top"|metaDataVersion||valign="top"|Int<br />
|-<br />
|valign="top"|[[MetaTypes|Meta types]]||A comma separated list of metatype names<br />
|valign="top"|metatypes||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Custom Props|Custom Props]]||A ';' separated list of custom prop key pairs, e.g. name=barry;company=lianja<br>From v5.3.<br />
|valign="top"|customprops||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Type|Type]]||The type of section: calendar (readonly)<br />
|valign="top"|type||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Caption|Caption]]||The section caption displayed in the section header<br />
|valign="top"|title||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Database|Database]]||The database for this section<br />
|valign="top"|database||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Table|Table]]||The table for this section<br />
|valign="top"|table||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Height|Height]]||The section height<br />
|valign="top"|height||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Fixed height|Fixed height]]||Fix the section height (True &#124; False)<br />
|valign="top"|fixedHeight||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Details Attributes#Auto layout percent|Auto layout percent]]||Auto layout percentage of page size. If set to 0, then all sections on a page are resized to an equal height.<br />
|valign="top"|autoLayoutPercentage||valign="top"|Int<br />
|-<br />
|valign="top"|[[Details Attributes#Readonly|Readonly]]||Section is readonly (True &#124; False)<br />
|valign="top"|readOnly||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Appearance==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Appearance#Margin|Margin]]||Margin size around the section<br />
|valign="top"|margin||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Appearance#Add spacer at bottom|Add spacer at bottom]]||Add spacer at bottom of section (True &#124; False)<br />
|valign="top"|spacerVisible||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Header==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Hide header|Hide header]]||Hide section header at runtime(True &#124; False)<br />
|valign="top"|hideHeaderAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide actionbar|Hide actionbar]]||Hide actionbar when stacked section is activated at runtime<br>(True &#124; False)<br />
|valign="top"|hideActionBarAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header CSS style|Header CSS style]]||CSS style (separate attributes with ; or use app:/filename.css)<br />
|valign="top"|headerCssStyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header icon|Header icon]]||The image for the Header (png &#124; jpg &#124; gif).<br>Use app:/imagename.ext for app specific images.<br />
|valign="top"|headerIcon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient colors|Gradient colors]]||Render the Header background color as a gradient (True &#124; False)<br />
|valign="top"|headerGradient||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Gradients#Gradient type|Gradient type]]||Specify the gradient type<br />
|valign="top"|headerGradientType||valign="top"|Int<br />
|-<br />
|valign="top"|[[Gradients#Gradient start color|Gradient start color]]||Gradient start color<br />
|valign="top"|headerFromColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient end color|Gradient end color]]||Gradient end color<br />
|valign="top"|headerToColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show OK/Cancel buttons|Show OK/Cancel buttons]]||Show OK/Cancel buttons in the section header (True &#124; False)<br />
|valign="top"|showOkCancelButtons||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Add/Delete buttons|Show Add/Delete buttons]]||Show Add/Delete buttons in the section header (True &#124; False)<br />
|valign="top"|showAddDeleteButtons||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Print button|Show Print button]]||Show Print button in the section header (True &#124; False)<br />
|valign="top"|showPrintButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Edit button|Show Edit button]]||Show Edit button in the section header (True &#124; False)<br />
|valign="top"|showEditButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide custom search icon|Hide custom search icon]]||Hide the custom search icon (True &#124; False)<br />
|valign="top"|hideCustomSearchIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Custom search dialog|Show Custom search dialog]]||Show custom search dialog when custom search icon clicked (True &#124; False)<br />
|valign="top"|showcustomsearchdialog||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show custom search dialog panel|Show custom search dialog panel]]||Show custom search dialog panel when custom search icon clicked<br>(True &#124; False)<br />
|valign="top"|showcustomsearchdialogpanel||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show info tips icon|Show info tips icon]]||Show the info tips icon in the section header (True &#124; False)<br />
|valign="top"|showInfoTipsIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show help icon|Show help icon]]||Show the help icon in the section header (True &#124; False)<br />
|valign="top"|showHelpIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Help topic|Help topic]]||Help topic to display when the help icon is clicked in the section header<br />
|valign="top"|helpTopic||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Custom Header Style==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Use custom header style|Use custom header style]]||Use a custom header style (True &#124; False)<br />
|valign="top"|headercustomstyle||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header background color|Header background color]]||Header background color<br />
|valign="top"|headerbackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header foreground color|Header foreground color]]||Header foreground color<br />
|valign="top"|headerforecolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border|Header bottom border]]||Display the header bottom border (True &#124; False)<br />
|valign="top"|headerbottomborder||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border height|Header bottom border height]]||Height (in pixels) of the header bottom border (if displayed)<br />
|valign="top"|headerbottomborderheight||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border color|Header bottom border color]]||Header bottom border color<br />
|valign="top"|headerbottombordercolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show record count badge|Show record count badge]]||Show the record count badge in the section header (True &#124; False).<br />
|valign="top"|showreccount||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Visual Component Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Visual_Components#Component_library_3|Component library]]||This specifies the Component library where the component will be saved.<br />
|valign="top"|componentlib||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_name_2|Component name]]||Save as this component name whenever the section is saved.<br />
|valign="top"|componentname||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_author_2|Component author]]||The author of this component.<br />
|valign="top"|componentauthor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_version_2|Component version]]||The version of this component.<br />
|valign="top"|componentversion||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_description_2|Component description]]||The description of this component.<br />
|valign="top"|componentdescription||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_permissions_2|Component permissions]]||The permissions required for this component in Lianja Cloud App Builder.<br />
|valign="top"|componentpermissions||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_width_2|Component width]]||The width of this component when activated as a Form.<br />
|valign="top"|componentwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[Visual_Components#Component_height_2|Component height]]||The height of this component when activated as a Form.<br />
|valign="top"|componentheight||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Calendar Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Calendar Options#Default view|Default view]]||The default view to be displayed (Month &#124; Week &#124; Day)<br />
|valign="top"|calendarUrlType||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Event resource column|Event resource column]]||The (character) event resource column from the table for the events in the calendar. From v8.0.<br />
|valign="top"|calendarEventResourceColumn||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Event resource caption|Event resource caption]]||The caption header for the event resource choices for the events in the calendar. From v8.0.<br />
|valign="top"|calendarEventResourceCaption||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Event resource choices|Event resource choices]]||The event resource choices for the events in the calendar. This can be a comma separated list or a SQL statement. From v8.0.<br />
|valign="top"|calendarEventResourceChoices||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Event resource width|Event resource width]]||The event resource panel width in pixels (default 0 = 120 pixels). From v8.0.<br />
|valign="top"|calendarEventResourcePanelWidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[Calendar Options#Event type column|Event type column]]||The (character) event type column from the table for the events in the calendar.<br />
|valign="top"|calendarEventTypeColumn||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Event type caption|Event type caption]]||The caption header for the event type choices for the events in the calendar. From v8.0.<br />
|valign="top"|calendarEventTypeChoices||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Event type choices|Event type choices]]||The event type choices for the events in the calendar. This can be a comma separated list or a SQL statement.<br />
|valign="top"|calendarEventTypeChoices||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Event title column|Event title column]]||The (character) event title column from the table.<br />
|valign="top"|calendarTitleColumn||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Event notes column|Event notes column]]||The (memo/varchar) event notes column from the table. From v9.5.<br />
|valign="top"|calendarnotescolumn||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Event start column|Event start column]]||The (datetime) event start column from the table.<br />
|valign="top"|calendarStartDatetimeColumn||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Event end column|Event end column]]||The (datetime) event end column from the table.<br />
|valign="top"|calendarEndDatetimeColumn||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Event repeat column|Event repeat column]]||The (int) event repeating flag column from the table.<br />
|valign="top"|calendarRepeatingColumn||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Event allday column|Event allday column]]||The (logical) event allday flag column from the table.<br />
|valign="top"|calendarAllDayColumn||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Event key column|Event key column]]||The key expression for events in the calendar.<br />
|valign="top"|calendarKeyExpr||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Event type value|Event type value]]||The event type for this calendar, e.g. meeting, vacation, appointment. Calendar contents will be filtered on this.<br />
|valign="top"|calendarEventTypeColumnValue||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Autosize|Autosize]]||Autosize the calendar into the viewport (True &#124; False)<br />
|valign="top"|calendarAutosize||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Calendar Options#Other options|Other options]]||Other calendar options<br />
|valign="top"|calendarOtherOptions||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Click delegate|Click delegate]]||Delegate to call when a calendar event is clicked<br />
|valign="top"|calendarDelegate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Dynamic day backcolor|Dynamic day backcolor]]||Delegate to return the background colors and dates. You should return this as a comma separated list. The delegate is called with one parameter: 'dates' or 'colors'. The currently selected cursor contains the selected records.<br />
|valign="top"|calendarDayBackColorDelegate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Dynamic event backcolor|Dynamic event backcolor]]||Delegate to return the background color of the event for the specified event type, which is passed as a parameter.<br />
|valign="top"|calendarEventBackolorDelegate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Dynamic event forecolor|Dynamic event forecolor]]||Delegate to return the foreground color of the event for the specified event type, which is passed as a parameter.<br />
|valign="top"|calendarEventForeColorDelegate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Custom delegate library|Custom delegate library]]||Custom library containing the day and event dynamic color delegates.<br />
|valign="top"|calendarCustomLibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[Calendar Options#Filter|Filter]]||The filter expression that restricts which events will be included in the calendar.<br />
|valign="top"|calendarFilter||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Related Data==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Related Data#Parent section name|Parent section name]]||Name of related parent section<br />
|valign="top"|parentid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Automatically relate|Automatically relate]]||Automatically relate the child section (True &#124; False). If this is unchecked then you need to manually relate it in the parentdatachanged delegate.<br />
|valign="top"|autoRelateChildSection||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Related Data#Parent key|Parent key]]||Parent key<br />
|valign="top"|parentKeyExpr||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Child key|Child key]]||Child key<br />
|valign="top"|childKeyExpr||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Menu==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Menus#Visible|Visible]]||Section menu visible (True &#124; False)<br />
|valign="top"|sectionMenuVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Menus#Height|Height]]||Section menu height<br />
|valign="top"|sectionMenuHeight||Int<br />
|-<br />
|valign="top"|[[Section Menus#Background color|Background color]]||Section menu background color<br />
|valign="top"|sectionMenuBackColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Foreground color|Foreground color]]||Section menu foreground color<br />
|valign="top"|sectionMenuForeColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu panel|Custom menu panel]]||The .rsp or .jssp page used to create the custom menu panel. This page should generate dynamic HTML5/JavaScript.<br />
|valign="top"|customSectionMenuPanel||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu|Custom menu]]||Section menu contents<br />
|valign="top"|customSectionMenu||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom action|Custom action]]||Action to perform when a menu item is selected<br />
|valign="top"|sectionMenuAction||Character<br />
|-<br />
|}<br />
<br />
==Search Panel==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Search Panels#Visible|Visible]]||Section search panel visible (True &#124; False)<br />
|valign="top"|searchPanelVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Height|Height]]||Section search panel height<br />
|valign="top"|searchPanelHeight||Int<br />
|-<br />
|valign="top"|[[Section Search Panels#Background color|Background color]]||Section search panel background color<br />
|valign="top"|searchPanelBackColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Foreground color|Foreground color]]||Section search panel foreground color<br />
|valign="top"|searchPanelForeColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Auto create|Auto create]]||Automatically create search panel for all Section search fields<br />
|valign="top"|searchPanelAutoCreate||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Custom search panel|Custom search panel]]||The delegate used to create the custom search panel<br />
|valign="top"|searchPanelAction||Character<br />
|-<br />
|}<br />
<br />
==Subtitle==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Subtitles#Visible|Visible]]||Section subtitle visible (True &#124; False)<br />
|valign="top"|subtitleVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Subtitles#Caption|Caption]]||Section subtitle caption<br />
|valign="top"|subtitleCaption||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Height|Height]]||Section subtitle height<br />
|valign="top"|subtitleHeight||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#Background color|Background color]]||Section subtitle background color<br />
|valign="top"|subtitleBackColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Foreground color|Foreground color]]||Section subtitle foreground color<br />
|valign="top"|subtitleForeColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Font|Font]]||Section subtitle font<br />
|valign="top"|subtitleFont||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#CSS style|CSS style]]||CSS style<br />
|valign="top"|subtitleCssStyle||Character<br />
|-<br />
|}<br />
<br />
==Footer==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Footers#Visible|Visible]]||Section footer visible (True &#124; False)<br />
|valign="top"|footerVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Footers#Caption|Caption]]||Section footer caption<br />
|valign="top"|footerText||Character<br />
|-<br />
|valign="top"|[[Section Footers#Height|Height]]||Section footer height<br />
|valign="top"|footerHeight||Int<br />
|-<br />
|valign="top"|[[Section Footers#Background color|Background color]]||Section footer background color<br />
|valign="top"|footerBackColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#Foreground color|Foreground color]]||Section footer foreground color<br />
|valign="top"|footerForeColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#CSS style|CSS style]]||CSS style (separate attributes with ; or use app:/filename.css or specify CSS classes separated by spaces).<br />
|valign="top"|footercssstyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom menu|Custom menu]]||Section footer menu contents<br />
|valign="top"|customOptionsMenu||Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom action|Custom action]]||Action to perform when a footer menu item is selected<br />
|valign="top"|customOptionsMenuAction||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button CSS|Footer button CSS]]||Footer button CSS style<br />
|valign="top"|footerButtonCss||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button width|Footer button width]]||Footer button width<br />
|valign="top"|footerButtonWidth||Int<br />
|-<br />
|}<br />
<br />
==Other Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Accordion Behavior#Hide form NavBar|Hide form NavBar]]||Hide form Navigation Bar at runtime if this section is in an Accordion Stack (True &#124; False)<br />
|valign="top"|hideFormNavBar||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Instant_Search#Hide_SearchBox|Hide SearchBox]]||Hide the Page Header Instant Search box when this section is selected in an Accordion Stack (True &#124; False). From v5.4.<br />
|valign="top"|hidesearchbox||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Appearance#Collapsable|Collapsable]]||The section is collapsible at runtime (True &#124; False)<br />
|valign="top"|collapsableAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Accordion Behavior#Exclude from accordion|Exclude from accordion]]||The section is excluded from accordion behavior at runtime (True &#124; False)<br />
|valign="top"|excludeAccordionAtRuntime||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Custom Delegates==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Custom Delegates#Scripting Language|Scripting language]]||The default scripting language for custom code in this section (Inherit &#124; Recital &#124; Visual FoxPro &#124; Python &#124; JavaScript &#124; PHP)<br />
|valign="top"|scriptingLanguage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom Library|Custom library]]||The filename of the library containing code for event handlers and custom procedures/functions<br />
|valign="top"|customLibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Print|Print]]||The delegate for the Print event.<br>This is called when you click the 'Print' icon.<br />
|valign="top"|printAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Expanded|Expanded]]||The delegate for the Expanded event<br />
|valign="top"|expandedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Collapsed|Collapsed]]||The delegate for the Collapsed event<br />
|valign="top"|collapsedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Hotkey|Hotkey]]||The delegate for the Hotkey event.<br />
|valign="top"|hotkeyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Parent data changed|Parent data changed]]||The delegate for the ParentDataChanged event<br />
|valign="top"|parentDataChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Data Producer|Data Producer]]||The delegate for the DataProducer (used in Web Components).<br>From v6.1.<br />
|valign="top"|dataproduceraction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer|Timer]]||The delegate for the Timer event<br />
|valign="top"|timerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer interval|Timer interval]]||The timer interval in seconds that the Timer event will be called at runtime<br />
|valign="top"|timerInterval||valign="top"|Int<br />
|-<br />
|valign="top"|[[Custom Delegates#State Changed|State Changed]]||The delegate for the Statechanged event.<br />
|valign="top"|stateChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom footer menu|Custom footer menu]]||The delegate for the footer menu event<br />
|valign="top"|customMenuAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom search command|Custom search command]]||The delegate for the search event<br />
|valign="top"|customSearch||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom section menu|Custom section menu]]||The delegate for the section menu event<br />
|valign="top"|customSectionMenuAction||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Permissions and Roles==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Users and Roles|Create roles]]||A comma separated list of roles that can perform create operations on data in the section.<br />
|valign="top"|permcreate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Read roles]]||A comma separated list of roles that can read (and view) the section.<br />
|valign="top"|permRead||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Update roles]]||A comma separated list of roles that can perform update operations on data in the section.<br />
|valign="top"|permUpdate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Delete roles]]||A comma separated list of roles that can perform delete operations on data in the section.<br />
|valign="top"|permDelete||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==UI Presentation Rules==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Desktop|Desktop]]||Include this section in a Desktop client (True &#124; False).<br />
|valign="top"|desktopUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Web|Web]]||Include this section in a Web client (True &#124; False).<br />
|valign="top"|webUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Tablet|Tablet]]||Include this section in a Tablet client (True &#124; False).<br />
|valign="top"|tabletUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Phone|Phone]]||Include this section in a Phone client (True &#124; False).<br />
|valign="top"|mobileUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#UI States|UI States]]||UI states that affect this section. Specify multiple states as a comma separated list.<br />
|valign="top"|state||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Initial UI state|Initial UI state]]||The initial UI state for this section. This will be applied to the section and all its fields and gadgets.<br />
|valign="top"|uiStateInit||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Readonly when|Readonly when]]||Section is readonly at runtime if specified expression evaluates to true.<br />
|valign="top"|readonlyWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Visible when|Visible when]]||Section is visible at runtime if specified expression evaluates to true.<br />
|valign="top"|visibleWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Display orientation|Display orientation]]||Display depending on mobile device orientation for Tablets and Phones. (Always &#124; Portrait &#124; Landscape)<br />
|valign="top"|displayOrientation||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on change|Apply rules on change]]||Apply UI presentation rules (Visible when and Readonly when) when data is changed interactively or when navigating records (True &#124; False).<br />
|valign="top"|applyRulesOnChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on parent change|Apply rules on parent change]]||Apply section UI presentation rules (Visible when and Readonly when) when parent data is changed by navigating records (True &#124; False)<br />
|valign="top"|applyRulesOnParentChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Search Panel Responsive UI width breakpoint|Search Panel Responsive UI width breakpoint]]||valign="top"|The Search Panel responsive UI width breakpoint in Web/Mobile Apps.<br />
|valign="top"|searchpanelresponsivevisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Menu Responsive UI width breakpoint|Menu Responsive UI width breakpoint]]||valign="top"|The Menu responsive UI width breakpoint in Web/Mobile Apps.<br />
|valign="top"|responsivemenuwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI width breakpoint|Responsive UI width breakpoint]]||valign="top"|The section responsive UI visibility width breakpoint in Web/Mobile Apps.<br />
|valign="top"|responsivewidthvisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI height breakpoint|Responsive UI height breakpoint]]||valign="top"|The section responsive UI visibility height breakpoint in Web/Mobile Apps.<br />
|valign="top"|responsiveheightvisibility||valign="top"|Int<br />
|-<br />
|}<br />
<br />
[[Category:Attributes|3 Calendar Section]]<br />
[[Category:Sections]]<br />
[[Category:WebView Based Sections]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/ArticleView_Section_AttributesArticleView Section Attributes2024-03-22T11:42:53Z<p>Yvonne.milne: /* UI Presentation Rules */</p>
<hr />
<div>=Overview=<br />
ArticleView Sections are used to display HTML pages with a default bootstrap theme. Click the keyboard icon in the Section header to open the HTML Editor.<br>From v5.3.<br />
{{DISPLAYTITLE:ArticleView Section}}<br />
[[{{ns:file}}:articleview1.png|800px|left|border|link={{filepath:articleview1.png}}|ArticleView Section]]<br />
<br clear=all><br />
<br />
From v8.0, click the '''Edit Article''' button to open the HTML file in the WYSIWYG HTML editor in place:<br />
[[{{ns:file}}:l8_articleview.png|800px|left|border|link={{filepath:l8_articleview.png}}|ArticleView Section]]<br />
<br clear=all><br />
<br />
[[{{ns:file}}:l8_articleview1.png|800px|left|border|link={{filepath:l8_articleview1.png}}|ArticleView Section]]<br />
<br clear=all><br />
<br />
You build Apps in Lianja App Builder visually using the [[:Category:Page_Builder|Page Builder]].<br />
<br />
If you have not yet done so please read [[Understanding_the_Lianja_App_Architecture|Understanding the Lianja Architecture]] and also [[Lianja_is_all_about_ART|Understanding ART]] to better understand this article.<br />
<br />
An App consists of pages. Pages are made up of Sections. Form sections are made up of FormItems. We call these collectively "UI Elements" or "Visual Elements".<br />
<br />
==Setting Attributes Declaratively==<br />
<br />
You adjust the appearance and behavior of each UI Element in the '''Attributes''' Tab of the [[:Category:App_Inspector|App Inspector]].<br />
<br />
[[{{ns:file}}:bm-attributes.png|800px|left|border|link={{filepath:bm-attributes.png}}|Attributes]]<br />
<br clear=all><br />
<br />
The attributes available consist of some common ones as well as some specific to the UI Element being inspected.<br />
<br />
==Getting and Setting Attributes Programmatically==<br />
The '''setAttribute(name, value)''' method can be used to set the value of an Attribute:<br />
<br />
<pre>Lianja.get("pageid.sectionid").setAttribute("title","Section1")</pre><br />
<br />
Note: on the desktop, the shortened form '''setAttr(name,value)''' is also available.<br />
<br />
The '''getAttribute(name)''' method can be used to get the value of an Attribute:<br />
<br />
<pre>cTitle = Lianja.get("pageid.sectionid").getAttribute("title")</pre><br />
<br />
Note: on the desktop, the shortened form '''getAttr(name)''' is also available.<br />
<br />
==See Also==<br />
[[ArticleView Options]]<br />
<br />
Demo Apps (included in the Lianja App Builder distribution):<br />
* example_datamerge (section1). Find it listed under 'Examples|Demo Cloud Apps' in the App Names explorer panel in the [[Apps Workspace]] or the [[Home Workspace]].<br />
* example_component (section3). Find it listed under 'Examples|General' in the App Names explorer panel in the [[Apps Workspace]].<br />
<br />
=Attributes=<br />
==Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Details Attributes#Name|Name]]||The name for this section (unique to the page)<br />
|valign="top"|id||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Full name|Full name]]||The full name for this section including its parent page, e.g. page1.section1<br />
|valign="top"|fullid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Alias name|Alias name]]||The alias name for this section<br />
|valign="top"|aliasid||Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Dashboard group]]||The dashboard section that this section belongs to. From v5.2.<br />
|valign="top"|horizontalgroup||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Horizontal stretch]]||The horizontal % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|horizontalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Dashboard Sections|Vertical stretch]]||The vertical % stretch factor that this section should occupy. From v5.2.<br />
|valign="top"|verticalgroupstretchfactor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#App Doc|App Doc]]||The App Doc file for this section. This will be included in the [[App Doc]] when it is generated.<br />
|valign="top"|appdoc||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#MetaData version|MetaData version]]||The MetaData version number. You can set this in the setupUI hook to prevent MetaData being applied multiple times.<br />
|valign="top"|metaDataVersion||valign="top"|Int<br />
|-<br />
|valign="top"|[[MetaTypes|Meta types]]||A comma separated list of metatype names<br />
|valign="top"|metatypes||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Custom Props|Custom Props]]||A ';' separated list of custom prop key pairs, e.g. name=barry;company=lianja<br>From v5.3.<br />
|valign="top"|customprops||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Type|Type]]||The type of section: documentview (readonly)<br />
|valign="top"|type||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Caption|Caption]]||The section caption displayed in the section header<br />
|valign="top"|title||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Height|Height]]||The section height<br />
|valign="top"|height||valign="top"|Character<br />
|-<br />
|valign="top"|[[Details Attributes#Fixed height|Fixed height]]||Fix the section height (True &#124; False)<br />
|valign="top"|fixedHeight||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Details Attributes#Auto layout percent|Auto layout percent]]||Auto layout percentage of page size. If set to 0, then all sections on a page are resized to an equal height.<br />
|valign="top"|autoLayoutPercentage||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Appearance==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Appearance#Margin|Margin]]||Margin size around the section<br />
|valign="top"|margin||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Appearance#Add spacer at bottom|Add spacer at bottom]]||Add spacer at bottom of section (True &#124; False)<br />
|valign="top"|spacerVisible||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Header==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Hide header|Hide header]]||Hide section header at runtime(True &#124; False)<br />
|valign="top"|hideHeaderAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide actionbar|Hide actionbar]]||Hide actionbar when stacked section is activated at runtime<br>(True &#124; False)<br />
|valign="top"|hideActionBarAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header CSS style|Header CSS style]]||CSS style (separate attributes with ; or use app:/filename.css)<br />
|valign="top"|headerCssStyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header icon|Header icon]]||The image for the Header (png &#124; jpg &#124; gif).<br>Use app:/imagename.ext for app specific images.<br />
|valign="top"|headerIcon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient colors|Gradient colors]]||Render the Header background color as a gradient (True &#124; False)<br />
|valign="top"|headerGradient||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Gradients#Gradient type|Gradient type]]||Specify the gradient type<br />
|valign="top"|headerGradientType||valign="top"|Int<br />
|-<br />
|valign="top"|[[Gradients#Gradient start color|Gradient start color]]||Gradient start color<br />
|valign="top"|headerFromColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Gradients#Gradient end color|Gradient end color]]||Gradient end color<br />
|valign="top"|headerToColor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show Print button|Show Print button]]||Show Print button in the section header (True &#124; False)<br />
|valign="top"|showPrintButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Edit button|Show Edit button]]||Show Edit button in the section header (True &#124; False)<br />
|valign="top"|showEditButton||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Hide custom search icon|Hide custom search icon]]||Hide the custom search icon (True &#124; False)<br />
|valign="top"|hideCustomSearchIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show Custom search dialog|Show Custom search dialog]]||Show custom search dialog when custom search icon clicked (True &#124; False)<br />
|valign="top"|showcustomsearchdialog||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show custom search dialog panel|Show custom search dialog panel]]||Show custom search dialog panel when custom search icon clicked<br>(True &#124; False)<br />
|valign="top"|showcustomsearchdialogpanel||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show info tips icon|Show info tips icon]]||Show the info tips icon in the section header (True &#124; False)<br />
|valign="top"|showInfoTipsIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Show help icon|Show help icon]]||Show the help icon in the section header (True &#124; False)<br />
|valign="top"|showHelpIcon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Help topic|Help topic]]||Help topic to display when the help icon is clicked in the section header<br />
|valign="top"|helpTopic||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Custom Header Style==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Header#Use custom header style|Use custom header style]]||Use a custom header style (True &#124; False)<br />
|valign="top"|headercustomstyle||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header background color|Header background color]]||Header background color<br />
|valign="top"|headerbackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header foreground color|Header foreground color]]||Header foreground color<br />
|valign="top"|headerforecolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border|Header bottom border]]||Display the header bottom border (True &#124; False)<br />
|valign="top"|headerbottomborder||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border height|Header bottom border height]]||Height (in pixels) of the header bottom border (if displayed)<br />
|valign="top"|headerbottomborderheight||valign="top"|Int<br />
|-<br />
|valign="top"|[[Section Header#Header bottom border color|Header bottom border color]]||Header bottom border color<br />
|valign="top"|headerbottombordercolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Header#Show record count badge|Show record count badge]]||Show the record count badge in the section header (True &#124; False).<br />
|valign="top"|showreccount||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Visual Component Details==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Visual_Components#Component_library_3|Component library]]||This specifies the Component library where the component will be saved.<br />
|valign="top"|componentlib||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_name_2|Component name]]||Save as this component name whenever the section is saved.<br />
|valign="top"|componentname||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_author_2|Component author]]||The author of this component.<br />
|valign="top"|componentauthor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_version_2|Component version]]||The version of this component.<br />
|valign="top"|componentversion||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_description_2|Component description]]||The description of this component.<br />
|valign="top"|componentdescription||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_permissions_2|Component permissions]]||The permissions required for this component in Lianja Cloud App Builder.<br />
|valign="top"|componentpermissions||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual_Components#Component_width_2|Component width]]||The width of this component when activated as a Form.<br />
|valign="top"|componentwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[Visual_Components#Component_height_2|Component height]]||The height of this component when activated as a Form.<br />
|valign="top"|componentheight||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==ArticleView Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[ArticleView Options#Database|Database]]||The name of the database that this ArticleView is bound to.<br />
|valign="top"|database||valign="top"|Character<br />
|-<br />
|valign="top"|[[ArticleView Options#Table|Table]]||The name of the table that this ArticleView is bound to.<br />
|valign="top"|table||valign="top"|Character<br />
|-<br />
|valign="top"|[[ArticleView Options#Data source|Data source]]||The varchar column that this ArticleView is bound to.<br />
|valign="top"|webviewcontrolsource||valign="top"|Character<br />
|-<br />
|valign="top"|[[ArticleView Options#File|File]]||The HTML file to be displayed.<br />
|valign="top"|reportcaption||valign="top"|Character<br />
|-<br />
|valign="top"|[[ArticleView Options#CSS stylesheet|CSS stylesheet]]||The custom CSS stylesheet for the article. From v9.0.<br />
|valign="top"|articlecssstyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[ArticleView Options#Editable|Editable]]||Whether the HTML content is editable (based on [[Users and Roles|user roles and permissions]]).<br />
|valign="top"|webvieweditable||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[ArticleView Options#Merge data|Merge data]]||Whether the HTML content should be merged. Use {macros} in the HTML. From v9.3.<br />
|valign="top"|webviewmergedata||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[ArticleView Options#Selectable|Selectable]]||Whether the Article is selectable by the end-user (operates as an article viewer). From v9.3.<br />
|valign="top"|reportselectable||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Related Data==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Related Data#Parent section name|Parent section name]]||Name of related parent section<br />
|valign="top"|parentid||valign="top"|Character<br />
|-<br />
|valign="top"|[[Related Data#Automatically relate|Automatically relate]]||Automatically relate the child section (True &#124; False). If this is unchecked then you need to manually relate it in the parentdatachanged delegate.<br />
|valign="top"|autoRelateChildSection||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Related Data#Parent key|Parent key]]||Parent key<br />
|valign="top"|parentKeyExpr||Character<br />
|-<br />
|valign="top"|[[Related Data#Child key|Child key]]||Child key<br />
|valign="top"|childKeyExpr||Character<br />
|-<br />
|}<br />
<br />
==Menu==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Menus#Visible|Visible]]||Section menu visible (True &#124; False)<br />
|valign="top"|sectionMenuVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Menus#Height|Height]]||Section menu height<br />
|valign="top"|sectionMenuHeight||Int<br />
|-<br />
|valign="top"|[[Section Menus#Background color|Background color]]||Section menu background color<br />
|valign="top"|sectionMenuBackColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Foreground color|Foreground color]]||Section menu foreground color<br />
|valign="top"|sectionMenuForeColor||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu panel|Custom menu panel]]||The .rsp or .jssp page used to create the custom menu panel. This page should generate dynamic HTML5/JavaScript.<br />
|valign="top"|customSectionMenuPanel||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom menu|Custom menu]]||Section menu contents<br />
|valign="top"|customSectionMenu||Character<br />
|-<br />
|valign="top"|[[Section Menus#Custom action|Custom action]]||Action to perform when a menu item is selected<br />
|valign="top"|sectionMenuAction||Character<br />
|-<br />
|}<br />
<br />
==Search Panel==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Search Panels#Visible|Visible]]||Section search panel visible (True &#124; False)<br />
|valign="top"|searchPanelVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Height|Height]]||Section search panel height<br />
|valign="top"|searchPanelHeight||Int<br />
|-<br />
|valign="top"|[[Section Search Panels#Background color|Background color]]||Section search panel background color<br />
|valign="top"|searchPanelBackColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Foreground color|Foreground color]]||Section search panel foreground color<br />
|valign="top"|searchPanelForeColor||Character<br />
|-<br />
|valign="top"|[[Section Search Panels#Auto create|Auto create]]||Automatically create search panel for all Section search fields<br />
|valign="top"|searchPanelAutoCreate||Boolean<br />
|-<br />
|valign="top"|[[Section Search Panels#Custom search panel|Custom search panel]]||The delegate used to create the custom search panel<br />
|valign="top"|searchPanelAction||Character<br />
|-<br />
|}<br />
<br />
==Subtitle==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Subtitles#Visible|Visible]]||Section subtitle visible (True &#124; False)<br />
|valign="top"|subtitleVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Subtitles#Caption|Caption]]||Section subtitle caption<br />
|valign="top"|subtitleCaption||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Height|Height]]||Section subtitle height<br />
|valign="top"|subtitleHeight||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#Background color|Background color]]||Section subtitle background color<br />
|valign="top"|subtitleBackColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Foreground color|Foreground color]]||Section subtitle foreground color<br />
|valign="top"|subtitleForeColor||Character<br />
|-<br />
|valign="top"|[[Section Subtitles#Font|Font]]||Section subtitle font<br />
|valign="top"|subtitleFont||Int<br />
|-<br />
|valign="top"|[[Section Subtitles#CSS style|CSS style]]||CSS style<br />
|valign="top"|subtitleCssStyle||Character<br />
|-<br />
|}<br />
<br />
==Footer==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Section Footers#Visible|Visible]]||Section footer visible (True &#124; False)<br />
|valign="top"|footerVisible||Boolean<br />
|-<br />
|valign="top"|[[Section Footers#Caption|Caption]]||Section footer caption<br />
|valign="top"|footerText||Character<br />
|-<br />
|valign="top"|[[Section Footers#Height|Height]]||Section footer height<br />
|valign="top"|footerHeight||Int<br />
|-<br />
|valign="top"|[[Section Footers#Background color|Background color]]||Section footer background color<br />
|valign="top"|footerBackColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#Foreground color|Foreground color]]||Section footer foreground color<br />
|valign="top"|footerForeColor||Character<br />
|-<br />
|valign="top"|[[Section Footers#CSS style|CSS style]]||CSS style (separate attributes with ; or use app:/filename.css or specify CSS classes separated by spaces).<br />
|valign="top"|footercssstyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom menu|Custom menu]]||Section footer menu contents<br />
|valign="top"|customOptionsMenu||Character<br />
|-<br />
|valign="top"|[[Section Footers#Custom action|Custom action]]||Action to perform when a footer menu item is selected<br />
|valign="top"|customOptionsMenuAction||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button CSS|Footer button CSS]]||Footer button CSS style<br />
|valign="top"|footerButtonCss||Character<br />
|-<br />
|valign="top"|[[Section Footers#Footer button width|Footer button width]]||Footer button width<br />
|valign="top"|footerButtonWidth||Int<br />
|-<br />
|}<br />
<br />
==Other Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Accordion Behavior#Hide form NavBar|Hide form NavBar]]||Hide form Navigation Bar at runtime if this section is in an Accordion Stack (True &#124; False)<br />
|valign="top"|hideFormNavBar||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Instant_Search#Hide_SearchBox|Hide SearchBox]]||Hide the Page Header Instant Search box when this section is selected in an Accordion Stack (True &#124; False). From v5.4.<br />
|valign="top"|hidesearchbox||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section Appearance#Collapsable|Collapsable]]||The section is collapsible at runtime (True &#124; False)<br />
|valign="top"|collapsableAtRuntime||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Accordion Behavior#Exclude from accordion|Exclude from accordion]]||The section is excluded from accordion behavior at runtime (True &#124; False)<br />
|valign="top"|excludeAccordionAtRuntime||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Custom Delegates==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Custom Delegates#Scripting Language|Scripting language]]||The default scripting language for custom code in this section (Inherit &#124; Recital &#124; Visual FoxPro &#124; Python &#124; JavaScript &#124; PHP)<br />
|valign="top"|scriptingLanguage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom Library|Custom library]]||The filename of the library containing code for event handlers and custom procedures/functions<br />
|valign="top"|customLibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Print|Print]]||The delegate for the Print event.<br>This is called when you click the 'Print' icon.<br />
|valign="top"|printAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Expanded|Expanded]]||The delegate for the Expanded event<br />
|valign="top"|expandedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Collapsed|Collapsed]]||The delegate for the Collapsed event<br />
|valign="top"|collapsedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Hotkey|Hotkey]]||The delegate for the Hotkey event.<br />
|valign="top"|hotkeyAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Parent data changed|Parent data changed]]||The delegate for the ParentDataChanged event<br />
|valign="top"|parentDataChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Data Producer|Data Producer]]||The delegate for the DataProducer (used in Web Components).<br>From v6.1.<br />
|valign="top"|dataproduceraction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer|Timer]]||The delegate for the Timer event<br />
|valign="top"|timerAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Timer interval|Timer interval]]||The timer interval in seconds that the Timer event will be called at runtime<br />
|valign="top"|timerInterval||valign="top"|Int<br />
|-<br />
|valign="top"|[[Custom Delegates#State Changed|State Changed]]||The delegate for the Statechanged event.<br />
|valign="top"|stateChangedAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom footer menu|Custom footer menu]]||The delegate for the footer menu event<br />
|valign="top"|customMenuAction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom search command|Custom search command]]||The delegate for the search event<br />
|valign="top"|customSearch||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom section menu|Custom section menu]]||The delegate for the section menu event<br />
|valign="top"|customSectionMenuAction||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Permissions and Roles==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Users and Roles|Create roles]]||A comma separated list of roles that can perform create operations on data in the section.<br />
|valign="top"|permcreate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Read roles]]||A comma separated list of roles that can read (and view) the section.<br />
|valign="top"|permRead||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Update roles]]||A comma separated list of roles that can perform update operations on data in the section.<br />
|valign="top"|permUpdate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Delete roles]]||A comma separated list of roles that can perform delete operations on data in the section.<br />
|valign="top"|permDelete||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==UI Presentation Rules==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="45%"|Description<br />
!width="25%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Desktop|Desktop]]||Include this section in a Desktop client (True &#124; False).<br />
|valign="top"|desktopUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Web|Web]]||Include this section in a Web client (True &#124; False).<br />
|valign="top"|webUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Tablet|Tablet]]||Include this section in a Tablet client (True &#124; False).<br />
|valign="top"|tabletUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Phone|Phone]]||Include this section in a Phone client (True &#124; False).<br />
|valign="top"|mobileUI||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#UI States|UI States]]||UI states that affect this section. Specify multiple states as a comma separated list.<br />
|valign="top"|state||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Initial UI state|Initial UI state]]||The initial UI state for this section. This will be applied to the section and all its fields and gadgets.<br />
|valign="top"|uiStateInit||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Readonly when|Readonly when]]||Section is readonly at runtime if specified expression evaluates to true.<br />
|valign="top"|readonlyWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Visible when|Visible when]]||Section is visible at runtime if specified expression evaluates to true.<br />
|valign="top"|visibleWhen||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Display orientation|Display orientation]]||Display depending on mobile device orientation for Tablets and Phones. (Always &#124; Portrait &#124; Landscape)<br />
|valign="top"|displayOrientation||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on change|Apply rules on change]]||Apply UI presentation rules (Visible when and Readonly when) when data is changed interactively or when navigating records (True &#124; False).<br />
|valign="top"|applyRulesOnChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Apply rules on parent change|Apply rules on parent change]]||Apply section UI presentation rules (Visible when and Readonly when) when parent data is changed by navigating records (True &#124; False)<br />
|valign="top"|applyRulesOnParentChange||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Search Panel Responsive UI width breakpoint|Search Panel Responsive UI width breakpoint]]||valign="top"|The Search Panel responsive UI width breakpoint in Web/Mobile Apps.<br />
|valign="top"|searchpanelresponsivevisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Menu Responsive UI width breakpoint|Menu Responsive UI width breakpoint]]||valign="top"|The Menu responsive UI width breakpoint in Web/Mobile Apps.<br />
|valign="top"|responsivemenuwidth||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI width breakpoint|Responsive UI width breakpoint]]||The section responsive UI visibility width breakpoint in Web/Mobile Apps.<br />
|valign="top"|responsivewidthvisibility||valign="top"|Int<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Responsive UI height breakpoint|Responsive UI height breakpoint]]||The section responsive UI visibility height breakpoint in Web/Mobile Apps.<br />
|valign="top"|responsiveheightvisibility||valign="top"|Int<br />
|-<br />
|}<br />
<br />
[[Category:Attributes|3 ArticleView Section]]<br />
[[Category:Sections]]<br />
[[Category:Lianja v5.3]]<br />
[[Category:Lianja v8.0]]<br />
[[Category:WebView Based Sections]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/LianjaLianja2024-03-20T10:43:10Z<p>Yvonne.milne: /* Properties */</p>
<hr />
<div>====Properties====<br />
<br />
This class supports the following properties:<br />
<br />
{| class="wikitable" width=100%<br />
!width="15%"|Property<br />
!width="5%"|Access<br />
!width="15%"|Value<br />
!width="50%"|Description<br />
!Desktop||&nbsp;&nbsp;Web&nbsp;&nbsp;||Mobile&nbsp;<br />
|-<br />
|valign="top"|activepage<br />
|valign="top"|RW<br />
|valign="top"|Object<br />
|valign="top"|Return an object reference to the currently active [[PageBuilder|Page]]<br />
|style="background: green"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp; <br />
|-<br />
|valign="top"|Appdir<br />
|valign="top"|R<br />
|valign="top"|Character<br />
|valign="top"|Full path of the current App directory<br />
|style="text-align: center;background: lightgreen"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|application<br />
|valign="top"|R<br />
|valign="top"|Character<br />
|Currently active App<br />
|style="background: green"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|args<br />
|valign="top"|RW<br />
|valign="top"|Character<br />
|Arguments passed to current App. From v6.0.<br />
|style="background: green"|&nbsp;<br />
|style="background: green"|&nbsp;<br />
|style="background: green"|&nbsp;<br />
|-<br />
|valign="top"|availablecameralist<br />
|valign="top"|R<br />
|valign="top"|Character<br />
|valign="top"|Comma separated list of available cameras. From v7.0.<br />
|style="background: lightgreen"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|availablecameras<br />
|valign="top"|R<br />
|valign="top"|Numeric<br />
|valign="top"|Number of available cameras. From v7.0.<br />
|style="background: lightgreen"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|Count<br />
|valign="top"|R<br />
|valign="top"|Numeric<br />
|valign="top"|Number of [[PageBuilder|Pages]] in the current App<br />
|style="text-align: center;background: lightgreen"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|database<br />
|valign="top"|R<br />
|valign="top"|Character<br />
|valign="top"|Currently active database<br />
|style="background: green"|&nbsp;<br />
|style="background: green"|&nbsp;<br />
|style="background: green"|&nbsp;<br />
|-<br />
|valign="top"|Datadir<br />
|valign="top"|R<br />
|valign="top"|Character<br />
|valign="top"|Full path of the current database directory<br />
|style="text-align: center;background: lightgreen"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|editor<br />
|valign="top"|R<br />
|valign="top"|Object<br />
|valign="top"|Return an object reference to the Editor<br />
|style="background: green"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|Fullscreen<br />
|valign="top"|W<br />
|valign="top"|Boolean (Int)<br />
|valign="top"|Set / unset main window to fullscreen<br />
|style="text-align: center;background: lightgreen"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|leftsidebarvisible<br />
|valign="top"|W<br />
|valign="top"|Boolean<br />
|valign="top"|Set / unset Left SideBar visibility<br />
|style="background: green"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|Libdir<br />
|valign="top"|R<br />
|valign="top"|Character<br />
|valign="top"|Full path of the current library directory<br />
|style="text-align: center;background: lightgreen"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|LockScreen<br />
|valign="top"|W<br />
|valign="top"|Boolean<br />
|valign="top"|Lock screen, disabling screen updates<br />
|style="text-align: center;background: lightgreen"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|localStorage<br />
|valign="top"|R<br />
|valign="top"|Object<br />
|valign="top"|Return an object reference to the currently active [[LocalStorage]]<br />
|style="background: green"|&nbsp;<br />
|style="background: green"|&nbsp;<br />
|style="background: green"|&nbsp;<br />
|-<br />
|valign="top"|Maximized<br />
|valign="top"|W<br />
|valign="top"|Boolean (Int)<br />
|valign="top"|Set / unset main window to maximized<br />
|style="text-align: center;background: lightgreen"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|Minimized<br />
|valign="top"|W<br />
|valign="top"|Boolean (Int)<br />
|valign="top"|Set / unset main window to minimized<br />
|style="text-align: center;background: lightgreen"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|ProgressLabel<br />
|valign="top"|W<br />
|valign="top"|Character<br />
|valign="top"|Progress bar text label<br />
|style="text-align: center;background: lightgreen"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|ProgressMaximum<br />
|valign="top"|W<br />
|valign="top"|Int<br />
|valign="top"|Progress bar maximum value<br />
|style="text-align: center;background: lightgreen"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|ProgressMinimum<br />
|valign="top"|W<br />
|valign="top"|Int<br />
|valign="top"|Progress bar minimum value<br />
|style="text-align: center;background: lightgreen"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|ProgressValue<br />
|valign="top"|W<br />
|valign="top"|Int<br />
|valign="top"|Set progress bar to the specified value<br />
|style="text-align: center;background: lightgreen"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|rightsidebarvisible<br />
|valign="top"|W<br />
|valign="top"|Boolean<br />
|valign="top"|Set / unset Right SideBar visibility<br />
|style="background: green"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|sessionStorage<br />
|valign="top"|R<br />
|valign="top"|Object<br />
|valign="top"|Return an object reference to the currently active [[SessionStorage]]<br />
|style="background: green"|&nbsp;<br />
|style="background: green"|&nbsp;<br />
|style="background: green"|&nbsp;<br />
|-<br />
|valign="top"|standalone<br />
|valign="top"|R<br />
|valign="top"|Boolean<br />
|valign="top"|Whether the App is running as a [[Standalone Executables on Windows|standalone App]]. From v9.5.<br />
|style="background: green"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|standalonefilepath<br />
|valign="top"|R<br />
|valign="top"|Character<br />
|valign="top"|Returns the filepath when the App is running as a [[Standalone Executables on Windows|standalone App]]. From v9.5.<br />
|style="background: green"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|table<br />
|valign="top"|R<br />
|valign="top"|Character<br />
|Currently active table<br />
|style="background: green"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|Theme<br />
|valign="top"|RW<br />
|valign="top"|Character<br />
|valign="top"|Set/Get the current App theme<br />
|style="text-align: center;background: lightgreen"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|UIState<br />
|valign="top"|R<br />
|valign="top"|Character<br />
|valign="top"|The last [[UI States|UI State]] applied.<br />
|style="background: green"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|valign="top"|version<br />
|valign="top"|R<br />
|valign="top"|Character<br />
|valign="top"|Software version<br />
|style="background: green"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|style="background: red"|&nbsp;<br />
|-<br />
|}<br />
<br />
====Methods====<br />
[[Lianja Methods|Click here for Lianja Methods]]<br />
<br />
====Key====<br />
{| class="wikitable" width=100%<br />
|style="background: green"|&nbsp;<br />
| Supported on this client.<br>Note that for the web/mobile client, this applies to client-side code. The Lianja system object is not available in server-side functions and procedures.<br />
|-<br />
|style="text-align: center;background: lightgreen"|&nbsp;<br />
| Supported in Lianja/VFP scripting only on this client.<br>&nbsp;<br />
|-<br />
|style="background: red"|&nbsp;<br />
| Not currently supported on this client.<br>&nbsp;<br />
|-<br />
|}<br />
<br />
<br />
[[Category:Documentation]]<br />
[[Category:Framework Classes]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-20T09:52:59Z<p>Yvonne.milne: /* Building Standalone Executables */</p>
<hr />
<div>=See Also=<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
=Overview=<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja visually build forms] in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
=Sample App: example_timeclock=<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
[[{{ns:file}}:standalone_uipres.png|left|link={{filepath:standalone_uipres.png}}|UI Presentation Rules and Standalone Options]]<br />
<br clear=all><br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will include a copy of the library folder in the executable's directory. When the standalone app is run the library directory is set to the standalone App library directory.<br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will create an installer as a self-extracting exe file for the standalone App. This can be unzipped / installed on a target machine.<br />
<br />
==Standalone Data==<br />
From v9.5, specifying a list of databases in the 'Standalone Data' setting ([[#Standalone|in 'Standalone Options' shown in the screenshot above]]) will copy the databases into the standalone App directory. When the standalone app is run the data directory is set to the standalone App data directory.<br />
<br />
==Setup==<br />
From v9.5, if the file setup.prg /.dbo is contained within the App it is executed before the standalone App is executed. You can check to see if the App is running standalone using [[Lianja|Lianja.standalone]] and check the file path using [[Lianja|Lianja.standalonefilepath]].<br />
<br />
You would typically do nothing in setup if the App is not running standalone.<br />
<br />
<code lang="recital"><br />
if not Lianja.standalone<br />
return<br />
endif<br />
<br />
// e.g. to share data on a network <br />
set datadir to f:\lianja\data<br />
</code><br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
=Building and Testing Standalone Executables=<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar:<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Deploying Standalone Executables==<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/File:Standalone_uipres.pngFile:Standalone uipres.png2024-03-20T09:45:11Z<p>Yvonne.milne: Yvonne.milne uploaded a new version of &quot;File:Standalone uipres.png&quot;</p>
<hr />
<div>Standalone Executables on Windows</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-20T09:07:24Z<p>Yvonne.milne: /* Setup */</p>
<hr />
<div>=See Also=<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
=Overview=<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja visually build forms] in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
=Sample App: example_timeclock=<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting will include a copy of the library folder in the executable's directory. When the standalone app is run the library directory is set to the standalone App library directory.<br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting will create an installer as a self-extracting exe file for the standalone App. This can be unzipped/ installed on a target machine.<br />
<br />
==Standalone Data==<br />
From v9.5, specifying a list of databases in the 'Standalone Data' setting will copy the databases into the standalone App directory. When the standalone app is run the data directory is set to the standalone App data directory.<br />
<br />
==Setup==<br />
From v9.5, if the file setup.prg/.dbo is contained within the App it is executed before the standalone App is executed. You can check to see if the App is running standalone using Lianja.standalone and check the file path using Lianja.standalonefilepath.<br />
<br />
You would typically do nothing in setup if the App is not running standalone.<br />
<br />
<code lang="recital"><br />
if not Lianja.standalone<br />
return<br />
endif<br />
<br />
// e.g. to share data on a network <br />
set datadir to f:\lianja\data<br />
</code><br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
=Building and Testing Standalone Executables=<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar:<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Deploying Standalone Executables==<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/App_SettingsApp Settings2024-03-19T16:46:15Z<p>Yvonne.milne: /* UI Presentation Rules */</p>
<hr />
<div>==Overview==<br />
Click the '''Settings''' icon in the ModeBar to open up the App Settings dialog. Select a setting category from the pulldown and/or use the scrollbar to browse the settings. With the settings grid selected, type a letter to jump to the first setting that starts with that letter. Typing the same letter again will move to the next setting starting with that letter.<br />
<br />
When you have finished editing the settings, click '''Done''' to save the changes and close the dialog or '''Cancel''' to close the dialog without saving.<br />
<br />
[[{{ns:file}}:open_app_settings.png|800px|border|left|link={{filepath:open_app_settings.png}}|Open App Settings]]<br />
<br clear=all><br />
<br />
Note: App Settings are selected in the [[Attributes]] tab when the [[App Inspector]] is open.<br />
<br />
[[{{ns:file}}:l5_settings.png|800px|border|left|link={{filepath:l5_settings.png}}|Select App Settings in App Inspector]]<br />
<br clear=all><br />
<br />
==Getting and Setting Attributes Programatically==<br />
The Lianja system object has desktop methods allowing App Settings to be queried and set programmatically:<br />
<br />
<pre>Lianja.getAttr(name)</pre><br />
<br />
<pre>Lianja.setAttr(name,value)</pre><br />
<br />
e.g.<br />
<br />
<code lang="recital"><br />
lIsPublished = Lianja.getAttr("apppublished")<br />
Lianja.setAttr("apppublished","true")<br />
</code><br />
<br />
See [[Custom Builders]] for details on intercepting the new App operation to allow it to be handled programmatically and for developer customizations to be applied.<br />
<br />
==General==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[General Settings#App Doc|App Doc]]||App Doc file. This html file will be included at the beginning of the [[App Doc]] when it is generated.<br />
|valign="top"|appdoc||valign="top"|Character<br />
|-<br />
|valign="top"|[[General Settings#Keep attribute versions|Keep attribute versions]]||Keep attribute versions in appname_appdoc.txt for diff comparison when the App is saved. From v6.3.<br />
|valign="top"|keepappdocversions||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Build mode|Build mode]]||The type of build for Web/Mobile Apps. Use Debug when testing and Release when deploying (Debug &#124; Release).<br />
|valign="top"|appbuildtype||valign="top"|Character<br />
|-<br />
|valign="top"|[[General Settings#Published|Published]]||App is published in the App Center (True &#124; False).<br />
|valign="top"|apppublished||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Use_wizards.2Fbuilders|Use wizards/builders]]||Use wizards/builders during development (True &#124; False).<br />
|valign="top"|usewizards||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Check for updates|Check for updates]]||Check for Lianja App Builder updates at startup (True &#124; False). From v5.2.<br />
|valign="top"|checkforupdates||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Event tracking|Event tracking]]||Trace App events in Web/Mobile Apps (True &#124; False). This is only effective in Debug mode.<br />
|valign="top"|appeventtracking||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Turn Password on|Turn Password on]]||Enter password when starting Lianja (True &#124; False).<br />
|valign="top"|&nbsp;||valign="top"|<br />
|-<br />
|valign="top"|[[General Settings#Password|Password]]||Password value.<br />
|valign="top"|&nbsp;||valign="top"|<br />
|-<br />
|valign="top"|[[General Settings#Confirm Password|Confirm Password]]||Confirm password value.<br />
|valign="top"|&nbsp;||valign="top"|<br />
|-<br />
|valign="top"|[[General Settings#Restore previous session on startup|Restore previous session on startup]]||valign="top"|Restore the previous session on startup. If checked, then the last App and editor files are reopened (True &#124; False).<br />
|valign="top"|&nbsp;||valign="top"|<br />
|-<br />
|valign="top"|[[General Settings#Login required|Login required]]||Authentication required to run App (True &#124; False).<br />
|valign="top"|apploginrequired||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Enable guest access|Enable guest access]]||Enable this App to be run as a guest without App Center login (True &#124; False).<br />
|valign="top"|appenableexternal||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Enable offline data|Enable offline data]]||Reserved for future use (True &#124; False).<br />
|valign="top"|appenableofflinedata||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Offline tables|Offline tables]]||Reserved for future use.<br />
|valign="top"|appofflinetables||valign="top"|Character<br />
|-<br />
|valign="top"|[[General Settings#Page libraries|Page libraries]]||The page libraries for this App. Comma-separate the filenames to specify more than one. From v9.1.4.<br />
|valign="top"|pagelibs||valign="top"|Character<br />
|-<br />
|valign="top"|[[General Settings#Database switcher list|Database switcher list]]||Comma separated list of databases that can be switched to.<br>From v6.3.<br />
|valign="top"|appdatabaseswitcherlist||valign="top"|Character<br />
|-<br />
|valign="top"|[[General Settings#Timelines Enabled|Timelines Enabled]]||Enable database timelines for sections that have timelines enabled (True &#124; False).<br />
|valign="top"|timelinesenabled||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Ask Before Deleting|Ask Before Deleting]]||Ask before deleting a record (True &#124; False).<br />
|valign="top"|confirmdeleterecord||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Add Form Section|Add Form Section]]||Always add a form section when creating a new blank page (True &#124; False).<br />
|valign="top"|addblankformsection||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Table information|Table information]]||Query for Table information in the data trees when an App is opened or a database is opened in the Data workspace<br>(True &#124; False).<br />
|valign="top"|&nbsp;||valign="top"|<br />
|-<br />
|valign="top"|[[General Settings#Deferred load|Deferred load]]||When this is checked all pages will be loaded with data only when they are first activated (speeds up App load time).<br>(True &#124; False).<br />
|valign="top"|deferredload||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General Settings#Help provider homepage URL|Help provider homepage URL]]||Context sensitive help provider URL to use when editing.<br />
|valign="top"|helpproviderurl||valign="top"|Character<br />
|-<br />
|valign="top"|[[General Settings#Help provider search URL|Help provider search URL]]||Context sensitive help provider search URL to use when editing. Use {keyword} for item to search for.<br />
|valign="top"|helpprovidersearchurl||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==CSS theming==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[CSS#Client_Specific_UI_Theming|Desktop CSS style]]||Specify the global Desktop App CSS style for UI theming.<br>From v6.3.<br />
|valign="top"|cssstyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[CSS#Client_Specific_UI_Theming|Web CSS style]]||Specify the global Web App CSS style for UI theming. From v6.3.<br />
|valign="top"|cssstyle_web||Character<br />
|-<br />
|valign="top"|[[CSS#Client_Specific_UI_Theming|Tablet CSS style]]||Specify the global Tablet App CSS style for UI theming. From v6.3.<br />
|valign="top"|cssstyle_tablet||valign="top"|Character<br />
|-<br />
|valign="top"|[[CSS#Client_Specific_UI_Theming|Phone CSS style]]||Specify the global Phone App CSS style for UI theming. From v6.3.<br />
|valign="top"|cssstyle_phone||Character<br />
|-<br />
|}<br />
<br />
==Editor==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Editor Settings#Use External Editor|Use External Editor]]||Use External Editor for editing (True &#124; False).<br />
|valign="top"|useexternaleditor||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#External Editor|External Editor]]||The External Editor for editing.<br />
|valign="top"|externaleditor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Editor Settings#External Editor Extensions|External Editor Extensions]]||A comma separated list of file extensions that will be edited externally.<br />
|valign="top"|externaleditorextensions||valign="top"|Character<br />
|-<br />
|valign="top"|[[Editor Settings#Activate Completion|Activate Completion]]||Activate statement completion (Always &#124; Manually &#124; Never).<br />
|valign="top"|activatecompletion||valign="top"|Character<br />
|-<br />
|valign="top"|[[Editor Settings#Activate completion timeout|Activate completion timeout]]||Activate statement completion timeout.<br />
|valign="top"|activatecompletiontimeout||valign="top"|Int<br />
|-<br />
|valign="top"|[[Editor Settings#Enable Intellitips|Enable Intellitips]]||Enable Intellitips (True &#124; False).<br />
|valign="top"|enableintellitips||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Enable code snippets|Enable code snippets]]||Enable code snippets (True &#124; False).<br />
|valign="top"|enablecodesnippets||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Enable command syntax hints|Enable command syntax hints]]||Enable command syntax hints (True &#124; False).<br />
|valign="top"|enablesyntaxhints||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Enable function parameter hints|Enable function parameter hints]]||Enable function parameter hints (True &#124; False).<br />
|valign="top"|enableparameterhints||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Enable command parameter hints|Enable command parameter hints]]||valign="top"|Enable command window parameter hints (True &#124; False).<br />
|valign="top"|enableparametercommandhints||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Insert matching characters|Insert matching characters]]||Automatically insert matching characters (True &#124; False).<br />
|valign="top"|automaticallyaddmatchingcharacters||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Enable code folding|Enable code folding]]||Enable code folding (True &#124; False).<br />
|valign="top"|enablecodefolding||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Enable word highlighting|Enable word highlighting]]||Enable highlighting of words in file as typed (True &#124; False).<br />
|valign="top"|enablehighlightwords||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Enable smart indenting|Enable smart indenting]]||Enable smart indenting of code blocks (True &#124; False).<br />
|valign="top"|smartindent||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Enable object naming conventions|Enable object naming conventions]]||Enable object naming conventions to display property/method pick lists based on identifier prefixes (True &#124; False).<br />
|valign="top"|objectnamingconventions||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Refresh advanced panel|Refresh advanced panel]]||Always refresh the editor advanced panel when a file is edited<br>(True &#124; False).<br />
|valign="top"|refresheditoradvanced||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Fast syntax highlighting|Fast syntax highlighting]]||Fast syntax highlighting (True &#124; False).<br>Set to True by default. The syntax highlighter for LianjaScript is much more responsive in the [[Troubleshooter_Debugger_Tab|debugger]] when opening large files.<br>(From v9.5).<br />
|valign="top"|minimalsyntaxhighlighting||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#Theme|Theme]]||The editor theme (Default &#124; Visual Studio Dark &#124; Visual Studio Light &#124; Eclipse &#124; Dreamweaver).<br />
|valign="top"|editortheme||valign="top"|Character<br />
|-<br />
|valign="top"|[[Editor Settings#Show Doc|Show Doc]]||Show the editor Doc when editing (True &#124; False).<br />
|valign="top"|editorhelp||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Editor Settings#App files search path|App files search path]]||A semi-colon (;) separated list of directories to search and refresh in the editor advanced panel when an App file is edited. (From v5.0).<br />
|valign="top"|appeditorsearchpath||valign="top"|Character<br />
|-<br />
|valign="top"|[[Editor Settings#Library files search path|Library files search path]]||A semi-colon (;) separated list of directories to search and refresh in the editor advanced panel when a Library file is edited. (From v5.0).<br />
|valign="top"|libeditorsearchpath||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Embedded HTTP Server==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Embedded_HTTP_Server#Listen_on|Listen on]]||The interface the HTTP server should listen for requests on<br />
|valign="top"|httpnodename||Character<br />
|-<br />
|valign="top"|[[Embedded_HTTP_Server#Port|Port]]||The port that the embedded HTTP server uses<br />
|valign="top"|httpport||Character<br />
|-<br />
|valign="top"|[[Embedded_HTTP_Server#Runtime_Port|Runtime Port]]||The port that the embedded HTTP server uses at runtime<br>(App Center).<br />
|valign="top"|runtimehttpport||valign="top"|Character<br />
|-<br />
|valign="top"|[[Embedded_HTTP_Server#API_key|API key]]||The API key that should be specified to invoke desktop web services.<br />
|valign="top"|httpapikey||Character<br />
|-<br />
|valign="top"|[[Embedded_HTTP_Server#Enable_services|Enable services]]||Enable embedded web services (True &#124; False)<br />
|valign="top"|httpenableservices||Boolean<br />
|-<br />
|}<br />
<br />
==Sessionstorage==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[SessionStorage in Lianja|Sessionstorage size]]||The size of the shared sessionstorage<br />
|valign="top"|sessionstoragesize||valign="top"|Int<br />
|-<br />
|valign="top"|[[SessionStorage in Lianja|Session data changed]]||The delegate procedure for the session data changed event<br />
|valign="top"|sessiondatachangedaction||Character<br />
|-<br />
|valign="top"|[[SessionStorage in Lianja|Session data changed interval]]||valign="top"|The interval in msecs that checks for session data changes will be made at runtime<br />
|valign="top"|sessiondatachangedinterval||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==Directories==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Directories Settings#Data directory|Data directory]]||The database directory where your databases are located.<br />
|valign="top"|datadir||valign="top"|Character<br />
|-<br />
|valign="top"|[[Directories Settings#Apps directory|Apps directory]]||The apps directory where your apps are located.<br />
|valign="top"|appsdir||valign="top"|Character<br />
|-<br />
|valign="top"|[[Directories Settings#Library directory|Library directory]]||The library directory where your libraries are located.<br />
|valign="top"|libdir||valign="top"|Character<br />
|-<br />
|valign="top"|[[Directories Settings#Templates directory|Templates directory]]||The template directory where your templates are located.<br />
|valign="top"|templatesdir||valign="top"|Character<br />
|-<br />
|valign="top"|[[Directories Settings#Deployment directory|Deployment directory]]||The deployment directory. This should contain apps, data and library sub-directories. It can be on a network drive to provide shared App and Data access.<br />
|valign="top"|runtimerootdir||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Deployment==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[A Guide to Deploying Web Apps|Publisher]]||The way to publish the Apps (Copy &#124; SFTP &#124; Custom).<br />
|valign="top"|apppublisher||valign="top"|Character<br />
|-<br />
|valign="top"|[[A Guide to Deploying Web Apps|Publisher path]]||The optional full path of the publisher program, e.g. /usr/bin/rsync.<br />
|valign="top"|apppublisherpath||valign="top"|Character<br />
|-<br />
|valign="top"|[[A Guide to Deploying Web Apps|Publisher arguments]]||The optional arguments to the publisher program, e.g. -avc for rsync.<br />
|valign="top"|apppublisherarguments||valign="top"|Character<br />
|-<br />
|valign="top"|[[A Guide to Deploying Web Apps|Server]]||The server IP address or nodename where the App will be deployed, e.g. localhost or myserver.mydomain.com.<br />
|valign="top"|apppublisherserver||valign="top"|Character<br />
|-<br />
|valign="top"|[[A Guide to Deploying Web Apps|Directory]]||The root lianja directory on the LAN or server where the Apps will be deployed.<br />
|valign="top"|apppublisherdirectory||valign="top"|Character<br />
|-<br />
|valign="top"|[[Packaging Lianja Desktop Apps for Windows|Build an installer]]||Build an installer for Windows desktop deployment (True &#124; False).<br />
|valign="top"|&nbsp;||valign="top"|<br />
|-<br />
|valign="top"|[[A Guide to Deploying Web Apps|Username]]||The optional username to authenticate with the remote server.<br />
|valign="top"|apppublisherusername||valign="top"|Character<br />
|-<br />
|valign="top"|[[A Guide to Deploying Web Apps|Password]]||The optional password to authenticate with the remote server.<br />
|valign="top"|apppublisherpassword||valign="top"|Character<br />
|-<br />
|valign="top"|[[A Guide to Deploying Web Apps|Private key (.pem file)]]||The (optional) private key (.pem file) to authenticate with the remote server.<br />
|valign="top"|apppublisherpemfile||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==App Center Tile==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Author]]||The App author displayed in the App Center.<br />
|valign="top"|appauthor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Category]]||The category for the App displayed in the App Center.<br />
|valign="top"|appsidebarcategory||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Version]]||The version for the App displayed in the App Center.<br />
|valign="top"|appversion||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Caption]]||The caption for the App displayed in the App Center.<br />
|valign="top"|appsidebarcaption||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Icon]]||The icon for the App displayed in the App Center.<br />
|valign="top"|appsidebaricon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Description]]||The description for the App displayed in the App Center.<br />
|valign="top"|appdescription||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Background color]]||The background color for the App displayed in the App Center.<br />
|valign="top"|apptilebackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Tile size]]||The size of the tile in the App Center.<br />
|valign="top"|apptilesize||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Dynamic contents]]||The tile in the App Center contains dynamic contents only (True &#124; False).<br />
|valign="top"|apptiledynamiccontents||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Tile order]]||The category position for the tile in the App Center.<br />
|valign="top"|apptileorder||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Tile URL]]||The URL to invoke when this tile is clicked at runtime.<br />
|valign="top"|apptileurl||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Dynamic tile producer]]||The dynamic tile producer used to update the dynamic tile in the App Center. This can be a procedure or a URL.<br />
|valign="top"|timeraction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Dynamic tile timer interval]]||The timer interval in seconds to update the dynamic tile in the App Center.<br />
|valign="top"|timerinterval||valign="top"|Int<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Dynamic badge producer]]||The dynamic badge producer used to update the dynamic badge in the tile in the App Center. This can be a procedure or a URL.<br />
|valign="top"|countertimeraction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Lianja App Center Tiles|Dynamic badge timer interval]]||The timer interval in seconds to update the dynamic badge in the tile in the App Center.<br />
|valign="top"|countertimerinterval||valign="top"|Int<br />
|-<br />
|}<br />
<br />
==General App Configuration==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Window Title|Window Title]]||The window title for this App.<br />
|valign="top"|apptitle||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Window Width|Window Width]]||The window width for this App.<br />
|valign="top"|appwidth||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Window Height|Window Height]]||The window height for this App.<br />
|valign="top"|appheight||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Maximize Window|Maximize Window]]||Maximize the window for this App (True &#124; False).<br />
|valign="top"|appmaximize||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Window Resizable|Window Resizable]]||Allow the user to resize the App window (True &#124; False).<br />
|valign="top"|appresizable||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Hide Header Bar|Hide Header Bar]]||Hide header bar at runtime (True &#124; False).<br />
|valign="top"|hideheaderbar||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Page_Menu#Show_navigation_history|Show navigation history]]||Show pages navigation history buttons in page header.<br />
|valign="top"|showbackbutton||valign="top"|Character<br />
|-<br />
|valign="top"|[[Page_Menu#Show_navigation_menu|Show navigation menu]]||Show pages navigation menu in page header (True &#124; False).<br />
|valign="top"|showpagesmenu||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Page_Menu#Show_Page_Center|Show Page Center]]||Show Page Center when navigation menu clicked (True &#124; False).<br />
|valign="top"|showpagecenter||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Disable VT requery when parentdatachanged|Disable VT requery when parentdatachanged]]||This will handle legacy VT usage prior to Lianja 6.3 (True &#124; False). From v6.3.<br />
|valign="top"|vtparentrequerydisabled||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Navigation menu caption|Navigation menu caption]]||Navigation menu caption text in the page header.<br />
|valign="top"|pagesmenucaption||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Hide header icons|Hide header icons]]||Hide the header icons in the page header bars (True &#124; False).<br />
|valign="top"|hideheadericons||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Desktop theme|Desktop theme]]||Desktop theme for this App (Default &#124; Android &#124; iOS &#124; Modern &#124; Modern2 &#124; ... (read from themes directory).<br />
|valign="top"|theme||valign="top"|Character<br />
|-<br />
|valign="top"|[[Help Attributes#Help table|Help table]]||Context sensitive help table for this App.<br />
|valign="top"|helptable||valign="top"|Character<br />
|-<br />
|valign="top"|[[MetaTypes|Meta types file]]||The Meta types file for this App.<br />
|valign="top"|metatypestable||valign="top"|Character<br />
|-<br />
|valign="top"|[[MetaTypes|Meta types library]]||The Meta types library for this App.<br />
|valign="top"|metatypeslib||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual Components|Component library]]||The Component library for this App. Components that are generated are saved here. (From v5.0).<br />
|valign="top"|componentlib||valign="top"|Character<br />
|-<br />
|valign="top"|[[Visual Components|Components]]||The Components needed for this App. Separate each with a ';' to specify more than one, e.g.<br> example_component.name;example_component.*. (From v5.0).<br />
|valign="top"|components||valign="top"|Character<br />
|-<br />
|valign="top"|[[CSS|CSS libraries]]||The CSS libraries for this App. Separate each filename with a ; to specify more than one.<br />
|valign="top"|csslibs||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Additional file path|Additional file path]]||A semi-colon (;) separated list of additional path locations to search for App specific files.<br />
|valign="top"|addinspath||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Autoload libraries|Autoload libraries]]||If True, then libraries are auto loaded if a file of the same name as the directory exists in the additional file paths (True &#124; False).<br />
|valign="top"|addinsautoload||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[UI States#UI states table|UI states table]]||UI states table for this App.<br />
|valign="top"|uistatestable||valign="top"|Character<br />
|-<br />
|valign="top"|[[UI States#Initial UI state|Initial UI state]]||The initial UI state for this App. This will be applied to all pages, sections and fields/gadgets.<br />
|valign="top"|uistateinit||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Home page app|Home page app]]||The App to load when the Home icon is clicked.<br />
|valign="top"|homeapp||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Initial page|Initial page]]||The first page to view for this App at runtime.<br />
|valign="top"|firstpage||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#HTML editor|HTML editor]]||Choose the HTML editor to use in this App (Desktop &#124; Web &#124; Mobile).<br />
|valign="top"|htmleditor||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Runtime connection|Runtime connection]]||The connection string to use for 'local' virtual tables. This will be substituted when the App is deployed at runtime in the App Center or the Web/Mobile clients.<br />
|valign="top"|runtimeconnstr||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Runtime database|Runtime database]]||The database that will be substituted when the App is deployed at runtime in the App Center or the Web/Mobile clients.<br />
|valign="top"|runtimedatabase||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Include in HTML HEAD|Include in HTML HEAD]]||Include HTML file contents into the HTML5 Client.<br />
|valign="top"|includehtmlhead||valign="top"|Character<br />
|-<br />
|valign="top"|[[:Category:Progressive Web Apps|Enable as PWA]]||Enable as a Progressive Web App when generating web/mobile/tablet Apps.<br />
|valign="top"|pwa||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Automatic Language Translation#Enable user translate|Enable user translate]]||Enable user translation in web/mobile/tablet Apps. From v5.5.<br />
|valign="top"|enableusertranslation||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Automatic Language Translation#Enable text translator|Enable text translator]]||Enable text translation in web/mobile/tablet Apps. This enables dynamic language translation of captions in the UI. From v5.5.<br />
|valign="top"|enabletranslation||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Automatic Language Translation#Enable google translate|Enable google translate]]||Enable google translate in web/mobile/tablet Apps. This enables dynamic language translation of captions in the UI. From v5.5.<br />
|valign="top"|enablegoogletranslation||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Readonly fields backcolor|Readonly fields backcolor]]||The background color that readonly fields should be displayed in.<br />
|valign="top"|readonlybackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[CSS|App CSS style]]||Specify the global App CSS style for UI theming.<br />
|valign="top"|cssstyle||valign="top"|Character<br />
|-<br />
|valign="top"|[[General App Configuration Settings#Disable inline editing|Disable inline editing]]||Disable inline editing (True &#124; False).<br />
|valign="top"|disableinlineediting||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Console Workspace|Show PerfMeter in console]]||Show PerfMeter in the Console (True &#124; False).<br />
|valign="top"|consoleperfmeter||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Locale Configuration==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Locale Configuration Settings#Currency character|Currency character]]||The currency character to use for this App<br>(default $).<br />
|valign="top"|localecurrencycharacter||valign="top"|Character<br />
|-<br />
|valign="top"|[[Locale Configuration Settings#Separator character|Separator character]]||The separator character to use in number formatting for this App<br>(default ,).<br />
|valign="top"|localeseparatorcharacter||valign="top"|Character<br />
|-<br />
|valign="top"|[[Locale Configuration Settings#Point character|Point character]]||valign="top"|The point character to use in number formatting for this App<br>(default .).<br />
|valign="top"|localepointcharacter||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Web/Mobile App Configuration==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Browser|Browser]]||Browser to use for [[Deploying_to_Local_Directory#Preview_live_in_browser|Preview live in browser]]. From v9.1.5.<br />
|valign="top"|browser||valign="top"|Character<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Custom browser location|Custom browser location]]||Location of browser to use for [[Deploying_to_Local_Directory#Preview_live_in_browser|Preview live in browser]].<br>From v9.1.5.<br />
|valign="top"|custombrowser||valign="top"|Character<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Character encoding|Character encoding]]||Character encoding for Web/Mobile Apps<br>(utf-8 is recommended).<br />
|valign="top"|htmlencoding||valign="top"|Character<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Language locale|Language locale]]||Locale for Web/Mobile Apps (affects date picker and various captions).<br />
|valign="top"|htmllocale||valign="top"|Character<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Header icon type|Header icon type]]||Icon to be displayed in the page header bar in Web/Mobile<br>(Default &#124; Custom &#124; None).<br />
|valign="top"|webheadericon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Custom header icon|Custom header icon]]||Custom icon to be displayed in the page header bar in Web/Mobile.<br />
|valign="top"|customwebheadericon||valign="top"|Character<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Disable right click|Disable right click]]||Disable right click context menu in Web Apps (True &#124; False).<br />
|valign="top"|disablerightclick||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Disable success notifications|Disable success notifications]]||Disable success notifications in Web/Mobile apps<br>(True &#124; False). From v7.2.<br />
|valign="top"|disablesysmessages||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Enable animations|Enable animations]]||Enable animated section transitions in Web/Mobile Apps<br>(True &#124; False).<br />
|valign="top"|enableanimations||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Web Theme|Web Theme]]||Web theme for this App (Default &#124; AndroidBlackGreen &#124; AndroidBlackBlue &#124; AndroidBlackOrange &#124; AndroidBlackPurple &#124; AndroidBlackRed &#124; AndroidBlackWhite &#124; AndroidWhiteGreen &#124; AndroidWhiteBlue &#124; AndroidWhiteOrange &#124; AndroidWhitePurple &#124; AndroidWhiteRed &#124; iOS &#124; Modern).<br />
|valign="top"|webtheme||valign="top"|Character<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Mobile Theme|Mobile Theme]]||Mobile theme for this App (Default &#124; AndroidBlackGreen &#124; AndroidBlackBlue &#124; AndroidBlackOrange &#124; AndroidBlackPurple &#124; AndroidBlackRed &#124; AndroidBlackWhite &#124; AndroidWhiteGreen &#124; AndroidWhiteBlue &#124; AndroidWhiteOrange &#124; AndroidWhitePurple &#124; AndroidWhiteRed &#124; iOS &#124; Modern).<br />
|valign="top"|mobiletheme||valign="top"|Character<br />
|-<br />
|valign="top"|[[Web/Mobile App Configuration Settings#Mini navigation panel|Mini navigation panel]]||Always show mini (phone) navigation panel on tablets<br>(True &#124; False).<br />
|valign="top"|showmininavigationpanel||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Page defaults==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Page_Appearance#Navigation_bar_type|Navigation bar type]]||Choose the appearance of the data navigation bar to use in this App (Flat &#124; Gradient).<br />
|valign="top"|navbartype||valign="top"|Character<br />
|-<br />
|valign="top"|[[Page_Appearance#Hide_navigation_bar_slider|Hide navigation bar slider]]||Hide navigation bar slider (True &#124; False).<br />
|valign="top"|hideslider||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Page_Appearance#Navigation_bar_CSS|Navigation bar CSS]]||Custom navigation bar CSS.<br />
|valign="top"|navbarcss||valign="top"|Character<br />
|-<br />
|valign="top"|[[Page_Menu#Page_menu|Page menu]]||Choose the appearance of the page navigation menu to use in this App (Menu &#124; Panel).<br />
|valign="top"|pagemenutype||valign="top"|Character<br />
|-<br />
|valign="top"|[[Page_Menu#Page menu theme|Page menu theme]]||Choose the page meu theme to use in this App (Dark &#124; Light).<br>From v9.0.<br />
|valign="top"|pagemenutheme||valign="top"|Character<br />
|-<br />
|valign="top"|[[Page_Menu#Page_menu_row_height|Page menu row height]]||The row height for the page menu items in this App.<br />
|valign="top"|pagemenurowheight||valign="top"|Character<br />
|-<br />
|valign="top"|[[Page_Menu#Page_menu_CSS|Page menu CSS]]||CSS for the page menu in this App.<br />
|valign="top"|pagemenucss||valign="top"|Character<br />
|-<br />
|valign="top"|[[Page_Menu#Additional page menuitems|Additional page menuitems]]||Additional menuitems (that can call [[Using the showdocument() function and Lianja.showDocument() method|showdocument()]] actions) for the page menu in this App. From v5.3.<br />
|valign="top"|custompagesmenuitems||valign="top"|Character<br />
|-<br />
|valign="top"|[[Left Sidebar|Left sidebar visible]]||Show left sidebar (True &#124; False).<br />
|valign="top"|pagedefault_leftsidebarvisible||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Right Sidebar|Right sidebar visible]]||Show right sidebar (True &#124; False).<br />
|valign="top"|pagedefault_rightsidebarvisible||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Page Header#Hide search box|Hide search box]]||Hide the search box in the page header bar (True &#124; False).<br />
|valign="top"|pagedefault_hidesearchbox||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Page Header#Hide notifications icon|Hide notifications icon]]||Hide the notifications icon in the page header bar (True &#124; False).<br />
|valign="top"|pagedefault_hidenotificationsicon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Page Header#Hide custom search icon|Hide search icon]]||Hide the custom search icon in the page header bar (True &#124; False).<br />
|valign="top"|pagedefault_hidecustomsearchicon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Page Header#Hide fullscreen icon|Hide fullscreen icon]]||Hide the fullscreen icon in the page header bar (True &#124; False).<br />
|valign="top"|pagedefault_hidefullscreenicon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Page Header#Hide share icon|Hide share icon]]||Hide the share icon in the page header bar (True &#124; False).<br />
|valign="top"|pagedefault_hideshareicon||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Page Header#Hide home icon|Hide home icon]]||Hide the home icon in the page header bar (True &#124; False).<br />
|valign="top"|pagedefault_hidehomeicon||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==Section defaults==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Data Attributes#Inherit dictionary rules|Inherit dictionary rules]]||Inherit the data dictionary rules (True &#124; False)<br />
|valign="top"|pagesectioninheritdictionary||valign="top"|Boolean<br />
|-<br />
|valign="top"|[[Section_Header#App_Settings|Header type]]||Choose the appearance of the section headers to use in this App<br>(Flat &#124; Gradient).<br />
|valign="top"|pagesectionheadertype||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section_Header#App_Settings|Icon set]]||Choose the icon set to use for the section headers in this App<br>(Gradient &#124; Black &#124; White &#124; Blue &#124; Gray &#124; Darkgray).<br />
|valign="top"|pagesectionheadericonset||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section_Header#App_Settings|Header height]]||The header height for the section headers in this App.<br />
|valign="top"|pagesectionheaderheight||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section_Header#App_Settings|Header background color]]||The background color for the section headers in this App.<br />
|valign="top"|pagesectionheaderbackcolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section_Header#App_Settings|Header foreground color]]||The foreground color for the section headers in this App.<br />
|valign="top"|pagesectionheaderforecolor||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section_Header#App_Settings|Header font size]]||The font size for the section headers in this App.<br />
|valign="top"|pagesectionheaderfontsize||valign="top"|Character<br />
|-<br />
|valign="top"|[[Section_Header#App_Settings|Header CSS]]||The CSS for the section headers in this App.<br />
|valign="top"|pagesectionheadercss||valign="top"|Character<br />
|-<br />
|valign="top"|[[CSS|Section CSS]]||The CSS for the sections in this App.<br />
|valign="top"|pagesectioncss||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Delegates==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Custom Delegates#Scripting Language|Scripting language]]||The default scripting language for custom code in this App (Recital &#124; Visual FoxPro &#124; Python &#124; JavaScript &#124; TypeScript &#124; Babel &#124; PHP).<br />
|valign="top"|scriptinglanguage||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Custom Library|Custom library]]||The filename of the library containing code for event handlers and custom procedures/functions.<br />
|valign="top"|customlibrary||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Hotkey|Hotkey]]||The delegate procedure for the Hotkey event.<br />
|valign="top"|hotkeyaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Init|Init]]||The delegate procedure for the Init event.<br />
|valign="top"|initaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Destroy|Destroy]]||The delegate procedure for the Destroy event.<br />
|valign="top"|destroyaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Load|Load]]||The delegate procedure for the Load event.<br />
|valign="top"|loadaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Ready|Ready]]||The delegate procedure for the Ready event.<br />
|valign="top"|readyaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Unload|Unload]]||The delegate procedure for the Unload event.<br />
|valign="top"|unloadaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Database changed|Database changed]]||The delegate procedure for the Database changed event.<br>From v6.3.<br />
|valign="top"|databasechangedaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#State Changed|State Changed]]||The delegate procedure for the State Changed event.<br />
|valign="top"|statechangedaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Text Translator|Text Translator]]||The delegate procedure for translating text messages.<br />
|valign="top"|texttranslatoraction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#File System Watcher|File System Watcher]]||The delegate procedure for watching for changes to directories and/or files.<br />
|valign="top"|watchaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Orientation Changed|Orientation Changed]]||The delegate procedure for the Orientation Changed event.<br>From v6.0.<br />
|valign="top"|orientationchangedaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Device Motion Changed|Device Motion Changed]]||The delegate procedure for the Device Motion Changed event.<br>From v6.0.<br />
|valign="top"|devicemotionchangedaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Connection State Changed|Connection State Changed]]||The delegate procedure for the Connection State Changed event.<br>From v6.0.<br />
|valign="top"|connectionchangedaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Inactive|Inactive]]||The delegate procedure for the Inactive event.<br />
|valign="top"|inactiveaction||valign="top"|Character<br />
|-<br />
|valign="top"|[[Custom Delegates#Inactive interval|Inactive interval]]||The inactive interval in seconds that the inactive delegate procedure will be called at runtime.<br />
|valign="top"|inactiveinterval||valign="top"|Int<br />
|-<br />
|valign="top"|[[Custom Delegates#Before preview|Before preview]]||The delegate procedure for the before preview event.<br>From v6.3.<br />
|valign="top"|beforepreviewaction||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Permissions and Roles==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Users and Roles#Available roles|Available roles]]||A comma separated list of roles that are available for the App<br />
|valign="top"|permavailable||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Admin roles]]||A comma separated list of roles that can perform admin operations on the App<br />
|valign="top"|permadmin||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Create roles]]||A comma separated list of roles that can perform create operations on data in the App<br />
|valign="top"|permcreate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Read roles]]||A comma separated list of roles that can read (and execute) the App<br />
|valign="top"|permread||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Update roles]]||A comma separated list of roles that can perform update operations on data in the App<br />
|valign="top"|permupdate||valign="top"|Character<br />
|-<br />
|valign="top"|[[Users and Roles|Delete roles]]||A comma separated list of roles that can perform delete operations on data in the App<br />
|valign="top"|permdelete||valign="top"|Character<br />
|-<br />
|}<br />
<br />
==Standalone Options==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Standalone_Executables_on_Windows#Standalone_Lib|Standalone Lib]]||Include library files in the standalone App directory<br>(True &#124; False). From v9.5.<br />
|valign="top"|standalonelib||Boolean<br />
|-<br />
|valign="top"|[[Standalone_Executables_on_Windows#Standalone_Zip|Standalone Zip]]||Create a zip file for the standalone App<br>(True &#124; False). From v9.5.<br />
|valign="top"|standalonezip||Boolean<br />
|-<br />
|valign="top"|[[Standalone_Executables_on_Windows#Standalone_Exe|Standalone Exe]]||Create an installer as a self-extracting exe file for the standalone App<br>(True &#124; False). From v9.5.<br />
|valign="top"|standaloneexe||valign="top"|Boolean<br />
|-<br />
|}<br />
<br />
==UI Presentation Rules==<br />
{| class="wikitable" width="100%"<br />
!width="20%"|Attribute<br />
!width="40%"|Description<br />
!width="30%"|Name<br />
!width="10%"|Type<br />
|-<br />
|valign="top"|[[Standalone_Executables_on_Windows#Standalone|Standalone]]||Build this App as a Standalone app (True &#124; False).<br />
|valign="top"|standaloneui||Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Form|Form]]||Run this App as a Form (True &#124; False).<br />
|valign="top"|formui||Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Desktop|Desktop]]||Include this App in a Desktop client (True &#124; False).<br />
|valign="top"|desktopui||Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Web|Web]]||Include this App in a Web client (True &#124; False).<br />
|valign="top"|webui||Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Tablet|Tablet]]||Include this App in a Tablet client (True &#124; False).<br />
|valign="top"|mobileui||Boolean<br />
|-<br />
|valign="top"|[[UI Presentation Rules#Phone|Phone]]||Include this App in a Phone client (True &#124; False).<br />
|valign="top"|phoneui||Boolean<br />
|-<br />
|}<br />
<br />
[[Category:Attributes|1 App]]<br />
[[Category:App Settings]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-19T16:38:46Z<p>Yvonne.milne: </p>
<hr />
<div>=See Also=<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
=Overview=<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also visually build forms in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
=Sample App: example_timeclock=<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting will include a copy of the library folder in the executable's directory. <br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting will create an installer as a self-extracting exe file for the standalone App.<br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
=Building and Testing Standalone Executables=<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar:<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Deploying Standalone Executables==<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-19T16:35:50Z<p>Yvonne.milne: /* Building Standalone Executables */</p>
<hr />
<div>==See Also==<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
==Overview==<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also visually build forms in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
==Sample App: example_timeclock==<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
=Building Standalone Executables=<br />
==Scripting Language==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
==Standalone==<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|UI Presentation Rules App Settings]].<br />
<br />
==Standalone Lib==<br />
From v9.5, checking the 'Standalone Lib' setting will include a copy of the library folder in the executable's directory. <br />
<br />
==Standalone Zip==<br />
From v9.5, checking the 'Standalone Zip' setting will create a zip file for the standalone App.<br />
<br />
==Standalone Exe==<br />
From v9.5, checking the 'Standalone Exe' setting will create an installer as a self-extracting exe file for the standalone App.<br />
<br />
==Script==<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
==Building Standalone Executables==<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar:<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Deploying Standalone Executables==<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]</div>Yvonne.milnehttps://www.lianja.com/doc/index.php/Standalone_Executables_on_WindowsStandalone Executables on Windows2024-03-13T16:38:29Z<p>Yvonne.milne: /* Building Standalone Executables */</p>
<hr />
<div>==See Also==<br />
[[:Category:Deployment|Deployment]], [[Lianja Package Manager]], [[Packaging Lianja Desktop Apps for Windows]]<br />
<br />
==Overview==<br />
From Lianja 7.0 developers can build standalone executables on Windows.<br />
<br />
These executables can only be built for Apps that have been hand-coded in LianjaScript, Python, JavaScript, TypeScript or Babel using the [[:Category:Framework_Classes|Lianja UI Framework]].<br />
<br />
Alternatively, you can also visually build forms in the App Builder that use any of the following scripting languages as the Lianja UI framework is scripting language independent across Desktop, Web and Mobile Apps.<br />
<br />
- LianjaScript/VFP<br />
<br />
- Python<br />
<br />
- JavaScript<br />
<br />
- Typescript<br />
<br />
Forms are based on a '''tabview''' section which contains canvas, grid or webview based sections in its tabs. See the blog article [https://www.lianja.com/community/entry.php?27-HOWTO-Working-with-forms-in-Lianja Working with forms in Lianja] for further details.<br />
<br />
This functionality is primarily for building small GUI Apps, not for business Apps running under the Lianja App Center with [[Users and Roles]].<br />
<br />
==Sample App: example_timeclock==<br />
The example_timeclock sample App is included in the Lianja App Builder distribution from v7.0.0 in the 'General' category.<br />
<br />
This app uses the new [[Camera]] [[:Category:Framework Classes|UI Framework]] class and is a small App to handle clocking in and out of employees in a company.<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock.png|left|link={{filepath:standalone_exampletimeclock.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
Feel free to enhance this to suit your own needs by adding support for storing the clock in/out date and time along with the employees photo.<br />
<br />
==Building Standalone Executables==<br />
Select the scripting language in the [[App_Settings#Delegates|App Settings]]:<br />
<br />
[[{{ns:file}}:standalone_scriptlang.png|left|link={{filepath:standalone_scriptlang.png}}|Scripting Language]]<br />
<br clear=all><br />
<br />
Check 'Standalone' in the [[App_Settings#UI_Presentation_Rules|App Settings]]:<br />
<br />
Note that from v9.5, checking the 'StandaloneLib' setting will include a copy of the library folder in the executable's directory. <br />
<br />
[[{{ns:file}}:standalone_uipres.png|left|link={{filepath:standalone_uipres.png}}|Standalone]]<br />
<br clear=all><br />
<br />
Then write the 'main' script with the same name as the App. In the case of the sample example_timeclock App, this is example_timeclock.prg or example_timeclock.js or example_timeclock.py (see code below). You can switch the 'Scripting language' in the [[App_Settings#Delegates|App Settings]] to test each one.<br />
<br />
===LianjaScript/Visual FoxPro===<br />
Note the READ EVENTS at the end of the code which is needed for a standalone App.<br />
<br />
====example_timeclock.prg====<br />
<br />
<code lang="recital"><br />
local oform = createObject("Form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - LianjaScript"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera")<br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "commandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "commandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
// event handlers<br />
proc clockin()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked in on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
proc clockout()<br />
ocamera.takePhoto()<br />
thisform.showSuccessMessage("You clocked out on " + dtoc(date()) + " at " + ampm())<br />
endproc<br />
<br />
obtn1.click = clockin<br />
obtn2.click = clockout<br />
<br />
// modal form<br />
oform.show()<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read events<br />
</code><br />
<br />
===Python===<br />
<br />
* Check that pip is the latest version. From a Windows Command Prompt (replace drive: with the drive for your Lianja App Builder installation):<br />
<pre>cd drive:\lianja\bin<br />
python -m pip install --upgrade pip --no-warn-script-location</pre><br />
<br />
* In the Lianja App Builder [[:Console Workspace|Console Workspace]], create the python3 directory to contain the modules local to the App (this has already been created for the example_timeclock App):<br />
<pre>mkdir python3</pre><br />
<br />
* Install local Python modules (pip can be run from the Lianja/VFP tab in the [[:Console Workspace|Console Workspace]] Command Window), e.g. numpy:<br />
<br />
<pre>pip install --target=drive:\lianja\apps\example_timeclock\python3\ numpy</pre><br />
<br />
Note: the local installation of the Python modules causes these modules to be included when the standalone executable is generated. During App development, any required modules also need to be installed in the default location for Lianja, i.e. without a --target specified.<br />
<br />
To check modules installed in the default location:<br />
<br />
<pre>pip list</pre><br />
<br />
To check the Python path (from the Python tab):<br />
<br />
<pre>import sys</pre><br />
<pre>print(sys.path)</pre> <br />
<br />
====example_timeclock.py====<br />
<code lang="python"><br />
import sys<br />
import types<br />
from datetime import datetime<br />
import Lianja<br />
<br />
class myCommandbutton(Lianja.Commandbutton):<br />
pass<br />
<br />
oform = createObject("form")<br />
oform.resize(600, 600)<br />
oform.closable = 1<br />
oform.caption = "Time clock - Python"<br />
oform.minwidth = 600<br />
oform.minheight = 600<br />
<br />
oform.addObject("ocont", "container")<br />
ocont.margin = 10<br />
ocont.autosize = 1<br />
ocont.layout = "V"<br />
ocont.backcolor = "black"<br />
<br />
ocont.addObject("obadgenolab", "label")<br />
obadgenolab.fixedheight = 24<br />
obadgenolab.autowidth = 1<br />
obadgenolab.alignment = "center"<br />
obadgenolab.caption = "Enter Badge Number"<br />
obadgenolab.backcolor = "darkgray"<br />
obadgenolab.forecolor = "white"<br />
obadgenolab.fontbold = 1<br />
obadgenolab.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgeno", "textbox")<br />
obadgeno.fixedheight = 24<br />
obadgeno.autowidth = 1<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab2", "label")<br />
obadgenolab2.fixedheight = 24<br />
obadgenolab2.autowidth = 1<br />
obadgenolab2.alignment = "center"<br />
obadgenolab2.caption = "Take a Photo"<br />
obadgenolab2.backcolor = "darkgray"<br />
obadgenolab2.forecolor = "white"<br />
obadgenolab2.fontbold = 1<br />
obadgenolab2.fontsize = 10<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("ocamera", "camera") <br />
ocamera.autowidth = 1<br />
ocamera.autoheight = 1<br />
ocamera.backcolor = "black"<br />
<br />
ocont.addspacing(10)<br />
ocont.addObject("obadgenolab3", "label")<br />
obadgenolab3.fixedheight = 24<br />
obadgenolab3.autowidth = 1<br />
obadgenolab3.alignment = "center"<br />
obadgenolab3.caption = "Clock in / Clock out"<br />
obadgenolab3.backcolor = "darkgray"<br />
obadgenolab3.forecolor = "white"<br />
obadgenolab3.fontbold = 1<br />
obadgenolab3.fontsize = 10<br />
<br />
ocont.addObject("ocont2", "container")<br />
ocont2.layout = "H"<br />
ocont2.fixedheight = 60<br />
ocont2.backcolor = "black"<br />
ocont2.spacing = 10<br />
<br />
ocont2.addObject("obtn1", "myCommandbutton") <br />
obtn1.resize(60, 50)<br />
obtn1.flat = 1<br />
obtn1.fixedheight = 50<br />
obtn1.caption = "CLOCK IN"<br />
obtn1.stylesheet = "btn"<br />
ocont2.addObject("obtn2", "myCommandbutton") <br />
obtn2.flat = 1<br />
obtn2.resize(60, 50)<br />
obtn2.fixedheight = 50<br />
obtn2.stylesheet = "btn"<br />
obtn2.caption = "CLOCK OUT" <br />
<br />
# event handlers<br />
def clockin(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked in at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
def clockout(self):<br />
ocamera.takePhoto()<br />
now = datetime.now()<br />
oform.showSuccessMessage("You clocked out at " + now.strftime("%m/%d/%Y %I:%M:%S %p"))<br />
<br />
# We can dynamically bind events to custom classes in Lianja/Python<br />
bindEvent(obtn1, clockin, "click")<br />
bindEvent(obtn2, clockout, "click")<br />
<br />
# modal form<br />
oform.show()<br />
Lianja.readEvents()<br />
</code><br />
<br />
===JavaScript===<br />
====example_timeclock.js====<br />
<br />
<code lang="javascript"><br />
var oform = createObject("Form");<br />
oform.resize(600, 600);<br />
oform.closable = 1;<br />
oform.caption = "Time clock - JavaScript";<br />
oform.minwidth = 600;<br />
oform.minheight = 600;<br />
oform.deleteonclose = 1;<br />
<br />
oform.addobject("ocont", "container"); <br />
ocont.margin = 10;<br />
ocont.autosize = 1;<br />
ocont.layout = "V";<br />
ocont.backcolor = "black";<br />
<br />
ocont.addObject("obadgenolab", "label"); <br />
obadgenolab.fixedheight = 24;<br />
obadgenolab.autowidth = 1;<br />
obadgenolab.alignment = "center";<br />
obadgenolab.caption = "Enter Badge Number";<br />
obadgenolab.backcolor = "darkgray";<br />
obadgenolab.forecolor = "white";<br />
obadgenolab.fontbold = 1;<br />
obadgenolab.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgeno", "textbox");<br />
obadgeno.fixedheight = 24;<br />
obadgeno.autowidth = 1;<br />
obadgeno.placeholder = "Enter your badge number, Take a Photo then CLOCK IN or CLOCK OUT";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab2", "label");<br />
obadgenolab2.fixedheight = 24;<br />
obadgenolab2.autowidth = 1;<br />
obadgenolab2.alignment = "center";<br />
obadgenolab2.caption = "Take a Photo";<br />
obadgenolab2.backcolor = "darkgray";<br />
obadgenolab2.forecolor = "white";<br />
obadgenolab2.fontbold = 1;<br />
obadgenolab2.fontsize = 10;<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("ocamera", "camera");<br />
ocamera.autowidth = 1;<br />
ocamera.autoheight = 1;<br />
ocamera.backcolor = "black";<br />
<br />
ocont.addspacing(10);<br />
ocont.addObject("obadgenolab3", "label");<br />
obadgenolab3.fixedheight = 24;<br />
obadgenolab3.autowidth = 1;<br />
obadgenolab3.alignment = "center";<br />
obadgenolab3.caption = "Clock in / Clock out";<br />
obadgenolab3.backcolor = "darkgray";<br />
obadgenolab3.forecolor = "white";<br />
obadgenolab3.fontbold = 1;<br />
obadgenolab3.fontsize = 10;<br />
<br />
ocont.addObject("ocont2", "container");<br />
ocont2.layout = "H";<br />
ocont2.fixedheight = 60;<br />
ocont2.backcolor = "black";<br />
ocont2.spacing = 10;<br />
<br />
ocont2.addObject("obtn1", "commandbutton"); <br />
obtn1.resize(60, 50);<br />
obtn1.flat = 1;<br />
obtn1.fixedheight = 50;<br />
obtn1.caption = "CLOCK IN";<br />
obtn1.stylesheet = "btn";<br />
ocont2.addObject("obtn2", "commandbutton"); <br />
obtn2.flat = 1;<br />
obtn2.resize(60, 50);<br />
obtn2.fixedheight = 50;<br />
obtn2.stylesheet = "btn";<br />
obtn2.caption = "CLOCK OUT"; <br />
<br />
// event handlers<br />
function clockin() <br />
{<br />
ocamera.takePhoto()<br />
oform.showSuccessMessage("You clocked in on " + new Date().toLocaleString())<br />
};<br />
<br />
function clockout()<br />
{<br />
ocamera.takePhoto();<br />
oform.showSuccessMessage("You clocked out on " + new Date().toLocaleString())<br />
};<br />
<br />
obtn1.click = clockin;<br />
obtn2.click = clockout;<br />
<br />
// modal form<br />
oform.show();<br />
<br />
// must put read events at the bottom so the window stays open until closed by user<br />
read_events();<br />
</code><br />
<br />
==Building Standalone Executables==<br />
To build and test, switch to the [[:Category:Console Workspace|Console workspace]] and click the 'Desktop App View' button in the Headerbar:<br />
<br />
[[{{ns:file}}:standalone_exampletimeclock2.png|800px|left|border|link={{filepath:standalone_exampletimeclock2.png}}|Sample App: example_timeclock]]<br />
<br clear=all><br />
<br />
The Output window will show the compilation and build operations.<br />
<br />
To build and test the other scripts in the example_timeclock App - LianjaScript (.prg), Python (.py) and JavaScript (.js) are available - just select the required scripting language in the [[App_Settings#Delegates|App Settings]] and click the 'Desktop App View' button again.<br />
<br />
==Deploying Standalone Executables==<br />
When building a standalone executable with LianjaScript, all the .prg files in the App directory are linked together into a .src file and this is compiled.<br />
<br />
The resulting object file is bound onto the end the Lianja runtime executable and the authenticode code signing is adjusted so as to not be affected by the application payload.<br />
<br />
All of the supporting libraries are included in the standalone application directory.<br />
<br />
If your application is built in Python, there is a python3 directory included which contains the python modules you have installed with pip. <br />
<br />
To deploy, install the whole standalone application directory, e.g for the example_timeclock App the directory is:<pre>drive:\lianja\installers\standalone\example_timeclock</pre><br />
<br />
and it has a single ''bin'' sub-directory containing the executable and required libraries:<br />
<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin</pre><br />
<br />
To run, the executable is:<br />
<pre>drive:\lianja\installers\standalone\example_timeclock\bin\example_timeclock.exe</pre><br />
<br />
Note: In v7.0, the exe and required libraries are located in the application directory itself, e.g. ''example_timeclock'' (this has been corrected in v7.1). These need to be placed in a ''bin'' directory, either by renaming the directory to ''bin'' or by creating a ''bin'' sub-directory and copying all the other files into the new sub-directory.<br />
<br />
[[Category:Lianja v7.0]]<br />
[[Category:Lianja v7.1]]<br />
[[Category:Deployment]]</div>Yvonne.milne