Child pages
  • Foundset property type

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

You might wonder - "why is setting a complete new foundset into a foundset typed property from server side scripting helpful?". This is helpful for example in implementing more advanced tree-like components, that need to operate with multiple foundsets.

 

Expand
titleFor Servoy < 8.3 expand this section.

In combination with Foundset Reference type ("foundsetRef"), Record Finder type ("rowRef") and calls from client-side scripting to server-side component scripting, such components can query/create foundsets on server on-the-fly according to different requirements, put them in the model of the component (for example in a foundset array property that is initially empty []). Then they also store in the properties the "unique id" using the Foundset Reference type and return that id as well from the server-side scripting call. This means that on the client it has access to the new foundset and it can identify it via the "unique id". Also if server-side scripting needs a record from a foundset that is already on the client to create it's new foundset (maybe they need to be related in some way), then all the client has to do is send to the server the foundset reference "unique id" together with the rowId (from the foundset property type's viewport) of that record and on the server you will be able to find the record using the Record Finder type.

Here is a partial example of what a tree-table might need to do in order to handle large amounts of data properly on all levels:

Code Block
languagejs
titleClient-side .js
function getChildFoundSetHash(parentFoundsetHash, rowId, parentLevelGroupColumnIndex,
                                                  newLevelGroupColumnIndex) {
	// parentFoundsetHash comes from the foundset referece type property
    // rowId comes from the foundset property type's viewport
    // parentLevelGroupColumnIndex and newLevelGroupColumnIndex are indexes in
    // an array property that holds dataproviders
    var childFoundsetPromise;

    if (newLevelGroupColumnIndex) {
        childFoundsetPromise = $scope.svyServoyapi.callServerSideApi("getGroupedChildFoundsetUUID",
                      [parentFoundsetHash, rowId, parentLevelGroupColumnIndex, newLevelGroupColumnIndex]);
    } else {
        childFoundsetPromise = $scope.svyServoyapi.callServerSideApi("getLeafChildFoundsetUUID",
                      [parentFoundsetHash, rowId, parentLevelGroupColumnIndex]);
	}

    childFoundsetPromise.then(function(childFoundsetUUID) {
        var childFoundset = getFoundSetByFoundsetUUID(childFoundsetUUID);
        mergeData(..., childFoundset);
    }, function() {
        // some error happened
        (...)
    });
}
(...)
function getFoundSetByFoundsetUUID(foundsetHash) {
    if ($scope.model.hashedFoundsets)
        for (var i = 0; i < $scope.model.hashedFoundsets.length; i++) {
            if ($scope.model.hashedFoundsets[i].foundsetHash == foundsetHash)
                return $scope.model.hashedFoundsets[i].foundset;
		 
    return null;
}
Code Block
languagejs
titleServer-side .js
$scope.getGroupedChildFoundsetUUID = function(parentFoundset, parentRecordFinder, parentLevelGroupColumnIndex,
                                                              newLevelGroupColumnIndex) {
        if (!parentFoundset) parentFoundset = $scope.model.myFoundset.foundset;
        var childQuery = parentFoundset.getQuery();
		
        if (parentLevelGroupColumnIndex == undefined) {
            // this is the first grouping operation; alter initial query to get all first level groups
            (...)
        } else {
			// this is an intemediate group expand; alter query of parent level for the child level
			childQuery.groupBy.clear();
            childQuery.groupBy.add(childQuery
                      .columns[$scope.model.columns[newLevelGroupColumnIndex].dataprovider]);
            var parentGroupColumnName = $scope.model.columns[parentLevelGroupColumnIndex].dataprovider;
            childQuery.where.add(childQuery.columns[parentGroupColumnName]
                      .eq(parentRecordFinder(parentFoundset)[parentGroupColumnName]));
        }
		
        var childFoundset = parentFoundset.duplicateFoundSet();
		childFoundset.loadRecords(childQuery);
		
		var dps = {};
		for (var idx = 0; idx < $scope.model.columns.length; idx++) {
			dps["dp" + idx] = $scope.model.columns[idx].dataprovider;
		}
		
		$scope.model.hashedFoundsets.push({ foundset: {
			foundset: childFoundset,
			dataproviders: dps,
			sendSelectionViewportInitially: false,
			initialPreferredViewPortSize: 15
		}, foundsetUUID: childFoundset}); // send it to client as a foundset property with a UUID
		
		return childFoundset; // return the UUID that points to this foundset (return type will make it UUID)
	};

For versions prior to Servoy 8.2 please use "api" instead of "internalApi" below:

Code Block
languagejs
title.spec file
	"serverscript": "mycomppck/mycompname/mycomp_server.js",
(...)
	"model": 
	{
        "columns": { "type": "columnDef[]", "droppable": true },
        "hashedFoundsets": { "type": "hashedFoundset[]", "default": [] }
(...)
	"types": 
	{
        "columnDef": {
            "dataprovider": { "type": "dataprovider", "forFoundset": "myFoundset" }
            (...)
        },
        "hashedFoundset" : {
	  		"foundset": "foundset",
	  		"foundsetUUID": "foundsetRef"
		}	
	},
	"internalApi" : {
		"getGroupedChildFoundsetUUID" : {
			"returns" : "foundsetRef",
			"parameters" : 
			[{
					"name" : "parentFoundset",
					"type" : "foundsetRef"
				}, {
					"name" : "parentRecordFinder",
					"type" : "rowRef"
				}, {
					"name": "parentLevelGroupColumnIndex",
					"type": "int"
				}, {
					"name": "newLevelGroupColumnIndex",
					"type": "int"
				}
			]
		},
(...)

...