Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Column sorted (instead of filtered) when tapping filter icon #2223

Open
mathlizee opened this issue Dec 22, 2024 · 7 comments
Open

Column sorted (instead of filtered) when tapping filter icon #2223

mathlizee opened this issue Dec 22, 2024 · 7 comments
Labels
data grid Data grid component waiting for customer response Cannot make further progress until the customer responds.

Comments

@mathlizee
Copy link

Bug description

Hello!

When tapping the filter icon, the column is sometimes (not always) sorted instead of opening the filter popup. I have provided a video capture that demonstrates the issue.

As you can see, when the filter icon is tapped, the column's sorting is sometimes changed instead of opening the filter popup. Furthermore, when I tap a 2nd time without moving my cursor, the filter popup opens normally as intended.

Sadly, I wasn't able to reproduce the issue in any of your examples. I have provided the code that customizes the filter and sort icons in my grid. Let me know if you need anything else!

Thanks!
Mathieu

Steps to reproduce

  1. Tap the filter icon
  2. Sometimes, the column is sorted rather than the filter's popup menu opened

Code sample

Code sample
SfDataGridThemeData(
  headerColor: Theme.of(context).colorScheme.surfaceContainerHighest,
  selectionColor: Theme.of(context).colorScheme.primaryContainer,
  gridLineStrokeWidth: 0,
  sortIcon: Builder(
    builder: (context) {
      // Modifie l'icône de tri en fonction du tri appliqué sur la
      // colonne. L'icône tient aussi compte de la densité visuelle.
      //
      // Basé sur https://pub.dev/documentation/syncfusion_flutter_core/latest/theme/SfDataGridThemeData/sortIcon.html
      String columnName = '';
      context.visitAncestorElements((element) {
        if (element is GridHeaderCellElement) {
          columnName = element.column.columnName;
        }
        return true;
      });
  
      final column = _gridSource.sortedColumns
          .where((element) => element.name == columnName)
          .firstOrNull;
      final isSortedColumn = column != null;
  
      late IconData iconData;
      switch (column?.sortDirection) {
        case DataGridSortDirection.ascending:
          iconData = Icons.arrow_upward;
          break;
        case DataGridSortDirection.descending:
          iconData = Icons.arrow_downward;
          break;
        default:
          iconData = Icons.swap_vert;
      }
  
      return Icon(
        iconData,
        size: 25.0 + widget.verticalVisualDensity * 1.5,
        color: isSortedColumn
            ? dirtyColor
            : Theme.of(context).colorScheme.outline,
      );
    },
  ),
  filterIcon: Builder(
    builder: (context) {
      // Affiche un badge sur l'icône de filtre de la colonne si celle-ci
      // est filtrée. L'icône tient aussi compte de la densité visuelle.
      //
      // Basé sur https://pub.dev/documentation/syncfusion_flutter_core/latest/theme/SfDataGridThemeData/filterIcon.html
      String columnName = '';
      context.visitAncestorElements((element) {
        if (element is GridHeaderCellElement) {
          columnName = element.column.columnName;
        }
        return true;
      });
  
      final isFilteredColumn =
          _gridSource.filterConditions.containsKey(columnName);
  
      return Icon(
        Icons.filter_alt_outlined,
        size: 25.0 + widget.verticalVisualDensity * 1.5,
        color: isFilteredColumn
            ? dirtyColor
            : Theme.of(context).colorScheme.outline,
      );
    },
  ),
  )

Screenshots or Video

Screenshots / Video demonstration

FilterBug

Stack Traces

No stack trace.

On which target platforms have you observed this bug?

Windows

Flutter Doctor output

Doctor output

Using syncfusion_flutter_datagrid: ^28.1.33

[✓] Flutter (Channel stable, 3.24.4, on Microsoft Windows [Version 10.0.19045.5247], locale en-CA)
[✓] Windows Version (Installed version of Windows is version 10 or higher)        
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)  
[✓] Chrome - develop for the web
[✓] Visual Studio - develop Windows apps (Visual Studio Professional 2022 17.12.3)
[!] Android Studio (version 2022.1)
    ✗ Unable to determine bundled Java version.
[✓] Android Studio (version 2023.3)
[✓] VS Code, 64-bit edition (version 1.96.0)
[✓] Connected device (3 available)
[✓] Network resources
@abineshPalanisamy
Copy link

Hi @mathlizee ,

In the SfDataGrid, the filter icon occupies the same space as the sort icon in the column header. When you tap on any area of the header, except where the filter icon is located, the grid triggers a sort action. However, if you specifically tap on the filter icon, the filter popup should open. Due to the overlap between the sorting and filtering areas, the sort action is triggered instead of the filter popup.

To resolve this issue, you can wrap the filter icon inside a container and set explicit width and height for the icons. This ensures that the space for the filter icon is clearly defined, allowing taps on the filter icon to reliably open the filter popup instead of triggering the sort action.

We have provided a code snippets and video reference for your reference. Please refer to the attached code for more details.

 filterIcon: Builder(
            builder: (context) {
              String columnName = '';
              context.visitAncestorElements((element) {
                if (element is GridHeaderCellElement) {
                  columnName = element.column.columnName;
                }
                return true;
              });

              final isFilteredColumn =
                  employeeDataSource.filterConditions.containsKey(columnName);

              return Container(
                width: 40,
                height: 40,
                color: Colors.green,
                child: Icon(
                  Icons.filter_alt_outlined,
                  size: 25.0 + verticalVisualDensity * 1.5,
                  color: isFilteredColumn ? Colors.red : Colors.black,
                ),
              );
            },
          ),

Regards,
Abinesh P

@ashok-kuvaraja ashok-kuvaraja added data grid Data grid component waiting for customer response Cannot make further progress until the customer responds. labels Dec 23, 2024
@mathlizee
Copy link
Author

Hi @abineshPalanisamy,

Thanks for the fix! Everything is now working as expected.

Kind regards,
Mathieu

@mathlizee
Copy link
Author

Hi @abineshPalanisamy,

Unfortunately, after more further testing, it appears that the issue is still not completely resolved with your suggestion (even though it appears a lot less often).

As you can see from the following capture, the issue is still there when the mouse cursor stays in the grid's header:

FilterIssue

Here's the code I'm using:

sortIcon: Builder(
  builder: (context) {
    String columnName = '';
    context.visitAncestorElements((element) {
      if (element is GridHeaderCellElement) {
        columnName = element.column.columnName;
      }
      return true;
    });
  
    final column = _gridSource.sortedColumns
        .where((element) => element.name == columnName)
        .firstOrNull;
    final isSortedColumn = column != null;
  
    late IconData iconData;
    switch (column?.sortDirection) {
      case DataGridSortDirection.ascending:
        iconData = Icons.arrow_upward;
        break;
      case DataGridSortDirection.descending:
        iconData = Icons.arrow_downward;
        break;
      default:
        iconData = Icons.swap_vert;
    }
  
    return HoverBuilder(
      builder: (isHovered) => Icon(
        iconData,
        size: 25.0 + widget.visualDensity.vertical * 1.5,
        color: isHovered
            ? Theme.of(context).colorScheme.primary
            : isSortedColumn
                ? dirtyColor
                : Theme.of(context).colorScheme.outline,
      ),
    );
  },
  ),
  filterIcon: Builder(
  builder: (context) {
    String columnName = '';
    context.visitAncestorElements((element) {
      if (element is GridHeaderCellElement) {
        columnName = element.column.columnName;
      }
      return true;
    });
  
    final isFilteredColumn =
        _gridSource.filterConditions.containsKey(columnName);
  
    return HoverBuilder(
      builder: (isHovered) => Container(
        width: 32,
        height: 32,
        color: Colors.green,
        child: Icon(
          Icons.filter_alt_outlined,
          size: 25.0 + widget.visualDensity.vertical * 1.5,
          color: isHovered
              ? Theme.of(context).colorScheme.primary
              : isFilteredColumn
                  ? dirtyColor
                  : Theme.of(context).colorScheme.outline,
        ),
      ),
    );
  },
  ),

Where HoverBuilder is:

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

class HoverBuilder extends StatefulWidget {
  const HoverBuilder({
    super.key,
    required this.builder,
  });

  final Widget Function(bool isHovered) builder;

  @override
  HoverBuilderState createState() => HoverBuilderState();
}

class HoverBuilderState extends State<HoverBuilder> {
  bool _isHovered = false;

  @override
  Widget build(BuildContext context) {
    return MouseRegion(
      onEnter: (PointerEnterEvent event) => _onHoverChanged(enabled: true),
      onExit: (PointerExitEvent event) => _onHoverChanged(enabled: false),
      child: widget.builder(_isHovered),
    );
  }

  void _onHoverChanged({required bool enabled}) {
    setState(() {
      _isHovered = enabled;
    });
  }
}

As always, thanks a lot for your help!
Mathieu

@mathlizee mathlizee reopened this Jan 6, 2025
@abineshPalanisamy
Copy link

Hi @mathlizee ,

In SfDataGrid, when you tap on any part of the header except where the filter icon is located, the grid triggers a sort action. This is because the sorting gesture is assigned to the entire header cell, except for the space reserved for the filter icon. This is the expected behavior on our end.

In your video, after careful analysis, we noticed that when the resizing indicator appears, you try to tap to open the popup menu. When this resizing indicator is visible, the focus is only on the entire header cell, not on the filter icon's space. The small area between the filter icon and the gridline is also considered part of the header. So, performing an action in this intermediate space also triggers a sort action. To open the popup without interruption, you need to tap precisely on the area designated for the filter icon gesture.

We have provided video for your reference. Please refer it for more details.

Video.reference.mp4

Regards,
Abinesh P

@mathlizee
Copy link
Author

Hi @abineshPalanisamy!

In your video, after careful analysis, we noticed that when the resizing indicator appears, you try to tap to open the popup menu.

That is not entirely true... These are the steps I used to reproduce the issue:

  1. I hover the filter icon
  2. Then, I slide the mouse's cursor to the right until the resizing indicator appears
  3. Next, I slide the mouse's cursor to the left until it is placed directly over the filter icon (the resizing indicator has disappeared by then)
  4. Lastly, I click on the mouse button

When reproducing these steps, the column is sometimes sorted instead of opening the popup menu... Here's another capture that shows the issue:

FilterIssue2

Thanks again!
Mathieu

@abineshPalanisamy
Copy link

Hi @mathlizee ,

We have reviewed your cases following the provided steps to reproduce the issue, but we were unable to replicate the problem on our end. To assist further, we have included a video reference and sample of our testing.

Please update the Flutter SDK and SfDataGrid to the latest versions and check if the issue persists. If you continue to encounter problems, kindly modify the attached sample to replicate the issue and provide clear and detailed steps to reproduce it. Sharing this additional information will help us address your request comprehensively and provide an appropriate solution.

Video :

Testing.video.mp4

Testing Sample : SfDataGrid.zip

Regards,
Abinesh P

@mathlizee
Copy link
Author

Hi @abineshPalanisamy!

I was able to reproduce the issue after modifying the provided example:

FilterIssue3

main.zip

I also discovered that the issue does not happen when the onCellDoubleTap callback is null. When it has a value, the filter popup appears after a longer delay because of the way the GestureDetector is implemented (see flutter/flutter#106170). Maybe this delay causes an issue inside the grid?

Thanks again!
Mathieu

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
data grid Data grid component waiting for customer response Cannot make further progress until the customer responds.
Projects
None yet
Development

No branches or pull requests

3 participants