Mike said:
Web-based applications have some fundamental differences from desktop apps, and there is no completely satisfactory way of automating the conversion of one to the other.
Sorry if I contradict you (it's the purpose of forums, right?), FoxInCloud has overcome all the 'fundamental differences' between a Desktop and a Web application.
Here are these differences:
user state management
[ul]
[li]On the desktop, each user deals with a dedicated instance of the application in a one-to-one relation; the user state can be held in a dedicated memory space and program can stop to wait for a user's choice (modal state).[/li]
[li]On the web, a user action (request) can be processed by any server in a many-to-many relation; this server must be able to retrieve what the user has done before to properly answer its request (just like in a conversation); also the server can't wait for the user to answer a question; it must provide the user an address where he can send the answer to be processed when ready (call-back).[/li]
[/ul]
We have addressed these issues over 15 years ago (first projects and attempts in 2000):
[ul]
[li]Upon each request, FoxInCloud retrieves (and later saves) the user's state from (to) disk (a VFP table), including the dataSession; this was the main 'initial' innovation: we realized that, in a VFP form, a relatively small number of properties was affected by a user action and saving the cursors contents in XML (using XMLtoCursor()) was fast enough to do both the saving and restoring in less than 500 ms (even less today). As a rule of thumb, FoxInCloud saves and retrieves 1 property per ms. Grid state can take a little longer, up to 200 ms, typically 50 ms (Attached is a sample form-user state table). Adaptation consists in adding at design time, or at [tt].Init()[/tt] time, which
native properties user action can affect (typically [tt].Visible, .Enabled, .ForeColor, etc.[/tt]) into a property called [tt].wcPropSave[/tt]; FoxInCloud Adaptation Assistant sees and adds all the properties modified by the object or the class itself, and the custom properties; dev needs to manually add the properties that are only modified by other objects or class code.[/li]
[li]When a user decision is required (and this is the main manual adaptation needed), the code processing the user's choice needs be moved to another method. After automated adaptations, each object and class in the application inherits 10 'standard' call-back methods called 'wFormCallBack?'. The name (or full address) of the call-back method needs be supplied to the form call such as: [tt]thisForm.wMessageBox('wFormCallBack', 'message'[, buttons[, title[, timeout]]])[/tt]; this code displays a regular messagebox in desktop mode, a 'web message box' otherwise, and will automatically call the [tt]wFormCallBack[/tt] method of the same object when user clicks any of the buttons or timeout elapses; this is illustrated with a simple example in the
FoxInCloud Live Tutorial.[/li]
[/ul]
Important note: ALL web applications need to implement these features! And the user state management can be VERY tricky using a regular web development language… (many discussions you can google)… FoxInCloud provides an automated solution for user state management, and a convenient solutions for call-backs.
granular updates
Since Graphical User Interface, user actions only change parts of the display, not the full display like it used to be in terminal mode. The Web has experienced a similar evolution: initially user would 'post' a full form (typically with the data for a full table record). Server would read and process the data, then send back a full HTML page for display. This process is not only uncomfortable (blinking display), it also requires a lot of band width as the full page, and all attached files such as images, scripts, etc. need be reloaded upon each user action; even with HTTP optimizations such as 304 status, it remains a lengthy process.
In 1999, Microsoft introduced a component that JavaScript could manipulate to send HTTP requests; after maturing by Google, this became 'AJAX' in 2005 and was progressively standardized in all browsers. We started working with AJAX right from the beginning as we understood that it was the solution to make Web Applications behave like Desktop Applications.
We also realized that most events existing in VFP ([tt].click(), .focus(), .valid(), etc.[/tt]) had an equivalent in the HTML event model. By traversing the VFP form, we generate an HTML with the same structure and matching element IDs; when user performs an event on an element of the web page, FoxInCloud sends this event to the server together with the element's ID, server restores the form state, executes the code of the matching VFP object, detects the visual changes (by comparing the saved properties before/after request), and sends the corresponding HTML/CSS/JS update orders to the web page.
One of the main benefit of this approach is that ALL BUSINESS CODE IS ON THE SERVER, NONE IN THE WEB PAGE. With frameworks like Angular or React, all business code is in the web page and protecting it is impossible.
responsive design
This was the last hurdle that we passed in 2017.
As explained earlier, FoxInCloud builds an HTML page matching the VFP form's structure. Initially the generated HTML used the so-called 'absolute positioning' like in VFP, and the HTML forms were visually very similar to what the user could see in VFP; advantage was that users saw a familiar form design, drawback that they could use the form only on a similar screen, not on a mobile terminal such as a smart phone or a tablet.
The first progress was to support [tt]form.move()[/tt] and [tt]form.resize()[/tt] (using [tt].Anchor[/tt]) with server-side memorization (demo'd by the
FoxInCloud Live Tutorial in 'classic' flavor, using the red buttons). Useful on a desktop, still unusable on a mobile device.
Then we focused on the relative (rather than absolute) dimensions and positioning to generate an HTML using the
Bootstrap classes. HTML generation takes a little longer (a lot of recursive stuff), however it's executed only once at initial form startup so it does not affect user's response time (another benefit of AJAX granular updates); this is demonstrated by the
FoxInCloud Live Tutorial in 'responsive' flavor.
Of course both classic and responsive flavors of the FoxInCloud Live Tutorial use the exact same VFP code; just 2 different .exe with a different startup program setting '[tt]server.BSlHTMLgen[/tt]' property to either .F. or .T.
Mike, if you see other fundamental differences between a Desktop and a Web application that were not covered here, please share them and let's start the discussion.