GetX works fine and update data if element have controller. But how to get it work if we have not direct to controller and widget done in way of changing date with onChange
.
I created small copy-paste example:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:web_date_picker/web_date_picker.dart';
void main() {
Get.put(SearchFormController());
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'GetX Demo',
home: MyHomePage(),
);
}
}
class SearchFormController extends GetxController {
var endDate = Rxn<DateTime?>();
setToNow() { // This function should set widget value
endDate.value = DateTime.now();
print('setToNow event: ${endDate.value}');
}
}
class MyHomePage extends StatelessWidget {
var ctrl = Get.find<SearchFormController>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Row(
children: [
Obx(() => SizedBox(
width: 160,
child: WebDatePicker(
initialDate: ctrl.endDate.value,
onChange: (value) {
if (value != null) {
ctrl.endDate.value = value;
print('onChange event: ${ctrl.endDate.value}');
}
},
),
)),
ElevatedButton(
onPressed: () {
ctrl.setToNow();
},
child: Text("Set Date"),
),
],
),
);
}
}
pubspec.yaml:
dependencies:
flutter:
sdk: flutter
web_date_picker: ^1.0.0 3
get: ^4.6.5
In this code I can't set date by clicking on Set Date
button.
I looked at widget code and it's controller is hidden with follow realization:
class _WebDatePickerState extends State<WebDatePicker> {
final FocusNode _focusNode = FocusNode();
late OverlayEntry _overlayEntry;
final LayerLink _layerLink = LayerLink();
final _controller = TextEditingController();
late DateTime? _selectedDate;
late DateTime _firstDate;
late DateTime _lastDate;
bool _isEnterDateField = false;
@override
void initState() {
super.initState();
_selectedDate = widget.initialDate;
_firstDate = widget.firstDate ?? DateTime(2000);
_lastDate = widget.lastDate ?? DateTime(2100);
if (_selectedDate != null) {
_controller.text = _selectedDate?.parseToString(widget.dateformat) ?? '';
}
_focusNode.addListener(() {
if (_focusNode.hasFocus) {
_overlayEntry = _createOverlayEntry();
Overlay.of(context)?.insert(_overlayEntry);
} else {
_controller.text = _selectedDate.parseToString(widget.dateformat);
widget.onChange.call(_selectedDate);
_overlayEntry.remove();
}
});
}
void onChange(DateTime? selectedDate) {
_selectedDate = selectedDate;
_controller.text = _selectedDate.parseToString(widget.dateformat);
_focusNode.unfocus();
}
...
Widget code https://github.com/duchdtran/web_date_picker/blob/master/lib/src/web_date_picker.dart#L98
Could anybody provide example how to get button work to set widget value?
CodePudding user response:
I experienced similar problems and solved them desribed as below.
It seems WebDatePicker does not process the value change. Try putting it in its own StatelessWidget
:
class MyWebDatePicker extends StatelessClass {
final DateTime dt;
var ctrl = Get.find<SearchFormController>();
MyWebDatePicker(this.dt);
Widget build(BuildContext context) {
return WebDatePicker(
initialDate: dt,
onChange: (value) {
if (value != null) {
ctrl.endDate.value = value;
print('onChange event: ${value}');
}
},
);
}
}
Then, call it like given below. This code looks unusual, but it forces Obx
to call MyWebDatePicker
with the current DateTime
value:
Obx(() => SizedBox(
width: 160,
child: MyWebDatePicker(ctrl.endDate.value)
)
)