Flutter web Forms display incorrectly and not functioning on Windows Browsers/iOS but fine on macOS

I’m having a problem getting forms to behave correctly with flutter web in browsers on Windows and iOS. I’m finding that my form works just fine in browsers under Mac OS but do not work at all in browsers on Windows or iOS. By “works”, I mean being able to use a button to submit data.

The goal is to have a user be able to enter data on a form so that I can perform a search and display results. What I expect is that it would work properly, as it does on macOS in several browsers. Actual results on Windows and iOS is that it is difficult for the user to set focus, the form gets submitted without being completed and/or it is impossible for the user to submit the form/click the button in many browsers on Windows and iOS.

Details:
Flutter 1.25.0-8.1.pre • channel beta • https://github.com/flutter/flutter.git Framework • revision 8f89f6505b (2 weeks ago) • 2020-12-15 15:07:52 -0800 Engine • revision 92ae191c17 Tools • Dart 2.12.0 (build 2.12.0-133.2.beta)

WORKS: (can enter data in fields, click submit, and data shows up below) macOS Catalina Version 10.15.7 Firefox: 84.0.1, Chrome: 87.0.4280.88 (Official Build) (x86_64), Safari: 14.0.1 (15610.2.11.51.10, 15610)

NOT WORKING (selecting fields is flakey, button not pressable, can’t submit data) Windows 10 Pro 20H2, Firefox 84.6.1, Edge iOS 14.2 Safari, Firefox, Chrome (latest versions)

I’m serving the flutter web build with nginx/1.18.0 (Ubuntu).

Here is some code (form_widget.dart) that demonstrates the problem:

    import 'package:field_test/helpers/size_helpers.dart';
    import 'package:flutter/material.dart';

    class FormWidget extends StatefulWidget {
      @override
      State<StatefulWidget> createState() => _FormWidgetState();

    }

    class _FormWidgetState extends State<FormWidget> {
      String _keywords, _keywords_display = "";
      String _type, _type_display = "";
      String _state, _state_display = "";

      final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

      Widget _buildKeywordsField() {
        return TextFormField(
            decoration: InputDecoration(labelText: 'Keywords'),
            onSaved: (String value) {
              _keywords = value;
              print(_keywords + "saved");
            }
        );
      }

      Widget _buildTypeField() {
        return TextFormField(
            decoration: InputDecoration(labelText: 'Type'),
            onSaved: (String value) {
              _type = value;
              print(_type + "saved");
            }
        );
      }

      Widget _buildStateField() {
        return TextFormField(
            decoration: InputDecoration(labelText: 'State'),
            onSaved: (String value) {
              _state = value;
              print(_state + "saved");
            }
        );
      }

      void _update() {
        print("update called");
        setState(() {
          _keywords_display = _keywords;
          _type_display = _type;
          _state_display = _state;
        });
      }

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("Form Widget",
              style: TextStyle(
                color: Colors.white, fontWeight: FontWeight.bold
              )
            )
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget> [
                Expanded(
                  child: Container(
                    margin: EdgeInsets.all(24),
                    child: Form(
                      key: _formKey,
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget> [
                          _buildKeywordsField(),
                          _buildTypeField(),
                          _buildStateField(),
                          SizedBox(height: 15),
                          RaisedButton(
                            child: Text(
                              'Search',
                              style: TextStyle(color: Colors.white, fontSize: 16),
                            ),
                            onPressed: () => {
                              _formKey.currentState.save(),
                              _update(),
                            }
                          )
                        ]
                      )
                    )
                  )
                ),
                Container(
                  width: displayWidth(context) * .95,
                  height: displayHeight(context) * .75,
                  child:
                    Builder(
                      builder: (_) {
                        return ListView.separated(
                          separatorBuilder: (_, __) =>
                          Divider(height: 1, color: Colors.orange),
                          itemBuilder: (_, index) {
                            return ListTile(
                              isThreeLine: true,
                              title: Text(
                                "Keywords: " + _keywords_display,
                                style: TextStyle(color: Theme.of(context).primaryColor),
                              ),
                              subtitle: Text(
                                  "Type: " + _type_display + "\nState: " + _state_display,
                              maxLines: 2,
                                ),
                              );
                            },
                          itemCount: 1,
                        );

                      }),
                )]
            )
          )
        );
      }
    }

a couple of methods are declared/defined in size_helpers.dart:

import 'package:flutter/material.dart';

Size displaySize(BuildContext context) {
  return MediaQuery.of(context).size;
}

double displayHeight(BuildContext context) {
  return displaySize(context).height;
}

double displayWidth(BuildContext context) {
  return displaySize(context).width;
}