So I am a beginner in Lianja, after watching all the video tutorials, I understood some of the basic features of the click and drops.
Unfortunately, I still have no idea where the coding begins and how they integrate.
I have no idea where to put lianja code vs where to put the PHP code, and what are the limit of these codes.
For example, I tried putting echo ‘hello world’ (simple PHP) and see how that would affect a section / gadget, but I don’t see hello world displayed anywhere in any section / gadget
Lianja is designed to help you be as productive as possible by allowing you to create Apps with little to no code. That being said, you can use code in a couple of ways.
First, you can write code to be executed by custom delegates at the Page, Section, or Field level.
The other way to use code in Lianja is in a Custom Section where you can write anything you like.
For example, adding a combobox to a canvas section.
a) I want to create my own version of that combo so I need to know how to subclass the existing combo and modify my version’s properties and methods, preferably without having to do that entirely in code
b) once I’ve got the class the way I want it, I want to be able to place it on the page, then tweak it’s properties through the UI
You cannot subclass components like that in Lianja.
you have a rich attribute set , which already includes some of the “new” (non VFP default) properties I use. (eg Mandatory input)
But I still need to add some of my own
No these attributes are fixed and are not user extensible. Delegates are scripting language independent.
there are a fixed set of UI controls which are customized by attributes and delegates.
You asked if you could call the same code from different delegates was my understanding and the answer is yes.
Open up your library in the init load or ready delegates and call the procs from your delegates. IOW use them as a wrapper.
When v2 development is underway we will be looking at the ability to subclass components from a component library
you can do whatever you want in custom sections but canvas sections do not support Subclassing of custom components.
You have to bear in mind that Lianja is not just for building desktop apps but for web and mobile also so we always look at the best way to implement functionality that makes sense across all clients.
we can’t “clone” pages and apps? That EVERY app has to be created from scratch?
we can go in and modify example apps, save them as our own and continue to modify…
If we can do that I cannot understand what would stop me copying a control from one app to another
Yes you can copy apps and save pages and sections as templates.
The Lianja Web Framework which is used in the Lianja Web Client provides a much higher level of abstraction.
You bind data to the sections and their UI elements. The heavy lifting is done for you.
Just design your Apps visually and use the delegates properly.
When data is added or updated (any CRUD operation in fact) the data is fetched back from the server automatically which will result in cascading section relationships and other related content such as sidebar content.
Delegates can remotely call server side procedures/functions. There is no need for any complex MVC style of page requests. Just develop as you would for a client server desktop App.
Validation can be client side or server side also.
Also bear in mind the anatomy of a section and how it is self contained and provides a great deal of built-in functionality.
– Section header
– Section menu
– Search panel
– Section content
– Section footer
Then further consider that all Lianja Apps are built out of pages containing a lot of built-in functionality.
– Page header
– Instant search
– Left collapsible sidebar
– Instant selections
– Recently viewed records
– Recently modified records
– Dynamic collapsible right sidebar
– Sections that can be related together (collapsible or accordion style)
– Page footer
– Data navigation
Page navigation is all handled for you and all the pages of a Lianja App are preloaded so that page navigation is instantaneous.
This level of abstraction is the same in desktop and web/mobile apps.
It’s a different way of thinking I do realize that but Lianja was specifically designed this way to provide a high level of abstraction closer to the way you think about how you want your Apps to look and how you want to be able to navigate between the pages that the App consists of.
The sample apps that I’ve reviewed all seem to bind the UI elements directly binding to tables/datasets?
Where and how does one implement a business logic layer?
Much of what other technologies force you into writing backend server business logic for is simpler in Lianja due to its data centric design paradigm.
I’m just trying to understand how to
1. Separate the UI from business logic and determine which files represent each.
2. Perform business logic before updating the database. i.e. The UI is interacting with objects rather than directly with the DB.
Simple Example – How do I implement the following …
When an Order is saved before completing the Order …
the UnitsInStock needs to be checked for each Product included in the Order to make sure there are Products available.
If there are UnitsInStock, update the UnitInStock for the Product and complete the Order.
If not, do not complete the Order and notify the user.
example_webapp iuses NoCode you are correct.
You can use validation, delegates and database triggers to do that.
In your validation you can call any server-side business logic (call a function) passing arguments from the active records that are represented by local data cursors in the client. (See the description of macro substitution in the Lianja HTML5 Client API).
When does the data actually get changed?
I have added code in the section beforeupdate() and afterupdate() events using curval() and oldval().
I have also accessed the field itself and tried the same code for the changed() and datachanged() events. Nothing seems to display the new value.
If I were to use SCATTER and SCATTER OLDVALUES, when would I access this?
Lianja uses row buffering. A record is updated when the buffer is flushed or when you commit or navigate to another record.
Data from the UI does not magically transfer into the buffers of the embedded database until the field loses focus at which point it will be pushed into the current buffer.
When a record is read, it becomes the “Active record”.
There are two buffers. The “old data” and the “current data“.
Changes in the UI update the “current data”.
When a check for updating a record is made there is an internal flag to denote “dirty” and the contents of the “old” and “new” values are compared.
Thats what oldval() and curval() give you.
The “Changed” delegate is called whenever data changes in the UI. There is a delegate for “Formitem”, “section” and “page”. Lianja looks up the UI hierarchy to determine which one to call. This means you can have a one for a section and not have to duplicate it for each formitem in the section. Thats where you would use SCATTER etc.