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
foreignKey
s; 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