Hi Kirk,
Thanks for your input, too.
I can explain what I have done to this point with my [UIClass] & [UIObjects]
tables.
Everything is done using ORDA. All the ‘variables’ are Form objects (i.e.
‘Form.curClassEdit.Note’ type things).
Unfortunately, iNUG still does not support anything other than plain text, so I
can’t bold anything or include any snapshots … : (
The purpose is to create objects for Storage. that will provide information
for the system or UI-related objects, such as menus, choiceLists, etc.
I am also using it to create one-time objects that formerly I would have
created as a table with one record: for example “COMPANY” or “SETTINGS” - type
stuff.
I am also creating ‘USER’ objects that have the login information for users and
the PRIVILEGES they get.
• thereafter, everywhere you see the attribute ‘Privilege’ is intended to allow
a particular thing NOT to be made available to the current user.
So, for instance, not every MENU or MENU ITEM should be available to every
user; When the user logs in, a project method will configure the menu bar with
respect for the privilege they have. The same is true for CHOICE-LISTS, and
other things (anything I want to control).
It is also going to be used for trivial things that formerly would have
required a specialized table [see ‘city’ below]
DATA STRUCTURE
UICLass — ID, Name, Note, InitMethod, storagePath [in Storage., for
instantiation], Seq (of initialization), Attrs {Object field}
UIObjects — ID, Name, Class, Note, Seq (of initialization, important for
lists), obj (attributes). I just added an ‘Owner’ field so I can have objects
contain objects. (Parent/Child). I am going to use this when I define ‘dClass’
and ‘dAttr’ — which will have the data classes [Tables] / attributes [Fields].
This way I can define things about the field such as a LABEL, displayFilter,
entryFilter, choiceList, etc. to simplify standardization.
CLASS / OBJECT MANAGEMENT — ‘UI Design'
I have a form called ‘UI Design’. On the left-hand column there are my CLASSES
in a listbox.
• When I highlight one of the CLASSES, then the setup for the class gets loaded
immediately to the right, so it can be edited.
I discovered a problem with relying solely on 4D’s listBox property: Current
Item. That is, when you need to create a NEW record but don’t want it
automatically added until you SAVE it. So I actually don’t strictly use that
method. Anyway…
• there is a TAB CONTROL that I can use to toggle between DEFINITION and
OBJECTS. So when I want to work on defining classes, I am in DEFINITION. When I
want to manage specific objects in a CLASS, I go to OBJECTS.
In the OBJECTS (form page 2) is an included layout with the personalized EDITOR
for the appropriately-chosen class; they always list all the OBJECTS of that
class in a listbox on the left. I have made EDITORs for any class that I want
to store into objects [UIObjects].
DEFINING A CLASS
Once a CLASS is loaded (selected, or NEW), I can specify what attributes to
define for this class. [This is done in a listbox].
So as an example, I have classes such as these:
sysMenu • menuRef (assigned by system);
• Name;
• privilege;
• itemList (collection of menuItems objects); level
(main or sub)
menuItem • itemName;
• subMenu;
• privilege;
• method;
• parameter;
• action (standard action);
• checkmark;
• isNewProcess;
• shortcut;
• various booleans for shortcut stuff (shift/alt),
booleans for bold/italic/underline. etc.
Basically, all the characteristics 4D supports
for menu Items
So a sysMenu has a collection of menuItem.
Then I also have a specially-made sysMenu definer that is used to GUI - design
the system menu [include for that show in the OBJECTS tab]
In this iteration, the ‘menuItem’ class is more of a template that is used when
making the itemList collection (an attribute of sysMenu); I don’t store
separate ‘objects’ for each menuItem.
The definer also shows the menu ‘real-time’ to confirm how it is set up. It
could even be capable of performing the method / standard action if one wanted
to test that too.
• the end result is that:
• I define the menus for my project; sequence them (left->right); PRIVILEGE is
assigned at menu and item levels;
• when the user LOGS IN, the menu objects are processed and 4D MENUS are
created in Storage.sysMenus [ ] for my use! including
Storage.sysMenus.menuBar, which is the menu used as the ‘menuBar’ by 4D.
For choice lists (static text):
choiceList • listRef (becomes listRef, assigned by 4D);
• name;
• itemList (collection of listItems)
listItem • display (text);
• ref (itemRef, a longint);
• subList [I can attach a list];
• privilege;
• textVal (an alternative to using ref, as sometimes a
text Value is needed to store rather than an ID (itemRef)
• again, the ‘listItem’ is more of a ’template’ for construction the
choiceList:itemList ; listItems are not stored as objects.
To use a choiceList in a UI object (dropdown, combo box, etc):
In the ‘on Load’ event of the Form method, just use a line like the following
to assign the choiceList to an object:
// **** assign choice Lists to some items here ****
OBJECT SET LIST BY REFERENCE(*;"choiceListPrivilege";Choice
list;Storage.lists.list_Privileges.listRef) // set the "Privileges" choice
list, which is defined as a choice-list object named 'list_Privileges'
• I discovered that I can assign a LIST to a combo-box. Then with OBJECT Get
list reference( ) I can get access to the VALUE:KEY pairs (itemRef).
So if I create a LIST that has VALUE:KEY (say, for customers, NAME:ID) then
it is a trivial thing to update the MANY field as the choice is made.
For example: ’set list’ for the box of CUSTOMERS; list has CustomerID
[itemRef] : CompanyName.
Then when a choice is made in the cbox, just look up the itemRef in the LIST
attached to the cBox, and you have the CustomerID! This can thereafter be
stored in your INVOICE:Customer field. I have implemented this with just two
simple methods.
Then I also have a choice-list-type class for ORDA-based queries. [Makes me
think I could define ORDA SELECTIONS as objects, but I digress].
ordaList • listRef (4D-assigned when created);
• dClass [name of data-class];
• displayField; selectionOrda [orda-style selection
statement];
• selectionClassic [formula that is ’true’ for records
to include. This will be used so that, in the Table’s Trigger,
I can figure out what existing ordaList's need
instant-update to reflect changes (add/remove)
• I have a special EDITOR for setting up these Objects.
USING [UIObjects] TO AVOID UNNECESSARY TRIVIAL TABLE CREATION
[UIOBJECTS] can also contain trivial information for which I do not wish to
create a dedicated table.
For example, to manage CITIES:
city • Name
• province
• fullName [ex. city, PR: Calgary, AB]
Then I created a ‘CITY’ object definer wherein I can add new cities. These
records are stored in [UIOBJECTS] with Class ‘city’.
Thereafter, to make these CITY’s comprise a LIST, I just defined an ordaList
for them.
ordaList definition for ‘city’ :
DataClass: UIObjects,
DisplayField: Name;
Orda Selection Statement: query("ObjectClass.Name =
:1";"city").orderBy("Name ASC”)
• AUTOMATICALLY, a list is created and maintained in STORAGE.Lists.list_Cities
! And I never had to create a new table merely for this trivial data.
This is completely usable, as in 4D if you defined a CUSTOMER table, you just
make a ‘city’ field and link it to [UIObjects]. It will work like normal!
————
I understand this may be a lot to take in. I could probably make it available
for you to check out yourself – obviously not through iNUG which makes it kinda
tough to share things.
regards,
Chris Belanger
> On May 6, 2019, at 10:38 PM, Kirk Brooks via 4D_Tech <[email protected]>
> wrote:
>
> Hi Chris,
> I apologize for such a late response. I left on a road trip about the time
> you sent this and frankly forgot to get back to you. Your enthusiasm is
> infectious. And you describe some excellent applications. I haven't played
> with OBJECT SET LIST BY REFERENCE yet... Thank you for the tips.
>
> And I completely agree about reviewing the whole menus thing. I work on
> some old projects with these insanely complicated schemes for menu bars and
> it is just so much wasted time and effort to accomplish so little. It was
> what was available 25 years ago but jeez I'm glad to be past that.
>
> I wonder if you would elaborate on how you use [UI_class] and [UI_object]?
> I have played with the concept a little but I fear I am over complicating
> it to no good effect.
——
——
>
> In addition to 4D POP David Adams and Cannon Smith shared some methods for
> creating constants with code. I was a little skeptical at first of this
> approach - writing a method to write an XLFF file for the constants but
> I've come to prefer it. Mainly because in that method I can comment what
> each constant is for. And once you do a couple of them it's quite easy.
>
> In v15 I came to rely on constants for object property names. Just a great
> way to deal with the need for consistency. With native dot notation you can
> use them with [[brackets]] but I'm not as big a fan. On the other hand
> without them there is a real issue about ever changing a property name. Or
> a field name.
>
> Of late I'm mucking around in v15. Looking forward to spending more time
> again in v17r5.
> --
> Kirk Brooks
> San Francisco, CA
> =======================
>
> What can be said, can be said clearly,
> and what you can’t say, you should shut up about
>
> *Wittgenstein and the Computer *
> **********************************************************************
> 4D Internet Users Group (4D iNUG)
> Archive: http://lists.4d.com/archives.html
> Options: https://lists.4d.com/mailman/options/4d_tech
> Unsub: mailto:[email protected]
> **********************************************************************
**********************************************************************
4D Internet Users Group (4D iNUG)
Archive: http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub: mailto:[email protected]
**********************************************************************