processRules method
Executes all rules associated with a specific cell upon value change.
Implementation
void processRules(int changedRow, int changedCol, String newValue) {
if (_formRules.isEmpty || _getTableDataCallback == null) return;
bool stateChanged = false;
List<List<String>> currentGrid = _getTableDataCallback!();
for (var rule in _formRules) {
if (rule.rowIndex == changedRow && rule.colIndex == changedCol) {
String stateKey = "${changedRow}_${changedCol}";
_cellStates.putIfAbsent(stateKey, () => CellFormState());
final state = _cellStates[stateKey]!;
String workingValue = newValue;
// 1. Process Overrides
if (rule.overrideValue != null) {
String? overrideResult = rule.overrideValue!(newValue, currentGrid);
if (overrideResult != null && overrideResult != newValue) {
workingValue = overrideResult;
state.isOverridden = true;
if (rule.overrideMessage != null) {
state.overrideMessage = rule.overrideMessage!(newValue, currentGrid);
} else {
state.overrideMessage = null;
}
// Update UI cursor cleanly
final tController = _textControllers[stateKey];
if (tController != null) {
tController.text = workingValue;
tController.selection = TextSelection.collapsed(offset: workingValue.length);
}
} else {
state.isOverridden = false;
state.overrideMessage = null;
}
}
// 2. Process Validation (Always runs on the RAW newValue)
String? errorResult = rule.validate(newValue, currentGrid);
if (state.errorText != errorResult) {
state.errorText = errorResult;
stateChanged = true;
}
if (state.isOverridden) stateChanged = true;
}
}
if (stateChanged) notifyListeners();
}