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

[syncfusion_flutter_datagrid] Filter does not work properly for Turkish characters. #2191

Open
EBBozkurt opened this issue Dec 2, 2024 · 2 comments
Labels
data grid Data grid component open Open

Comments

@EBBozkurt
Copy link

EBBozkurt commented Dec 2, 2024

Bug description

Filter does not work properly for Turkish characters.

Ex: The filter does not work properly when it contains a word with a capital “İ”. Probably when doing toLowerCase(), it makes uppercase “İ” as lowercase “ı”. But the Turkish equivalent should be small “i”. For this, we need to do operations like the following line of code in our own filtering. We also want to do this in SFDataGrid.

We use syncfusion_flutter_datagrid: ^24.2.3

Sample Code for me to integrate Turkish Character editing: (Example Code)

List<dynamic> getFilteredList() {
    return employeeList.where((element) {
      if (searchController.text.isNotEmpty) {
        return (element["account"]
                .toString()
                .replaceAll('İ', 'i')
                .replaceAll('I', 'ı')
                .toLowerCase()
                .contains(searchController.text
                    .replaceAll('İ', 'i')
                    .replaceAll('I', 'ı')
                    .toLowerCase()) ||
            element["name"]
                .toString()
                .replaceAll('İ', 'i')
                .replaceAll('I', 'ı')
                .toLowerCase()
                .contains(searchController.text
                    .replaceAll('İ', 'i')
                    .replaceAll('I', 'ı')
                    .toLowerCase()));
      }
      return true;
    }).toList();
  }

Steps to reproduce

  1. To see the error, just type “iş ”. Don't forget to add the space at the end. When you do this, “İş Geliştirme” should appear, but it does not.

  2. When I type “iş”, the capitalized “İş” does not appear.

Code sample

Code sample
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';

void main() {
  runApp(const MaterialApp(home: SfDataGridDemo()));
}

class SfDataGridDemo extends StatefulWidget {
  const SfDataGridDemo({Key? key}) : super(key: key);

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

class SfDataGridDemoState extends State<SfDataGridDemo> {
  List<Employee> _employees = <Employee>[];
  late DataGridSource _source;

  @override
  void initState() {
    super.initState();
    _employees = getEmployeeData();
    _source = EmployeeDataSource(_employees);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter DataGrid Sample'),
      ),
      body: Card(
        margin: const EdgeInsets.all(20),
        child: Column(
          children: [
            Row(
              children: [
                SizedBox(
                  height: 48.0,
                  width: 300.0,
                  child: TextFormField(
                      onChanged: (value) {
                        if ((_source.filterConditions.keys
                            .contains('account'))) {
                          _source.clearFilters(columnName: 'account');
                        }

                        _source.addFilter(
                          'account',
                          FilterCondition(
                            type: FilterType.contains,
                            value: value,
                            filterOperator: FilterOperator.and,
                            filterBehavior: FilterBehavior.stringDataType,
                          ),
                        );
                      },
                      decoration: const InputDecoration(
                        hintText: 'Search',
                        border: OutlineInputBorder(borderSide: BorderSide()),
                        contentPadding: EdgeInsets.all(16.0),
                      )),
                ),
                const Padding(padding: EdgeInsets.all(30)),
                SizedBox(
                  height: 48.0,
                  width: 200,
                  child: ElevatedButton(
                    onPressed: () async {
                      List<Widget> widget = [];
                      for (var row in _source.effectiveRows) {
                        widget.add(Text('${row.getCells()[0].value}'));
                      }

                      await showDialog<String>(
                          context: context,
                          builder: (BuildContext context) => AlertDialog(
                              scrollable: true,
                              titleTextStyle: const TextStyle(
                                  color: Colors.black,
                                  fontWeight: FontWeight.bold,
                                  fontSize: 16),
                              title: const Text('Filtered Record Customer ID'),
                              actions: [
                                TextButton(
                                    onPressed: () {
                                      Navigator.pop(context);
                                    },
                                    child: const Text('OK'))
                              ],
                              content: SingleChildScrollView(
                                  child: Column(
                                children: widget,
                              ))));
                    },
                    child: const Text('Print Effective Rows'),
                  ),
                )
              ],
            ),
            const Padding(padding: EdgeInsets.all(30)),
            Expanded(
              child: SfDataGrid(
                source: _source,
                columns: getColumns,
                columnWidthMode: ColumnWidthMode.fill,
              ),
            ),
          ],
        ),
      ),
    );
  }

  List<GridColumn> get getColumns {
    return [
      GridColumn(
        columnName: 'id',
        label: Container(
          padding: const EdgeInsets.symmetric(horizontal: 16.0),
          alignment: Alignment.center,
          child: const Text(
            'Customer ID',
            overflow: TextOverflow.ellipsis,
          ),
        ),
      ),
      GridColumn(
        columnName: 'name',
        label: Container(
          padding: const EdgeInsets.symmetric(horizontal: 16.0),
          alignment: Alignment.center,
          child: const Text(
            'Name',
            overflow: TextOverflow.ellipsis,
          ),
        ),
      ),
      GridColumn(
        columnName: 'account',
        label: Container(
          padding: const EdgeInsets.symmetric(horizontal: 16.0),
          alignment: Alignment.center,
          child: const Text(
            'Account',
            overflow: TextOverflow.ellipsis,
          ),
        ),
      ),
    ];
  }
}

List<Employee> getEmployeeData() {
  return [
    Employee(10001, 'Lara', 'İş Geliştirme'),
    Employee(10002, 'Perry', 'Yazılım Geliştirme'),
    Employee(10003, 'Adams', 'Here is the problem İş'),
    Employee(10004, 'Michael', 'İş'),
    Employee(10005, 'Thomas', 'iş'),
  ];
}

class EmployeeDataSource extends DataGridSource {
  EmployeeDataSource(this.employees) {
    buildDataGridRow(employees);
  }

  List<Employee> employees = [];

  List<DataGridRow> dataGridRows = [];

  @override
  List<DataGridRow> get rows => dataGridRows;

  void buildDataGridRow(List<Employee> employeeData) {
    dataGridRows = employeeData.map<DataGridRow>((employee) {
      return DataGridRow(cells: [
        DataGridCell<int>(columnName: 'id', value: employee.id),
        DataGridCell<String>(columnName: 'name', value: employee.name),
        DataGridCell<String>(columnName: 'account', value: employee.account),
      ]);
    }).toList();
  }

  @override
  DataGridRowAdapter? buildRow(DataGridRow row) {
    return DataGridRowAdapter(
        cells: row.getCells().map<Widget>((dataGridCell) {
      return Container(
          alignment: Alignment.center,
          padding: const EdgeInsets.symmetric(horizontal: 16.0),
          child: Text(
            dataGridCell.value.toString(),
            overflow: TextOverflow.ellipsis,
          ));
    }).toList());
  }
}

class Employee {
  Employee(this.id, this.name, this.account);

  int? id;
  String? name;
  String? account;
}

Screenshots or Video

Screenshots / Video demonstration

[Upload media here] (I will provide it if needed, but for now I think it is obvious.)

Stack Traces

Stack Traces
[Add the Stack Traces here]

On which target platforms have you observed this bug?

Android, iOS, Web, Web (Android browser), Web (iOS browser), Windows, macOS, Linux

Flutter Doctor output

Doctor output
[√] Flutter (Channel stable, 3.19.1, on Microsoft Windows [Version 10.0.22631.4460], locale en-GB)
[√] 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
[√] Android Studio (version 2024.2)
[√] VS Code (version 1.95.3)
[√] Connected device (2 available)
[√] Network resources
@EBBozkurt EBBozkurt changed the title [syncfusion_flutter_datagrid] Filter for List<T> column type [syncfusion_flutter_datagrid] Filter does not work properly for Turkish characters. Dec 2, 2024
@VijayakumarMariappan VijayakumarMariappan added data grid Data grid component open Open labels Dec 3, 2024
@abineshPalanisamy
Copy link

Hi @EBBozkurt ,

Based on the details and steps you provided to reproduce the issue, we have tested your sample. However, we were unable to replicate the issue as described. Everything works fine on our end without any issues. We have included a video of our testing for your reference. Please review the video for clarity.

  • Testing Video
Video.reference.mp4

To assist you further and better understand the issue, we kindly request that you provide any additional details or steps that may help us reproduce the problem. Additionally, a video recording demonstrating the issue would greatly help us investigate thoroughly and provide a more accurate resolution

Regards,
Abinesh P

@EBBozkurt
Copy link
Author

EBBozkurt commented Dec 3, 2024

Hello @abineshPalanisamy ,

Thank you for your review, and I appreciate your time. I realized there was a typo in the steps I initially provided—my apologies for the confusion.

To clarify, I have prepared two use-cases below for you to recreate the scenarios. Additionally, I’ve updated the Employee Data for better clarity. Please replace the old data with the following:

List<Employee> getEmployeeData() {
  return [
    Employee(10001, 'Lara', 'İş Geliştirme'),
    Employee(10002, 'Perry', 'İş Yönetimi'),
    Employee(10003, 'Adams', 'Here is the problem İş'),
    Employee(10004, 'Michael', 'İş '),
    Employee(10005, 'Thomas', 'iş'),
  ];
}

Use-case 1:
Input: The user types "iş".
Expected Output: The following IDs should be displayed: 10001, 10002, 10003, 10004, 10005.
Reason: This behavior occurs because the uppercase "İ" is equivalent to the lowercase "i" in Turkish character handling.

Use-case 2:
Input: The user types "iş " (with a space at the end).
Expected Output: The following IDs should be displayed: 10001, 10002, 10004.
Reason: The trailing space narrows down the matches to fields that explicitly include "iş ".
Please let me know if anything is unclear or if further adjustments are needed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
data grid Data grid component open Open
Projects
None yet
Development

No branches or pull requests

3 participants