Repository: gregnb/mui-datatables
Pull request #654 (2019-05-29 20:25:02)

Allow search bar to be shown when switching between toolbars
Only handles the case where the search bar has entered text.

Helps https://github.com/gregnb/mui-datatables/issues/653.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/23680869/badge)](https://coveralls.io/builds/23680869)

Coverage increased (+0.04%) to 77.234% when pulling **ee4b30adb7cf0d3101b572efe306a410154e1f78 on enhancement/issue-653-searchbar-selectbar** into **9690884dc3ce28790859dd98b21a80085774891d on master**.


Patch:
diff --git a/README.md b/README.md
index b7040ac..d9a05af 100644
--- a/README.md
+++ b/README.md
@@ -179,6 +179,7 @@ The component accepts the following props:
 |**`onColumnSortChange`**|function||Callback function that triggers when a column has been sorted. `function(changedColumn: string, direction: string) => void`
 |**`onColumnViewChange`**|function||Callback function that triggers when a column view has been changed. `function(changedColumn: string, action: string) => void`
 |**`onTableChange`**|function||Callback function that triggers when table state has changed. `function(action: string, tableState: object) => void`
+|**`onTableInit`**|function||Callback function that triggers when table state has been initialized. `function(action: string, tableState: object) => void`
 |**`setRowProps`**|function||Is called for each row and allows to return custom props for this row based on its data. `function(row: array, dataIndex: number) => object`
 
 ## Customize Columns
diff --git a/examples/on-table-init/index.js b/examples/on-table-init/index.js
new file mode 100644
index 0000000..27ee565
--- /dev/null
+++ b/examples/on-table-init/index.js
@@ -0,0 +1,79 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import MUIDataTable from '../../src';
+
+class Example extends React.Component {
+  constructor(props) {
+    super(props);
+
+    this.tableState = {};
+    this.handleTableInit = this.handleTableInit.bind(this);
+    this.handleTableChange = this.handleTableChange.bind(this);
+  }
+
+  /** onTableInit gives access to initial MuiDataTable state
+   *  if the application needs access to internal state prior to
+   *  the user performing a table mutation (sort, filter, etc.)
+   *  that triggers onTableChange
+   */
+  handleTableInit = (action, tableState) => {
+    console.log('handleTableInit: ', tableState);
+    this.tableState = tableState;
+  };
+
+  handleTableChange = (action, tableState) => {
+    this.tableState = tableState;
+  };
+
+  render() {
+    const columns = ['Name', 'Title', 'Location', 'Age', 'Salary'];
+
+    const data = [
+      ['Gabby George', 'Business Analyst', 'Minneapolis', 30, 100000],
+      ['Aiden Lloyd', 'Business Consultant', 'Dallas', 55, 200000],
+      ['Jaden Collins', 'Attorney', 'Santa Ana', 27, 500000],
+      ['Franky Rees', 'Business Analyst', 'St. Petersburg', 22, 50000],
+      ['Aaren Rose', 'Business Consultant', 'Toledo', 28, 75000],
+      ['Blake Duncan', 'Business Management Analyst', 'San Diego', 65, 94000],
+      ['Frankie Parry', 'Agency Legal Counsel', 'Jacksonville', 71, 210000],
+      ['Lane Wilson', 'Commercial Specialist', 'Omaha', 19, 65000],
+      ['Robin Duncan', 'Business Analyst', 'Los Angeles', 20, 77000],
+      ['Mel Brooks', 'Business Consultant', 'Oklahoma City', 37, 135000],
+      ['Harper White', 'Attorney', 'Pittsburgh', 52, 420000],
+      ['Kris Humphrey', 'Agency Legal Counsel', 'Laredo', 30, 150000],
+      ['Frankie Long', 'Industrial Analyst', 'Austin', 31, 170000],
+      ['Brynn Robbins', 'Business Analyst', 'Norfolk', 22, 90000],
+      ['Justice Mann', 'Business Consultant', 'Chicago', 24, 133000],
+      ['Addison Navarro', 'Business Management Analyst', 'New York', 50, 295000],
+      ['Jesse Welch', 'Agency Legal Counsel', 'Seattle', 28, 200000],
+      ['Eli Mejia', 'Commercial Specialist', 'Long Beach', 65, 400000],
+      ['Gene Leblanc', 'Industrial Analyst', 'Hartford', 34, 110000],
+      ['Danny Leon', 'Computer Scientist', 'Newark', 60, 220000],
+      ['Lane Lee', 'Corporate Counselor', 'Cincinnati', 52, 180000],
+      ['Jesse Hall', 'Business Analyst', 'Baltimore', 44, 99000],
+      ['Danni Hudson', 'Agency Legal Counsel', 'Tampa', 37, 90000],
+      ['Terry Macdonald', 'Commercial Specialist', 'Miami', 39, 140000],
+      ['Justice Mccarthy', 'Attorney', 'Tucson', 26, 330000],
+      ['Silver Carey', 'Computer Scientist', 'Memphis', 47, 250000],
+      ['Franky Miles', 'Industrial Analyst', 'Buffalo', 49, 190000],
+      ['Glen Nixon', 'Corporate Counselor', 'Arlington', 44, 80000],
+      ['Gabby Strickland', 'Business Process Consultant', 'Scottsdale', 26, 45000],
+      ['Mason Ray', 'Computer Scientist', 'San Francisco', 39, 142000],
+    ];
+
+    const options = {
+      filter: true,
+      selectableRows: true,
+      filterType: 'dropdown',
+      responsive: 'scroll',
+      rowsPerPage: 10,
+      download: false, // hide csv download option
+      onTableInit: this.handleTableInit,
+      onTableChange: this.handleTableChange,
+    };
+
+    return <MUIDataTable title={'ACME Employee list'} data={data} columns={columns} options={options} />;
+  }
+}
+
+ReactDOM.render(<Example />, document.getElementById('app-root'));
diff --git a/rollup.config.js b/rollup.config.js
index 6591d5c..01adf0e 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -1,37 +1,38 @@
-import babel from "rollup-plugin-babel";
-import commonjs from "rollup-plugin-commonjs";
-import replace from "rollup-plugin-replace";
-import uglify from "rollup-plugin-uglify";
+import babel from 'rollup-plugin-babel';
+import commonjs from 'rollup-plugin-commonjs';
+import replace from 'rollup-plugin-replace';
+import uglify from 'rollup-plugin-uglify';
 
 export default {
   input: 'src/index.js',
   plugins: [
     replace({
-      'process.env.NODE_ENV': JSON.stringify('production')
+      'process.env.NODE_ENV': JSON.stringify('production'),
     }),
     commonjs({
-      include: [
-        'node_modules/**'
-      ]
+      include: ['node_modules/**'],
     }),
     babel({
-      "presets": [
-        "react",
-        ["env", {
-          "targets": {
-            "browsers": ["last 2 versions", "ie >= 10"]
+      presets: [
+        'react',
+        [
+          'env',
+          {
+            targets: {
+              browsers: ['last 2 versions', 'ie >= 10'],
+            },
+            debug: false,
+            modules: false,
           },
-          "debug": false,
-          "modules": false
-        }]
+        ],
       ],
-      "plugins": [
-        "external-helpers",
-        "transform-object-rest-spread",
-        "babel-plugin-transform-class-properties",
-        "transform-react-remove-prop-types"
+      plugins: [
+        'external-helpers',
+        'transform-object-rest-spread',
+        'babel-plugin-transform-class-properties',
+        'transform-react-remove-prop-types',
       ],
-      babelrc: false
+      babelrc: false,
     }),
     uglify({
       compress: {
@@ -46,13 +47,13 @@ export default {
       },
       output: {
         comments: false,
-      }
-    })
+      },
+    }),
   ],
   output: {
     file: 'dist/index.js',
     format: 'cjs',
-    exports: 'named'
+    exports: 'named',
   },
-  sourcemap: true
+  sourcemap: true,
 };
diff --git a/src/MUIDataTable.js b/src/MUIDataTable.js
index fdbbaf4..a5120dc 100644
--- a/src/MUIDataTable.js
+++ b/src/MUIDataTable.js
@@ -118,6 +118,7 @@ class MUIDataTable extends React.Component {
       isRowSelectable: PropTypes.func,
       serverSide: PropTypes.bool,
       onTableChange: PropTypes.func,
+      onTableInit: PropTypes.func,
       caseSensitive: PropTypes.bool,
       rowHover: PropTypes.bool,
       fixedHeader: PropTypes.bool,
@@ -196,7 +197,9 @@ class MUIDataTable extends React.Component {
 
   componentDidUpdate(prevProps) {
     if (this.props.data !== prevProps.data || this.props.columns !== prevProps.columns) {
-      this.setTableData(this.props, TABLE_LOAD.INITIAL);
+      this.setTableData(this.props, TABLE_LOAD.INITIAL, () => {
+        this.setTableAction('propsUpdate');
+      });
     }
 
     if (this.props.options.searchText !== prevProps.options.searchText) {
@@ -213,7 +216,9 @@ class MUIDataTable extends React.Component {
   initializeTable(props) {
     this.getDefaultOptions(props);
     this.setTableOptions(props);
-    this.setTableData(props, TABLE_LOAD.INITIAL);
+    this.setTableData(props, TABLE_LOAD.INITIAL, () => {
+      this.setTableInit('tableInitialized');
+    });
   }
 
   /*
@@ -275,6 +280,12 @@ class MUIDataTable extends React.Component {
     }
   };
 
+  setTableInit = action => {
+    if (typeof this.options.onTableInit === 'function') {
+      this.options.onTableInit(action, this.state);
+    }
+  };
+
   setTableOptions(props) {
     const optionNames = ['rowsPerPage', 'page', 'rowsSelected', 'rowsPerPageOptions'];
     const optState = optionNames.reduce((acc, cur) => {
diff --git a/src/components/TableFilter.js b/src/components/TableFilter.js
index a871ff3..2cd4083 100644
--- a/src/components/TableFilter.js
+++ b/src/components/TableFilter.js
@@ -18,7 +18,7 @@ import { TextField, Grid, GridList, GridListTile } from '@material-ui/core';
 export const defaultFilterStyles = theme => ({
   root: {
     backgroundColor: theme.palette.background.default,
-    padding: '16px 24px 16px 24px',
+    padding: '24px 24px 36px 24px',
     fontFamily: 'Roboto',
   },
   header: {
@@ -90,9 +90,7 @@ export const defaultFilterStyles = theme => ({
     justifyContent: 'space-between',
   },
   selectFormControl: {
-    flex: '1 1 calc(50% - 24px)',
-    marginRight: '24px',
-    marginBottom: '24px',
+    flex: '1 1 calc(50% - 24px)'
   },
   /* textField */
   textFieldRoot: {
@@ -104,8 +102,6 @@ export const defaultFilterStyles = theme => ({
   },
   textFieldFormControl: {
     flex: '1 1 calc(50% - 24px)',
-    marginRight: '24px',
-    marginBottom: '24px',
   },
 });
 
@@ -251,7 +247,7 @@ class TableFilter extends React.Component {
                 <MenuItem value={filterValue} key={filterIndex + 1}>
                   <Checkbox
                     checked={filterList[index].indexOf(filterValue) >= 0 ? true : false}
-                    value={filterValue.toString()}
+                    value={filterValue !== null ? filterValue.toString() : ''}
                     className={classes.checkboxIcon}
                     classes={{
                       root: classes.checkbox,
@@ -295,7 +291,7 @@ class TableFilter extends React.Component {
           </div>
           <div className={classes.filtersSelected} />
         </div>
-        <GridList cellHeight="auto" cols={filterGridColumns}>
+        <GridList cellHeight="auto" cols={filterGridColumns} cellHeight={64} spacing={34}>
           {columns.map((column, index) => {
             if (column.filter) {
               const filterType = column.filterType || options.filterType;
diff --git a/src/components/TableToolbar.js b/src/components/TableToolbar.js
index 0e3cbed..2cbd812 100644
--- a/src/components/TableToolbar.js
+++ b/src/components/TableToolbar.js
@@ -84,7 +84,7 @@ export const responsiveToolbarStyles = theme => ({
 class TableToolbar extends React.Component {
   state = {
     iconActive: null,
-    showSearch: Boolean(this.props.options.searchText),
+    showSearch: Boolean(this.props.searchText || this.props.options.searchText),
     searchText: this.props.searchText || null,
   };
 


Test patch:
diff --git a/test/MUIDataTable.test.js b/test/MUIDataTable.test.js
index 523c342..6007531 100644
--- a/test/MUIDataTable.test.js
+++ b/test/MUIDataTable.test.js
@@ -824,6 +824,25 @@ describe('<MUIDataTable />', function() {
     assert.deepEqual(state.data[0].data[2], 'Las Vegas');
   });
 
+  it('should call onTableInit when MUIDataTable is initialized', () => {
+    const options = { selectableRows: true, onTableInit: spy() };
+    const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} options={options} />).dive();
+    const instance = shallowWrapper.instance();
+
+    assert.strictEqual(options.onTableInit.callCount, 1);
+  });
+
+  it('should call onTableInit only 1 time when creating table and calling selectRowUpdate method with type=head', () => {
+    const options = { selectableRows: true, onTableInit: spy() };
+    const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} options={options} />).dive();
+    const instance = shallowWrapper.instance();
+
+    instance.selectRowUpdate('head', 0);
+    shallowWrapper.update();
+
+    assert.strictEqual(options.onTableInit.callCount, 1);
+  });
+
   it('should call onTableChange when calling selectRowUpdate method with type=head', () => {
     const options = { selectableRows: true, onTableChange: spy() };
     const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} options={options} />).dive();