Skip to main content

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 typePurpose
FdcStringFieldText values
FdcIntegerFieldInteger values
FdcDecimalFieldFixed-scale decimal values
FdcBooleanFieldBoolean values
FdcDateFieldDate-only values
FdcTimeFieldTime-only values
FdcDateTimeFieldDate and time values
FdcGuidFieldGUID values
FdcObjectFieldArbitrary 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