Giter Club home page Giter Club logo

Comments (27)

bosskmk avatar bosskmk commented on July 21, 2024 10

Pagination is a must-have feature. There are plans to add.
I think I will do it when the filtering I'm currently doing is over.

from pluto_grid.

bosskmk avatar bosskmk commented on July 21, 2024 3

@Minsamin
First of all, thanks for your comments.

The features you mentioned are currently available.

stateManager.setPage()
stateManager.setPageSize()
stateManager.page
stateManager.pageSize
stateManager.totalPage
stateManager.setShowLoading()

However, additional callback events are required for filtering and sorting.

I'll try to add server-side pagination to the next release.

from pluto_grid.

fehernyul avatar fehernyul commented on July 21, 2024 2

Is there any progression on this feature?

from pluto_grid.

bosskmk avatar bosskmk commented on July 21, 2024 1

I am working on paging.

Pagination happens on the client side when the existing createFooter callback returns a pagination widget.

One pagination widget is provided by default and you can customize it.

It will be completed by tomorrow or next weekend at the latest.

from pluto_grid.

jsanchez-98 avatar jsanchez-98 commented on July 21, 2024

Any news on that or should I just give up on this plugin.

from pluto_grid.

Minsamin avatar Minsamin commented on July 21, 2024

Hello, are you working on the pagination part? Any ETA ? I want to use this library in my project.

from pluto_grid.

bosskmk avatar bosskmk commented on July 21, 2024

I'm thinking about how to do it, but I can't because I don't have much time.

from pluto_grid.

amasahara avatar amasahara commented on July 21, 2024

Hope that you can do it soon because it very very necessary for big data with render. long time for waiting

from pluto_grid.

amasahara avatar amasahara commented on July 21, 2024

thanks for great package, hope it will be soon

from pluto_grid.

bosskmk avatar bosskmk commented on July 21, 2024

Version 2.4.0 has been released.

example demo
https://weblaze.dev/pluto_grid/build/web/#feature/row-pagination

from pluto_grid.

bosskmk avatar bosskmk commented on July 21, 2024

I found a bug where if I filter on a paged list and then release it again, the list doesn't come back.(fixed 2.4.1)

There may be bugs due to insufficient testing. (to be fixed in next release)

If you find any other bugs, please report them to me.

from pluto_grid.

Minsamin avatar Minsamin commented on July 21, 2024

Can we use this with lazy data loading?
Like, get the particular page data from api, then put data in dataTable.
For every page, it will first fetch then show in dataTable...

from pluto_grid.

bosskmk avatar bosskmk commented on July 21, 2024

@Minsamin
That feature should be added to the server-side rendering feature.
Or you have to implement it yourself.
Most APIs can be called from StateManager that is passed as an argument to the onLoaded callback function when creating a grid.
If you use this, you will be able to implement it yourself.

from pluto_grid.

Minsamin avatar Minsamin commented on July 21, 2024

I think, if PlutoPagination has buttonPress callback(first, last, next, Prev) for user, and any method to show loading while fetching data from server, that will be helpful.

reference
https://dev-owl.github.io/advanced_datatable/#/

from pluto_grid.

amasahara avatar amasahara commented on July 21, 2024

stateManager.totalPage is getter only which way i can use it. Could you make an example for it

from pluto_grid.

bosskmk avatar bosskmk commented on July 21, 2024

@amasahara yes it is. `stateManager.totalPage is getter.

from pluto_grid.

amasahara avatar amasahara commented on July 21, 2024

So if i want so data like advance datatable i will be waiting ultil next update or another way to do it

from pluto_grid.

jamolina2021 avatar jamolina2021 commented on July 21, 2024

Hi @bosskmk,
Any progress on server-side pagination?
Thanks for such a wonderful datagrid.
Regards,
Jose

from pluto_grid.

tuananh432 avatar tuananh432 commented on July 21, 2024

@bosskmk how can i set the page change event?

from pluto_grid.

reke592 avatar reke592 commented on July 21, 2024

hi, is there a way to manually define the paging process? I'm trying to figure out how to use the paginator, below is my sample backend response.

{
  data: [...],
  first: "/api/v1/models?page=1&limit=50",
  last: "/api/v1/models?page=261&limit=50",
  next: "/api/v1/models?page=4&limit=50",
  previous: "/api/v1/models?page=2&limit=50",
  page_no: 3,
  page_size: 50,
  total_page: 261,
  total_rows: 13029
}

what we are trying to achieve is something like this in UI
image

from pluto_grid.

a7mdragab avatar a7mdragab commented on July 21, 2024

I think, if PlutoPagination has buttonPress callback(first, last, next, Prev) for user, and any method to show loading while fetching data from server, that will be helpful.

reference https://dev-owl.github.io/advanced_datatable/#/

Any updates about this?

from pluto_grid.

acamenhas avatar acamenhas commented on July 21, 2024

Hello,

Unfortunately from what I see the async pagination is not ready yet.

It's something that is not very complex:

1- page change event (know what page we are)
2- possibility to show a spinner
3- api call
4- refresh data
5- hide spinner

from pluto_grid.

bosskmk avatar bosskmk commented on July 21, 2024

Yes, I am planning to provide a widget for asynchronous pagination.
I just haven't started doing this yet.
I'll start this up and let you know when I'm done.
thank you

from pluto_grid.

bosskmk avatar bosskmk commented on July 21, 2024

I am not yet developing the asynchronous pagination feature, but users can implement server side pagination as shown below.
(I have plans to add features in the future)

Sorting and filtering require minor modifications to the current event part.

Currently, when a user's sorting or filtering event occurs, it is processed as local data. In server-side pagination, only the user's event is generated and the data must be imported as the event information.

import 'dart:math';

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

import '../dummy_data/development.dart';

class EmptyScreen extends StatefulWidget {
  static const routeName = 'empty';

  const EmptyScreen({Key? key}) : super(key: key);

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

class _EmptyScreenState extends State<EmptyScreen> {
  final List<PlutoColumn> columns = DummyData.textColumns(5);

  final List<PlutoRow> rows = [];

  final List<PlutoRow> fakeFetchedRows = [];

  late PlutoGridStateManager stateManager;

  final int pageSize = 30;

  @override
  void initState() {
    super.initState();

    /// 100 data generation for fake server data.
    fakeFetchedRows.addAll(
      DummyData.rowsByColumns(length: 100, columns: columns),
    );
  }

  Future<_PaginationData> fetch(
    _PaginationParams params,
  ) async {
    /// Get data from server.
    final start = (params.page - 1) * pageSize;
    final end = min(start + pageSize, fakeFetchedRows.length);
    final fetchRows = fakeFetchedRows.getRange(start, end);
    await Future.delayed(const Duration(seconds: 1));

    /// Change server data to Map<String, dynamic> type.
    return Future.value(
      _PaginationData(
        totalPage: (fakeFetchedRows.length / pageSize).ceil(),
        rows: fetchRows
            .map(
              (e) => e.cells.map<String, dynamic>(
                (key, value) => MapEntry(key, value.value),
              ),
            )
            .toList(),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          padding: const EdgeInsets.all(15),
          child: PlutoGrid(
            columns: columns,
            rows: rows,
            onChanged: (PlutoGridOnChangedEvent event) {
              print(event);
            },
            onLoaded: (PlutoGridOnLoadedEvent event) {
              stateManager = event.stateManager;
            },
            configuration: const PlutoGridConfiguration(),
            createFooter: (s) => PlutoPaginationServerSide(s, fetch: fetch),
          ),
        ),
      ),
    );
  }
}

class PlutoPaginationServerSide extends StatefulWidget {
  const PlutoPaginationServerSide(
    this.stateManager, {
    required this.fetch,
    super.key,
  });

  final PlutoGridStateManager stateManager;

  final Future<_PaginationData> Function(
    _PaginationParams params,
  ) fetch;

  @override
  State<PlutoPaginationServerSide> createState() =>
      _PlutoPaginationServerSideState();
}

class _PlutoPaginationServerSideState extends State<PlutoPaginationServerSide> {
  PlutoGridStateManager get stateManager => widget.stateManager;

  final int initialPage = 1;

  int totalPage = 0;

  @override
  void initState() {
    super.initState();

    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      setPage(initialPage);
    });
  }

  Future<void> setPage(int page) async {
    stateManager.setShowLoading(true, level: PlutoGridLoadingLevel.rows);

    final data = await widget.fetch(
      _PaginationParams(page: page),
    );

    if (totalPage != data.totalPage) setState(() => totalPage = data.totalPage);

    stateManager.refRows.clearFromOriginal();
    stateManager.insertRows(
      0,
      data.rows
          .map(
            (e) => PlutoRow(
              cells: {
                for (var v in e.entries) v.key: PlutoCell(value: v.value)
              },
            ),
          )
          .toList(),
    );

    stateManager.setShowLoading(false);
  }

  @override
  Widget build(BuildContext context) {
    return _PaginationWidget(
      iconColor: stateManager.style.iconColor,
      disabledIconColor: stateManager.style.disabledIconColor,
      activatedColor: stateManager.style.activatedBorderColor,
      iconSize: stateManager.style.iconSize,
      height: stateManager.footerHeight,
      initialPage: initialPage,
      totalPage: totalPage,
      setPage: setPage,
    );
  }
}

class _PaginationData {
  _PaginationData({
    required this.totalPage,
    required this.rows,
  });

  final int totalPage;

  final List<Map<String, dynamic>> rows;
}

class _PaginationParams {
  _PaginationParams({
    required this.page,
  });

  final int page;
}

class _PaginationWidget extends StatefulWidget {
  const _PaginationWidget({
    required this.iconColor,
    required this.disabledIconColor,
    required this.activatedColor,
    required this.iconSize,
    required this.height,
    this.initialPage = 1,
    required this.totalPage,
    required this.setPage,
  });

  final Color iconColor;

  final Color disabledIconColor;

  final Color activatedColor;

  final double iconSize;

  final double height;

  final int initialPage;

  final int totalPage;

  final void Function(int page) setPage;

  @override
  State<_PaginationWidget> createState() => _PaginationWidgetState();
}

class _PaginationWidgetState extends State<_PaginationWidget> {
  @override
  void initState() {
    super.initState();

    _page = widget.initialPage;
  }

  int get totalPage => widget.totalPage;

  int _page = 1;

  late double _maxWidth;

  final _iconSplashRadius = PlutoGridSettings.rowHeight / 2;

  bool get _isFirstPage => _page < 2;

  bool get _isLastPage => _page > totalPage - 1;

  /// maxWidth < 450 : 1
  /// maxWidth >= 450 : 3
  /// maxWidth >= 550 : 5
  /// maxWidth >= 650 : 7
  int get _itemSize {
    final countItemSize = ((_maxWidth - 350) / 100).floor();

    return countItemSize < 0 ? 0 : min(countItemSize, 3);
  }

  int get _startPage {
    final itemSizeGap = _itemSize + 1;

    var start = _page - itemSizeGap;

    if (_page + _itemSize > totalPage) {
      start -= _itemSize + _page - totalPage;
    }

    return start < 0 ? 0 : start;
  }

  int get _endPage {
    final itemSizeGap = _itemSize + 1;

    var end = _page + _itemSize;

    if (_page - itemSizeGap < 0) {
      end += itemSizeGap - _page;
    }

    return end > totalPage ? totalPage : end;
  }

  List<int> get _pageNumbers {
    return List.generate(
      _endPage - _startPage,
      (index) => _startPage + index,
    );
  }

  void _firstPage() {
    _movePage(1);
  }

  void _beforePage() {
    int beforePage = _page - 1 + (_itemSize * 2);

    if (beforePage < 1) {
      beforePage = 1;
    }

    _movePage(beforePage);
  }

  void _nextPage() {
    int nextPage = _page + 1 + (_itemSize * 2);

    if (nextPage > totalPage) {
      nextPage = totalPage;
    }

    _movePage(nextPage);
  }

  void _lastPage() {
    _movePage(totalPage);
  }

  void _movePage(int page) {
    setState(() {
      _page = page;
      widget.setPage(page);
    });
  }

  ButtonStyle _getNumberButtonStyle(bool isCurrentIndex) {
    return TextButton.styleFrom(
      disabledForegroundColor: Colors.transparent,
      shadowColor: Colors.transparent,
      padding: const EdgeInsets.fromLTRB(5, 0, 0, 10),
      backgroundColor: Colors.transparent,
    );
  }

  TextStyle _getNumberTextStyle(bool isCurrentIndex) {
    return TextStyle(
      fontSize: isCurrentIndex ? widget.iconSize : null,
      color: isCurrentIndex ? widget.activatedColor : widget.iconColor,
    );
  }

  Widget _makeNumberButton(int index) {
    var pageFromIndex = index + 1;

    var isCurrentIndex = _page == pageFromIndex;

    return TextButton(
      onPressed: () {
        _movePage(pageFromIndex);
      },
      style: _getNumberButtonStyle(isCurrentIndex),
      child: Text(
        pageFromIndex.toString(),
        style: _getNumberTextStyle(isCurrentIndex),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (_, size) {
        _maxWidth = size.maxWidth;

        final Color iconColor = widget.iconColor;

        final Color disabledIconColor = widget.disabledIconColor;

        return Container(
          width: _maxWidth,
          height: widget.height,
          alignment: Alignment.center,
          child: SingleChildScrollView(
            scrollDirection: Axis.horizontal,
            child: Row(
              children: [
                IconButton(
                  onPressed: _isFirstPage ? null : _firstPage,
                  icon: const Icon(Icons.first_page),
                  color: iconColor,
                  disabledColor: disabledIconColor,
                  splashRadius: _iconSplashRadius,
                  mouseCursor: _isFirstPage
                      ? SystemMouseCursors.basic
                      : SystemMouseCursors.click,
                ),
                IconButton(
                  onPressed: _isFirstPage ? null : _beforePage,
                  icon: const Icon(Icons.navigate_before),
                  color: iconColor,
                  disabledColor: disabledIconColor,
                  splashRadius: _iconSplashRadius,
                  mouseCursor: _isFirstPage
                      ? SystemMouseCursors.basic
                      : SystemMouseCursors.click,
                ),
                ..._pageNumbers.map(_makeNumberButton).toList(),
                IconButton(
                  onPressed: _isLastPage ? null : _nextPage,
                  icon: const Icon(Icons.navigate_next),
                  color: iconColor,
                  disabledColor: disabledIconColor,
                  splashRadius: _iconSplashRadius,
                  mouseCursor: _isLastPage
                      ? SystemMouseCursors.basic
                      : SystemMouseCursors.click,
                ),
                IconButton(
                  onPressed: _isLastPage ? null : _lastPage,
                  icon: const Icon(Icons.last_page),
                  color: iconColor,
                  disabledColor: disabledIconColor,
                  splashRadius: _iconSplashRadius,
                  mouseCursor: _isLastPage
                      ? SystemMouseCursors.basic
                      : SystemMouseCursors.click,
                ),
              ],
            ),
          ),
        );
      },
    );
  }
}

from pluto_grid.

bosskmk avatar bosskmk commented on July 21, 2024

Released PlutoGrid 5.3.0

Refer to below link.
#601

from pluto_grid.

github-actions avatar github-actions commented on July 21, 2024

This issue is stale because it has been open for 30 days with no activity.

from pluto_grid.

github-actions avatar github-actions commented on July 21, 2024

This issue was closed because it has been inactive for 14 days since being marked as stale.

from pluto_grid.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.