doonfrs / pluto_grid_plus

PlutoGrid is a dataGrid for flutter that can be controlled by the keyboard on desktop and web. Of course, it works well on Android and IOS.
https://pluto.weblaze.dev
MIT License
27 stars 28 forks source link

[Help] header or Footer in TextField can't editing on Flutter Web #58

Closed yunchiri closed 4 months ago

yunchiri commented 4 months ago
image image

TextField(in createdFooter)
on Android device TextField work normally but on Flutter web app can't write text using keyboard in Textfield , only can paste clipboard text using mouse

What is problem?

Execution Environment Flutter version is 3.22.2

PlutoGrid version 8.4.0

OS Google Chrome , Windows 11

antiv commented 4 months ago

Hi, I have same problem today. The main problem is that PlutoColumnFilter class add focusNode with key handler here.

_focusNode = FocusNode(onKeyEvent: _handleOnKey);

When you add widget that not use keyboards, it works fine, eg. dropdown. But if you use text field, keyboards doesn't work. That's why paste with mouse works.

My solution is to add my own FocusNode with key handler and TextEditingController. That is not a best way to work with TextFields, but that's only way for now that I find, to force it to work.

My Code:

final workWithoutOrder = stateManager.columns.firstWhereOrNull((element) => element.field == 'workWithoutOrder');
    workWithoutOrder?.filterWidget ??= PopupMenuFilter(
      stateManager: stateManager, column: workWithoutOrder, options: const ['', 'SOA', 'SMA'],);
    final fromColumn = stateManager.columns.firstWhereOrNull((element) => element.field == 'fromDate');
    TextEditingController controller = TextEditingController();
    FocusNode focusNode = FocusNode(onKeyEvent: (node, event) {
      /// if on key up
      if (event.runtimeType == KeyDownEvent) {
        return KeyEventResult.handled;
      }
      /// if enter key
      if (event.logicalKey == LogicalKeyboardKey.enter) {
        String filterValue = getFormatedFilterValue(controller.text);
        stateManager.setFilterWithFilterRows(getFilterRows(
            stateManager, fromColumn!, fromColumn.defaultFilter, filterValue));
        return KeyEventResult.handled;
      }
      /// if backspace
      if (event.logicalKey == LogicalKeyboardKey.backspace) {
        if (controller.text.isNotEmpty) {
          controller.text =
                controller.text.substring(0, controller.text.length - 1);
          if (controller.text.isEmpty) {
            stateManager.setFilterWithFilterRows(getFilterRows(
                stateManager, fromColumn!, fromColumn.defaultFilter, ''));
          }
        }
        return KeyEventResult.handled;
      }
      /// set maxLength
      if (controller.text.length == 10) {
        return KeyEventResult.handled;
      }
      /// skip if not number
      if (!['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'].contains(event.logicalKey.keyLabel)) {
        return KeyEventResult.handled;
      }
      controller.text = event.logicalKey ==
          LogicalKeyboardKey.enter ? controller.text
          : controller.text + (event.logicalKey.keyLabel);
      return KeyEventResult.handled;
    });
    // fromColumn?.setFilterFocusNode(focusNode);
    fromColumn?.filterWidget ??= TextFormField(
      controller: controller,
      focusNode: focusNode,
      enabled: true,
      onTap: () {
        stateManager.setKeepFocus(false);
      },
      inputFormatters: [
        FilteringTextInputFormatter.allow(RegExp(r'[0-9-]')),
      ],
      decoration: const InputDecoration(
        hintText: 'Filter by date',
      ),
    );
  }

Screenshot 2024-07-23 at 15 51 26

Screenshot 2024-07-23 at 15 51 46

I fire filter on enter key only, but you can easy change that.

It will be nice if plugin can support custom text fields, so we not need hacks like this :)

yunchiri commented 4 months ago

Thanks for your reply!

Greate job