Purpose of this property type

The 'foundset' property type can be used by web components to access/change a foundset's data/state directly from the browser.

The foundset typed property in the browser will work based on a 'viewport' of the server's foundset. The viewport is controlled directly by the component's code. Server will adjust foundset viewport bounds/contents only when needed due to data changes, removes, inserts...

The foundset property also gives the possibility of knowing/changing the selection of the foundset.

For advanced uses, the foundset property can be linked to/interact with other property types (dataprovider, tagstring, component, ...), so that those other properties will provide a viewport as well - representing the same rows/records as in the foundset's viewport. The properties that support foundset view of data will allow the web component to specify a "forFoundset: "[foundsetPropertyName]" in their own property's description in the .spec file.

Foundset property value in browser

In browser js, a foundset property value has the following content:

myFoundset: {
    serverSize: 44, // the size of the foundset on server (so not necessarily the total record count in case of large DB tables)

    // this is the data you need to have loaded on client (just request what you need via provided loadRecordsAsync or loadExtraRecordsAsync)
    viewPort: {
        startIndex: 15,
        size: 5,
        rows: [ { _svyRowId: 'someRowIdHASH1', name: "Bubu", type: 2 },
                { _svyRowId: 'someRowIdHASH2', name: "Ranger", type: 1 },
                { _svyRowId: 'someRowIdHASH3', name: "Yogy", type: 2 },
                { _svyRowId: 'someRowIdHASH4', name: "Birdy", type: 3 },
                { _svyRowId: 'someRowIdHASH5', name: "Wolfy", type: 4 } ],

        /** Request a change of viewport bounds from the server; the requested data will be loaded asynchronously in 'viewPort'
          * @param startIndex the index that you request the first record in "viewPort.rows" to have in the real foundset (so the beginning of the viewPort).
          * @param size the number of records to load in viewPort.
          */
        loadRecordsAsync: function(startIndex, size),

        /** Request more records for your viewPort; if the argument is positive more records will be loaded at the end of the 'viewPort', when negative more records will be loaded at the beginning of the 'viewPort' - asynchronously.
          * @param negativeOrPositiveCount the number of records to extend the viewPort.rows with before or after the current loaded records.
          */
        loadExtraRecordsAsync: function(negativeOrPositiveCount),
 
		/**
          * Sort the foundset by the dataproviders contained in sortColumns. The name property can be filled with the dataprovider name the foundset provides or specifies, or if the foundset is used with a component type (like a portal) then the name is the name of the component name on which the sort should happen on.
          * @param {JSONArray} sortColumns an array of JSONObjects {name:dataprovider, direction:sortDirection},
          *                    where the sortDirection can be "asc" or "desc".
          */
		sort: function(sortColumns),
		/**
          * Request a selection change of the selected row indexes. Returns a promise that is resolved when the client receives the updated selection from the server. If successful, the array selectedRowIndexes will also be updated. If the server does not allow the selection change, the reject function will get called with the 'old' selection as parameter. If requestSelectionUpdate is called a second time, before the first call is resolved, the first call will be rejected and the caller will receive the string 'canceled' as the value for the parameter serverRows.
		  * E.g.: foundset.requestSelectionUpdate([2,3,4]).then(function(serverRows){},function(serverRows){});
		  */
		requestSelectionUpdate : function(selectedRowIdxs) 
    },

    selectedRowIndexes: [16], // array of selected records in foundset; indexes can be out of current viewPort as well
    multiSelect: false // the multiselect mode of the server's foundset; if this is false, selectedRowIndexes can only have one item in it
}

 

Defining/using a foundset property with random set of dataproviders

A web component might want to work with as many dataproviders available in the viewport as the developer wants. Servoy Developer will allow selecting any number of dataproviders of the foundset to be sent to browser web component property value. For example a component that shows graphical representation of data might allow adding as many 'categories' to it as the developer wants to (each category getting data from one viewport column/dataprovider) .

.spec file

"myFoundset": { "type": "foundset", "dynamicDataproviders": true }

So the component has a property called "myfoundset" that it want linked to any foundset chosen in ServoyDeveloper, and it allows the developer to choose any number of dataproviders from the foundset.

browser js

Let's say the developer has chosen a foundset and 3 dataproviders (for example 3 database columns) from it. Those would generate for example a viewPort like this inside the browser property.

myFoundset: {
    (...)
    viewPort: {
        startIndex: 15,
        size: 2,
        rows: [ { _svyRowId: 'someRowIdHASH1', dp1: (...), dp2: (...), dp3: (...) },
                { _svyRowId: 'someRowIdHASH2', dp1: (...), dp2: (...), dp3: (...) } ],
        (...)
    },
    (...)
}

Notice the fixed column names: dp1, dp2, ... dp[N] where N is the number of foundset dataproviders that the developer has chosen.

Defining/using a foundset property with fixed set of dataproviders

 

A web component can specify in it's .spec file that it requires a foundset property and a fixed number of dataproviders from it. The foundset and required dataproviders are then selected by the developer when creating a solution.

.spec file

"myFoundset": { "type": "foundset", "dataproviders": ["firstName", "lastName"] }

So component has a property called "myfoundset" that it want linked to any foundset chosen in ServoyDeveloper, and it needs two dataproviders from that foundset to be present in the foundset's property viewport.

browser js

Let's say the developer has chosen a foundset and selected for "firstName" a foundset dataprovider (for example a database column called parentFirstName) and for lastName another dataprovider (for example a database column called parentLastName). Those would generate for example a viewport like this inside the browser property:

myFoundset: {
    (...)
    viewPort: {
        startIndex: 15,
        size: 2,
        rows: [ { _svyRowId: 'someRowIdHASH1', firstName: (...), lastName: (...) },
                { _svyRowId: 'someRowIdHASH2', firstName: (...), lastName: (...) } ],
        (...)
    },
    (...)
}

In this way any foundset dataprovider/column can be mapped to one of the two dataproviders that the component requires. The actual foundset dataprovider name is not even used in browser js.

Linking other "foundset aware" property types to a foundset property

Other property types can have content that is 'linked' to foundset records in some way. These property types can be configured in the .spec file as shown below - linking to any other property they have defined with 'foundset' type. When they are linked to a foundset, their javascript value in the browser is no longer only one value, but a viewPort of values (or it will also contain a viewPort of values - the exact content is property type specific) - corresponding to the records loaded in the linked foundset property's viewPort.

In this scenario, the viewPort of the foundset value only contains '_svyRowId' if it's own .spec property configuration doesn't list a dynamic or static list of dataproviders ("dataproviders" : [...] or "dynamicDataproviders": true), and the "foundset aware" property type value will have the viewPort contents in it (check each "foundset aware" type to see how that works, as it could differ from type to type).

Component type (child components that are linked to a foundset - for tables, lists, ...) or custom object types built of/containing other "foundset aware" property types (let's call them 'configurations' - can be used to build lightweight pure HTML tables, lists, ...) are the most common uses in this area.

Examples of foundset aware types are 'component', 'dataprovider', 'tagstring'.

.spec file

One child component linked to the foundset:

"myFoundset": "foundset",
"childElement" : { "type" : "component", "forFoundset": "myFoundset" }

Multiple child components (array of them, notice 'elementConfig' that specifies a config value for each contained element) linked to the foundset. This type of linking is currently used by Servoy's tableviews, listviews and portals:

"myFoundset": "foundset",
"childElements" : { "type" : "component[]", "elementConfig" : {"forFoundset": "myFoundset"} }

Have a look at 'component' page to see how these two properties above will look like in browser js.

 

'Configuration' object for sending several "foundset aware" types as viewPorts (Note: the "forFoundset" usage for "dataprovider" and "tagstring" types is not yet implemented in first 8.0 public alpha, but it is implemented in first public beta):

"myFoundset": "foundset",
"myconfiguration": "MyConfig", // or:
"myconfigurations": "MyConfig[]"
(...)
"types": {
    "MyConfig": { 
        "mydataprovider" : { "type" : "dataprovider", "forFoundset": "myFoundset"}
        "mytagstring" : { "type" : "tagstring", "forFoundset": "myFoundset"}
    }
}

Runtime property access

Runtime usage: in Servoy server side JS 'foundset' typed properties are not currently available. This could change though in the near future to allow access to the real underlying foundset object (and maybe other customisations as well).