flutter-form-builder-ecosystem / flutter_form_builder

Simple form maker for Flutter Framework
https://pub.dev/packages/flutter_form_builder
MIT License
1.48k stars 535 forks source link

[FormBuilderDateTimePicker]: onPressed of suffixIcon don't work on Windows / Web #1357

Open kouroku-room opened 8 months ago

kouroku-room commented 8 months ago

Is there an existing issue for this?

Package/Plugin version

9.2.0

Platforms

Flutter doctor

Flutter doctor ```bash [√] Flutter (Channel stable, 3.16.9, on Microsoft Windows [Version 10.0.22621.3007], locale ja-JP) • Flutter version 3.16.9 on channel stable at C:\src\flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 41456452f2 (2 days ago), 2024-01-25 10:06:23 -0800 • Engine revision f40e976bed • Dart version 3.2.6 • DevTools version 2.28.5 [√] Windows Version (Installed version of Windows is version 10 or higher) [√] Android toolchain - develop for Android devices (Android SDK version 34.0.0) • Android SDK at C:\Users\sugur\AppData\Local\Android\sdk • Platform android-34, build-tools 34.0.0 • Java binary at: C:\Program Files\Android\Android Studio\jbr\bin\java • Java version OpenJDK Runtime Environment (build 17.0.7+0-b2043.56-10550314) • All Android licenses accepted. [√] Chrome - develop for the web • Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe [√] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.5.3) • Visual Studio at C:\Program Files\Microsoft Visual Studio\2022\Community • Visual Studio Community 2022 version 17.5.33516.290 • Windows 10 SDK version 10.0.22000.0 [√] Android Studio (version 2023.1) • Android Studio at C:\Program Files\Android\Android Studio • Flutter plugin can be installed from: https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 17.0.7+0-b2043.56-10550314) [√] VS Code (version 1.79.2) • VS Code at C:\Users\sugur\AppData\Local\Programs\Microsoft VS Code • Flutter extension can be installed from: https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter [√] Connected device (4 available) • sdk gphone64 x86 64 (mobile) • emulator-5554 • android-x64 • Android 13 (API 33) (emulator) • Windows (desktop) • windows • windows-x64 • Microsoft Windows [Version 10.0.22621.3007] • Chrome (web) • chrome • web-javascript • Google Chrome 120.0.6099.225 • Edge (web) • edge • web-javascript • Microsoft Edge 121.0.2277.83 [√] Network resources • All expected network resources are available. • No issues found! ```

Minimal code example

Code sample ```dart import 'package:flutter/material.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: const MyHomePage(), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @override State createState() => _MyHomePageState(); } class _MyHomePageState extends State { DateTime? _datetime = DateTime.now(); void _pickedDateTime(DateTime? pickedDateTime) { print('_pickedDateTime: $pickedDateTime'); if (pickedDateTime == null) return; setState(() { _datetime = pickedDateTime; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(), body: FormBuilderDateTimePicker( name: 'datetime', initialValue: _datetime, onChanged: _pickedDateTime, inputType: InputType.both, decoration: InputDecoration( suffixIcon: IconButton( icon: const Icon(Icons.clear), onPressed: () { print('onIconPressed'); }, ), ), onReset: () { print('onReset'); }, ), ); } } ```

Current Behavior

I have tried to set IconButton to FormBuilderDateTimePicker.decoration.suffixIcon.

However, when I run the app on Windows and Web, when I tap the IconButton, the IconButton's onPressed is not called and the Form's tap event is called.

Same situation as #1205.

Expected Behavior

When the application is run on Windows and Web, onPressed function (like Reset) cannot be used using the IconButton.

Steps To Reproduce

  1. Create a New Flutter Project in Android Studio.
  2. Overwrite "main.dart" with the contents of "Minimal code example".
  3. Add "flutter_form_builder: ^9.2.0" to "pubspec.yaml".
  4. Set the application execution to "Chrome (web)" or "Windows (desktop)" and Run.

Aditional information

If the application is set to run as "Android Emulator API 33 (mobile)" and Run, "onIconPressed" will be logged when the IconButton is clicked.

The same problem occurs in the official example application. https://github.com/flutter-form-builder-ecosystem/flutter_form_builder/blob/26bba7b36e8af84e2fc9f6f2e076e47562ee8f03/example/lib/sources/complete_form.dart

https://github.com/flutter-form-builder-ecosystem/flutter_form_builder/assets/57855128/930e1083-3b44-4e68-a903-36ba15080b5f

InTheClodus commented 8 months ago

This calendar component has so many bugs

Dingdash commented 4 months ago

still bug i cannot set them to null

ch-arslan-kip-tm commented 4 months ago

This issue is present in Linux build as well. Further testing revealed that a picker is erroneously shown only when the suffix button is being long pressed. A very quick tap does seem to trigger the button's onPressed callback.

Digging deeping, it would seem that the issue is caused by the way a tap event is handled: https://github.com/flutter-form-builder-ecosystem/flutter_form_builder/blob/acb73642d6ddb5635679c3e269637aa31285436e/lib/src/fields/form_builder_date_time_picker.dart#L272-L277

Instead of adding a tap listener the normal way, it seems that a focus listener is attached to the entire widget, which includes the prefix/suffix widgets. And it seems that touch events on those widgets propagate as focus events to the parent widget, causing the picker to appear.

This implementation also causes another type of bug. When autoScrollWhenFocusOnInvalid is set to true, then a failed validation it will open a picker, rather that just focus on the invalid field.