Well, this was entertaining struggle of many hours.
Long story short, I needed to implement a controlled
AsyncTypeahead field from
react-bootstrap-typeahead as an editable and insertable field in
react-bootstrap-table in a redux app. Oh, and the typeahead needed to allow new values to be entered.
You Just… or Do You?
According to the instructions provided by
react-bootstrap-table “you just”:
- Use the
customEditorprop to pass in your custom field component which implements
updateData()(see: react-bootstrap-table: custom cell edit example).
- Use the
customInsertEditorprop to pass in another custom field component which implements
getFieldValue(). (see: React Bootstrap Table – Customization)
- Implement a wrapped component of
AsyncTypeaheadthat implements the required interfaces above, so that you can also pass in the necessary params that
Sadly, “you don’t just”.
There were a few side-effects which made this not work quite as expected.
- Typeahead suggestions vanish inside the table cell.
Resolved with some CSS.
AsyncTypeaheadas a controlled field removes focus on change.
Could be the result of
blurToSavehandling by the table, as typeahead selection would fire the
onBlurevent because you’re clicking out of the field, or something hinky from using the typeahead as a controlled field. Or both.
- Once an option is selected, when you refocus on the field and hit backspace, instead of removing one letter, it clears the selected value. Makes sense, but means you can’t use it like a regular controlled field. Which you probably shouldn’t in the table anyway seeing as it handles updates separately.
Note: The demo doesn’t show this side effect because it’s not a controlled field.
- Once the typeahead is no longer in focus, the table doesn’t reset the editable mode so the field still looks in focus.
blurToSaveand custom fields, you have to fire the
onBlurhandler yourself in the custom component. Logically it would make sense to do this in the typeahead
onChangebut that handler doesn’t pass the event at all, and the table’s
onBlurrequires the event target. Woe.
- When inserting a new row,
Uncaught TypeError: dom.getFieldValue is not a functionis thrown and the row cannot be saved.
Even if you have implemented the function in your component, the way the insert modal builds the fields for value retrieval doesn’t retrieve the correct component reference. When I put debugging in the lib, the ref attribute that was being passed from the table was
undefined. Could this be the problem? Either way, the
domobject was broken so of course
getFieldValuewas not a function.
Here’s a gist of the applied solution. Commented where relevant changes were made.