Indicates that this field should be fetched from another, related DataSource.
The includeFrom attribute should be of the form "dataSourceId.fieldName", for example:
<field includeFrom="supplyItem.itemName"/>
A foreignKey declaration must exist between the two DataSources, establishing either a 1-to-1 relationship or a many-to-1 relationship from this DataSource to the related DataSource. The inclusion can be indirect (traverse multiple DataSources) so long as there is a chain of foreignKey declarations from the target DataSource to the DataSource where the includeFrom field is declared. You may use dot-notation to provide an explicit path between DataSources, or provide the name of only the last DataSource in the chain to have the complete path calculated for you at runtime. i.e., either of the following are acceptable forms, where foreign keys are defined to link records in the current DataSource to Employee records and in turn to Office records:
<field includeFrom="Employee.Office.territory"/>
<!-- OR -->
<field includeFrom="Office.territory"/>
Note that when using the shorthand form, there is potential ambiguity: there could be multiple ways in which two DataSources are related via different intervening DataSources, so the auto-discovered relation may be different depending on which other DataSources are loaded in the page. For this reason, explicitly spelling out the inclusion path is preferred.
Nested inclusions, where an included field is itself an included field, are also supported - for details on this and other complex scenarios see includeVia docs.
In all cases, name will default to the name of the included field, or you can specify a different name.
If both DataSources are SQLDataSources, HibernateDataSources or JPADataSources (with Hibernate as the provider) the related data will be retrieved via a SQL join and criteria and sort directions applied to the field work normally (they become part of the generated SQL query).
Note that includeFrom is also supported between two clientOnly or MockDataSources, but not for any other combination (for example, a RestDataSource cannot use includeFrom with a clientOnly DataSource). Here, the related data (including any values derived via includeSummaryFunction) will be retrieved from cacheData after the primary (fetch, add, or update) operation has returned its response.
Otherwise, the related data will be retrieved via performing a DSRequest against the related DataSource once the data from the primary DataSource has been retrieved. In this case, criteria or sorting directions applied to the included field are only allowed if data paging is not in use (for example ListGrid.dataFetchMode:"basic"); otherwise, criteria and sort direction are ignored for the included field and a warning is logged on the server.
Editing included fields
An included field is canEdit:false by default. Note that included fields are not updatable, even if you set canEdit:true; the server will simply drop values for included fields if client code sends them.
When thinking about editing an included field value, typically what is really intended is to edit the value of the foreignKey field. For example, take the scenario of a system that tracks accounts and the employees assigned to manage them. Given a DataSource "account" related one-to-one with DataSource "employee" by a "managerId" foreignKey field, we might declare an includeFrom so that the name of the account manager can be shown with each "account" record.
Editing the manager's name while viewing the account would be intended to pick a new account manager, and not to change the legal name of the employee who happens to be the current account manager.
To correctly set up this scenario, declare an includeFrom field that is hidden, but is used as the displayField for the foreign key field:
<field name="managerId" foreignKey="employee.id" displayField="managerName" />
<field name="managerName" includeFrom="employee.name" hidden="true"/>
Now:
- the "managerId" foreignKey field is shown in grids and forms, but takes its displayed value from the hidden
includeFrom field. Note that when the foreignKey and displayField are specified, the framework automatically defaults useLocalDisplayFieldValue to true to ensure the displayed value is picked up from the record being edited. - the automatically chosen editor will be a SelectItem with
optionDataSource set to "employees": it will allow picking a different "employee" record from the "employee" DataSource. - saving will save the ID of a new "employee" record to the "managerId" foreign key field, as intended
You can alternatively set
editorType="ComboBoxItem" on the "managerId" field to allow typeahead search of the "employee" DataSource. Note that the
foreignDisplayField attribute allows developers to have a different fieldName be used locally as a displayField from the field name for the display field in the foreign dataSource.
Including fields that use summary functions
The Include Summary Function feature is used for including from a related DataSource where there are multiple related records. It applies a SummaryFunctionType to the related records aggregating them into single value. It is regularly used on directly included fields, but it supports indirect inclusions as well, when entire includeFrom+includeSummaryFunction setup is included from another DataSource. See includeSummaryFunction docs for more details.
For best results, ensure that the field with includeFrom has its type explicitly set to the included field's type.
includeFrom combined with multiple:true
If you specify multiple:true on an includeFrom field, it has one of two quite different meanings:
- It is including a field which is itself marked
multiple:true, across a regular many-to-one or one-to-one relation. In this case, the value of the included field is likely to be a flattened list of text values stored in a regular text field - see multipleStorage - It is including multiple related values across a one-to-many or many-to-many relation
The first of these is exactly the same as any other regular
includeFrom, except that it will have normal
multiple:true processing applied to the included value, so the client sees a true list of values rather than a flat string of text.
The second is more involved. With this type of includeFrom we will actually fetch multiple records from the included DataSource. You should read the One-to-many and Many-to-many sections of the relations overview to make sure you understand how these relation types work, but essentially you declare a foreignKey on a field that is also marked multiple:true, and this causes Smart GWT to return a list of key values that your client-side code can use to obtain the related records (some Smart GWT UI components will do this automatically).
Once one of these relation types is in place, it is also possible to declare includeFrom fields that make use of the relation to include fields other than the identifying key field, for convenience. For example, if a Country dataSource declared a one-to-many relation to a City dataSource, like this:
<field name="majorCities" multiple="true" foreignKey="City.cityId" />
The same dataSource could make use of that relation to include the names of all related cities for convenience, so you can show a list of "Major Cities" against each country without having to go back to the server and fetch the actual City records. The declaration would look like this:
<field name="cityNames" multiple="true" includeFrom="City.cityName" />
With
Many-to-many related includeFroms - which require a "middle" dataSource, and thus a three-part
foreignKey declaration - you may specify either the entire inclusion path, or just the endpoint. For example, if your
Country dataSource has a many-to-many relation with a
River dataSource - necessary, because most countries contain more than one river, and many rivers flow through more than one country - via the following
foreignKey definition:
<field name="rivers" multiple="true" foreignKey="CountryRivers.Rivers.riverId" />
you could
includeFrom the list of related river names with either this:
<field name="riverNames" multiple="true" includeFrom="CountryRivers.Rivers.name" />
or slightly simpler, this:
<field name="riverNames" multiple="true" includeFrom="Rivers.name" />
If just the endpoint is specified, Smart GWT will figure out the remainder of the path based on the available
foreignKeys; if there is ambiguity that makes this impossible - ie, two
foreignKey fields that target the same endpoint via different paths - you can either specify the entire include path in the
includeFrom definition, or declare an
includeVia setting on the field.
Default value is null