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