GithubHelp home page GithubHelp logo

rickypid / flutter_expandable_table Goto Github PK

View Code? Open in Web Editor NEW
37.0 3.0 27.0 5.52 MB

A Flutter widget for create an expandable table with header and first column fixed.

Home Page: https://pub.dev/packages/flutter_expandable_table

License: BSD 3-Clause "New" or "Revised" License

Kotlin 0.24% Swift 0.63% Objective-C 0.06% Dart 99.07%
flutter dart flutter-widget datatables-plugin datatable datatables flutter-package expandable expandable-table widget-ui

flutter_expandable_table's Introduction

flutter_expandable_table

Expandable Table

Pub Package Pub Points Pub Likes

Package Issue Package License

ExpandableTable is a widget for Flutter that create a Table with header and first column fixed. You can create a nested Rows/Columns grouped in expandable Row/Column

Image
ExpandableTable

Features

  • Header and first column fixed
  • Supports vertical and horizontal scroll
  • Customizable animation Duration and Curve
  • Specific height definition for each single row
  • Specific width definition for each single column
  • Access to cell address when building cell content
  • Access to the parent rows and columns of the cell while building the contents of a cell

ย 

Usage

Make sure to check out the examples on GitHub.

Installation

Add the following line to pubspec.yaml:

dependencies:
  flutter_expandable_table: <last-release>

Basic setup

Complete example available here.

     return ExpandableTable(
      firstHeaderCell: ExpandableTableCell(
        child: Text('Simple\nTable'),
      ),
      headers: headers,
      rows: rows,
    );

Use with the controller

You can create an external controller to be able to dynamically manage the table, for example to add or remove rows within it.

Here is an example:

    //... Inside Widget State
    late ExpandableTableController controller;
    //....
    @override
    void initState() {
      controller = ExpandableTableController(
        firstHeaderCell: ExpandableTableCell(child: Container()),
        headers: [],
        rows: [],
        headerHeight: 263,
        defaultsColumnWidth: 200,
        firstColumnWidth: 300,
        scrollShadowColor: AppColors.black,
      );
      super.initState();
    }
    void _onEvent(){    
      controller.rows.add(...your code...);
    }
    @override
    Widget build(BuildContext context) {
      return ExpandableTable(
        controller: controller,
      );
    }
//....

ExpandableTable Properties

  • firstHeaderCell: Is the top left cell, i.e. the first header cell.
  • headers: contains the list of all column headers, each one of these can contain a list of further headers, this allows you to create nested and expandable columns.
  • rows: contains the list of all the rows of the table, each of these can contain a list of further rows, this allows you to create nested and expandable rows.
  • headerHeight: is the height of each column header, i.e. the first row.
  • firstColumnWidth: determines first Column width size.
  • defaultsColumnWidth: defines the default width of all columns, it is possible to redefine it for each individual column.
  • defaultsRowHeight: defines the default height of all rows, it is possible to redefine it for every single row.
  • duration: determines duration rendered animation of Rows/Columns expansion.
  • curve: determines rendered curve animation of Rows/Columns expansion.
  • scrollShadowDuration: determines duration rendered animation of shadows.
  • scrollShadowFadeInCurve: determines rendered curve animation of shadows appearance.
  • scrollShadowFadeOutCurve: determines rendered curve animation of shadows disappearance.
  • scrollShadowColor: determines rendered color of shadows.
  • scrollShadowSize: determines size of shadows.
  • visibleScrollbar: determines visibility of horizontal and vertical scrollbars.
  • trackVisibilityScrollbar: indicates that the scrollbar track should be visible.
  • thumbVisibilityScrollbar: indicates that the scrollbar thumb should be visible, even when a scroll is not underway.
  • expanded: indicates that the table expands, so it fills the available space along the horizontal and vertical axes.

ย 

๐Ÿ“š My open source projects

Flutter

Package Verison Score Likes Test Coverage
Pub Package Pub Points Pub Likes
Pub Package Pub Points Pub Likes
Pub Package Pub Points Pub Likes
Pub Package Pub Points Pub Likes

Dart

Package Verison Score Likes Test Coverage
Pub Package Pub Points Pub Likes Test CI codecov
Pub Package Pub Points Pub Likes Test CI codecov

flutter_expandable_table's People

Contributors

allato avatar richib20 avatar rickypid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

flutter_expandable_table's Issues

Row assertion failure

I'm having difficulties getting this to run. I have studied the example code, but keep hitting the following assertion failure in the row.dart file:

assert(children is List<Widget> || children is List<ExpandableTableRow>)

Unlike the provided example, I am building the row as a List<Widget> as shown below, which seems to fail, since the debugger shows this as a List. It might be helpful to include a small example with manually generated cells versus the List<Widget>.generate( ones? I'm certain this is not a bug, but user error on my part, but I can't seem to get this to work.

image

Dynamic cell width

Would it be possible to make a column as wide as it's widest cell? Or be the width of a header cell in case it's the widest.

Cannot dynamically update table contents

Cannot dynamically update table contents

ExpandableTableCell _buildCell(String content, {CellBuilder? builder}) {
    return ExpandableTableCell(
      child: builder != null
          ? null
          : GestureDetector(
              onTap: () {
                print('Cell $content tapped');
                // update cell content
                setState(() {
                  data['rows'][0]['columns'][0]['value'] = 'Updated';
                });
              },
              child: DefaultCellCard(
                child: Center(
                  child: Text(
                    content,
                    style: textStyle,
                  ),
                ),
              ),
            ),
      builder: builder,
    );
  }

New feautures implementations

After some user requests to implement new features, I thought I'd open this issue to be able to do a review and decide whether or not to implement the requests made.

  1. Dynamic cell width #9
  2. Filter data #3
  3. Select a row #2

RangeError (index): Invalid value: Valid value range is empty: 0

For the tablebody I keep getting this error in the _buildBodyColumns method because the visibleColumn is empty at first.

for (Widget cell in cells) {
        cellsRow.add(ExpandableTableCell(
          child: cell,
          height: row.height,
          width: ExpandableTableData.of(context).cellWidth,
          horizontalExpanded:
              ExpandableTableData.of(context).visibleColumn[x] == true,
          verticalExpanded: rowParent != null ? rowParent.isExpanded : true,
        ));
        x++;
      }

If I hot reload the emulator after going to the page it works.

Filter data

Hi!!
I want to add some Filtering to my table. is that possible? and how?

Elements Don't Hide: Flutter Form Builder 2

I am using elements from flutter_form_builder(9.1.1), and want to use form builder elements within the expanded table.

For typical Flutter elements like Text or ElevatedButton, they are hidden once the row collapses.

However, for flutter_form_builder elements, they don't hide very well.

image image

As you can see, the checkbox from FormBuilderCheckbox still shows, and the boarders and text from the FormBuilderDateTimePicker show as well. The same behavior occurs with other elements in the library.

Not working well with ValueListenableBuilder

Each time I try to re-build the table as I have some functionality to filter the columns, if I print the data inside the build method, it prints the updated data, but the columns remain the same, until I move away from this screen and come back again. I pass my data as the Constructor Attribute.

`import 'package:flutter/material.dart';
import 'package:flutter_expandable_table/flutter_expandable_table.dart';

import '../../../constants.dart';
import '../../dashboard/components/default_cell_card.dart';

///Make a table that places the company names as columns,
///policy names as first row, and places an icon on each cell to indicate
///whether the company has that policy or not
class DynamicTable extends StatefulWidget {
  const DynamicTable({super.key, required this.data});

  ///the transformed Map to be used for rows and columns
  final Map<String, Map<String, double>> data;

  @override
  State<DynamicTable> createState() => _DynamicTableState();
}

class _DynamicTableState extends State<DynamicTable> {
  Color primaryColor = Colors.white; //corner
  Color accentColor = const Color(0xffffdc6e); //background
  TextStyle textStyle =
      const TextStyle(color: bgColor, fontWeight: FontWeight.bold);
  TextStyle textStyleSubItems = const TextStyle(color: Colors.grey);

  _buildCell(String content, {CellBuilder? builder}) {
    return ExpandableTableCell(
      child: builder != null
          ? null
          : DefaultCellCard(
              child: Center(
                child: Text(
                  content,
                  style: textStyle,
                ),
              ),
            ),
      builder: builder,
    );
  }

  ///Make a table cell that has formatting that allows the text to be aligned
  /// as centerLeft
  _buildCellPolicyName(String content, {CellBuilder? builder}) {
    return ExpandableTableCell(
      child: builder != null
          ? null
          : DefaultCellCard(
              child: Center(
                child: Align(
                  alignment: Alignment.centerLeft,
                  child: Text(
                    content,
                    style: const TextStyle(
                      color: bgColor,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                ),
              ),
            ),
      builder: builder,
    );
  }

  ///Instead of placing the values 1 or 0, place a green check icon for 1,
  ///and place a red block icon for 0
  _buildCellIcons(double value, {CellBuilder? builder}) {
    return ExpandableTableCell(
      child: builder != null
          ? null
          : DefaultCellCard(
              child: Center(
                child: _setIcon(value),
              ),
            ),
      builder: builder,
    );
  }

  ///Given the policyName as key and the Map of it's value map, make a row
  ///By placing the policyName as first cell, and the rest of the values as
  ///icons for each company.
  ExpandableTableRow _getRow(String policyName, Map<String, double> companies) {
    List<ExpandableTableCell> cells = [];
    // //add policy name in first cell
    // cells.add(_buildCell(policyName));
    // Iterate through company values and add cells with 1 or 0 accordingly
    companies.forEach((companyName, value) {
      cells.add(_buildCellIcons(value));
    });

    return ExpandableTableRow(
        firstCell: _buildCellPolicyName(policyName), cells: cells, height: 50);
  }

  ///Make the ExpandableTable by setting up the headers and rows, and other
  ///relevant customizations
  ExpandableTable _buildTable() {
    //make all company names as columns
    List<ExpandableTableHeader> headers = [
      ...widget.data.values.first.keys.map((companyName) =>
          ExpandableTableHeader(
              cell: _buildCell(companyName),
              width: 200,
              disableDefaultOnTapExpansion: true)),
    ];
    //make the policy and each company value as rows
    List<ExpandableTableRow> rows = [];
    widget.data.forEach((policyName, companies) {
      rows.add(_getRow(policyName, companies));
    });

    return ExpandableTable(
      firstHeaderCell: _buildCell(''),
      headers: headers,
      headerHeight: 50,
      scrollShadowColor: accentColor,
      rows: rows,
      visibleScrollbar: true,
    );
  }

  @override
  Widget build(BuildContext context) {
    print(widget.data.values.first.keys);
    return Container(
      padding: const EdgeInsets.all(8.0),
      margin: const EdgeInsets.all(20),
      decoration: const BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.all(Radius.circular(10)),
      ),
      child: Flex(
        direction: Axis.vertical,
        mainAxisSize: MainAxisSize.min,
        children: [
          Flexible(
            child: SizedBox(
              width: double.infinity,
                height: 400,
                child: _buildTable()
            ),
          )
        ],
      ),
    );
  }

  Icon _setIcon(double value) {
    if (value == 1.0) {
      return const Icon(
        Icons.check_circle_outline_outlined,
        color: Colors.green,
        size: 20,
        weight: 5,
      );
    } else {
      return const Icon(
        Icons.block_outlined,
        color: Colors.red,
        size: 20,
        weight: 5,
      );
    }
  }

}

What am I missing?

Does the flutter_expandable_table package support pagination of items?

Hi, I'm currently exploring the flutter_expandable_table package for displaying tabular data in my Flutter application. One feature I'm particularly interested in is pagination, which allows for efficient navigation through large datasets by displaying a subset of items per page.

Could you please confirm whether the flutter_expandable_table package includes built-in support for pagination of items? If so, I'd appreciate any guidance on how to implement and configure this feature within the package.

Thank you in advance for your assistance!

select a row

Hi !!
I want to select a row and make some editing on it, is there a way to do it?

UI become slow and unresponsive when you have more than 100 rowsCount

Screen.Recording.2023-12-06.at.3.33.16.PM.mov

i set the data as follow
static const int columnsCount = 29;
static const int subColumnsCount = 2;
static const int rowsCount = 100;
static const int subRowsCount = 10;
static const int totalColumns = columnsCount + subColumnsCount;

PTN: i used the same code in example

UI Overflow

If there are children in a row, and there are no rows to the parent row UI of the row's first cell that has children is getting overflow
image

Request to add horizontal scroll bar functionality

I am attempting to display my data on PC devices (Windows, Mac OS) using this library, and it's working very well! I must say this is a praiseworthy library, but I encountered an issue. Most PC devices do not have touch screens or touchpads, and by default, there is no explicit horizontal scrollbar, causing these users to be unable to view all the data. Therefore, I request the addition of an explicit horizontal scrollbar to accommodate more PC devices, thank you!

Try to run the example, but got RangeError (index): Index out of range: no indices are valid: 0

`
Performing hot restart... 1,805ms
Restarted application in 1,807ms.
โ•โ•โ•ก EXCEPTION CAUGHT BY WIDGETS LIBRARY โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
The following IndexError was thrown building ExpandableTableBody(dirty, dependencies:
[_ExpandableTableDataInherited], state: _ExpandableTableBodyState#e9e22):
RangeError (index): Index out of range: no indices are valid: 0

The relevant error-causing widget was:
ExpandableTableBody
ExpandableTableBody:file:///C:/Users/AppData/Local/Pub/Cache/hosted/pub.dev/flutter_expandable_table-1.1.1/lib/src/expandable_table.dart:249:20

When the exception was thrown, this was the stack:
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/internal/js_dev_runtime/private/ddc_runtime/errors.dart 266:49 throw
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/js_array.dart 581:7 _get]
packages/flutter_expandable_table/src/body.dart 102:45 [_buildBodyColumns]

`

I copy and paste it in one of my GetView page, and it fire up this error message.
The table is able to show but not able to do anything such as expand or scroll horizontally.
I am using :
Dart SDK version: 2.19.2 (stable) (Tue Feb 7 18:37:17 2023 +0000) on "windows_x64"
Flutter 3.7.3 โ€ข channel stable โ€ข https://github.com/flutter/flutter.git
Framework โ€ข revision 9944297138 (4 weeks ago) โ€ข 2023-02-08 15:46:04 -0800
Engine โ€ข revision 248290d6d5
Tools โ€ข Dart 2.19.2 โ€ข DevTools 2.20.1

The flutter_expandable_table 2.0.0-beta.1 won't refresh the view/state

Sorry but doing setState() on the data I used to be displayed in the table didn't make the table refresh.
However, the data do refresh with new values when I download them to excel file.

How to refresh the view of this table? I'm still new to Flutter so I hope you don't mind answering. This package has been a huge help, but I'm troubled on how to refresh the table with new values.

Best regards,
Vardina

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.