Repository: gregnb/mui-datatables
Pull request #647 (2019-05-24 21:27:50)

Bugfix/search text issues
Fixes a couple of issues introduced by the `searchText` option.

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

Coverage decreased (-0.1%) to 77.25% when pulling **266953bd5002dbb4569a2fee1c4350b2a1124114 on bugfix/search-text-issues** into **face83a98fddc6d73dec01121e1b1ff48ff71382 on master**.

ericpyle: @gabrielliwerant thanks for fixing those! 

I believe the other searchText behavior I need is that if searchText is used to initialize the table, then the table will initially show the search text box as being open with the searchText as its text value. Otherwise the table would not look like it's in the right state. Is that how you expect it to work?
gabrielliwerant: @ericpyle That should be working in this branch. Feel free to pull it down and test it out!

Patch:
diff --git a/examples/customize-search/index.js b/examples/customize-search/index.js
index d9bef72..8ff1701 100644
--- a/examples/customize-search/index.js
+++ b/examples/customize-search/index.js
@@ -1,8 +1,12 @@
-import React from 'react';
+import React, { Fragment } from 'react';
 import ReactDOM from 'react-dom';
 import MUIDataTable from '../../src/';
 
 class Example extends React.Component {
+  state = {
+    searchText: 'Computer'
+  };
+
   render() {
     const columns = [
       {
@@ -77,7 +81,8 @@ class Example extends React.Component {
       filter: true,
       filterType: 'dropdown',
       responsive: 'stacked',
-      searchText: 'Computer',
+      page: 1,
+      searchText: this.state.searchText,
       customSearch: (searchQuery, currentRow, columns) => {
         let isFound = false;
         currentRow.forEach(col => {
@@ -89,7 +94,12 @@ class Example extends React.Component {
       },
     };
 
-    return <MUIDataTable title={'ACME Employee list'} data={data} columns={columns} options={options} />;
+    return (
+      <Fragment>
+        <button onClick={() => this.setState({ searchText: '' })}>Reset Search</button>
+        <MUIDataTable title={'ACME Employee list'} data={data} columns={columns} options={options} />
+      </Fragment>
+    );
   }
 }
 
diff --git a/src/MUIDataTable.js b/src/MUIDataTable.js
index 882e456..fdbbaf4 100644
--- a/src/MUIDataTable.js
+++ b/src/MUIDataTable.js
@@ -189,6 +189,9 @@ class MUIDataTable extends React.Component {
 
   componentDidMount() {
     this.setHeadResizeable(this.headCellRefs, this.tableRef);
+
+    // When we have a search, we must reset page to view it
+    if (this.props.options.searchText) this.setState({ page: 0 });
   }
 
   componentDidUpdate(prevProps) {
@@ -196,6 +199,11 @@ class MUIDataTable extends React.Component {
       this.setTableData(this.props, TABLE_LOAD.INITIAL);
     }
 
+    if (this.props.options.searchText !== prevProps.options.searchText) {
+      // When we have a search, we must reset page to view it
+      this.setState({ page: 0 });
+    }
+
     if (this.options.resizableColumns) {
       this.setHeadResizeable(this.headCellRefs, this.tableRef);
       this.updateDividers();
@@ -464,10 +472,10 @@ class MUIDataTable extends React.Component {
         columns: columns,
         filterData: filterData,
         filterList: filterList,
-        searchText: searchText || prevState.searchText,
+        searchText: searchText,
         selectedRows: selectedRowsData,
         data: tableData,
-        displayData: this.getDisplayData(columns, tableData, filterList, searchText || prevState.searchText),
+        displayData: this.getDisplayData(columns, tableData, filterList, searchText),
       }),
       callback,
     );
@@ -1074,6 +1082,7 @@ class MUIDataTable extends React.Component {
               filterUpdate={this.filterUpdate}
               options={this.options}
               resetFilters={this.resetFilters}
+              searchText={searchText}
               searchTextUpdate={this.searchTextUpdate}
               tableRef={this.getTableContentRef}
               title={title}
@@ -1129,7 +1138,6 @@ class MUIDataTable extends React.Component {
               expandedRows={expandedRows}
               toggleExpandRow={this.toggleExpandRow}
               options={this.options}
-              searchText={searchText}
               filterList={filterList}
             />
           </MuiTable>
diff --git a/src/components/TableSearch.js b/src/components/TableSearch.js
index 5329a80..5cacbd6 100644
--- a/src/components/TableSearch.js
+++ b/src/components/TableSearch.js
@@ -52,7 +52,7 @@ class TableSearch extends React.Component {
   };
 
   render() {
-    const { classes, options, onHide, initialSearchText } = this.props;
+    const { classes, options, onHide, searchText } = this.props;
 
     return (
       <Grow appear in={true} timeout={300}>
@@ -64,7 +64,7 @@ class TableSearch extends React.Component {
             InputProps={{
               'aria-label': options.textLabels.toolbar.search,
             }}
-            defaultValue={initialSearchText}
+            value={searchText || ''}
             onChange={this.handleTextChange}
             fullWidth={true}
             inputRef={el => (this.searchField = el)}
diff --git a/src/components/TableToolbar.js b/src/components/TableToolbar.js
index 2380eb9..0e3cbed 100644
--- a/src/components/TableToolbar.js
+++ b/src/components/TableToolbar.js
@@ -85,9 +85,15 @@ class TableToolbar extends React.Component {
   state = {
     iconActive: null,
     showSearch: Boolean(this.props.options.searchText),
-    searchText: this.props.options.searchText || null,
+    searchText: this.props.searchText || null,
   };
 
+  componentDidUpdate(prevProps) {
+    if (this.props.searchText !== prevProps.searchText) {
+      this.setState({ searchText: this.props.searchText });
+    }
+  }
+
   handleCSVDownload = () => {
     const { data, columns, options } = this.props;
     createCSVDownload(columns, data, options);
@@ -169,7 +175,7 @@ class TableToolbar extends React.Component {
         <div className={classes.left}>
           {showSearch === true ? (
             <TableSearch
-              initialSearchText={searchText}
+              searchText={searchText}
               onSearch={this.handleSearch}
               onHide={this.hideSearch}
               options={options}


Test patch:
diff --git a/test/MUIDataTable.test.js b/test/MUIDataTable.test.js
index 7959a1b..523c342 100644
--- a/test/MUIDataTable.test.js
+++ b/test/MUIDataTable.test.js
@@ -536,6 +536,20 @@ describe('<MUIDataTable />', function() {
     assert.deepEqual(JSON.stringify(state.displayData), expectedResult);
   });
 
+  it('should filter displayData when searchText is set', () => {
+    const options = {
+      searchText: 'Joe'
+    };
+    const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} options={options} />);
+    const state = shallowWrapper.dive().state();
+
+    const expectedResult = JSON.stringify([
+      { data: ['James, Joe', 'Test Corp', renderCities('Yonkers', { rowIndex: 0 }), 'NY', undefined], dataIndex: 0 },
+    ]);
+
+    assert.deepEqual(JSON.stringify(state.displayData), expectedResult);
+  });
+
   it('should sort provided column in descending order when calling toggleSortColum method for the first time', () => {
     const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} />).dive();
     const instance = shallowWrapper.instance();
diff --git a/test/MUIDataTableSearch.test.js b/test/MUIDataTableSearch.test.js
index ba8e09f..0d1f38e 100644
--- a/test/MUIDataTableSearch.test.js
+++ b/test/MUIDataTableSearch.test.js
@@ -25,11 +25,24 @@ describe('<TableSearch />', function() {
     const onHide = () => {};
 
     const mountWrapper = mount(
-      <TableSearch onSearch={onSearch} onHide={onHide} options={options} initialSearchText="searchText" />,
+      <TableSearch onSearch={onSearch} onHide={onHide} options={options} searchText="searchText" />,
     );
     const actualResult = mountWrapper.find(TextField);
     assert.strictEqual(actualResult.length, 1);
-    assert.strictEqual(actualResult.props().defaultValue, 'searchText');
+    assert.strictEqual(actualResult.props().value, 'searchText');
+  });
+
+  it('should change search bar text when searchText changes', () => {
+    const options = { textLabels };
+    const onSearch = () => {};
+    const onHide = () => {};
+
+    const mountWrapper = mount(
+      <TableSearch onSearch={onSearch} onHide={onHide} options={options} searchText="searchText" />,
+    );
+    const actualResult = mountWrapper.setProps({ searchText: 'nextText' }).update();
+    assert.strictEqual(actualResult.length, 1);
+    assert.strictEqual(actualResult.find(TextField).props().value, 'nextText');
   });
 
   it('should trigger handleTextChange prop callback when calling method handleTextChange', () => {
diff --git a/test/MUIDataTableToolbar.test.js b/test/MUIDataTableToolbar.test.js
index f0ef27f..3d6bf24 100644
--- a/test/MUIDataTableToolbar.test.js
+++ b/test/MUIDataTableToolbar.test.js
@@ -77,7 +77,7 @@ describe('<TableToolbar />', function() {
     );
     const actualResult = mountWrapper.find(TableSearch);
     assert.strictEqual(actualResult.length, 1);
-    assert.strictEqual(actualResult.props().initialSearchText, 'searchText');
+    assert.strictEqual(actualResult.props().options.searchText, 'searchText');
   });
 
   it('should render a toolbar with no search icon if option.search = false', () => {