Repository: gregnb/mui-datatables
Pull request #603 (2019-05-09 20:28:15)

Add searchText option to initialise datatable with search text

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

Coverage increased (+0.2%) to 76.607% when pulling **8c0dfd14fc0f7a3ada3324f5b0bdbda572dafeca on karthick-vinod:feature/initial-search-text** into **d3c7bcaec126314e1ec4d83bedf94bfe03c8d9c1 on gregnb:master**.


Patch:
diff --git a/README.md b/README.md
index a974c1b..cabcf5c 100644
--- a/README.md
+++ b/README.md
@@ -147,6 +147,7 @@ The component accepts the following props:
 |**`customToolbar`**|function||Render a custom toolbar
 |**`customToolbarSelect`**|function||Render a custom selected rows toolbar. `function(selectedRows, displayData, setSelectedRows) => void`
 |**`customFooter`**|function||Render a custom table footer. `function(count, page, rowsPerPage, changeRowsPerPage, changePage) => string`&#124;` React Component`
+|**`customRowRender `**|function||Override default row rendering with custom function. `customRowRender(data, dataIndex, rowIndex) => React Component`
 |**`customSort`**|function||Override default sorting with custom function. `function(data: array, colIndex: number, order: string) => array`
 |**`customSearch `**|function||Override default search with custom function. `customSearch(searchQuery: string, currentRow: array, columns: array) => boolean`
 |**`elevation`**|number|4|Shadow depth applied to Paper component
@@ -160,6 +161,7 @@ The component accepts the following props:
 |**`sort`**|boolean|true|Enable/disable sort on all columns
 |**`filter`**|boolean|true|Show/hide filter icon from toolbar
 |**`search`**|boolean|true|Show/hide search icon from toolbar
+|**`searchText`**|string||Initial search text
 |**`print`**|boolean|true|Show/hide print	 icon from toolbar
 |**`download`**|boolean|true|Show/hide download icon from toolbar
 |**`downloadOptions`**|object||Options to change the output of the CSV file. Default options: `{filename: 'tableDownload.csv', separator: ','}`
diff --git a/examples/column-filters/index.js b/examples/column-filters/index.js
index e6368b2..02c9d5b 100644
--- a/examples/column-filters/index.js
+++ b/examples/column-filters/index.js
@@ -15,11 +15,12 @@ class Example extends React.Component {
           customFilterListRender: v => `Name: ${v}`,
           filterOptions: ['a', 'b', 'c', 'Business Analyst']
         }
-      },      
+      },
       {
         name: "Title",
         options: {
           filter: true,
+          filterList: ['Business Analyst'],
           customFilterListRender: v => `Title: ${v}`,
           filterType: 'textField' // set filterType's at the column level
         }
@@ -44,7 +45,7 @@ class Example extends React.Component {
           customFilterListRender: v => `Salary: ${v}`,
           sort: false
         }
-      }      
+      }
     ];
     const data = [
       ["Gabby George", "Business Analyst", "Minneapolis", 30, 100000],
@@ -81,6 +82,9 @@ class Example extends React.Component {
 
     const options = {
       filter: true,
+      onFilterChange: (changedColumn, filterList) => {
+        console.log(changedColumn, filterList);
+      },
       selectableRows: true,
       filterType: 'dropdown',
       responsive: 'stacked',
diff --git a/examples/customize-rows/index.js b/examples/customize-rows/index.js
new file mode 100644
index 0000000..33bf240
--- /dev/null
+++ b/examples/customize-rows/index.js
@@ -0,0 +1,96 @@
+/*
+  See another example of how to use `customRowRender` at
+  https://github.com/Skn0tt/mui-datatables-responsive-demo
+  https://mui-datatables-responsive-demo.skn0tt.now.sh
+*/
+
+import React from 'react';
+import ReactDOM from "react-dom";
+import MuiDataTable from "../../src/";
+
+function YourCustomRowComponent(props) {
+  const { name, cardNumber, cvc, expiry } = props;
+
+  return (
+    <div>
+      <h1>
+        {name}
+      </h1>
+      <p>
+        Number: {cardNumber} <br/>
+        CVC: {cvc} <br/>
+        expiry: {expiry}
+      </p>
+    </div>
+  );
+}
+
+const creditCards = [
+  {
+    name: "Tom Tallis",
+    cardNumber: "5500005555555559",
+    cvc: "582",
+    expiry: "02/24"
+  },
+  {
+    name: "Rich Harris",
+    cardNumber: "4444444444444448",
+    cvc: "172",
+    expiry: "03/22"
+  },
+  {
+    name: "Moby Dixon",
+    cardNumber: "3566003566003566",
+    cvc: "230",
+    expiry: "12/25"
+  }
+];
+
+function Example() {
+  return (
+    <MuiDataTable
+      title="Cards"
+      data={creditCards}
+      columns={[
+        {
+          name: "name",
+          label: "Name",
+        },
+        {
+          name: "cardNumber",
+          label: "Card Number"
+        },
+        {
+          name: "cvc",
+          label: "CVC"
+        },
+        {
+          name: "expiry",
+          label: "Expiry"
+        },
+      ]}
+      options={{
+        selectableRows: "none",
+        responsive: "scroll",
+        customRowRender: data => {
+          const [ name, cardNumber, cvc, expiry ] = data;
+          
+          return (
+            <tr key={cardNumber}>
+              <td colSpan={4} style={{ paddingTop: "10px"}}>
+                <YourCustomRowComponent
+                  name={name}
+                  cardNumber={cardNumber}
+                  cvc={cvc}
+                  expiry={expiry}
+                />
+              </td>
+            </tr>
+          );
+        },
+      }}
+    />
+  );
+}
+
+ReactDOM.render(<Example />, document.getElementById("app-root"));
diff --git a/examples/customize-search/index.js b/examples/customize-search/index.js
index a79b781..d9bef72 100644
--- a/examples/customize-search/index.js
+++ b/examples/customize-search/index.js
@@ -1,101 +1,96 @@
-import React from "react";
-import ReactDOM from "react-dom";
-import MUIDataTable from "../../src/";
+import React from 'react';
+import ReactDOM from 'react-dom';
+import MUIDataTable from '../../src/';
 
 class Example extends React.Component {
-
   render() {
-
     const columns = [
       {
-        name: "Name",
+        name: 'Name',
         options: {
           filter: true,
           display: 'excluded',
-        }
-      },      
+        },
+      },
       {
-        label: "Modified Title Label",
-        name: "Title",
+        label: 'Modified Title Label',
+        name: 'Title',
         options: {
           filter: true,
-        }
+        },
       },
       {
-        name: "Location",
+        name: 'Location',
         options: {
           filter: false,
-        }
+        },
       },
       {
-        name: "Age",
+        name: 'Age',
         options: {
           filter: true,
-        }
+        },
       },
       {
-        name: "Salary",
+        name: 'Salary',
         options: {
           filter: true,
-          sort: false
-        }
-      }      
+          sort: false,
+        },
+      },
     ];
 
-
     const data = [
-      ["Gabby George", "Business Analyst", "Minneapolis", 30, "$100,000"],
-      ["Aiden Lloyd", "Business Consultant", "Dallas",  55, "$200,000"],
-      ["Jaden Collins", "Attorney", "Santa Ana", 27, "$500,000"],
-      ["Franky Rees", "Business Analyst", "St. Petersburg", 22, "$50,000"],
-      ["Aaren Rose", "Business Consultant", "Toledo", 28, "$75,000"],
-      ["Blake Duncan", "Business Management Analyst", "San Diego", 65, "$94,000"],
-      ["Frankie Parry", "Agency Legal Counsel", "Jacksonville", 71, "$210,000"],
-      ["Lane Wilson", "Commercial Specialist", "Omaha", 19, "$65,000"],
-      ["Robin Duncan", "Business Analyst", "Los Angeles", 20, "$77,000"],
-      ["Mel Brooks", "Business Consultant", "Oklahoma City", 37, "$135,000"],
-      ["Harper White", "Attorney", "Pittsburgh", 52, "$420,000"],
-      ["Kris Humphrey", "Agency Legal Counsel", "Laredo", 30, "$150,000"],
-      ["Frankie Long", "Industrial Analyst", "Austin", 31, "$170,000"],
-      ["Brynn Robbins", "Business Analyst", "Norfolk", 22, "$90,000"],
-      ["Justice Mann", "Business Consultant", "Chicago", 24, "$133,000"],
-      ["Addison Navarro", "Business Management Analyst", "New York", 50, "$295,000"],
-      ["Jesse Welch", "Agency Legal Counsel", "Seattle", 28, "$200,000"],
-      ["Eli Mejia", "Commercial Specialist", "Long Beach", 65, "$400,000"],
-      ["Gene Leblanc", "Industrial Analyst", "Hartford", 34, "$110,000"],
-      ["Danny Leon", "Computer Scientist", "Newark", 60, "$220,000"],
-      ["Lane Lee", "Corporate Counselor", "Cincinnati", 52, "$180,000"],
-      ["Jesse Hall", "Business Analyst", "Baltimore", 44, "$99,000"],
-      ["Danni Hudson", "Agency Legal Counsel", "Tampa", 37, "$90,000"],
-      ["Terry Macdonald", "Commercial Specialist", "Miami", 39, "$140,000"],
-      ["Justice Mccarthy", "Attorney", "Tucson", 26, "$330,000"],
-      ["Silver Carey", "Computer Scientist", "Memphis", 47, "$250,000" ],
-      ["Franky Miles", "Industrial Analyst", "Buffalo", 49, "$190,000"],
-      ["Glen Nixon", "Corporate Counselor", "Arlington", 44, "$80,000"],
-      ["Gabby Strickland", "Business Process Consultant", "Scottsdale", 26, "$45,000"],
-      ["Mason Ray", "Computer Scientist", "San Francisco", 39, "$142,000"]
+      ['Gabby George', 'Business Analyst', 'Minneapolis', 30, '$100,000'],
+      ['Aiden Lloyd', 'Business Consultant', 'Dallas', 55, '$200,000'],
+      ['Jaden Collins', 'Attorney', 'Santa Ana', 27, '$500,000'],
+      ['Franky Rees', 'Business Analyst', 'St. Petersburg', 22, '$50,000'],
+      ['Aaren Rose', 'Business Consultant', 'Toledo', 28, '$75,000'],
+      ['Blake Duncan', 'Business Management Analyst', 'San Diego', 65, '$94,000'],
+      ['Frankie Parry', 'Agency Legal Counsel', 'Jacksonville', 71, '$210,000'],
+      ['Lane Wilson', 'Commercial Specialist', 'Omaha', 19, '$65,000'],
+      ['Robin Duncan', 'Business Analyst', 'Los Angeles', 20, '$77,000'],
+      ['Mel Brooks', 'Business Consultant', 'Oklahoma City', 37, '$135,000'],
+      ['Harper White', 'Attorney', 'Pittsburgh', 52, '$420,000'],
+      ['Kris Humphrey', 'Agency Legal Counsel', 'Laredo', 30, '$150,000'],
+      ['Frankie Long', 'Industrial Analyst', 'Austin', 31, '$170,000'],
+      ['Brynn Robbins', 'Business Analyst', 'Norfolk', 22, '$90,000'],
+      ['Justice Mann', 'Business Consultant', 'Chicago', 24, '$133,000'],
+      ['Addison Navarro', 'Business Management Analyst', 'New York', 50, '$295,000'],
+      ['Jesse Welch', 'Agency Legal Counsel', 'Seattle', 28, '$200,000'],
+      ['Eli Mejia', 'Commercial Specialist', 'Long Beach', 65, '$400,000'],
+      ['Gene Leblanc', 'Industrial Analyst', 'Hartford', 34, '$110,000'],
+      ['Danny Leon', 'Computer Scientist', 'Newark', 60, '$220,000'],
+      ['Lane Lee', 'Corporate Counselor', 'Cincinnati', 52, '$180,000'],
+      ['Jesse Hall', 'Business Analyst', 'Baltimore', 44, '$99,000'],
+      ['Danni Hudson', 'Agency Legal Counsel', 'Tampa', 37, '$90,000'],
+      ['Terry Macdonald', 'Commercial Specialist', 'Miami', 39, '$140,000'],
+      ['Justice Mccarthy', 'Attorney', 'Tucson', 26, '$330,000'],
+      ['Silver Carey', 'Computer Scientist', 'Memphis', 47, '$250,000'],
+      ['Franky Miles', 'Industrial Analyst', 'Buffalo', 49, '$190,000'],
+      ['Glen Nixon', 'Corporate Counselor', 'Arlington', 44, '$80,000'],
+      ['Gabby Strickland', 'Business Process Consultant', 'Scottsdale', 26, '$45,000'],
+      ['Mason Ray', 'Computer Scientist', 'San Francisco', 39, '$142,000'],
     ];
 
     const options = {
       filter: true,
       filterType: 'dropdown',
       responsive: 'stacked',
+      searchText: 'Computer',
       customSearch: (searchQuery, currentRow, columns) => {
         let isFound = false;
         currentRow.forEach(col => {
           if (col.toString().indexOf(searchQuery) >= 0) {
             isFound = true;
-          }          
+          }
         });
         return isFound;
-      }
+      },
     };
 
-    return (
-      <MUIDataTable title={"ACME Employee list"} data={data} columns={columns} options={options} />
-    );
-
+    return <MUIDataTable title={'ACME Employee list'} data={data} columns={columns} options={options} />;
   }
 }
 
-ReactDOM.render(<Example />, document.getElementById("app-root"));
+ReactDOM.render(<Example />, document.getElementById('app-root'));
diff --git a/src/MUIDataTable.js b/src/MUIDataTable.js
index 5b45796..eda42cf 100644
--- a/src/MUIDataTable.js
+++ b/src/MUIDataTable.js
@@ -111,6 +111,7 @@ class MUIDataTable extends React.Component {
       customToolbar: PropTypes.oneOfType([PropTypes.func, PropTypes.element]),
       customToolbarSelect: PropTypes.oneOfType([PropTypes.func, PropTypes.element]),
       customFooter: PropTypes.oneOfType([PropTypes.func, PropTypes.element]),
+      customRowRender: PropTypes.func,
       onRowClick: PropTypes.func,
       resizableColumns: PropTypes.bool,
       selectableRows: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['none', 'single', 'multiple'])]),
@@ -130,6 +131,7 @@ class MUIDataTable extends React.Component {
       customSort: PropTypes.func,
       customSearch: PropTypes.func,
       search: PropTypes.bool,
+      searchText: PropTypes.string,
       print: PropTypes.bool,
       viewColumns: PropTypes.bool,
       download: PropTypes.bool,
@@ -375,6 +377,7 @@ class MUIDataTable extends React.Component {
     let sortDirection = null;
 
     const data = status === TABLE_LOAD.INITIAL ? this.transformData(columns, props.data) : props.data;
+    const searchText = status === TABLE_LOAD.INITIAL ? options.searchText : null;
 
     columns.forEach((column, colIndex) => {
       for (let rowIndex = 0; rowIndex < data.length; rowIndex++) {
@@ -461,9 +464,10 @@ class MUIDataTable extends React.Component {
         columns: columns,
         filterData: filterData,
         filterList: filterList,
+        searchText: searchText || prevState.searchText,
         selectedRows: selectedRowsData,
         data: tableData,
-        displayData: this.getDisplayData(columns, tableData, filterList, prevState.searchText),
+        displayData: this.getDisplayData(columns, tableData, filterList, searchText || prevState.searchText),
       }),
       callback,
     );
@@ -792,21 +796,21 @@ class MUIDataTable extends React.Component {
     );
   };
 
-  filterUpdate = (index, column, type) => {
+  filterUpdate = (index, value, column, type) => {
     this.setState(
       prevState => {
         const filterList = cloneDeep(prevState.filterList);
-        const filterPos = filterList[index].indexOf(column);
+        const filterPos = filterList[index].indexOf(value);
 
         switch (type) {
           case 'checkbox':
-            filterPos >= 0 ? filterList[index].splice(filterPos, 1) : filterList[index].push(column);
+            filterPos >= 0 ? filterList[index].splice(filterPos, 1) : filterList[index].push(value);
             break;
           case 'multiselect':
-            filterList[index] = column === '' ? [] : column;
+            filterList[index] = value === '' ? [] : value;
             break;
           default:
-            filterList[index] = filterPos >= 0 || column === '' ? [] : [column];
+            filterList[index] = filterPos >= 0 || value === '' ? [] : [value];
         }
 
         return {
@@ -1045,6 +1049,7 @@ class MUIDataTable extends React.Component {
     const rowCount = this.options.count || displayData.length;
     const rowsPerPage = this.options.pagination ? this.state.rowsPerPage : displayData.length;
     const showToolbar = hasToolbarItem(this.options, title);
+    const columnNames = columns.map(column => ({ name: column.name }));
 
     return (
       <Paper
@@ -1085,6 +1090,7 @@ class MUIDataTable extends React.Component {
           })}
           filterList={filterList}
           filterUpdate={this.filterUpdate}
+          columnNames={columnNames}
         />
         <div
           style={{ position: 'relative' }}
diff --git a/src/components/TableBody.js b/src/components/TableBody.js
index 58924a3..6a0e9df 100644
--- a/src/components/TableBody.js
+++ b/src/components/TableBody.js
@@ -120,53 +120,61 @@ class TableBody extends React.Component {
     return (
       <MuiTableBody>
         {tableRows && tableRows.length > 0 ? (
-          tableRows.map(({ data: row, dataIndex }, rowIndex) => (
-            <React.Fragment key={rowIndex}>
-              <TableBodyRow
-                {...(options.setRowProps ? options.setRowProps(row, dataIndex) : {})}
-                options={options}
-                rowSelected={options.selectableRows !== 'none' ? this.isRowSelected(dataIndex) : false}
-                onClick={this.handleRowClick.bind(null, row, { rowIndex, dataIndex })}
-                id={'MUIDataTableBodyRow-' + dataIndex}>
-                <TableSelectCell
-                  onChange={this.handleRowSelect.bind(null, {
-                    index: this.getRowIndex(rowIndex),
-                    dataIndex: dataIndex,
-                  })}
-                  onExpand={toggleExpandRow.bind(null, {
-                    index: this.getRowIndex(rowIndex),
-                    dataIndex: dataIndex,
-                  })}
-                  fixedHeader={options.fixedHeader}
-                  checked={this.isRowSelected(dataIndex)}
-                  expandableOn={options.expandableRows}
-                  selectableOn={options.selectableRows}
-                  isRowExpanded={this.isRowExpanded(dataIndex)}
-                  isRowSelectable={this.isRowSelectable(dataIndex)}
-                  id={'MUIDataTableSelectCell-' + dataIndex}
-                />
-                {row.map(
-                  (column, columnIndex) =>
-                    columns[columnIndex].display === 'true' && (
-                      <TableBodyCell
-                        {...(columns[columnIndex].setCellProps
-                          ? columns[columnIndex].setCellProps(column, dataIndex, columnIndex)
-                          : {})}
-                        dataIndex={dataIndex}
-                        rowIndex={rowIndex}
-                        colIndex={columnIndex}
-                        columnHeader={columns[columnIndex].label}
-                        print={columns[columnIndex].print}
-                        options={options}
-                        key={columnIndex}>
-                        {column}
-                      </TableBodyCell>
-                    ),
-                )}
-              </TableBodyRow>
-              {this.isRowExpanded(dataIndex) && options.renderExpandableRow(row, { rowIndex, dataIndex })}
-            </React.Fragment>
-          ))
+          tableRows.map((data, rowIndex) => {
+            const { data: row, dataIndex } = data;
+
+            if (options.customRowRender) {
+              return options.customRowRender(row, dataIndex, rowIndex);
+            }
+
+            return (
+              <React.Fragment key={rowIndex}>
+                <TableBodyRow
+                  {...(options.setRowProps ? options.setRowProps(row, dataIndex) : {})}
+                  options={options}
+                  rowSelected={options.selectableRows !== 'none' ? this.isRowSelected(dataIndex) : false}
+                  onClick={this.handleRowClick.bind(null, row, { rowIndex, dataIndex })}
+                  id={'MUIDataTableBodyRow-' + dataIndex}>
+                  <TableSelectCell
+                    onChange={this.handleRowSelect.bind(null, {
+                      index: this.getRowIndex(rowIndex),
+                      dataIndex: dataIndex,
+                    })}
+                    onExpand={toggleExpandRow.bind(null, {
+                      index: this.getRowIndex(rowIndex),
+                      dataIndex: dataIndex,
+                    })}
+                    fixedHeader={options.fixedHeader}
+                    checked={this.isRowSelected(dataIndex)}
+                    expandableOn={options.expandableRows}
+                    selectableOn={options.selectableRows}
+                    isRowExpanded={this.isRowExpanded(dataIndex)}
+                    isRowSelectable={this.isRowSelectable(dataIndex)}
+                    id={'MUIDataTableSelectCell-' + dataIndex}
+                  />
+                  {row.map(
+                    (column, columnIndex) =>
+                      columns[columnIndex].display === 'true' && (
+                        <TableBodyCell
+                          {...(columns[columnIndex].setCellProps
+                            ? columns[columnIndex].setCellProps(column, dataIndex, columnIndex)
+                            : {})}
+                          dataIndex={dataIndex}
+                          rowIndex={rowIndex}
+                          colIndex={columnIndex}
+                          columnHeader={columns[columnIndex].label}
+                          print={columns[columnIndex].print}
+                          options={options}
+                          key={columnIndex}>
+                          {column}
+                        </TableBodyCell>
+                      ),
+                  )}
+                </TableBodyRow>
+                {this.isRowExpanded(dataIndex) && options.renderExpandableRow(row, { rowIndex, dataIndex })}
+              </React.Fragment>
+            );
+          })
         ) : (
           <TableBodyRow options={options}>
             <TableBodyCell
diff --git a/src/components/TableFilter.js b/src/components/TableFilter.js
index ea975fa..758ffde 100644
--- a/src/components/TableFilter.js
+++ b/src/components/TableFilter.js
@@ -125,22 +125,22 @@ class TableFilter extends React.Component {
     classes: PropTypes.object,
   };
 
-  handleCheckboxChange = (index, column) => {
-    this.props.onFilterUpdate(index, column, 'checkbox');
+  handleCheckboxChange = (index, value, column) => {
+    this.props.onFilterUpdate(index, value, column, 'checkbox');
   };
 
-  handleDropdownChange = (event, index) => {
+  handleDropdownChange = (event, index, column) => {
     const labelFilterAll = this.props.options.textLabels.filter.all;
     const value = event.target.value === labelFilterAll ? '' : event.target.value;
-    this.props.onFilterUpdate(index, value, 'dropdown');
+    this.props.onFilterUpdate(index, value, column, 'dropdown');
   };
 
-  handleMultiselectChange = (index, column) => {
-    this.props.onFilterUpdate(index, column, 'multiselect');
+  handleMultiselectChange = (index, value, column) => {
+    this.props.onFilterUpdate(index, value, column, 'multiselect');
   };
 
-  handleTextFieldChange = (event, index) => {
-    this.props.onFilterUpdate(index, event.target.value, 'textField');
+  handleTextFieldChange = (event, index, column) => {
+    this.props.onFilterUpdate(index, event.target.value, column, 'textField');
   };
 
   renderCheckbox(column, index) {
@@ -155,7 +155,7 @@ class TableFilter extends React.Component {
             </Typography>
           </Grid>
           <Grid container>
-            {filterData[index].map((filterColumn, filterIndex) => (
+            {filterData[index].map((filterValue, filterIndex) => (
               <Grid item key={filterIndex}>
                 <FormControlLabel
                   key={filterIndex}
@@ -166,16 +166,16 @@ class TableFilter extends React.Component {
                   control={
                     <Checkbox
                       className={classes.checkboxIcon}
-                      onChange={this.handleCheckboxChange.bind(null, index, filterColumn)}
-                      checked={filterList[index].indexOf(filterColumn) >= 0 ? true : false}
+                      onChange={this.handleCheckboxChange.bind(null, index, filterValue, column.name)}
+                      checked={filterList[index].indexOf(filterValue) >= 0 ? true : false}
                       classes={{
                         root: classes.checkbox,
                         checked: classes.checked,
                       }}
-                      value={filterColumn != null ? filterColumn.toString() : ''}
+                      value={filterValue != null ? filterValue.toString() : ''}
                     />
                   }
-                  label={filterColumn}
+                  label={filterValue}
                 />
               </Grid>
             ))}
@@ -197,14 +197,14 @@ class TableFilter extends React.Component {
             <Select
               value={filterList[index].toString() || textLabels.all}
               name={column.name}
-              onChange={event => this.handleDropdownChange(event, index)}
+              onChange={event => this.handleDropdownChange(event, index, column.name)}
               input={<Input name={column.name} id={column.name} />}>
               <MenuItem value={textLabels.all} key={0}>
                 {textLabels.all}
               </MenuItem>
-              {filterData[index].map((filterColumn, filterIndex) => (
-                <MenuItem value={filterColumn} key={filterIndex + 1}>
-                  {filterColumn != null ? filterColumn.toString() : ''}
+              {filterData[index].map((filterValue, filterIndex) => (
+                <MenuItem value={filterValue} key={filterIndex + 1}>
+                  {filterValue != null ? filterValue.toString() : ''}
                 </MenuItem>
               ))}
             </Select>
@@ -224,7 +224,7 @@ class TableFilter extends React.Component {
             <TextField
               label={column.label}
               value={filterList[index].toString() || ''}
-              onChange={event => this.handleTextFieldChange(event, index)}
+              onChange={event => this.handleTextFieldChange(event, index, column.name)}
             />
           </FormControl>
         </div>
@@ -245,20 +245,20 @@ class TableFilter extends React.Component {
               value={filterList[index] || []}
               renderValue={selected => selected.join(', ')}
               name={column.name}
-              onChange={event => this.handleMultiselectChange(index, event.target.value)}
+              onChange={event => this.handleMultiselectChange(index, event.target.value, column.name)}
               input={<Input name={column.name} id={column.name} />}>
-              {filterData[index].map((filterColumn, filterIndex) => (
-                <MenuItem value={filterColumn} key={filterIndex + 1}>
+              {filterData[index].map((filterValue, filterIndex) => (
+                <MenuItem value={filterValue} key={filterIndex + 1}>
                   <Checkbox
-                    checked={filterList[index].indexOf(filterColumn) >= 0 ? true : false}
-                    value={filterColumn.toString()}
+                    checked={filterList[index].indexOf(filterValue) >= 0 ? true : false}
+                    value={filterValue.toString()}
                     className={classes.checkboxIcon}
                     classes={{
                       root: classes.checkbox,
                       checked: classes.checked,
                     }}
                   />
-                  <ListItemText primary={filterColumn} />
+                  <ListItemText primary={filterValue} />
                 </MenuItem>
               ))}
             </Select>
diff --git a/src/components/TableFilterList.js b/src/components/TableFilterList.js
index 9729f05..2f4ece6 100644
--- a/src/components/TableFilterList.js
+++ b/src/components/TableFilterList.js
@@ -21,6 +21,13 @@ class TableFilterList extends React.Component {
     filterList: PropTypes.array.isRequired,
     /** Filter List value renderers */
     filterListRenderers: PropTypes.array.isRequired,
+    /** Columns used to describe table */
+    columnNames: PropTypes.PropTypes.arrayOf(
+      PropTypes.oneOfType([
+        PropTypes.string,
+        PropTypes.shape({ name: PropTypes.string.isRequired }),
+      ]),
+    ).isRequired,
     /** Callback to trigger filter update */
     onFilterUpdate: PropTypes.func,
     /** Extend the style applied to components */
@@ -28,7 +35,7 @@ class TableFilterList extends React.Component {
   };
 
   render() {
-    const { classes, filterList, filterUpdate, filterListRenderers } = this.props;
+    const { classes, filterList, filterUpdate, filterListRenderers, columnNames } = this.props;
 
     return (
       <div className={classes.root}>
@@ -37,7 +44,7 @@ class TableFilterList extends React.Component {
             <Chip
               label={filterListRenderers[index](data)}
               key={colIndex}
-              onDelete={filterUpdate.bind(null, index, data, 'checkbox')}
+              onDelete={filterUpdate.bind(null, index, data, columnNames[index].name, 'checkbox')}
               className={classes.chip}
             />
           )),
diff --git a/src/components/TableSearch.js b/src/components/TableSearch.js
index e4e33a7..5329a80 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 } = this.props;
+    const { classes, options, onHide, initialSearchText } = this.props;
 
     return (
       <Grow appear in={true} timeout={300}>
@@ -64,6 +64,7 @@ class TableSearch extends React.Component {
             InputProps={{
               'aria-label': options.textLabels.toolbar.search,
             }}
+            defaultValue={initialSearchText}
             onChange={this.handleTextChange}
             fullWidth={true}
             inputRef={el => (this.searchField = el)}
diff --git a/src/components/TableToolbar.js b/src/components/TableToolbar.js
index 59c0829..31a0a4d 100644
--- a/src/components/TableToolbar.js
+++ b/src/components/TableToolbar.js
@@ -84,8 +84,8 @@ export const responsiveToolbarStyles = theme => ({
 class TableToolbar extends React.Component {
   state = {
     iconActive: null,
-    showSearch: false,
-    searchText: null,
+    showSearch: Boolean(this.props.options.searchText),
+    searchText: this.props.options.searchText || null,
   };
 
   handleCSVDownload = () => {
@@ -162,13 +162,18 @@ class TableToolbar extends React.Component {
     } = this.props;
 
     const { search, downloadCsv, print, viewColumns, filterTable } = options.textLabels.toolbar;
-    const { showSearch } = this.state;
+    const { showSearch, searchText } = this.state;
 
     return (
       <Toolbar className={classes.root} role={'toolbar'} aria-label={'Table Toolbar'}>
         <div className={classes.left}>
           {showSearch === true ? (
-            <TableSearch onSearch={this.handleSearch} onHide={this.hideSearch} options={options} />
+            <TableSearch
+              initialSearchText={searchText}
+              onSearch={this.handleSearch}
+              onHide={this.hideSearch}
+              options={options}
+            />
           ) : typeof title !== 'string' ? (
             title
           ) : (
diff --git a/webpack.config.js b/webpack.config.js
index f3cd389..6a2037e 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -3,7 +3,7 @@ const webpack = require('webpack');
 
 module.exports = {
   entry: {
-    app: "./examples/selectable-rows/index.js"
+    app: "./examples/column-filters/index.js"
   },
   stats: "verbose",
   context: __dirname,


Test patch:
diff --git a/test/MUIDataTable.test.js b/test/MUIDataTable.test.js
index 640b624..32bf2c5 100644
--- a/test/MUIDataTable.test.js
+++ b/test/MUIDataTable.test.js
@@ -369,7 +369,7 @@ describe('<MUIDataTable />', function() {
     const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} />);
     const table = shallowWrapper.dive();
     const instance = table.instance();
-    instance.filterUpdate(0, 'Joe James', 'checkbox');
+    instance.filterUpdate(0, 'Joe James', 'Name', 'checkbox');
     table.update();
 
     const state = table.state();
@@ -380,7 +380,7 @@ describe('<MUIDataTable />', function() {
     const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} />);
     const table = shallowWrapper.dive();
     const instance = table.instance();
-    instance.filterUpdate(0, 'Joe James', 'checkbox');
+    instance.filterUpdate(0, 'Joe James', 'Name', 'checkbox');
     table.update();
 
     let state = table.state();
@@ -397,7 +397,7 @@ describe('<MUIDataTable />', function() {
     const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} />);
     const table = shallowWrapper.dive();
     const instance = table.instance();
-    instance.filterUpdate(0, 'Joe James', 'dropdown');
+    instance.filterUpdate(0, 'Joe James', 'Name', 'dropdown');
     table.update();
 
     const state = table.state();
@@ -413,9 +413,10 @@ describe('<MUIDataTable />', function() {
       defaultRenderCustomFilterList,
       defaultRenderCustomFilterList,
     ];
+    const columnNames = columns.map(column => ({ name: column.name }));
 
     const mountWrapper = mount(
-      <TableFilterList filterList={filterList} filterListRenderers={filterListRenderers} filterUpdate={() => true} />,
+      <TableFilterList filterList={filterList} filterListRenderers={filterListRenderers} filterUpdate={() => true} columnNames={columnNames} />,
     );
     const actualResult = mountWrapper.find(Chip);
     assert.strictEqual(actualResult.length, 1);
@@ -428,9 +429,10 @@ describe('<MUIDataTable />', function() {
         ? c.options.customFilterListRender
         : defaultRenderCustomFilterList;
     });
+    const columnNames = columns.map(column => ({ name: column.name }));
 
     const mountWrapper = mount(
-      <TableFilterList filterList={filterList} filterListRenderers={filterListRenderers} filterUpdate={() => true} />,
+      <TableFilterList filterList={filterList} filterListRenderers={filterListRenderers} filterUpdate={() => true} columnNames={columnNames} />,
     );
     const actualResult = mountWrapper.find(Chip);
     assert.strictEqual(actualResult.length, 1);
@@ -441,13 +443,13 @@ describe('<MUIDataTable />', function() {
     const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} />);
     const table = shallowWrapper.dive();
     const instance = table.instance();
-    instance.filterUpdate(0, 'Joe James', 'dropdown');
+    instance.filterUpdate(0, 'Joe James', 'Name', 'dropdown');
     table.update();
 
     let state = table.state();
     assert.deepEqual(state.filterList, [['Joe James'], [], [], [], []]);
 
-    instance.filterUpdate(0, 'Joe James', 'dropdown');
+    instance.filterUpdate(0, 'Joe James', 'Name', 'dropdown');
     table.update();
 
     state = table.state();
@@ -459,7 +461,7 @@ describe('<MUIDataTable />', function() {
     const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} />);
     const table = shallowWrapper.dive();
     const instance = table.instance();
-    instance.filterUpdate(0, 'Joe James', 'checkbox');
+    instance.filterUpdate(0, 'Joe James', 'Name', 'checkbox');
     table.update();
 
     // now remove it
@@ -472,6 +474,42 @@ describe('<MUIDataTable />', function() {
     assert.deepEqual(state.filterList, [[], [], [], [], []]);
   });
 
+  it('should have the proper column name in onFilterChange when applying filters', () => {
+    let changedColumn;
+    const options = {
+      onFilterChange: column => changedColumn = column
+    };
+
+    const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} options={options} />);
+    const table = shallowWrapper.dive();
+    const instance = table.instance();
+
+    // test checkbox filter
+    instance.filterUpdate(0, 'Joe James', 'Name', 'checkbox');
+    table.update();
+    assert.strictEqual(changedColumn, 'Name');
+
+    // test dropdown filter
+    instance.filterUpdate(0, 'Test Corp', 'Company', 'dropdown');
+    table.update();
+    assert.strictEqual(changedColumn, 'Company');
+
+    // test textField filter
+    instance.filterUpdate(0, 'Joe James', 'Name', 'textField');
+    table.update();
+    assert.strictEqual(changedColumn, 'Name');
+
+    // test multiselect filter
+    instance.filterUpdate(0, 'Test Corp', 'Company', 'multiselect');
+    table.update();
+    assert.strictEqual(changedColumn, 'Company');
+
+    // test reset filters
+    instance.resetFilters();
+    table.update();
+    assert.strictEqual(changedColumn, null);
+  });
+
   it('should properly set searchText when calling searchTextUpdate method', () => {
     const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} />);
     const table = shallowWrapper.dive();
@@ -814,7 +852,7 @@ describe('<MUIDataTable />', function() {
     const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} />);
     const table = shallowWrapper.dive();
     const instance = table.instance();
-    instance.filterUpdate(0, 'James, Joe', 'checkbox');
+    instance.filterUpdate(0, 'James, Joe', 'Name', 'checkbox');
     table.update();
     const state = table.state();
 
@@ -831,7 +869,7 @@ describe('<MUIDataTable />', function() {
     const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} options={options} />);
     const table = shallowWrapper.dive();
     const instance = table.instance();
-    instance.filterUpdate(0, 'James', 'textField');
+    instance.filterUpdate(0, 'James', 'Name', 'textField');
     table.update();
     const state = table.state();
 
@@ -848,7 +886,7 @@ describe('<MUIDataTable />', function() {
     const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} options={options} />);
     const table = shallowWrapper.dive();
     const instance = table.instance();
-    instance.filterUpdate(0, 'Joe James', 'dropdown');
+    instance.filterUpdate(0, 'Joe James', 'Name', 'dropdown');
     table.update();
     const state = table.state();
 
@@ -886,7 +924,7 @@ describe('<MUIDataTable />', function() {
       const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} options={options} />);
       const table = shallowWrapper.dive();
       const instance = table.instance();
-      instance.filterUpdate(1, 'b', 'dropdown');
+      instance.filterUpdate(1, 'b', 'Name', 'dropdown');
       table.update();
       const { displayData } = table.state();
 
@@ -934,7 +972,7 @@ describe('<MUIDataTable />', function() {
       const shallowWrapper = shallow(<MUIDataTable columns={columns} data={data} options={options} />);
       const table = shallowWrapper.dive();
       const instance = table.instance();
-      instance.filterUpdate(1, 'b', 'dropdown');
+      instance.filterUpdate(1, 'b', 'Name', 'dropdown');
       table.update();
       const { displayData } = table.state();
 
diff --git a/test/MUIDataTableBody.test.js b/test/MUIDataTableBody.test.js
index f62cf9d..46458d5 100644
--- a/test/MUIDataTableBody.test.js
+++ b/test/MUIDataTableBody.test.js
@@ -207,7 +207,7 @@ describe('<TableBody />', function() {
     const selectRowUpdate = stub();
     const toggleExpandRow = () => {};
 
-    const t = mount(
+    const mountWrapper = mount(
       <TableBody
         data={displayData}
         count={displayData.length}
@@ -224,7 +224,7 @@ describe('<TableBody />', function() {
       />,
     );
 
-    t.find('#MUIDataTableBodyRow-2')
+    mountWrapper.find('#MUIDataTableBodyRow-2')
       .first()
       .simulate('click');
 
@@ -237,7 +237,7 @@ describe('<TableBody />', function() {
     const selectRowUpdate = stub();
     const toggleExpandRow = () => {};
 
-    const t = mount(
+    const mountWrapper = mount(
       <TableBody
         data={displayData}
         count={displayData.length}
@@ -254,7 +254,7 @@ describe('<TableBody />', function() {
       />,
     );
 
-    const props = t
+    const props = mountWrapper
       .find('#MUIDataTableBodyRow-1')
       .first()
       .props();
@@ -263,4 +263,31 @@ describe('<TableBody />', function() {
     assert.isAtLeast(options.setRowProps.callCount, 1);
     assert(options.setRowProps.calledWith(data[1]));
   });
+
+  it("should use 'customRowRender' when provided", () => {
+    const options = { customRowRender: () => <div>Test_Text</div> };
+    const selectRowUpdate = stub();
+    const toggleExpandRow = () => {};
+
+    const mountWrapper = mount(
+      <TableBody
+        data={displayData}
+        count={displayData.length}
+        columns={columns}
+        page={0}
+        rowsPerPage={10}
+        selectedRows={[]}
+        selectRowUpdate={selectRowUpdate}
+        expandedRows={[]}
+        toggleExpandRow={toggleExpandRow}
+        options={options}
+        searchText={''}
+        filterList={[]}
+      />,
+    );
+
+    const html = mountWrapper.html();
+
+    expect(html).to.contain("Test_Text");
+  });
 });
diff --git a/test/MUIDataTableSearch.test.js b/test/MUIDataTableSearch.test.js
index d75245e..ba8e09f 100644
--- a/test/MUIDataTableSearch.test.js
+++ b/test/MUIDataTableSearch.test.js
@@ -19,6 +19,19 @@ describe('<TableSearch />', function() {
     assert.strictEqual(actualResult.length, 1);
   });
 
+  it('should render a search bar with text initialized', () => {
+    const options = { textLabels };
+    const onSearch = () => {};
+    const onHide = () => {};
+
+    const mountWrapper = mount(
+      <TableSearch onSearch={onSearch} onHide={onHide} options={options} initialSearchText="searchText" />,
+    );
+    const actualResult = mountWrapper.find(TextField);
+    assert.strictEqual(actualResult.length, 1);
+    assert.strictEqual(actualResult.props().defaultValue, 'searchText');
+  });
+
   it('should trigger handleTextChange prop callback when calling method handleTextChange', () => {
     const options = { onSearchChange: () => true, textLabels };
     const onSearch = spy();
diff --git a/test/MUIDataTableToolbar.test.js b/test/MUIDataTableToolbar.test.js
index 7e0b7ec..f0ef27f 100644
--- a/test/MUIDataTableToolbar.test.js
+++ b/test/MUIDataTableToolbar.test.js
@@ -70,6 +70,16 @@ describe('<TableToolbar />', function() {
     assert.strictEqual(actualResult.length, 1);
   });
 
+  it('should render a toolbar with search text initialized if option.searchText = some_text', () => {
+    const newOptions = { ...options, search: true, searchText: 'searchText' };
+    const mountWrapper = mount(
+      <TableToolbar columns={columns} data={data} options={newOptions} setTableAction={setTableAction} />,
+    );
+    const actualResult = mountWrapper.find(TableSearch);
+    assert.strictEqual(actualResult.length, 1);
+    assert.strictEqual(actualResult.props().initialSearchText, 'searchText');
+  });
+
   it('should render a toolbar with no search icon if option.search = false', () => {
     const newOptions = { ...options, search: false };
     const mountWrapper = mount(