Skip to content

Release Candidate Version 1.1 - #196

Open
clauspruefer wants to merge 10 commits into
mainfrom
v1.0.1
Open

Release Candidate Version 1.1#196
clauspruefer wants to merge 10 commits into
mainfrom
v1.0.1

Conversation

@clauspruefer

@clauspruefer clauspruefer commented Jul 30, 2026

Copy link
Copy Markdown
Member

Pull Request

Description

Release Candidate v1.1.

  • Add Static / DB-less (100% serverless) Component
  • DOM ID Layer handling massively shortened (reduces overall rendering times)
  • Fixed Global Variable Handling / Source Data Handling
  • Add DivUnique, ProgressBar and RangeSlider Object Types
  • Fix Default Loader XMLRPC Type from POST to GET
  • Set Button default type to POST, add RequestMethod Property (object.json) for all Button Types
  • Improve CSS / Bootstrap Styling
  • Documentation Update

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Copilot AI review requested due to automatic review settings July 30, 2026 08:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Release candidate v1.0.1 update focused on the JS runtime/UI object layer: new object types (ProgressBar/RangeSlider/DivUnique), updated DOM/Bootstrap rendering, button request-method handling, and global variable/source-object integration.

Changes:

  • Updated XMLRPC request defaults/headers and introduced button-controlled request method selection.
  • Refactored several UI components to use Bootstrap list-group/card patterns and shortened/overridden DOM IDs.
  • Added new system objects: DivUnique, ProgressBar, and RangeSlider, plus global var set/get plumbing.

Reviewed changes

Copilot reviewed 20 out of 21 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
www/sysXMLRPCRequest.js Changes XMLRPC request defaults (GET) and request URL/header construction.
www/sysSourceObjectHandler.js Implements GlobalVar source-object resolution via sysFactory.getGlobalVar.
www/sysObjTreeSimple.js Bootstrap-based TreeSimple refactor (list-group + icon behavior + container changes).
www/sysObjTabContainer.js Adjusts DOM ID handling/initialization for tab containers.
www/sysObjSQLText.js Tweaks post-icon HTML formatting for text rendering.
www/sysObjRangeSlider.js Adds new RangeSlider system object (input[type=range]).
www/sysObjProgressBar.js Adds new ProgressBar system object with percent rendering.
www/sysObjOpenCloseContainer.js Switches header text rendering to sysObjSQLText and updates ID handling.
www/sysObjList.js Enables override DOM object IDs for list instances.
www/sysObjFormfieldList.js Adds DOM ID overrides + SetDataMapping support + validation refactors.
www/sysObjFormfieldItem.js Formatting/alignment changes in formfield item text constructor.
www/sysObjFileUpload.js Sets ObjectID from ID and fixes a missing semicolon in progress rendering.
www/sysObjDiv.js Refactors Div constructor formatting and adds sysObjDivUnique.
www/sysObjContextMenu.js Refactors context menu structure to a Bootstrap list-group + hover highlighting.
www/sysObjButtonInternal.js Adds DOM ID override + object ID setting and clarifies property comments.
www/sysObjButtonCallback.js Adds DOM ID override + object ID setting and clarifies property comments.
www/sysObjButton.js Reorders click processing and adds request-method selection + new actions (set/setglobalvar).
www/sysFormfieldValidate.js Updates group validation fallback to UserValidateGroup and adds debug logging.
www/sysFactory.js Registers new object types and adds setGlobalVar.
www/sysBaseObject.js Minor formatting/spacing change in object-type lookup section.
www/sysAsyncNotifyIndicatorItem.js Adjusts Bootstrap styling classes for async notify indicator items.

Comment thread www/sysXMLRPCRequest.js
Comment thread www/sysFormfieldValidate.js
Comment thread www/sysObjButton.js
Comment thread www/sysObjFormfieldList.js
Comment thread www/sysObjTreeSimple.js
@clauspruefer clauspruefer changed the title Release Candidate Version 1.0.1 Release Candidate Version 1.1 Jul 30, 2026
clauspruefer and others added 3 commits July 30, 2026 10:56
@clauspruefer

clauspruefer commented Jul 30, 2026

Copy link
Copy Markdown
Member Author

@copilot Please do the following:

Base Behaviour

Currently a single system object (prefixed with sysObj...js) can contain overidable RuntimeGetDataFunc, RuntimeSetDataFunc and RuntimeAppendDataFunc function pointers to set, get and append data to an objects internal data structures.

This makes it possible for each object to handle its own routines for an objects internal data manipulation.

Object Relationship

Recursive "Object Relationship" is handled by sysBaseObject.js, especially the sysBaseObject.render() method when called, recursive constructs / renders object hierarchies. So an objects reference is handled by this.ChildObjects Array and the ParentObject property of an object the relation to the parent.

Recursive Data Getter and Setter

Currently it is only possible to set a single objects data. It must be possible to do getting and setting in a recursive way, appending is only possible to a single object, for appenfing, nothing should change / must be done.

Recursive Setter

The RuntimeSetDataFunc must be modified, so that its input parameter JSON can be set hierarchical / recursive.

The following example data shows a sysObjList type which gets filled with two "rows" with sum of 4 values.

{
    "ObjectIDs":
    {
        "sysObjListID":
        [
            {
                "ObjectIDs":
                {
                    "Column1":
                    {
                        "Property1": "Value1"
                    },
                    "Column2":
                    {
                        "Property1": "Value2"
                    }
                }
            },
            {
                "ObjectIDs":
                {
                    "Column1":
                    {
                        "Property1": "Value3"
                    },
                    "Column2":
                    {
                        "Property1": "Value4"
                    }
                }
            }
        ]
} 

This is a simple example, imagine a more complex setup with two container objects:

{
    "ObjectIDs":
    {
        "Container1":
        {
            "ObjectIDs":
            {
                "sysObjListID":
                [
                    {
                        "ObjectIDs":
                        {
                            "Column1":
                            {
                                "Property1": "Value1"
                            },
                            "Column2":
                            {
                                "Property1": "Value2"
                            }
                        }
                    },
                    {
                        "ObjectIDs":
                        {
                            "Column1":
                            {
                                "Property1": "Value3"
                            },
                            "Column2":
                            {
                                "Property1": "Value4"
                            }
                        }
                    }
                ]
            }
        },
        "Container2":
        {
            "ObjectIDs":
            {
                "Container3":
                {
                    "ObjectIDs":
                    {
                        "Property10": "Value5"
                    }
                }
            }            
        }
    }
} 

Recursive Getter

Each object must also have the possibility to get data automatically in a recursive way. The obect hierarchy is already known by the system with ChildObjects Array.

Objects containing no data get or set references RuntimeGetDataFunc, RuntimeSetDataFunc (only-div-container objects) must be not be processed.

So the recursive loop must process all obect instances (starting with the selected root object:

sysFactory.getObjectByID().RuntimeGetDataFunc(recursive=true)

This must return only the hierarchical JSON data without the "ObjectIDs" definitions (setter).

Proposals

Please propose some integration approaches.

Copilot AI commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@copilot Please do the following:

Base Behaviour

...

Here are two concrete integration approaches. Both build on the existing RuntimeGetDataFunc/RuntimeSetDataFunc pattern without changing any per-object implementations.


Approach A — Two dedicated recursive helpers on sysBaseObject

Add getObjectDataRecursive() and setObjectDataRecursive(data) as new prototype methods. No existing callers are affected at all.

// sysBaseObject.js

// Recursive getter: returns flat { ObjectID: value, ... } for every descendant
// that has RuntimeGetDataFunc defined. Pure containers (no RuntimeGetDataFunc) are skipped.
sysBaseObject.prototype.getObjectDataRecursive = function() {
    var Result = new Object();
    for (const ChildItem of this.ChildObjects) {
        if (typeof ChildItem.RuntimeGetDataFunc === 'function') {
            Result[ChildItem.ObjectID] = ChildItem.RuntimeGetDataFunc();
        }
        var ChildResult = ChildItem.getObjectDataRecursive();
        for (var Key in ChildResult) {
            Result[Key] = ChildResult[Key];
        }
    }
    return Result;
};

// Recursive setter: walks the ObjectIDs hierarchy and dispatches to matching objects.
// Pure containers (no RuntimeSetDataFunc) are skipped.
sysBaseObject.prototype.setObjectDataRecursive = function(Data) {
    if (Data === undefined || Data === null) return;
    var ObjectIDs = Data['ObjectIDs'];
    if (ObjectIDs === undefined) return;
    for (var ObjID in ObjectIDs) {
        var ObjData = ObjectIDs[ObjID];
        var TargetObj = this.getObjectByID(ObjID);
        if (TargetObj === undefined) continue;
        if (Array.isArray(ObjData)) {
            // Array → list-type data, call RuntimeSetDataFunc directly
            if (typeof TargetObj.RuntimeSetDataFunc === 'function') {
                TargetObj.RuntimeSetDataFunc(ObjData);
            }
        } else if (ObjData !== null && typeof ObjData === 'object' && ObjData['ObjectIDs'] !== undefined) {
            // Nested container → recurse
            TargetObj.setObjectDataRecursive(ObjData);
        } else {
            // Leaf value (plain object, string, number) → call RuntimeSetDataFunc directly
            if (typeof TargetObj.RuntimeSetDataFunc === 'function') {
                TargetObj.RuntimeSetDataFunc(ObjData);
            }
        }
    }
};

Call site:

var data = sysFactory.getObjectByID('RootID').getObjectDataRecursive();
sysFactory.getObjectByID('RootID').setObjectDataRecursive({ "ObjectIDs": { ... } });

Approach B — Extend existing getObjectData / setObjectData with an optional recursive flag

Keep the same internal helpers from Approach A, but expose them via the existing wrapper methods using an optional parameter. No existing callers break (they pass no argument).

sysBaseObject.prototype.getObjectData = function(recursive) {
    if (recursive === true) {
        return this.getObjectDataRecursive();
    }
    return this.RuntimeGetDataFunc();
};

sysBaseObject.prototype.setObjectData = function(Data, recursive) {
    if (recursive === true) {
        return this.setObjectDataRecursive(Data);
    }
    this.RuntimeSetDataFunc(Data);
};

Call site (matches the API from your comment exactly):

var data = sysFactory.getObjectByID('RootID').getObjectData(true);
sysFactory.getObjectByID('RootID').setObjectData({ "ObjectIDs": { ... } }, true);

Notes common to both approaches

  • Getter output is a flat { ObjectID: value, ... } map — no ObjectIDs wrappers, as specified.
  • Setter dispatch uses getObjectByID() (which already walks the full object tree) to resolve each ID in the hierarchy, so the caller does not need to know the tree depth.
  • Append stays single-object only (appendObjectData() is unchanged), as you specified.
  • Objects with RuntimeGetDataFunc === undefined or RuntimeSetDataFunc === undefined are silently skipped in both directions.

Recommendation: Approach B, since it matches the getObjectData(recursive=true) call signature you described and requires the fewest new entry points. The recursive logic lives in the two private helpers (getObjectDataRecursive / setObjectDataRecursive), and getObjectData / setObjectData remain the single public API. Let me know which approach to implement.

@clauspruefer

Copy link
Copy Markdown
Member Author

@copilot please implement Recommendation: Approach B, but modify it, so that it is possible at a specified setter NODE it is possible to specify to "SET" or "APPEND" (yes, i changed my mind, appending also must be possible). E.g. we have two container objects which contain 2 list objects, it must be possible to set data in a container object and to append data to a specified list object.

Copilot AI commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@copilot please implement Recommendation: Approach B, but modify it, so that it is possible at a specified setter NODE it is possible to specify to "SET" or "APPEND" (yes, i changed my mind, app...

Implemented in commit Add recursive get/set with per-node Action support to sysBaseObject.

GettergetObjectData(true) walks the subtree rooted at the caller. Objects that have RuntimeGetDataFunc contribute their data and stop recursion (they own their own subtree). Pure containers (no RuntimeGetDataFunc) are skipped but their children are still traversed. Returns a flat { ObjectID: value, ... } map.

SettersetObjectData(data, true) walks the "ObjectIDs" hierarchy. At any node you can either:

  • Pass data directly (array or plain value) → calls RuntimeSetDataFunc (default set)
  • Pass a nested { "ObjectIDs": { ... } } object → recurses into that container
  • Pass an action directive → controls set vs. append at that specific node:
{
    "ObjectIDs": {
        "Container1": {
            "ObjectIDs": {
                "ListA": { "Action": "set",    "Data": [...] },
                "ListB": { "Action": "append", "Data": [...] }
            }
        }
    }
}

All existing getObjectData() / setObjectData(data) callers are unaffected (the new parameters are optional).

@clauspruefer

Copy link
Copy Markdown
Member Author

@copilot please a) add 1 example in /examples containing multiple object get / set scenarios (apx. 10 different ones) b) update the documentation for getObjectData, setObjectData, getObjectDataRecursive and getObjectDataRecursive.

Copilot AI commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@copilot please a) add 1 example in /examples containing multiple object get / set scenarios (apx. 10 different ones) b) update the documentation for getObjectData, setObjectData, `getObjectData...

Done in commit Add recursive object data example and doc updates for getObjectData/setObjectData.

a) example/recursive_object_data/recursive_object_data_examples.js — 10 scenarios:

  1. Flat single-object GET (non-recursive baseline)
  2. Flat single-object SET (non-recursive baseline)
  3. Recursive GET from a container root
  4. Recursive SET on a leaf inside a container
  5. Recursive SET on a list object (array data)
  6. Recursive SET across two sibling containers
  7. Recursive SET with explicit "Action": "set" directive
  8. Recursive SET with explicit "Action": "append" directive
  9. Mixed SET + APPEND in one call across nested containers
  10. Recursive GET after recursive SET (round-trip verification)

The new example is also listed in example/README.md.

b) doc/dev-oop-classes.rst — new sections 24.1.6 and 24.1.7 covering:

  • getObjectData / setObjectData — signatures, parameters, non-recursive usage, recursive getter, recursive setter ObjectIDs schema (with Action directive), backward compatibility note
  • getObjectDataRecursive / setObjectDataRecursive — implementation listing, traversal rules, reference to the example file

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants