texts = parseStringList('texts', map);
listType =
parseEnum<ComboboxListType>('listType', map, ComboboxListType.values);
- listOption = parseString('listOption', map) ?? '';
+ listOption = parseString('listOption', map);
values = parseValueList('values', map, dataType);
switch (listType) {
case ComboboxListType.undef:
/// and [values].
static ComboboxData createByType(
DataType dataType, List<String> texts, Iterable values) {
- ComboboxData rc;
- switch (dataType) {
- case DataType.bool:
- rc = ComboboxData<bool>(texts, values);
- break;
- case DataType.currency:
- case DataType.int:
- case DataType.reference:
- rc = ComboboxData<int>(texts, values);
- break;
- case DataType.date:
- case DataType.dateTime:
- rc = ComboboxData<DateTime>(texts, values);
- break;
- case DataType.float:
- rc = ComboboxData<double>(texts, values);
- break;
- case DataType.string:
- rc = ComboboxData<String>(texts, values);
- break;
+ if (values != null && values.length == 0) {
+ values = null;
}
+ ComboboxData rc = ComboboxData(texts, values);
return rc;
}
}
-class ComboboxData<T> {
+class ComboboxData {
final List<String> texts;
- final List<T> values;
+ List _values;
WaitState waitState;
- ComboboxData(this.texts, this.values, [this.waitState = WaitState.undef]);
+ ComboboxData(this.texts, this._values, [this.waitState = WaitState.undef]);
+
+ /// Returns the length of [_values].
+ int get valuesLength => _values == null ? 0 : _values.length;
+
+ /// Adds a [value] to the [values].
+ void addValue(dynamic value) {
+ if (_values == null) {
+ _values = [value];
+ } else {
+ _values.add(value);
+ }
+ }
+
+ /// Adds a [value] to the [values].
+ void insertValue(int index, dynamic value) {
+ if (_values == null) {
+ _values = [value];
+ } else {
+ _values.insert(index, value);
+ }
+ }
+
+ /// Returns the value at the [index] or null on error.
+ dynamic value(int index) {
+ final rc =
+ _values == null || index >= _values.length ? null : _values[index];
+ return rc;
+ }
}
enum ComboboxListType {
maxSize = parseInt('maxSize', map, required: false);
rows = parseInt('rows', map, required: false);
options = parseOptions('options', map);
+ label ??= column.label;
+ toolTip ??= column.toolTip;
+ filterType ??= column.filterType;
+ options = parseOptions('options', map);
+ dataType ??= column.dataType;
+ texts ??= column.texts;
+ values ??= column.values;
+ listOption ??= column.listOption;
+ listType ??= column.listType;
checkOptionsByRegExpr(options, regExprOptions);
+ options += column.options;
}
}
"name": "user_name",
"column": "user_name",
"toolTip":
- "Filter bezüglich des Names der anzuzeigenden Einträge: Joker '*' (beliebiger String) ist erlaubt."
+ "Filter bezüglich des Namens der anzuzeigenden Einträge: Joker '*' (beliebiger String) ist erlaubt."
},
{
"widgetType": "dbReference",
import 'package:flutter/material.dart';
import 'package:flutter_bones/src/widget/callback_controller_bones.dart';
-import '../../widget/widget_list.dart';
import '../../widget/list_form.dart';
import '../application_data.dart';
import 'user_controller.dart';
GlobalKey<FormState>(debugLabel: 'user_list');
Iterable<dynamic> rowsDeprecated;
UserController controller;
- WidgetList filters;
UserListPageState(this.applicationData);
),
]),
],
- filters: filters,
+ filters: controller.widgetList,
errorMessage:
applicationData.lastErrorMessage(controller.page.fullName()),
),
Persistence persistence;
static BSettings lastInstance;
- /// Returns the singleton of VSetting.
+ /// Returns the singleton of BSetting.
factory BSettings() {
final map = {
'form.card.padding': '16.0',
import 'package:flutter/material.dart';
-import '../model/model_types.dart';
import '../model/combobox_model.dart';
import '../model/combo_base_model.dart';
import '../model/field_model.dart';
void buildRows();
/// Returns the [ComboboxData] (texts and values) of the [ComboboxModel] named [name].
- ComboboxData comboboxData(String name, DataType dataType);
+ ComboboxData comboboxData(String name);
/// Frees all resources.
void dispose();
/// Completes database based components to the model, e.g. the list for
/// comboboxes.
void completeModelByPersistence(WidgetModel model) {
- if (model is ComboBaseModel) {
+ if (model is ComboBaseModel && model.listType != null) {
if (model.data == null) {
if (model.listType == ComboboxListType.explicite) {
model.data = ComboBaseModel.createByType(
model.dataType, model.texts, model.values);
model.data.waitState = WaitState.ready;
} else {
- model.data = comboboxData(model.name, model.dataType);
+ model.data = comboboxData(model.name);
}
}
}
}
- @override
- ComboboxData comboboxData(String name, DataType dataType) {
- ComboboxData rc;
- switch (dataType) {
- case DataType.bool:
- rc = comboboxDataByType<bool>(name);
- break;
- case DataType.currency:
- case DataType.int:
- case DataType.reference:
- rc = comboboxDataByType<int>(name);
- break;
- case DataType.date:
- case DataType.dateTime:
- rc = comboboxDataByType<DateTime>(name);
- break;
- case DataType.float:
- rc = comboboxDataByType<double>(name);
- break;
- case DataType.string:
- comboboxDataByType<String>(name);
- break;
- }
- return rc;
- }
-
- ComboboxData<T> comboboxDataByType<T>(String name) {
+ ComboboxData comboboxData(String name) {
ComboboxData rc = comboboxDataMap.containsKey(name)
? comboboxDataMap[name]
- : ComboboxData<T>([], []);
+ : ComboboxData([], null);
comboboxDataMap[name] = rc;
if (rc.waitState == WaitState.undef) {
ComboBaseModel model = page.fieldByName(name) as ComboBaseModel;
if (model != null) {
switch (model.listType) {
case ComboboxListType.explicite:
- rc = ComboboxData<T>(model.texts, model.values, WaitState.ready);
+ rc = ComboboxData(model.texts, model.values, WaitState.ready);
comboboxDataMap[name] = rc;
break;
case ComboboxListType.undef:
- rc = ComboboxData<T>([], [], WaitState.ready);
+ rc = ComboboxData([], [], WaitState.ready);
comboboxDataMap[name] = rc;
break;
case ComboboxListType.dbColumn:
- comboboxDataDb<T>(model, rc);
+ comboboxDataDb(model, rc);
break;
case ComboboxListType.configuration:
break;
return rc;
}
- void comboboxDataDb<T>(ComboBaseModel model, ComboboxData<T> data) {
- // example: role.list;role_displayname role_id;:role_name=% :excluded=0'
- final parts = model.listOption.split(';');
- final moduleName = parts[0].split('.');
- final cols = parts[1].split(' ');
+ void comboboxDataDb(ComboBaseModel model, ComboboxData data) {
+ // example: xxx.role.list;role_displayname role_id;:role_name=% :excluded=0'
+ final keyColumnsParams = model.listOption.split(';');
+ final nameModuleSql = keyColumnsParams[0].split('.');
+ final cols = keyColumnsParams[1].split(' ');
final params = <String, dynamic>{};
- if (parts.length > 2 && parts[2].isNotEmpty) {
- parts[2].split(' ').forEach((element) {
+ if (keyColumnsParams.length > 2 && keyColumnsParams[2].isNotEmpty) {
+ keyColumnsParams[2].split(' ').forEach((element) {
final keyValue = element.split('=');
params[keyValue[0]] = keyValue[1];
});
}
applicationData.persistence
- .list(module: moduleName[0], sqlName: moduleName[1], params: params)
+ .list(module: nameModuleSql[1], sqlName: nameModuleSql[2], params: params)
.then((rows) {
rows.forEach((row) {
data.texts.add(row[cols[0]]);
- data.values.add(row[cols[1]]);
+ var value = row[cols[1]];
+ if (value is String){
+ value = StringHelper.fromString(value, model.dataType);
+ }
+ data.addValue(value);
});
if (model.hasOption('undef')) {
data.texts.insert(0, '-');
- data.values.insert(0, null);
+ data.insertValue(0, null);
}
data.waitState = WaitState.ready;
redraw(RedrawReason.redraw);
rc = comboboxByType<double>(model, controller, initialValue);
break;
case DataType.string:
- comboboxByType<String>(model, controller, initialValue);
+ rc = comboboxByType<String>(model, controller, initialValue);
break;
}
return rc;
/// with an [initialValue].
Widget comboboxByType<T>(
FieldModel model, CallbackControllerBones controller, initialValue) {
- ComboboxData<T> comboboxData = (model as ComboBaseModel).data;
+ ComboboxData comboboxData = (model as ComboBaseModel).data;
final items = <DropdownMenuItem<T>>[];
- for (var ix = 0; ix < comboboxData.texts.length; ix++) {
+ if (comboboxData == null || comboboxData.texts.length == 0) {
items.add(DropdownMenuItem(
onTap: controller.getOnTap(model.name, controller),
- value: comboboxData.values[ix],
- child: Text(comboboxData.texts[ix])));
+ value: null,
+ child: Text('-')));
+ } else {
+ for (var ix = 0; ix < comboboxData.texts.length; ix++) {
+ items.add(DropdownMenuItem(
+ onTap: controller.getOnTap(model.name, controller),
+ value: comboboxData.value(ix),
+ child: Text(comboboxData.texts[ix])));
+ }
}
final rc = DropdownButtonFormBone(
model.name,
again = false;
for (var model in waitCandidates) {
if (model is ComboBaseModel) {
- data = controller.comboboxData(model.listOption, model.dataType);
+ data = controller.comboboxData(model.listOption);
if (data != null && data.waitState == WaitState.ready) {
model.data = data;
waitCandidates.remove(model);
expect(logger.errors.length, equals(0));
expect(data, isNotNull);
expect(data.texts.length, greaterThan(4));
- expect(data.texts.length, equals(data.values.length));
+ expect(data.texts.length, equals(data.valuesLength));
expect(data2, isNotNull);
expect(data2.texts.length, greaterThan(4));
- expect(data2.texts.length, equals(data2.values.length));
- expect(data.texts.length, equals(data2.values.length + 1));
+ expect(data2.texts.length, equals(data2.valuesLength));
+ expect(data.texts.length, equals(data2.valuesLength + 1));
expect(cache.leastReasentlyUsed.length, equals(2));
const key3 = 'id3.role.list;role_name role_id;:role_name=%';
var data3 = cache.combobox(key3, hasUndef: false);