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

[Data Pager] "ScrollController not attached to any scroll views." error in syncfusion_flutter_datagrid 27.2.2 #2173

Closed
muhammadhuzaifakhan1133 opened this issue Nov 19, 2024 · 5 comments
Labels
data grid Data grid component

Comments

@muhammadhuzaifakhan1133

Bug description

I Implemented DataGrid with DataPager. When I click on next button or last page button, which are on the right most side of the pager, or previous bttuon or first page button, which are on the left most side of the pager. I got this error

Steps to reproduce

  1. Implement Data Grid with Data Source
  2. Implement Data Pager with Data Source
  3. Run application
  4. Don't press on individual pages, but click on page navigation buttons directly in Data Pager

Code sample

Code sample
import 'dart:async';
import 'package:attendance_management_system/widgets/data_table_content_conponent.dart';
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import '../widgets/data_table_header_component.dart';

Map<int, int> pageStartIndex = {1: 0};
int currentWidgetPage = 1;

class CustomPaginatedTable extends StatefulWidget {
  final List<Map<String, dynamic>> columns;
  final List<dynamic> data;
  final int totalDataCount;
  final int rowsPerPage;
  final String Function(dynamic, int) getCellValue;
  final Future<void> Function(int)? onNewPageFetched;
  const CustomPaginatedTable({
    super.key,
    required this.columns,
    required this.data,
    required this.totalDataCount,
    this.rowsPerPage = 10,
    this.onNewPageFetched,
    required this.getCellValue,
  });

  @override
  State<CustomPaginatedTable> createState() => _CustomPaginatedTableState();
}

class _CustomPaginatedTableState extends State<CustomPaginatedTable> {
  final bool isRunNextPage = false;

  @override
  Widget build(BuildContext context) {
    CustomPaginatedTableSource source = CustomPaginatedTableSource(
      columns_: widget.columns,
      isRunNextPage_: isRunNextPage,
      data_: widget.data,
      dataCount_: widget.totalDataCount,
      currentPage_: currentWidgetPage,
      rowsPerPage_: widget.rowsPerPage,
      getCellValue_: widget.getCellValue,
      onNewPageFetched_: widget.onNewPageFetched,
      updateCurrentPage_: (newPage) {
        setState(() {
          currentWidgetPage = newPage;
        });
      },
    );
    return Column(
      children: [
        Expanded(
          child: SfDataGrid(
            rowsPerPage: widget.rowsPerPage,
            source: source,
            gridLinesVisibility: GridLinesVisibility.none,
            headerGridLinesVisibility: GridLinesVisibility.none,
            columns: [
              for (int i = 0; i < widget.columns.length; i++)
                GridColumn(
                    width: widget.columns[i]['width'],
                    columnName: widget.columns[i]['name'].toString(),
                    label: DataTableHeaderComponent(
                      headerTitle: widget.columns[i]['name'].toString(),
                      width: widget.columns[i]['width'],
                    )),
            ],
          ),
        ),
        SfDataPager(
          initialPageIndex: currentWidgetPage,
          pageCount:
              (widget.totalDataCount / widget.rowsPerPage).ceilToDouble(),
          direction: Axis.horizontal,
          delegate: source,
        ),
      ],
    );
  }
}

class CustomPaginatedTableSource extends DataGridSource {
  int rowsPerPage = 10;
  List<dynamic> allData = [];
  int currentPage = 1;
  late void Function(int) updateCurrentPage;
  late Future<void> Function(int)? onNewPageFetched;
  late String Function(dynamic, int) getCellValue;
  List<Map<String, dynamic>> columns = [];
  bool isRunNextPage = false;
  int dataCount = 0;

  CustomPaginatedTableSource({
    required List<dynamic> data_,
    required int rowsPerPage_,
    required void Function(int) updateCurrentPage_,
    required Future<void> Function(int)? onNewPageFetched_,
    required String Function(dynamic, int) getCellValue_,
    required List<Map<String, dynamic>> columns_,
    required int currentPage_,
    required bool isRunNextPage_,
    required int dataCount_,
  }) {
    currentPage = currentPage_;
    dataCount = dataCount_;
    updateCurrentPage = updateCurrentPage_;
    onNewPageFetched = onNewPageFetched_;
    getCellValue = getCellValue_;
    columns = columns_;
    allData = data_;
    rowsPerPage = rowsPerPage_;
}

  @override
  List<DataGridRow> get rows {
    List<dynamic> sourceData = [];
    int startIndex = pageStartIndex[currentPage]!;
    int lastPage = (dataCount / rowsPerPage).ceil();
    int endIndex;
    if (currentPage == lastPage) {
      int rem = dataCount % rowsPerPage;
      if (rem == 0) {
        endIndex = startIndex + rowsPerPage - 1;
      } else {
        endIndex = startIndex + rem - 1;
      }
    } else {
      endIndex = startIndex + rowsPerPage - 1;
    }
    if (endIndex > allData.length) {
      sourceData = allData.getRange(startIndex, allData.length).toList();
    } else {
      sourceData = allData.getRange(startIndex, endIndex + 1).toList();
    }
    return sourceData
        .map<DataGridRow>((e) => DataGridRow(cells: [
              for (int i = 0; i < columns.length; i++)
                DataGridCell<String>(
                    columnName: columns[i]["name"], value: getCellValue(e, i)),
            ]))
        .toList();
  }

  @override
  Future<bool> handlePageChange(
    int oldPageIndex,
    int newPageIndex,
  ) async {
    if (!isRunNextPage) {
      isRunNextPage = true;
      return true;
    }
    if (oldPageIndex == newPageIndex) return true;
    if (!pageStartIndex.containsKey(newPageIndex + 1)) {
      pageStartIndex[newPageIndex + 1] = allData.length;
      currentWidgetPage = newPageIndex + 1;
      await onNewPageFetched!(newPageIndex + 1);
      return true;
    }
    updateCurrentPage(newPageIndex + 1);
    return true;
  }

  @override
  DataGridRowAdapter? buildRow(DataGridRow row) {
    return DataGridRowAdapter(cells: [
      for (int i = 0; i < row.getCells().length; i++)
        DataTableContentComponent1(
          width: columns[i]["width"],
          contentText: row.getCells()[i].value?.toString() ?? 'N/A',
          toolTipText: row.getCells()[i].value?.toString() ?? 'N/A',
        ),
    ]);
  }
}

Screenshots or Video

Screenshots / Video demonstration
19.11.2024_12.52.47_REC.mp4

Stack Traces

Stack Traces
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 45:50           <fn>
async_patch.dart:45
dart-sdk/lib/async/zone.dart 1661:54                                         runUnary
zone.dart:1661
dart-sdk/lib/async/future_impl.dart 163:18                                   handleValue
future_impl.dart:163
dart-sdk/lib/async/future_impl.dart 861:44                                   handleValueCallback
future_impl.dart:861
dart-sdk/lib/async/future_impl.dart 890:13                                   _propagateToListeners
future_impl.dart:890
dart-sdk/lib/async/future_impl.dart 666:5                                    [_completeWithValue]
future_impl.dart:666
dart-sdk/lib/async/future_impl.dart 736:7                                    callback
future_impl.dart:736
dart-sdk/lib/async/schedule_microtask.dart 40:11                             _microtaskLoop
schedule_microtask.dart:40
dart-sdk/lib/async/schedule_microtask.dart 49:5                              _startMicrotaskLoop
schedule_microtask.dart:49
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:7           <fn>
async_patch.dart:181

On which target platforms have you observed this bug?

Web

Flutter Doctor output

Doctor output
[√] Flutter (Channel stable, 3.24.5, on Microsoft Windows [Version 10.0.19045.5131], locale en-US)
    • Flutter version 3.24.5 on channel stable at C:\flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision dec2ee5c1f (6 days ago), 2024-11-13 11:13:06 -0800
    • Engine revision a18df97ca5
    • Dart version 3.5.4
    • DevTools version 2.37.3

[√] 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\PMLS\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 21.0.3+-12282718-b509.11)
    • 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.12.0)
    • Visual Studio at C:\Program Files\Microsoft Visual Studio\2022\Community
    • Visual Studio Community 2022 version 17.12.35506.116
    • Windows 10 SDK version 10.0.22621.0

[√] Android Studio (version 2024.2)
    • 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 21.0.3+-12282718-b509.11)

[√] VS Code (version 1.95.3)
    • VS Code at C:\Users\PMLS\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.100.0

[√] Connected device (3 available)
    • Windows (desktop) • windows • windows-x64    • Microsoft Windows [Version 10.0.19045.5131]
    • Chrome (web)      • chrome  • web-javascript • Google Chrome 131.0.6778.70
    • Edge (web)        • edge    • web-javascript • Microsoft Edge 131.0.2903.51

[√] Network resources
    • All expected network resources are available.

• No issues found!
@SethupathyD
Copy link

Hi @muhammadhuzaifakhan1133

We tried to run your sample, but due to the missing files, it could not run. Therefore, we checked the issue with a simple sample, and it worked correctly without any issues. The problem you are facing that occurs only when accessing the position of scroll controller before assigning it to any scroll view. Could you share if any customizations have been made in this area?

Regards,
Sethupathy D

@VijayakumarMariappan VijayakumarMariappan added data grid Data grid component waiting for customer response Cannot make further progress until the customer responds. labels Nov 21, 2024
@ashok-kuvaraja
Copy link
Collaborator

Hi @muhammadhuzaifakhan1133,

We suspect that the reported issue has been resolved at your end. Hence, we are closing this issue. If you need any further assistance, please reopen this. We are always happy to help.

Regards,
Ashok K

@ashok-kuvaraja ashok-kuvaraja removed the waiting for customer response Cannot make further progress until the customer responds. label Dec 5, 2024
@muhammadhuzaifakhan1133
Copy link
Author

Here is the missing files.

implementation of 'data_table_content_conponent.dart':

import 'package:flutter/material.dart';

class DataTableContentComponent1 extends StatelessWidget {
  final double width;
  final String contentText;
  final String? toolTipText;
  final String? profileImgPath;
  final bool isShowProfile;
  final bool? isRightBorder;
  final bool? isBottomBorder;
  final TextStyle? myTextStyle;

  const DataTableContentComponent1(
      {super.key,
      required this.width,
      required this.contentText,
      this.toolTipText,
      this.profileImgPath,
      this.isShowProfile = false,
      this.myTextStyle,
      this.isRightBorder,
      this.isBottomBorder});

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 15),
      height: double.maxFinite,
      width: width,
      // padding: const EdgeInsets.only(left: 30.0),
      // decoration: BoxDecoration(
      // border: Border(
      //     left: BorderSide(color: AppColors.blackShade2Color),
      //     bottom: isBottomBorder == true
      //         ? BorderSide(color: AppColors.blackShade2Color)
      //         : BorderSide(color: Colors.transparent),
      //     right: isRightBorder == true
      //         ? BorderSide(color: AppColors.blackShade2Color)
      //         : BorderSide(color: Colors.transparent))),
      child: Row(
        // mainAxisAlignment: MainAxisAlignment.center,
        children: [
          if (isShowProfile) ...[
            Container(
              height: 18,
              width: 18,
              decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(9),
                  image: DecorationImage(
                      image: AssetImage(profileImgPath.toString()))),
            ),
            const SizedBox(
              width: 10,
            ),
          ],
          Flexible(
            child: Tooltip(
              message: toolTipText,
              // textStyle: AppTextstyles.l300white12,
              triggerMode: TooltipTriggerMode.tap,
              showDuration: const Duration(milliseconds: 2000),
              padding: const EdgeInsets.all(8),
              child: Text(
                contentText,
                style: myTextStyle,
                maxLines: 1,
                overflow: TextOverflow.ellipsis,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

Here is the implementation of 'data_table_header_component.dart':

import 'package:flutter/material.dart';

class DataTableHeaderComponent extends StatelessWidget {
  final String headerTitle;
  final String? iconPath;
  final double? width;
  final bool? isCenter;
  final bool? isTopRightRound;
  final bool? isRightRound;

  final bool? isLeftRound;

  final bool? isTopLeftRound;

  const DataTableHeaderComponent({
    super.key,
    required this.headerTitle,
    this.iconPath,
    this.width,
    this.isCenter = false,
    this.isTopRightRound = false,
    this.isTopLeftRound = false,
    this.isRightRound,
    this.isLeftRound,
  });

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Container(
          padding: const EdgeInsets.symmetric(horizontal: 15),
          height: 40,
          width: width,
          decoration: BoxDecoration(
              // color: AppColors.darkSkyBlueColor.withOpacity(0.2),
              // color: AppColors.purpleColor.withOpacity(0.8),
              borderRadius: BorderRadius.only(
                topLeft: isLeftRound == true
                    ? const Radius.circular(4)
                    : Radius.zero,
                topRight: isRightRound == true
                    ? const Radius.circular(4)
                    : Radius.zero,
                bottomLeft: isLeftRound == true
                    ? const Radius.circular(4)
                    : Radius.zero,
                bottomRight: isRightRound == true
                    ? const Radius.circular(4)
                    : Radius.zero,
              )),
          child: Center(
            child: Row(
              mainAxisAlignment: (isCenter == true)
                  ? MainAxisAlignment.center
                  : MainAxisAlignment.start,
              children: [
                Text(
                  headerTitle,
                  // style: AppTextStyles.pop600White17
                  //     .copyWith(fontSize: 14, color: AppColors.whiteColor),
                )
              ],
            ),
          ),
        ),
      ],
    );
  }
}

@muhammadhuzaifakhan1133
Copy link
Author

@SethupathyD
Please see this issue as soon as possible.

@abineshPalanisamy
Copy link

Hi @muhammadhuzaifakhan1133 ,

Based on the provided code, we have adjusted the sample and made it runnable on our side. However, we were unable to replicate the issue as described. For your reference, we have attached a video of our testing process and the sample we used.

Video.reference.mp4

We kindly request you to update Flutter (3.24.5) and SfDataGrid (27.2.5) to the latest versions and test it on your end. If the issue persists, please modify the attached sample to reproduce the problem. Additionally, we request you to share a video recording demonstrating the issue with the modified sample for better clarity. This information will help us address your concerns comprehensively and provide an appropriate solution.

Regards,
Abinesh P

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

No branches or pull requests

5 participants