Fields
Fields define the typed schema of an FdcDataSet. A field definition describes what a value means, how it is validated, how it participates in persistence, and how data-aware controls should treat it.
Available field types
FD Components provides typed field definitions for:
| Field type | Purpose |
|---|---|
FdcStringField | Text values |
FdcIntegerField | Integer values |
FdcDecimalField | Fixed-scale decimal values |
FdcBooleanField | Boolean values |
FdcDateField | Date-only values |
FdcTimeField | Time-only values |
FdcDateTimeField | Date and time values |
FdcGuidField | GUID values |
FdcObjectField | Arbitrary object values |
Combo behavior is provided by combo editors and grid columns over these typed values; it is not a separate dataset field type.
Define a schema
final customers = FdcDataSet(
fields: const <FdcFieldDef>[
FdcIntegerField(
name: 'id',
label: 'ID',
isKey: true,
storage: FdcFieldStorage(updateable: false),
),
FdcStringField(
name: 'company',
label: 'Company',
size: 120,
required: true,
),
FdcDecimalField(
name: 'credit_limit',
label: 'Credit limit',
precision: 12,
scale: 2,
minValue: 0,
),
FdcBooleanField(
name: 'active',
label: 'Active',
defaultValue: true,
),
],
);
Field names are part of the data contract. They are used by row maps, adapters, database columns or JSON keys, filtering, sorting, grids, and editors.
Field lookup through the dataset is case-insensitive, while the declared name casing remains available for metadata and output.
FdcFieldDef and FdcField serve different roles
This distinction is fundamental.
FdcFieldDef: schema metadata
A field definition is stable metadata:
final amountDef = dataSet.fieldDef<FdcDecimalField>('amount');
print(amountDef.precision);
print(amountDef.scale);
print(amountDef.required);
Use field definitions when you need type-specific schema information.
FdcField: current runtime value
fieldByName returns a runtime accessor bound to the dataset current record or active edit buffer:
final amount = dataSet.fieldByName('amount');
print(amount.asDecimal);
print(amount.isNull);
Writing through FdcField.value follows normal dataset editing rules:
dataSet.edit();
dataSet.fieldByName('company').value = 'Northstar Systems';
dataSet.post();
For short code, bracket access is equivalent:
final company = dataSet['company'];
dataSet.edit();
dataSet['company'] = 'Northstar Systems';
dataSet.post();
Typed runtime accessors
FdcField exposes type-aware read accessors:
final name = dataSet.fieldByName('name').asString;
final quantity = dataSet.fieldByName('quantity').asInteger;
final amount = dataSet.fieldByName('amount').asDecimal;
final active = dataSet.fieldByName('active').asBoolean;
final dueDate = dataSet.fieldByName('due_date').asDate;
Using an accessor that does not match the field data type throws a StateError. This makes type mismatches visible instead of silently coercing unrelated types.
Validation metadata
Field definitions can carry built-in and custom validation rules:
FdcStringField(
name: 'company',
required: true,
size: 120,
)
Type-specific fields add their own constraints. For example, numeric fields can enforce ranges and decimal fields can define precision and scale.
Validation participates in the normal editing lifecycle and is covered in detail in the validation guide.
Defaults
Defaults initialize new records:
FdcBooleanField(
name: 'active',
defaultValue: true,
)
A zero-argument factory can create a fresh value for each new record:
FdcGuidField(
name: 'id',
isKey: true,
defaultValue: FdcGuid.newGuid,
)
Defaults apply when a new inserted or appended record is materialized. They are not applied when existing rows are loaded.
Calculated and persistent fields
A field can derive its value from the current row through calculatedValue. Calculated fields are read-only to normal dataset writes.
Persistence is controlled by the field definition. Regular fields are persistent by default; calculated fields are non-persistent by default unless explicitly overridden.
This distinction matters for changeSet, hasUpdates, adapter writes, and toMaps output.
Storage metadata
FdcFieldStorage controls persistence write behavior:
FdcIntegerField(
name: 'id',
isKey: true,
storage: FdcFieldStorage(
generated: true,
),
)
The main flags are:
generated— storage generates the value;insertable— value may participate in inserts;updateable— value may participate in updates.
Storage metadata controls persistence behavior. A grid column or editor may impose additional UI-level read-only policy independently.
Next: Records