the input text box focus is getting exited while navigating to the second page react-bootstrap-table2-toolkit

123 Views Asked by At

I am using:

"react-bootstrap-table-next": "4.0.3",
"react-bootstrap-table2-paginator": "^2.1.2",
"react-bootstrap-table2-toolkit": "^2.1.3",

I am using input text in my row, here is the code:

const [focusedRowIndex, setFocusedRowIndex] = useState(null);

// ...

{
  dataField: "newCredit",
  text: "new Credit",
  headerAlign: "center",
  align: "center",
  formatter: (cell, row, rowIndex, formatExtraData) => {
    return (
      <input
        type="text"
        value={cell}
        onChange={(e) =>
          formatExtraData.handleCreditChange(rowIndex, e.target.value)
        }
        onFocus={() => formatExtraData.handleFocusChange(rowIndex)}
        onClick={() => formatExtraData.handleFocusChange(rowIndex)}
        autoFocus={rowIndex === focusedRowIndex}
      />
    );
  },
  formatExtraData: {
    handleCreditChange: (rowIndex, value) => {
      const newUserList = [...userList];
      newUserList[rowIndex].newCredit = value;
      setUserList(newUserList);
    },
    handleFocusChange: (rowIndex) => {
      console.log(rowIndex);
      setFocusedRowIndex(rowIndex);
    },
  },
};

This input box is working fine on the first page, but when navigating to the second page whatever I am writing in the input box is also showing the value in the first page input box.

I want the input text to work similarly to how it is working on the first page.

1

There are 1 best solutions below

0
adsy On

You are referencing the user to modify by using rowIndex, but that rowIndex is scoped to the page you are on. On page two, the top item has a rowIndex of 0 just like the top item on page one also has a rowIndex of 0. Because of that, each cell on each row of a page is also editing the cell that happens to be in that same position across all other pages.

The way you get around this is by avoiding using the rowIndex as an identifier for the row because as you have discovered it is not actually unique and you absolutely need a unique & stable identifier for the row, that (crucially) is unique across all pages.

Items in your userList should have an id property or another unique identifier, assuming that is coming from some external source like the server. I'm assuming that's your use case, but if this list is instead being constructed entirely on the client side, you should assign some client-side generated id to each item in the array.

You would then use this to lookup the right item in the array to edit. Below, I am assuming that each entry in usersList already has an id.

const [focusedRowId, setFocusedRowId] = useState(null);

// ...

{
  dataField: "newCredit",
  text: "new Credit",
  headerAlign: "center",
  align: "center",
  formatter: (cell, row, rowIndex, formatExtraData) => {
    return (
      <input
        type="text"
        value={cell}
        onChange={(e) =>
          formatExtraData.handleCreditChange(row.id, e.target.value)
        }
        onFocus={() => formatExtraData.handleFocusChange(row.id)}
        onClick={() => formatExtraData.handleFocusChange(row.id)}
        autoFocus={row.id === focusedRowId}
      />
    );
  },
  formatExtraData: {
    handleCreditChange: (id, value) => {
      // Cleaner way of mutating object in array
      setUserList(prevUsersList => prevUsersList.map(
        user => user.id === id ? {...user, newCredit: value} : user 
      ));
    },
    handleFocusChange: (id) => {
      console.log(id);
      setFocusedRowId(id);
    },
  },
};