Child pages
  • Foundset property type
Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 8 Next »

Purpose of this property type

The 'foundset' property type can be used by web components to access/change a foundset's data 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:

Browser side provided property content in model
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)
    },

    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
}

 

  • serverSize is controlled by the server; you should not change it

  • viewPort initially has size 0, and startIndex 0. When the component detects that records are available (serverSize > 0) it care request viewPort contents using one of the two load async methods
  • viewPort.startIndex and viewPort.size will have the values requested by the async load methods. But if for example you are using data at the end of the foundset and records are deleted from there then viewport.size will be corrected/decreased from server (as there aren't enough records). A similar thing can happen to viewPort.startIndex. Do not modify these directly as that will have no effect. Use the load async methods instead.
  • viewPort.rows contains the viewPort data. Each item of the array represents data from a server-side record. Each item will always contain a "_svyRowId" ($foundsetTypeConstants.ROW_ID_COL_KEY in angular world) entry that uniquely identifies the record on server. Then there's one entry for every dataprovider that the component needs to use (how those are selected is described below). You should never change the "_svyRowId" entry, but it is possible to change the values of any of the other entries - the new values will be pushed back into the server side record that they belong to.
  • selectedRowIndexes is an array of selected foundset record indexes. This can get updated by the server if foundset selection changes server side. You can change the contents of this array to change foundset selection (new selection will be pushed to server).
  • multiselect represents the foundset multiselect state; do not change it as it will not be pushed to server.

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" }

or

"myfoundset": "foundset"

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.

Browser side provided property content in model
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:

Browser side provided property content in model
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.

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

.spec file

"childElements" : { "type" : "component", "forFoundsetTypedProperty": "myfoundset" }, `

browser js

Then we have to have also a components property that maps on this one:

 

 Then the components dictate which dataproviders will be send over for that foundset selector.

Or we can have by configuration type, so instead of childelements we have:

 

"myconfigurations": "MyConfig"
"types": {
    "MyConfig": { 
        "mydataprovider" : { "type" : "dataprovider", "forFoundsetTypedProperty": "myfoundset"}
    }
}

Then the configuration dictates which dataproviders are send over  for that foundset.

In these 2 scenario's the viewport of the foundset only contains the rowid's and the components (childElements) or configuration (myconfigurations) have the viewPort for that row data (we as an example below)

 

Besides these 2 options where which dataproviders are defined by another property the foundset property can also define the dataprovider itself:

"myfoundset": {"type":"foundset", "dataproviders":["firstname","lastname"]}

 

Now the foundset itself just specifies what dataproviders it expects in its viewport rows.

The dataproviders will be mapped just like a normal webcomponent, so in the browser value you will have "firstname" and "lastname" and those are filled in on the server side based on the dataprovider they are mapped on in the designer.

Browser value:

Here is a sample of what the value of a 'foundset' typed property contains in the browser - web component model:

Initially the viewPort is an empty array (size 0) and startIndex is 0 as well. Client side JS can watch the value of serverSize and when recods become available it can request the desired Viewport using loadRecordsAsync.

If more records need to be shown besides the already loaded ones use loadExtraRecordsAsync.

Changes made in browser to viewPort.rows data content (so column value modifications) will be sent server-side.

Changes made in browser to selectedRowIndexes content will change selection on server side as well.

Design value (generated visually by form designer and written in .frm file, so Servoy users don't need to know about it)

Contents in .frm file
myFoundset: {
        foundsetSelector: "", 
        dataproviders: [firstname:'columnOrOtherDataprovider',lastname:"someotherDataprovider"]
    }
}"

'foundsetSelector' can be:

  • "" - use parent (form's) foundset;
  • "myRelation" will give a related foundset;
  • "datasource" would give a seoarate foundset for the given datasource

'dataProviders' specifies what are the data columns mappings that need to be available in the browser - in the foundset property's 'viewPort' - in rows. These are only there if the foundset property in the spec are asking for specific dataproviders.

Runtime usage (server side Servoy JS)

[TODO] just make the ususal foundset obj. available in scripting

  • No labels