NonDesktop

Q:

I created a sample page with 1 canvas section and 1 grid (VFP as scripting language).
It runs ok within the APP builder, but when I try to go web app view, I cannot see the input fields and the grid at all. I “inspect” the web view and seems that it is created but just not showing….
Name:  lianja.jpg Views: 50 Size:  85.5 KB

A:

for web/mobile Apps the scripting language must be JavaScript.


Q:

Does “Lianja.get” runs in server side.prg ? I tried with 1 simple screen and Lianja.get is unable to get the variable value. I have a test screen with 4 variables. On compute click, I run a _test.prg, where the value of 4th variable is the summation of the first 3 variables.

Name:  lj-test1.jpg Views: 35 Size:  36.2 KB

Name:  lj-testcode.jpg Views: 33 Size:  54.5 KB

It works if I change _test.prg to read parameters and pass in the variables on click e.g. txt4.value=Lianja.evaluate(“_test(“+txt1.value+”, “+txt2.value+”, “+txt3.value+”)”)…but this will be very tedious if there is a lot of variables to be passed in.

A:

Server side programs do not have access to the UI, so you cannot use Lianja methods.

In your simple example you could process on the client:

Code:
txt4.value = parseInt(txt1.value) + parseInt(txt2.value) + parseInt(txt3.value);

Or as you say, pass the individual values to the server side program.

You can also pass all the values from a section using the section.getJSON() method, e.g.

Client side JS click delegate:

Code:
////////////////////////////////////////////////////////////////
// Event delegate for 'click' event
function page1_section1_field1_click()
{
	oJSON = Lianja.get('page1.section1').getJSON();
        // convert from object to string
	var cJSON = json_encode(oJSON);
	txt4.value = Lianja.evaluate("addvals('"+cJSON+"')");
};

Server side addvals.prg:

Code:
para p1
oJSON = json_decode(p1)
total = val(oJSON.txt1) + val(oJSON.txt2) + val(oJSON.txt3)
return etos(total)


Q:

I can’t seem to get my Lianja to generate a tablet_index.html.

I opened my deployment folder: D:\lianja\cloudserver\tenants\public\wwwroot\apps. The folder is empty.

I opened example_webapp1 and checked that the tablet UI Presentation Rule is ticked and that the directory and deployment directory settings were correct.
I saved the app. Message: App Saved
I clicked the Tablet App View and the app is displayed in the Tablet App View and works as expected.
I clicked the Tablet App View Deploy button. Message: example_webapp1 generated in debug mode and the folder example_webapp1 is created in the deployment folder.
On checking the folder there is an index.html but no tablet_index.html.

When I try to load the app on a tablet, I get a message saying tablet_index.html not found.

A:

run the Tablet View. Right click the results screen and click Inspect. See if there is a red x in a circle, bottom right of Inspector. If there is, that means there’s an error. Click it and it will tell you the location of the error, showing you where in it happened.


Q:

I’m testing the Lianja Tablet Web UI Demo app on an iPad 4 and I’m running into some issues. I’m not sure if these are Lianja issues or iPad issues.

I am unable to scroll the App Centre main screen. I’ve published 13 apps and I can see 12 in portrait and 6 in landscape orientations, and I can run the apps that I can see, but I can’t scroll the screen to see all the apps.

The App Centre LogOut button doesn’t appear to do anything. Tapping the icon simply highlights LogOut and nothing else.

In the example_webapp1, in the Customers Orders page, click add or edit on a record and it displays three date fields with drop down date controls. When I touch these controls a Lianja date selector is displayed but then an iPad date style selector is displayed over the top. Can this be prevented? It isn’t particularly bothersome other than the iPad date selector has a clear button and allows entering an empty date.

I have tested this on my Galaxy Tab and found that it appears the App Centre allows scrolling but it’s nearly impossible to actually scroll without accidentally selecting a tile and the LogOut button still does nothing. However, editing date fields only shows the Lianja selector.

A:

The App Center is primarily for desktop and web apps.

Mobile apps are normally built as discrete apps that are installed on mobile devices.

Running web apps on a touch enabled mobile device you will also encounter some permission issues if you are trying to access the camera, local storage etc. Mobile apps handle these permissions as well as the native UI controls such as the date picker.

Building a native PhoneGap app with the correct settings will allow you to request permission to access hardware specific functionality that may be rejected in a web app for security reasons.

A2:

a “native” device (phone or tablet) app is generally considered one to be written directly to the underlying framework (Android or iOS or Windows-whatever-they-are-calling-it-this-year). A PhoneGap (Cordova) app is a JavaScript app running in the Cordova framework that interfaces with native functionality on the device.

There is much debate (but less than there used to, because JavaScript compilers and native graphics have advanced so far) about whether a Native app (which will actually use webview for much of its display) is better than a Cordova app (sometimes called a “hybrid” app). For business apps there is very little noticeable difference.

The good news is that Lianja does all the heavy lifting needed to make a Lianja app (written for mobile) into a Cordova app.

Those writing “desktop” apps need to be aware of an alternative, which Lianja also supports: Electron apps. The app is delivered as an EXE (along with a lot of other files). It looks like a modern app, but runs directly on the desktop. It gets its data from the Lianja Cloud Server, just like other mobile apps. Underneath, Electron runs on node.js — which is important because node dll’s can interface to anything on the desktop machine. And, just as there are Cordova add-ins (tons of them) that provide additional functionality, there are node dlls (tons of them) that provide additional functionality.

Lianja facilitates mobile app development by allowing other-language calls to be made transparently on the backend, from the JavaScript in the UI (using exports.conf). Except for very special apps (like some stuff that Herb has developed), there is every good reason to write for mobile, and then package for what you need.


Q:

develop an Android app linked to our vfp product and we’re proposing to use Lianja. Once the App is written, the client wants to distribute it via an internal, secure web site rather than using GooglePlay. My brief research would indicate that this can be done fairly easily by simply providing a a link to the .apk file. I’ve read through the process of deploying a mobile app using Lianja and the online PhoneGap build service and was not clear on the availability of the .apk file.

A:

if you use G Suite (aka Google Apps), there’s an easy answer: https://support.google.com/a/answer/2494992?hl=en

Setting up your own is a bit of work, apparently. I have not done this: https://f-droid.org/wiki/page/Setup_an_FDroid_App_Repo

And then there’s the private channel in the official Play Storehttps://support.google.com/googlepla…/2623322?hl=en

You will get privacy without much work with the first or last options.

Unless you are using PhoneGap plug-ins to access device hardware, you can create an icon for the user to run the app without PhoneGap. https://developer.chrome.com/multide…lltohomescreen


Q:

I was looking for a little advise when deploying my app for a Windows 10 Tablet. Should I stay with a desktop deployment or use a tablet deployment? I tested it using the windows deployment for desktop, but everything is a bit small. When designing apps for tablets do you typically resize everything larger to make it more functional with a touch screen? This is for internal server use, we will not be accessing it over the internet.

A:

If you write it for mobile, you won’t be confined to Windows 10 tablets. The bad new is the rewrite required. The good news is you can call all your VFP routines directly from JavaScript using exports.conf. When data mapping and advanced form layout arrive (currently in the 4.0 release map, starting after the current bugfix release 3.2) there won’t be any reasons not to write for mobile first/mobile only.Desktop users can use the mobile app in Electron, and will think they are using a desktop app.


Q:

a web/phone APP using VFP as the main scripting language. I need 2 sections:
(1) A canvas section for user to key in the variables, click on “compute” then…
(2) A grid section to show the results.

we can’t build mobile/web Apps with VFP ?

A:

You write client-side code in JavaScript.

You can make proc calls to server-side VFP code and return the result to the client.

You can write dynamically generated WebViews in Lianja/VFP server side .rsp pages or server-side .jssp pages.

Your build apps visually using Lianja standard sections, custom section for canvas sections.

A2:

In a mobile app:

1) if you press the keyboard icon in a webview, you are creating a .js or .ts (depending on what you have set in app and page and section settings), The file will be named <page>_<section>.[js|ts] and will run in the client. A mobile app can only run JavaScript because that’s all that browsers run, at least for now (there’s a concerted effort to change this, but that’s a couple of years away from being universally available).

2) however, alternatively, you can create an .rsp (vfp language server page — r stands for recital, the earlier product in the Lianja line that uses a VFP-workalike, extended) or .jssp (javascript server page), and attach that filename to the URL attribute in the Data section. You can specify that url to take a static or dynamic parameter: https://www.lianja.com/community/sho…-Visual-FoxPro

Choice 1) gets executed in the client.

Choice 2) gets executed on the the Lianja Cloud Server.

The neat part about Choice 1), executing on the client, is that as Barry points out you can use exports.conf to turn VFP calls into JavaScript calls. That is huge if you have, for example, a need to munge a bunch of data that will then be used in the webview.

The neat part about Choice 2) is that you can use 3rd-party tools, like KendoUI: http://www.lianja.com/community/show…ja-and-KendoUI This will get even easier to accomplish with the “Component Builder API” on the Roadmap for V5.0.

A3:

You cannot use VFP as the main scripting language.

In a web/mobile app VFP can be used server side.

Let me explain.

You create an app and set the scripting language to JavaScript (or typescript).

You build your app out of standard sections.

You code any delegates in JavaScript.

You have *most* of the VFP built-in functions available to you in JavaScript.

The “grid” section is a standard section. So if you need any delegates just code them in JavaScript.

A “Custom” section is coded by you in JavaScript.

A “Canvas” section is laid out visually and delegates are written in JavaScript.

You can use Lianja.evaluate() to evaluate VFP code from Javascript. This code runs on the server.

Its all in the doc:
https://www.lianja.com/doc/index.php/Web_Apps

I would recommend you get it working in desktop using JavaScript then run it as a “Web App View”.

Hint: use the requery() method of a grid to refresh its contents.

If you open up example_webapp3 you will see it has a canvas section at the top, a standard form section beneath that and a grid beneath that.

It is simple to edit the delegates in the canvas section and in those delegates:

Lianja.showDocument(“page: page1.section1?action=search&text=” + m_companyname.text);

That will cause the form to refresh and then the related grid under the form.

A4:

The UI has to be in JavaScript.

There are two exceptions. 1) an .rsp page can be used in a mobile app, as it generates on the Cloud Server, and so what gets pushed to the client is HTML and 2) using exports.conf, you can call VFP prgs on the server that get executed there and return information to the mobile UI.


I have live desktop apps that I re-wrote in Lianja.
The front end is all html5, so it looks any way you want it to. Meaning, you can leave the controls as they are, or use a CSS file.

Also – Lianja gives you the ability to create mobile and web via drag and drop, or custom code.


Whether building Desktop, Web or Mobile Apps in Lianja you can execute your own functions (known as delegates) when actions occur e.g. a user changes some data in a field or clicks on a menuitem or button. In desktop Apps these delegates can be written in Lianja/VFP, PHP, Python or JavaScript.

In Web and Mobile Apps these delegates need to be written in JavaScript — the language of the browser.

In your JavaScript delegates you can call the built-in functions and object methods that are available in the Lianja HTML5 Client API.

Additionally you can make both synchronous and asynchronous calls to server-side business logic (procedures or functions) that are written in Lianja/VFP or JavaScript (soon PHP and Python too) and return the result to your JavaScript code.

So the essence of what you are doing is building a multi-tier client/server App with its UI presentation layer running in the browser and its business logic and data access running on the server — under the control of the Lianja Cloud Server.

Now you may be wondering, how can I build one App that runs in Desktop, Web and Mobile. This is all accomplished using UI personalities. Each UI element in your App can be included or excluded from the target client when the Lianja App Builder generates the code for it.

When developing a Web or Mobile App, firstly tell the App Builder to use JavaScript for the App (This can be set at the App, Page and Section level).

 


 

Advertisements

NonDesktop apps

Building a web app with Visual FoxPro Code only.
vfpwebdemo – https://youtu.be/_FhVyBtcWjM


Q:
I would like the VFP9 app to be able to communicate with the Lianja database either remotely or on the same network, depending on the settings of the implementation. I have a few different clients that use my VFP6 app, and some may prefer to host the Lianja database on their own servers, while others may prefer to use a third party hosting service in the cloud. From Barry’s response, I gather that as long as VFP9 accesses the Lianja SQL Server via the Lianja ODBC driver, either configuration would work. Would this work using an Amazon AWS-hosted instance of Lianja Cloud Server?
A:
Yes. Lianja SQL Server is part of the Lianja Cloud Server install. When you create an AWS EC2 instance it has a FQDN which you can point to from DNS e.g. You purchase a meaningful domain name from network solutions (or other) and set it up to point at your AWS FQDN. So yes is the answer.

So you can have web apps sharing the data with Lianja SQL server and VFP accessing the data using an ODBC connection to Lianja SQL server.

Lianja ODBC driver communicates with the server using TCP/IP so it can in fact be used across the Internet.

When the cloud server us running Lianja SQL is running too.


Yes, RSP. Use the benefit of CRUD in Lianja Framework. Delegates need to be written in language:

Client side: js
Server side: VFP (PHP is on the roadmap)
Client and server sides need to be separated.

Some quotes:

Building Web / Mobile Apps requires a traditional client / server design approach.
What at we have done is provide the equivalent of the VFP base classes and many of the VFP built-in functions in the Lianja Web Framework. This allows you to create objects, call their methods and get/set their properties just as you would in VFP, albeit in javascript.
Everthing in Lianja revolves around the Lianja Object Model and ART (Actions, Rules and Transitions).
All data processing (CRUD operations) is performed on the server.
You can
use Lianja.evaluate() in javascript to call server side procedures that are all written in VFP.

You currently use javascript on the client and Lianja/VFP on the server side when you want to call server side procedures.
The equivalent of .php pages are .rsp pages or .jssp pages as documented in the Developers Guide.

.php pages generate dynamic HTML content.
.rsp pages generate dynamic HTML content but with embedded Lianja/VFP data centric scripting.
.jssp pages generate dynamic HTML content using server side javascript.
These are used
to render WebView sections in Lianja.
Most sections are automatically data bound as can be seen in the example Apps.
Server side PHP and Python scripts are on the roadmap. The others are already supported in Lianja Cloud Server.
you
test your server side Lianja/VFP procedures in desktop mode.
You
test and debug client side javascript delegates in the web app view.



 

NonDesktop apps

Lianja.getElementByID(“page.section”).menu is exposed on the Desktop client only (Lianja/VFP), you can’t currently modify the Section custom menu options in JavaScript code for Web Apps.


Q:
If I have an app for desktop with language VFP, and I want to create the same app for WEB, do I have to replace all the code in Java
A:
The client side code that runs in the browser needs to be written in JavaScript but you can call Lianja/VFP procedures on the server.
If you follow best practices and use standard sections whenever possible, the app will run on desktop, web and mobile.


Q:
My client-side ‘evaluateJavascript’ call is working fine back to the server file but it will be great if you could expand a little on what actually makes the server file run server-side.
My understanding: evaluateJavascript effectively does an RPC to the backend, sending the call back in a JSON string, getting the result, and sending it back in a JSON string
A:
The client-side code is in LianjaHtmlClient*.js, which is present in minified form in the distribution. There are tools on the web for formatting minified scripts if you want to look at it.
The framework is not minified unless the app is previewed in release mode. Looking at the framework will not help to prove that it’s running server-side.
Development mode and runtime views are a core requirement to understand how to build apps in Lianja.
In this case the requirement of the OP to write in JavaScript on the client and the server is fully supported but not yet properly understood.


Q:
I’m writing a little server-side function that searches a table for a given value in a given field, and returns a different given field in the same record. For instance, you could tell it to return the name of a customer with ID=5. I’ve gotten it working (muliple ways, actually) on a desktop app but can’t seem to do it on a web/mobile app. The original basic logic was building a string out of my different variables and then run Lianja.execute on that string. Lianja.execute doesn’t work on web/mobile clients so I needed another way.

I found the PREPARE/EXECUTE commands in the documentation and tried them. I couldn’t work out how it handled different types of parameters but found a way to get it to work on desktop. What I thought should work was:

Code:
local mystring = "select ? from ? where ? = ?"
local selectfield = "total"
local tablename = "expenseclaim"
local searchfield = "claimid"
local searchvalue = 5
prepare stmt from :mystring
execute stmt using :selectfield, :tablename, :searchfield, :searchvalue

This seemed to behave oddly with respect to data types. For example, it accepted expenseclaim as the name of a table, but literally output the string “total” instead of the value in the field named total.

What I got to work on a desktop app was building “mystring” by placing the variables in it directly, then calling PREPARE/EXECUTE on it. Since EXECUTE needs at least one parameter and the table name seemed to behave properly, I left that in the string as a parameter:

Code:
local selectfield = "total"
local tablename = "expenseclaim"
local searchfield = "claimid"
local searchvalue = 5
local mystring = "select " + selectfield
mystring += " from ?"
mystring += " where " + searchfield + " = " + searchvalue
PREPARE stmt from :mystring
EXECUTE stmt USING :tablename

This works perfectly fine on desktop, but on web/mobile clients it breaks on the EXECUTE line.

That might be a bug , it might not be implemented on web/mobile or I might even be making some silly mistake, but even then it feels like a rather convoluted way of going about things. Is there a way to just execute a string within a Lianja/VFP script on a server? Or to just place variables into a Lianja/VFP command?
A:
just create a statement as a string using &macro substitution or use sprintf() if you find that easier.

Commands stored in character variables can be executed dynamically

Code:
cmd = "select * from " + p_tablename + " where id=&p_id"
&cmd

You can’t use &macros in the console. Just type

ed ryan

and put your code in that file then from the console issue

do ryan

you can call your server side proc from the client using

Code:
var result = Lianja.evaluate("ryan()");

to substitute parameters you can use {…} macros on the client too.


Q:
I’m building a web/mobile app and I’ve run into a really frustrating problem. I can’t open my database from a preview in my browser, but I can from the app builder and web preview screens? i’m trying to open it on the init of my app and do some manipulation to make sure it’s set up properly before the app loads, but I can’t even get past the opening part. It works fine with Southwind so I know I’ve done something wrong in the database itself. For reference the code in my app is:

app init delegate

Code:
var initstatus = Lianja.evaluate("appinit()");
Lianja.showNotification(initstatus,true);

appinit.prg

Code:
try
    open database mydatabase
catch
    return "unable to open database"
endtry
return "success"

This shows the message “unable to open database”, but when I replace mydatabase with southwind it shows “success”. Does anyone know what I could have messed up inside my database to cause this?
Oh and yes it’s deployed. It’s sitting in lianja\cloudserver\tenants\public\data, right next to where I deployed southwind.
A:
Have a look at strerror( errno() ) which will tell you what the issue is.
Does your database have a ‘dbc_opendata’ database open event delegate (empty or containing code)?

This is not currently supported in the Lianja Web Client, so needs to be removed before deployment.


It runs on the server when the database is opened not on the client.
Q2:
Ah, yes I do have an opendata script!
I wasn’t aware it wasn’t working in the cloud server.
A2:
Please submit a ticket. It runs on the server when the database is opened not on the client.


Q:
I am seeking advice for writing apps that will be used on web & mobile – should these be written in .rsp (I know php/asp) or regular Lianja pages that are enabled for web/mobile? + benefits of one approach over the other.
A:
If you want to hand code everything and ignore the Lianja development methodology of pages, sections, UI navigation, transparent client/server interaction, automatic data binding, roles and permissions, user authentication, etc… You can write everything in .rsp and roll your own framework and methodology.

To develop web and mobile apps you should follow Lianja best practices using pages and sections. Custom HTML content should be generated dynamically on the server and bound to a Webview section.

Lianja PhoneGap apps are executables that interact with the cloud server to handle CRUD operations.

rsp pages are used by various webviewwidgets in Lianja to dynamically generate content for charts, reports, and other static display content.


Q:
I created an App using Visual Foxpro as my scripting language and now cannot generate Web, Tablet or Phone Apps from it. I now understand that I should have used Javascript as the Scripting Language when I created the original app and I have subsequently changed the Scripting Language in the Settings but to no avail.
Is there anyway to correct this or must I redo the app from scratch and select Javascript at the time of app creation?
A:
You need to replace any custom libraries and delegates with JavaScript ones.
You probably have some strange setting in the app which is preventing it being generated for the web.


You need to configure your VM with “Bridged networking” so that your mobile phone or tablet can communicate on the same IP subnet that the Cloud Server is listening on.

NATing your IP address with the host will not work. You need bridged networking.

Oh and one last thing… Remember to enable port 8001 (that the Cloud Server uses) or else turn off your firewall for testing otherwise you won’t be able to talk to the Cloud Server.


In Lianja v2.1, Lianja Mobile Apps now allow you to navigate the records in your apps using the familiar left, right, up and down “swipe” gestures.

Swipe Left navigates to the next record, Swipe Right navigates to the previous record, Swipe Up goes to the last record and Swipe Down goes to the first record.
Tap and Hold edits the record.

These gestures are only effective in Form, Canvas and Custom sections.

You can override this behavior by enabling gestures in the section attributes and write your own gesture delegate (which may me specified using the inline delegate syntax).

Note also that navigation swipe gestures are not available if you have enabled “Swipe Navigation” in the page attributes. If you have enabled “Swipe Navigation” in the page attributes, then Swipe Left and Swipe Right navigates between the next and previous pages in the App. Swipe navigation is also available in TabPanel sections.Swiping Left and Right navigates between the different Tabs.


Q:
When I try to preview in Web App View, I get the “Server connection lost” message as shown below.
The connection to local host is ok from my other system which uses it (MS Visual Web Developer).
Do I need to set a parameter somewhere for “Local Host”, or…?
A:
when i’ve had the issue, it has a) been with a lot of records using a build < 1.5 release; or b) a sign that I messed up one of the grid's (I've only seen it in a grid) column controlsources.


Q:
I’m confused about how a phone app interacts with a cloud server. How do I access data on a Lianja cloud server from a mobile app (for that matter how do I access it with a desktop app)? I know how to run a web app on a cloud server and access it via a web browser, is there a way to just run a database on the server without an app? Does the associated database get packaged with the mobile app for local access or is it supposed to access it remotely?
A:
If you build a mobile app using best practices and standard sections the data is automatically bound for you. It is a seamless SPA interacting with the database under the control of the cloud server.

If everything is data bound and validation is handled by remote procedure calls for you, and… you can dynamically create HTML5 content into webview sections in what other way are you wanting to access data on the server? You have Lianja.evaluate() and Lianja.evaluateJavaScript() as well as a lot of built-in OData functionality.

Just to clarify…

– You deploy your app and its database.
– You specify the mobile app settings in the project settings for phonegap
– You build your mobile app
– In there while testing, it will inject a reference to your local machine and access the cloud server using port 8001
After you have fully tested everything you change that URL to point at your cloud server production installation

There are example mobile apps included that you can study and install on your mobile devices.
Mobile Apps are regular client/server apps with the UI on the mobile device and the database on a remote server under the control of the cloud server.
A2:

1) User app on mobile phone opens a page. It needs data. It says to the Cloud Server (using a JSON call) “hey, I need the data from view vt_myview with parameter x set to value n.”

2) The Cloud Server says, “OK, I need to get the data from vt_myview with parameter x set to value n” — it then runs the view, just as one would run the view from the command console, connected to the backend. Now, that could be Lianja SQL Server, which could be on the same machine or could be somewhere else on the network (reachable by ODBC). Or it could be MSSQL, etc.

3) Having gotten the data back, the Cloud Server replies to the mobile app: “OK, I’ve got your data, here it comes,” and sends it back as oData (a JSON string).

4) the Mobile app then gets the oData string, decodes it into a JSON object, and the UI does its work off that object. When the mobile app makes a change to the data it sends the old and changed values back to the the Cloud server and the general cycle repeats.


Integration with AWS (Amazon) — do you know how (expletive deleted) hard it is to set up AWS right? Do you know how many resources you’ll pay for when you aren’t sharing them? Basically, it’s a 3-year learning curve to do it on your own, and even then you’ll run into challenges. There’s no mention of pricing on the roadmap, but the concept for economies through sharing instances is there, so with a “share the wealth” pricing model, what you see will almost certainly be less than you would pay if you spent that 3 years learning enough to get it almost right.


Q:
I have a wedding application (for my son) that guests will be using during the wedding.
I would like them to not have to type in the entire url.

Meaning – to get there now, you need to type in.
Samswedding.online/apps/wedding/index.html

I would like them to only type samswedding.online and have it re-directed.
A:
you can create a QR code for a URL. There are several free sites. Then print the QR code on folding cards, and put them on each table.
A2:
you need to obtain a domain from someone like network solutions or setup a CNAME in DNS.
I use easydns.com for my domains and DNS. They have Forward and Stealth options (the latter continues to show the original entered URL).

If you’re using the IIS plug-in then you will have actual rewrite capabilities, of course. <a href="http://nicolas.guelpa.me/blog/2015/02/21/rewrite-redirect-iis.html&quot; target="_blank" rel="nofollow"http://nicolas.guelpa.me/blog/2015/02/21/rewrite-redirect-iis.html I haven’t tried a rewrite with the LCS, so let us know if you try it.


Q:
I understand that all delegates should be written in javascript (for now) if I want an app that will be both web & desktop. But what about other code?

I mean if I write a VFP function and use it as an expression in an attribute (eg. grid ‘Filter’) it works fine in desktop but it doesn’t work in web (I have tested this).
But to write these functions in javascript doesn’t make sense either if I need to use VFP Lianja.execX() to run them anyway (as per the replies in the other post).
A:
I can only speak for myself, but anything that I am doing that is web based, I am doing in javascript sections as this will work for both desktop and web.

I have my apps seperated into client side and server side.
My client side is all javascript, the server side foxpro.

I dont think you would need to go back to the client to filter a grid unless it was very large. But that should be handled with a virtual table (Not yet ready for the web client – but coming soon – I hope

For example, when I filter my grid in a javascript section, I dont go back to the server. I am using a button (as combobox and optiongroups are not yet available for a web canvas section).
The click event of the button is in a file called lib_page1_section2.js

Here is the sample code.

Code:
function page1_section2_field7_click()
{
Lianja.get("page1.section1").filter ="machine_type='Physical'";
Lianja.get("page1.section1").refresh();
}

This code is exaclty the same as it would be in foxpro except it is case sensitive and has a semi-colon.
That said, I could have put all sorts of logic in the function written in javascript and not need anything in Foxpro.

However if there was a call that had to be done in foxpro, then I would use the LianjaExec(), but only when client side would not work.

Best practices are to use the standard sections, not the custom sections if you want to make sure your app will run everywhere.

When I create a project, I select Javascript as my language.
If I didnt, I could always set it up in the App,Page or Section setting under Custom Delegates.

The App setting is the bottom left hand side of the app builder. It’s the cogwheel that says settings.
If you click on that, the settings panel will slide in from the right.
Navigate down to custom Delegates. There you will find the Scripting language.
You will find the same thing for the page (Cogwheel at the top of the page) and for each section.

As long as these are set to javascript, the functions for all your events will be in a .JS file.

So to put javascript code behind a button, do the following.

Set my app to Javascript.
select Sections | Canvas.
Make sure the canvas section is highlighed with a blue border around it.
Select Advanced from the bottom menu.
Click on CommandButton. A button will appear on the canvas section.
Select the edge of the commandbutton.
Double click the commandbutton to bring up the field attributes.
Scroll down and click on the click event.

The file editor will appear where you can add your javascript code.
A2:
if in your delegate you call LianjaExec(“yourprgontheserver()” all the ajax stuff is done for you.
everything in an .rsp or .jsp etc. is evaluated on the server, not on the client. This works out well for me, as I can have a webview section in a mobile app that is running VFP code, on the server. Delegates on the page, of course, have to be in Javascript. But if the language at the top is set to VFP, the code sections will run on the server.


Q:
I cant use a canvas section since they may be using a different size devices, so I need something responsive.

I decided to try and do this with a custom javascript section and not an rsp page. The click functions work on the phone, but the text for the buttons are not showing up.
Are the custom javascripts sections not yet fully supported on web/mobile?
A:
Yes they are fully supported, both canvas and custom.
You may want to just use a footer menu and prefix the captions with a + e.g.

+Add,View,Delete

That will layout the buttons across any device size and you can just use the footer menu delegate to do whatever you want.



NonDesktop apps

Look at the getJSON() method for a section in the webview console.

See what it returns for a canvas section when you type in data into the fields on the canvas section.

Look at the base64_encode() function. Use it to encode the JSON string returned from getJSON() on the client.

Call a server side proc passing that base64 encoded string as a parameter to it.

In the server side procedure use base64_decode() to get the JSON string.

Now use json_decode() on that string.

Hey presto you have exchanged the data from your canvas on the client into an object on the server.

Now figure out what you want to do and then send a result back to the client. This is normally sent as a JSON string so that you can send an object back to the client rather than a single value.

Create a JavaScript object from the JSON you sent back to the client using JSON.parse( result ). You can also use JSON.stringify() to encode a JavaScript object as a string. Just google these. They are standard in all browsers.

Now you can reference the members of the JavaScript object, update your canvas section accordingly and then requery() your child section(s) by constructing a where condition that will be given as an argument to the requery() method for the target section.

Note that there currently is no setJSON() method for a section but I can see that would be useful for this scenario of handling manual querying of data. Submit an enhancement request ticket for that as it would reduce coding and be more consistent.

Also remember, Lianja.evaluate() is synchronous if no onsuccess callback is specified.


Q:
you can create an application “mobile” with DB “local” on the device?
A:
No, it is client/server just like you build Web Apps.



NonDesktop apps

Q:
My data will all be derived from .dbf files and is currently accessed from an ODBC connection.
I do not know Javascript and I do not know what is needed to convert my Lianja/VFP so that it can be dynamic HTML5/Javascript Code.

Currently all CRUD operations are primarily handled through virtual tables.
I do not understand how server side data access is not required.
1. How much of my current Lianja/VFP code can be used (there is lots of code)?
2. Can existing .prg files still be used?
3. If I create .rsp pages, how do I know what needs to be placed in it and what shouldn’t be?
4. If I don’t know JavaScript, isn’t it still required for client side programming?
5. The scripting language is set to ‘Inhert’. Does this need to be changed?
If I change the view of my app to preview in a browser, my menu items do not work (one of which shows/hides a search panel), the grid can’t display, the page doesn’t scroll and my data isn’t displayed.
How would you recommend proceeding in changing my app to be web usable as well (as best as you can without having it in front of you)?

A:
look at the web app examples. Work through them to better understand what is going on client/server.

The client web app running in the browser dispatches requests to the cloud server using an odata url. Read the doc about odata on the website.

The cloud server handles odata requests, generates the SQL for them, executes it and sends the data back in industry standard JSON.
It handles native tables and virtual tables.

In a client/server application the UI is separated from the backend business logic procedures and the database access.

So, the delegates that are related to UI events must be written in JavaScript which is the core scripting language that a web browser understands.

The Lianja object model (LOM) is available to your JavaScript code just as it is in your Lianja/VFP code in your desktop application.
This is one of the ways Lianja achieves UI device independence.

The Lianja Web Framework provides most of the Lianja system object that you are familiar with in writing desktop apps, so Lianja.evaluate() etc is available to call server side business logic written in Lianja/VFP and (in v2.0) Lianja.evaluateJavaScript() for calling server side business logic written in JavaScript.

Client/server development requires you to separate UI from the business logic. The client needs to handle client specific functionality not be designed as one large monolithic application that does everything all in one place as you would in a desktop app.

Hint: if you have a page or section that is bound to the desktop app you can omit it from your web app by using UI personalities which are enabled or disabled in the attributes.


(?A):
What I find amazing about Lianja is the myriad of ways to get things done.

For example, a beginner can use very little coding to get a fully functional web application done just by using the best practices.

He/she doesn’t need to now much about javascript, CSS, PHP (or .net), html etc.

Fully updatable data driven web applications.

Brilliant really.

But it doesn’t stop there. The more advanced users have tools build in the Lianja world to allow interaction between the Lianja objects and purely web based technologies. The showdialogs,evaluate and Odata come to mind.

But it goes further. If you are like me and like to tinker with all sorts of technologies, you can quickly appreciate the Lianja world as one that allows you to go as deep as you want into database web applications.

For example, I downloaded a Bootstrap theme that I liked, added my own rsp pages for the look and feel using Kendo UI.
I have created RSP pages that have a mix of SQL Server code and VFP code for a logic layer and return that all back the front end. All using the powerful cloud server for very quick response.

For this particular project, I am developing directly into the cloudserver apps root directory. Meaning, I am not using the Lianja IDE to create a fully Lianja supported project.
I am doing that, because in this particular project, it makes sense and being that the flexibility exists, I am happy to use it.

My point is to illustrate the incredible flexibility of the cloud server and the RSP pages.

Together, they can do anything you can think of.

Here is what my dev environment looks like.


Best practices for one App that runs on desktop and web and mobile. (As already stated in the doc link you provided).
1. Client code (delegates, custom sections, canvas section) should be JavaScript.
2. Server code can be Lianja/VFP (or JavaScript in v2.0).
3. You can call Lianja/VFP “Business procedures” that run on the server using Lianja.evaluate() (and Lianja.evaluateJavaScript() respectively in v2.0). So you can call validation, perform calculations and lookups on the server. Its seamless.
In the final release of v2.0 there is also an app.conf file which you can add to an App that “tells” the client what procedures/functions are handled by the server.
This provides transparent remote function calls that are made in the client that execute on the remote server.


ability to call server side procedures that are contained in libraries as follows.

Code:
// Client side JavaScript (notice the :: preceding myfunc()
var result = Lianja.evaluate("mylib::myfunc()");
Code:
// Server side Lianja/VFP in mylib.prg
proc myfunc()
    return "hello world"
endproc

We will be providing a way to register server side functions in the Web/mobile client so that they can be called as if they were JavaScript client side functions.

So for example you will be able to just do this in your client code.

Code:
// Client side JavaScript
var result = myfunc();

And myfunc() will be executed on the server.


Q:
I have a canvas section, with a textbox, used to set search criteria.
I have a form section bound to a virtual table. Data is loaded into a form section by requerying the section.
Next I need to populate a grid section (also bound to a virtual table) based on a value from the form section.
(Note: setting the relationship isn’t used because of multiple related fields).

This does not seem to be an issue in the desktop, although it is an issue in the web client do to asynchronous calls (which I believe is happening in this case). The form data most likely will not be loaded when the grid section is processed. I am using the value in the textbox to perform a separate query to get the value needed to populate the grid section (by requerying the secton). This is why I am attempting to figure out the best way to access the data.
How would you suggest I perform queries such as the one described with sqllookup?

A:
You cannot use sqlxxx() functions in the client.
The registration form code is all there so you can study it.
It calls business procs on the server.

You do not need to do anything at all with JSON if you build a business app using best practices.

There is no such thing as “a table is already open” in a web client/server app as this is stateless.

You can call a server side lianja/vfp procedure to perform your lookup. If you are doing that the proc is running on the server NOT the client.

Pages are made up of sections that can be related together (as you already know).

If you call the “requery” method on a section and give it a query expression then the data will be looked up on the server asynchronously.
When the call completes if data is found to match the query the section will be refreshed with the data then any child sections will be refreshed based on the data relationship between the sections.

This is no different to desktop operation.


Q:
What is a primary key in SQL
A:
A column NOT an expression

When you add a record to a child section the parent expression is used to maintain the child relationship.
An expression cannot be used to link the parent and child sections it is makes no sense.

If you want to do everything manually, fetch your data from your server side proc, populate the fields if you want to build things manually, then use requery() on the target child section to populate the child grid.

You can use the requery() method on a section to lookup records on the server and populate the section.



NonDesktop apps

Web and Mobile Apps are stateless.
What this means is that you cannot guarantee a persistent connection between the Web client and the server.

When requests are made by the browser these arrive on the server and are handled by worker processes based on their availability. Lianja uses connection pooling to optimize performance.
Not only does it use connection pooling for web requests it also uses ODBC connection pooling to handle Virtual Table access.

Therefore, executing a command only affects the server process that the command runs on. It has no effect on the client and the next Lianja.execute() may run in a completely different server context.


In Lianja v2.0 we have made it dramatically easier to share data in real time between multiple Lianja processes running in parallel.

In HTML5 Web/Mobile there is the concept of “localStorage” and “sessionStorage”.

In the Lianja v2.0 Desktop client “sessionStorage” is non persistent data that can be shared across multiple concurrent processes e.g. background processes gathering data from instruments or multiple Lianja windows on the desktop.

Access to data in sessionStorage is handled automatically for you so that concurrent reads, updates and removing of data items is atomic.

You access sessionstorage from the Lianja system object Lianja.sessionStorage.

Properties:

// The number of key/value pairs in sessionStorage
length

Methods:

Code:
// These should be quite explanatory
Lianja.sessionStorage.setItem(key, value)
value = Lianja.sessionStorage.getItem(key)
Lianja.sessionStorage.removeItem(key)
Lianja.sessionStorage.clear()

Lianja uses a shared memory segment to maintain sessionStorage.

Lianja will automatically keep the keys and their values consistent between each running process as you reference the items stored in SessionStorage. If you want to keep complex objects as the values for keys then use json_encode() and json_decode() to handle serialization and deserialization of the objects.

Code:
// in the main process App
private myobj = object("name" => "Barry", "company" => "Lianja")
Lianja.setItem("myobj", json_encode(myobj) )
Code:
// then in another process that needs to read objects from the main App window
private myobj = json_decode( Lianja.sessionStorage.getItem("myobj") )

Note that each time you call any of the methods or reference the length property the shared sessionStorage will be automatically kept current for you.


there is a “Session data changed” delegate and a “Session data changed interval” in App Settings.

Lianja will check for changes in the sessionStorage every #msecs and call the “Section data changed” if any changes in the sessionStorage have been made.
This is fast as a transaction sequence number is kept as part of the sessionStorage so no deserialization of data is required.
There is also a property called “datachanged” and “datachangedinterval” (in milliseconds) so this can be used by non GUI applications (background worker processes etc).


In Lianja v2.0 you also have several new classes that handle custom shared memory access and custom system semaphores.
New “SharedMemory” system class

Code:
m_shareddata = createObject("sharedmemory")

// attach will create the shared memory if it does not exist. Args are the "key" and the "size"
m_shareddata.attach("com.lianja.myshareddata", 64*1024)

// set key/value pairs
m_shareddata.setItem("mykey", somevalue)

// get value
m_value = m_shareddata.getItem("mykey")

New “SystemSemaphore” system class

Code:
m_sem = createObject("SystemSemaphore")

// setKey will create the SystemSemahore if it does not exist. 
m_sem.setKey("com.lianja.mysem")

// acquire exclusive access to a resource across multiple running processes
m_sem.aquire()

// do something...

// release access to the resource 
m_sem.release

Q:
Up until now, I have only created desktop apps. I am now planning on making my apps available for the web.
My current apps use VFP/Recital code.
I am also not used to programming for a client / server design.
I have read that you use javascript on the client and Lianja/VFP on the server side when you want to call server side procedures.
Here are just some of the questions I have.
1. When do you use rsp (Visual FoxPro Server) pages?
2. When do you use jssp (JavaScript Server) pages?
3. What and when is jquery, json or odata used?
4. How and why would you use each of these?

A:
Lianja is a complete Apps platform.
It is not just an IDE nor is it just a language.
You build Apps visually using “best practices“.

Apps are built out of pages and pages consist of sections etc.
You can build Web and Mobile Apps just as you can build desktop apps if you follow best practices. “Think NoCode“.
There are many pre-built sections that have a lot of built-in functionality. “Think Login page -> App Center -> Apps -> Pages -> UI Navigation“.

The Lianja HTML5/JavaScript Client for an Web/Mobile App is generated for you. It incorporates the LianjaWebFramework which manages all of the UI layout management, App and page navigation, data navigation, and all CRUD (Create Read Update Delete) operations on the sections (Forms, Grids etc) assembled into an App. You do not need to write any server side data access code. None.

The LianjaWebFramework is an HTML5/JavaScript library that takes care of the heavy lifting and handles automatic and transparent data binding between the client App running in the browser and your data which is on a remote server under the control of the Lianja Cloud Server.

The LianjaWebFramework was developed by ourselves in JavaScript and it uses jQuery, jQuery Mobile, Twitter Bootstrap and a variety of other JavaScript components some of which are commercial and some of which are open source licensed (Apache 2, BSD, LGPL).

There are occasions where you may want to build a custom UI that incorporates other UI widgets that you like.
You do this by building a WebViewWidget which is loaded into a WebView. The HTML5/JavaScript for the WebViewWidget can be dynamically generated by an .rsp page (Server side Lianja/VFP) or a .jssp page (Server side JavaScript). Both Lianja/VFP pages and JavaScript pages are part of the Lianja Cloud Server. (PHP will be included in this too very soon).

To answer your questions.
1. Do you know Lianja/VFP? Then write your dynamic HTML5/JavaScript code in that data centric language.
2. Do you know JavaScript? Then write your dynamic HTML5/JavaScript code in JavaScript.
3. You don’t need to know unless you are building custom WebViews.
4. See above.



NonDesktop apps

Q:
Hi, I am struggling a bit with the concept of which code runs where (if there is a doc which explains this please point me to it).
If I use php code (which I would assume is server-side) a message is popped up just fine in the IDE and in Desktop mode but I get nothing in web/tablet/mobile mode?

Code:
////////////////////////////////////////////////////////////////
// Event delegate for 'click' event
function Test_section1_field1_click()
{
        Lianja.ShowMessage("hello");
}

If php is indeed running server-side then surely this should never show a message at the client?
The other thing that I am not sure about is that “Lianja.ShowMessage” is not like any php code I have seen, surely this should be “$Lianja->ShowMessage”?
I get it now that delegates in JavaScript will work in web & desktop apps. It would appear then that PHP is kinda treated as a ‘client-side’ script for desktop apps?
Would the correct place to put server-side business logic then be JavaScript/Lianja Server Pages? How do you create those files? can they be debugged?
My questions are coming form the fact that I have used PHP/JavaScript extensively so am trying to relate the Lianja client/server bits to what I know.
A:
In PHP . Is used to add strings together so :: is required to be used.
Lianja/VFP, Python and JavaScript use . to reference properties and methods
whereas PHP uses ::

You currently use javascript on the client and Lianja/VFP on the server side when you want to call server side procedures.
The equivalent of .php pages are .rsp pages or .jssp pages as documented in the Developers Guide.
http://www.lianja.com/documentation/developers-guide

.php pages generate dynamic HTML content.

.rsp pages generate dynamic HTML content but with embedded Lianja/VFP data centric scripting.
.jssp pages generate dynamic HTML content using server side javascript.
These are used to render WebView sections in Lianja.

Most sections are automatically data bound as can be seen in the example Apps.
Server side PHP and Python scripts are on the roadmap. The others are already supported in Lianja Cloud Server.

you test your server side Lianja/VFP procedures in desktop mode.

You test and debug client side javascript delegates in the web app view.

if you are building desktop Apps, you can build them in Lianja/VFP, JavaScript, PHP or Python. The latter two are not yet supported in the Lianja Cloud Server but will be as detailed in the development roadmap.
Lianja is all about visually designing Apps out of pages and sections. This is all described in the developers guide and the videos. It’s not code centric, it is data centric with a high level of abstraction.