mirror of
https://git.meshkee.com/applications/cssd.git
synced 2026-10-11 20:38:55 +03:30
380 lines
12 KiB
Dart
380 lines
12 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/rendering.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:meta/meta.dart';
|
|
import 'package:multiselect_formfield/multiselect_formfield.dart';
|
|
|
|
class FormCreator extends StatefulWidget {
|
|
const FormCreator({
|
|
@required this.form,
|
|
@required this.onChanged,
|
|
this.padding,
|
|
});
|
|
|
|
final dynamic form;
|
|
final double padding;
|
|
final ValueChanged<dynamic> onChanged;
|
|
|
|
@override
|
|
_FormCreatorState createState() => _FormCreatorState(form);
|
|
}
|
|
|
|
class _FormCreatorState extends State<FormCreator> {
|
|
final dynamic formItems;
|
|
DateTime selectedDate = DateTime.now();
|
|
|
|
int rangeValue;
|
|
String selectValue;
|
|
|
|
Future<Null> _selectDate() async {
|
|
final DateTime picked = await showDatePicker(
|
|
context: context,
|
|
initialDate: selectedDate,
|
|
firstDate: DateTime(2015, 8),
|
|
lastDate: DateTime(2101));
|
|
if (picked != null && picked != selectedDate)
|
|
setState(() {
|
|
selectedDate = picked;
|
|
});
|
|
}
|
|
|
|
List<Widget> jsonToForm() {
|
|
List<Widget> listWidgets = List<Widget>();
|
|
|
|
for (var count = 0; count < formItems.length; count++) {
|
|
Map item = formItems[count];
|
|
|
|
if (item['type'] == "Date") {
|
|
selectedDate = formItems[count]['value'];
|
|
listWidgets.add(
|
|
OutlineButton(
|
|
onPressed: () {
|
|
_selectDate().then((_) {
|
|
formItems[count]['value'] = selectedDate;
|
|
_handleChanged();
|
|
});
|
|
},
|
|
child: Text(
|
|
'Date: ${selectedDate.year}/${selectedDate.month}/${selectedDate.day}'),
|
|
padding: EdgeInsets.symmetric(vertical: 20),
|
|
),
|
|
);
|
|
}
|
|
|
|
if (item['type'] == "Label") {
|
|
listWidgets.add(
|
|
Container(
|
|
decoration: BoxDecoration(
|
|
border: Border.all(),
|
|
borderRadius: BorderRadius.circular(30),
|
|
color: Colors.black,
|
|
),
|
|
padding: EdgeInsets.only(top: 20, bottom: 20),
|
|
margin: EdgeInsets.only(bottom: 20),
|
|
child: Text(
|
|
item['name'],
|
|
textAlign: TextAlign.center,
|
|
style: TextStyle(color: Colors.white, fontSize: 20),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
if (item['type'] == "Text") {
|
|
listWidgets.add(
|
|
Padding(
|
|
padding: const EdgeInsets.all(8.0),
|
|
child: TextFormField(
|
|
decoration: InputDecoration(
|
|
labelText: item['name'] ?? "",
|
|
border: UnderlineInputBorder(),
|
|
contentPadding: EdgeInsets.all(0),
|
|
),
|
|
initialValue: item['value'] ?? '',
|
|
onChanged: (String value) {
|
|
formItems[count]['value'] = value;
|
|
_handleChanged();
|
|
},
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
if (item['type'] == "Range" ||
|
|
item['type'] == "Temperature" ||
|
|
item['type'] == "Pressure") {
|
|
double startValue, endValue;
|
|
if (item['type'] == "Range") {
|
|
startValue = double.parse(item['options'][0]['title']);
|
|
endValue = double.parse(item['options'][1]['title']);
|
|
} else {
|
|
startValue = item['type'] == "Temperature" ? 0.0 : -1.0;
|
|
endValue = item['type'] == "Temperature" ? 200.0 : 3.0;
|
|
}
|
|
|
|
formItems[count]['value'] = formItems[count]['value'] ?? startValue;
|
|
int divisions = (endValue - startValue).round();
|
|
listWidgets.add(
|
|
Padding(
|
|
padding: EdgeInsets.only(top: 35),
|
|
child: Slider(
|
|
min: startValue,
|
|
max: endValue,
|
|
value: formItems[count]['value'],
|
|
label: '${formItems[count]['value'].round()}',
|
|
divisions: divisions,
|
|
onChanged: (double value) {
|
|
setState(() {
|
|
formItems[count]['value'] = value;
|
|
});
|
|
},
|
|
semanticFormatterCallback: (double newValue) {
|
|
return '${newValue.round()}';
|
|
},
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
if (item['type'] == "Time") {
|
|
listWidgets.add(
|
|
Padding(
|
|
padding: const EdgeInsets.all(8.0),
|
|
child: TextFormField(
|
|
inputFormatters: <TextInputFormatter>[
|
|
LengthLimitingTextInputFormatter(5),
|
|
WhitelistingTextInputFormatter.digitsOnly,
|
|
// BlacklistingTextInputFormatter.singleLineFormatter,
|
|
TextInputFormatter.withFunction(
|
|
(TextEditingValue oldValue, TextEditingValue newValue) {
|
|
final int newTextLength = newValue.text.length;
|
|
int selectionIndex = newValue.selection.end;
|
|
int usedSubstringIndex = 0;
|
|
final StringBuffer newText = StringBuffer();
|
|
if (newTextLength >= 2) {
|
|
newText.write(
|
|
newValue.text.substring(0, usedSubstringIndex = 2) +
|
|
':');
|
|
if (newValue.selection.end >= 2) selectionIndex++;
|
|
}
|
|
// Dump the rest.
|
|
if (newTextLength >= usedSubstringIndex)
|
|
newText.write(newValue.text.substring(usedSubstringIndex));
|
|
return TextEditingValue(
|
|
text: newText.toString(),
|
|
selection: TextSelection.collapsed(offset: selectionIndex),
|
|
);
|
|
})
|
|
],
|
|
keyboardType: TextInputType.datetime,
|
|
decoration: InputDecoration(
|
|
labelText: item['name'] ?? "",
|
|
border: UnderlineInputBorder(),
|
|
contentPadding: EdgeInsets.all(0),
|
|
),
|
|
initialValue: item['value'] ?? '',
|
|
onChanged: (String value) {
|
|
formItems[count]['value'] = value;
|
|
_handleChanged();
|
|
},
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
if (item['type'] == "Select") {
|
|
var listItems = item['options'] as List<dynamic>;
|
|
listWidgets.add(MultiSelectFormField(
|
|
autovalidate: false,
|
|
titleText: item['name'],
|
|
dataSource: listItems,
|
|
textField: 'title',
|
|
valueField: 'id',
|
|
okButtonLabel: 'OK',
|
|
cancelButtonLabel: 'CANCEL',
|
|
hintText: 'Please choose one or more',
|
|
value: item['value'],
|
|
onSaved: (value) {
|
|
if (value == null) return;
|
|
setState(() {
|
|
item['value'] = value;
|
|
});
|
|
_handleChanged();
|
|
},
|
|
));
|
|
|
|
// listWidgets.add(
|
|
// DropdownButtonFormField<String>(
|
|
// items: listItems.map((dynamic value) {
|
|
// String stringValue = value['id'].toString();
|
|
// String textValue = value['title'].toString();
|
|
// return DropdownMenuItem<String>(
|
|
// value: stringValue,
|
|
// child: Text(textValue),
|
|
// );
|
|
// }).toList(),
|
|
// isDense: true,
|
|
// value: item['value'],
|
|
// hint: Text(item['name']),
|
|
|
|
// onChanged: (String value) {
|
|
// this.setState(
|
|
// () {
|
|
// _setInput(item['name'], value);
|
|
// formItems[count]['value'] = value;
|
|
// _handleChanged();
|
|
// },
|
|
// );
|
|
// },
|
|
// ),
|
|
// );
|
|
}
|
|
|
|
if (item['type'] == "Radiobutton") {
|
|
listWidgets.add(
|
|
Container(
|
|
margin: EdgeInsets.only(top: 14.0, bottom: 0),
|
|
child: Text(
|
|
item['name'],
|
|
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16.0),
|
|
),
|
|
),
|
|
);
|
|
var valueOrFirst =
|
|
formItems[count]['value'] ?? formItems[count]['options'][0]['id'];
|
|
for (var i = 0; i < item['options'].length; i++) {
|
|
var isSelected = formItems[count]['options'][i]['id'] == valueOrFirst;
|
|
formItems[count]['value'] = valueOrFirst;
|
|
listWidgets.add(
|
|
RadioListTile<int>(
|
|
dense: true,
|
|
controlAffinity: ListTileControlAffinity.trailing,
|
|
title: Text(formItems[count]['options'][i]['title']),
|
|
value: formItems[count]['options'][i]['id'],
|
|
selected: isSelected,
|
|
groupValue: formItems[count]['value'],
|
|
onChanged: (int value) {
|
|
this.setState(
|
|
() {
|
|
_setInput(item['name'], value.toString());
|
|
formItems[count]['value'] = value;
|
|
_handleChanged();
|
|
},
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
if (item['type'] == "Switch") {
|
|
listWidgets.add(SwitchListTile(
|
|
activeColor: Colors.green,
|
|
inactiveTrackColor: Colors.red.withAlpha(150),
|
|
inactiveThumbColor: Colors.red,
|
|
title: Text(item['name']),
|
|
value: item['value'] ?? false,
|
|
onChanged: (bool value) {
|
|
this.setState(() {
|
|
formItems[count]['value'] = value;
|
|
_handleChanged();
|
|
});
|
|
}));
|
|
}
|
|
|
|
if (item['type'] == "Form") {
|
|
listWidgets.add(
|
|
Container(
|
|
margin: EdgeInsets.symmetric(vertical: 10),
|
|
decoration: BoxDecoration(border: Border.all()),
|
|
child: Column(
|
|
children: <Widget>[
|
|
Container(
|
|
margin: EdgeInsets.only(top: 10),
|
|
child: Text(
|
|
item['name'],
|
|
style:
|
|
TextStyle(fontWeight: FontWeight.bold, fontSize: 16.0),
|
|
),
|
|
),
|
|
FormCreator(
|
|
form: item['children'],
|
|
padding: 4,
|
|
onChanged: (value) {
|
|
// _handleChanged();
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
if (item['type'] == "Checkbox") {
|
|
formItems[count]['value'] = formItems[count]['value'] ?? [];
|
|
listWidgets.add(
|
|
Container(
|
|
margin: EdgeInsets.only(top: 14.0, bottom: 0),
|
|
child: Text(
|
|
item['name'],
|
|
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16.0),
|
|
),
|
|
),
|
|
);
|
|
for (var i = 0; i < item['options'].length; i++) {
|
|
listWidgets.add(
|
|
CheckboxListTile(
|
|
title: Text(formItems[count]['options'][i]['title']),
|
|
value: (formItems[count]['value'] ?? [])
|
|
.contains(formItems[count]['options'][i]['id']),
|
|
onChanged: (bool value) {
|
|
this.setState(
|
|
() {
|
|
setState(() {
|
|
if (value) {
|
|
(formItems[count]['value'] as List)
|
|
.add(formItems[count]['options'][i]['id']);
|
|
} else {
|
|
(formItems[count]['value'] as List)
|
|
.remove(formItems[count]['options'][i]['id']);
|
|
}
|
|
});
|
|
_handleChanged();
|
|
},
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|
|
// listWidgets.add(
|
|
// TestResultAddSaveButton(
|
|
// deviceBlockSize: null,
|
|
// ),
|
|
// );
|
|
}
|
|
return listWidgets;
|
|
}
|
|
|
|
_FormCreatorState(this.formItems);
|
|
|
|
void _handleChanged() {
|
|
widget.onChanged(formItems);
|
|
}
|
|
|
|
void _setInput(String key, String value) {}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return ListView.builder(
|
|
padding: EdgeInsets.all(widget.padding ?? 16.0),
|
|
itemCount: jsonToForm().length,
|
|
itemBuilder: (context, index) {
|
|
return jsonToForm()[index];
|
|
},
|
|
shrinkWrap: true,
|
|
controller: ScrollController(keepScrollOffset: false),
|
|
);
|
|
}
|
|
}
|