Material-table: Set focus to search field

Created on 29 Aug 2019  路  4Comments  路  Source: mbrn/material-table

Is there any way that I can set the focus to the search bar on the table, so that as soon as the page renders users can type what they want to search?

Most helpful comment

@harveyappleton @yakuphanbilgic

Another way you could do this is by overriding the toolbar, wrapping in div, giving that div an ID, and setting focus that way.

You also may be able to do this using refs? Not sure..

Check out a live demo here

// Main bits from demo
import React, { useState, useEffect, useRef } from "react";
import { render } from "react-dom";
import MaterialTable, { MTableToolbar } from "material-table";
import tableIcons from "./TableIcons.js";

const originalData = ["Rock", "Paper", "Scissors"].map(word => ({
  id: Math.floor(Math.random() * 300),
  name: word
}));

const columns = [
  { title: "Id", field: "id" },
  { title: "Name", field: "name" }
];

function App() {
  /**
   * SET THIS TO WHATEVER ID YOU NEED.. could even have this in state..etc..
   *
   * May be able to do this using a ref on the table or toolbar component(s)?
   * ...instead of querying the DOM outside of React, which isn't really best practices.
   * // const tableRef = useRef();
   * // const toolbarRef = useRef();
   */
  const TOOLBAR_ID = "some__unique__hacky__id";

  const [data, setData] = useState(originalData);

  useEffect(() => {
    const searchBar = document.querySelector(`#${TOOLBAR_ID} input`);
    if (!searchBar) return;
    searchBar.focus();
  });

  return (
    <MaterialTable
      //// See comments above..
      // tableRef={tableRef}
      data={data}
      icons={tableIcons}
      columns={columns}
      components={{
        Toolbar: props => {
          // Override component by wrapping in div and injecting an ID..
          // This will make it easier to query..
          // Simply pass all 'main props' thru to the default Toolbar component
          return (
            <div id={TOOLBAR_ID}>
              <MTableToolbar {...props} />
            </div>
          );
        }
      }}
    />
  );
}

render(<App />, document.querySelector("#root"));

All 4 comments

There is no option for this but you do have the ability to override components (in this case, the Toolbar component).. or you could even use your own custom search field outside of the table - there are many ways to solve this - all of which are not a simple focus={true} prop.

@oze4 We can override the search bar, but how do we get the table to recall our remote data function? I'm currently looking for a way to do this. Will be making an issue if I can't find anything in the issues about this.

Edit: This problem is mentioned in issue 983.

@yakuphanbilgic - I ended up wrapping the MUI table in a div with a unique id (used lodash to generate and store in a useRef hook to keep it "constant").

you can then use a simple querySelector to focus the input

let input = document.querySelector( ``.${id.current} input[type='text'].MuiInput-input`` ); if (input) input.focus();

its a bit hacky, but it worked for me, and you can get it to focus after each re-render using useEffect hooks

@harveyappleton @yakuphanbilgic

Another way you could do this is by overriding the toolbar, wrapping in div, giving that div an ID, and setting focus that way.

You also may be able to do this using refs? Not sure..

Check out a live demo here

// Main bits from demo
import React, { useState, useEffect, useRef } from "react";
import { render } from "react-dom";
import MaterialTable, { MTableToolbar } from "material-table";
import tableIcons from "./TableIcons.js";

const originalData = ["Rock", "Paper", "Scissors"].map(word => ({
  id: Math.floor(Math.random() * 300),
  name: word
}));

const columns = [
  { title: "Id", field: "id" },
  { title: "Name", field: "name" }
];

function App() {
  /**
   * SET THIS TO WHATEVER ID YOU NEED.. could even have this in state..etc..
   *
   * May be able to do this using a ref on the table or toolbar component(s)?
   * ...instead of querying the DOM outside of React, which isn't really best practices.
   * // const tableRef = useRef();
   * // const toolbarRef = useRef();
   */
  const TOOLBAR_ID = "some__unique__hacky__id";

  const [data, setData] = useState(originalData);

  useEffect(() => {
    const searchBar = document.querySelector(`#${TOOLBAR_ID} input`);
    if (!searchBar) return;
    searchBar.focus();
  });

  return (
    <MaterialTable
      //// See comments above..
      // tableRef={tableRef}
      data={data}
      icons={tableIcons}
      columns={columns}
      components={{
        Toolbar: props => {
          // Override component by wrapping in div and injecting an ID..
          // This will make it easier to query..
          // Simply pass all 'main props' thru to the default Toolbar component
          return (
            <div id={TOOLBAR_ID}>
              <MTableToolbar {...props} />
            </div>
          );
        }
      }}
    />
  );
}

render(<App />, document.querySelector("#root"));
Was this page helpful?
0 / 5 - 0 ratings

Related issues

bohrsty picture bohrsty  路  3Comments

kfirshahar picture kfirshahar  路  3Comments

roseak picture roseak  路  3Comments

terapepo picture terapepo  路  3Comments

timrchavez picture timrchavez  路  3Comments