datetime_picker_formfield icon indicating copy to clipboard operation
datetime_picker_formfield copied to clipboard

Can't get text field to update on rebuild of form

Open fetcorp opened this issue 5 years ago • 4 comments

I have a stateful widget that builds and displays a Form that contains several DateTimeField widgets. The first time the form is built the initialValue that I specify is correctly set for each DateTimeField. However, when the build method is called again (because one or more of the time values has changed externally) the new initialValue is not shown - it keeps what's there. It's as if the initialValue is being ignored totally. I suspect this is not a bug but a problem with the way I'm using the DateTimeField widget.

Here's a snippet from the build method where one of the DateTimeFields is created:

          DateTimeField(
            initialValue: DateTime(0, 0, 0, _data.awakeWindowStartInMinutesAfterMidnight ~/ 60, _data.awakeWindowStartInMinutesAfterMidnight % 60),
            format: timeFormat,
            decoration: new InputDecoration(
              hintText: 'Use the time picker to set the wakeup time',
              labelText: 'Daily Awake Window Start',
              suffixIcon: null
            ),
            readOnly: true,
            showCursor: false,
            onSaved: (DateTime value)
            {
              this._data.awakeWindowStartInMinutesAfterMidnight = value.hour * 60 + value.minute;
            },
            onShowPicker: (context, currentValue) async {
              final time = await showTimePicker(
                context: context,         
                initialTime: TimeOfDay.fromDateTime(currentValue ?? DateTime.now()),
              );
              return DateTimeField.convert(time);
            },
          ),

fetcorp avatar Feb 09 '20 18:02 fetcorp

I found the problem. I am now using a controller and it works.

fetcorp avatar Feb 10 '20 15:02 fetcorp

what's the purpose of using TextEditingController when we should pass value by initialValue ?

fpv999 avatar Mar 03 '20 12:03 fpv999

Initial value can only be set once it would appear. I wanted to be able to update the displayed value on the fly if it changed by some external operation.

fetcorp avatar Mar 03 '20 13:03 fetcorp

I know what you mean, I had very similar situation. Data is loaded from the storage, and date field is updated some milliseconds after UI widget is initialized. So I ended up with a code like this:

in widget:

final ValueNotifier<DateTime> controller;

in widget state:

 final TextEditingController ctrl = TextEditingController();
 @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder(
      valueListenable: widget.controller,

      builder: (context, value, child) {
        ctrl.text = (widget.controller.value!=null) ? dateFormat.format(widget.controller.value) : "";
        return DateTimeField(
          initialValue: widget.controller.value,
          validator: widget.validator,
          controller: ctrl,
...

EDIT: this above is actually bad idea

what is required to do: after modifying controller.value you just need to update controller.text too.

fpv999 avatar Mar 03 '20 14:03 fpv999