Skip to content

Commit 683c268

Browse files
committed
Trigger onInputChange when clicking the clear button (#594)
1 parent df6f89d commit 683c268

File tree

3 files changed

+31
-5
lines changed

3 files changed

+31
-5
lines changed

example/src/examples/BasicExample.js

+2
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ const BasicExample = () => {
1616
<Form.Group>
1717
<Form.Label>Single Selection</Form.Label>
1818
<Typeahead
19+
clearButton
1920
id="basic-typeahead-single"
2021
labelKey="name"
2122
onChange={setSingleSelections}
23+
onInputChange={console.log}
2224
options={options}
2325
placeholder="Choose a state..."
2426
selected={singleSelections}

src/__tests__/components/Typeahead.test.js

+12-4
Original file line numberDiff line numberDiff line change
@@ -1263,21 +1263,29 @@ describe('<Typeahead> `change` events', () => {
12631263
}
12641264
);
12651265

1266-
it('calls `onChange` when clicking the clear button', () => {
1267-
const selected = states.slice(0, 1);
1266+
it('calls change events when clicking the clear button', () => {
1267+
let event, value;
1268+
1269+
onInputChange = jest.fn((v, e) => {
1270+
value = v;
1271+
event = e;
1272+
});
1273+
12681274
render(
12691275
<TestComponent
12701276
clearButton
12711277
onChange={onChange}
12721278
onInputChange={onInputChange}
1273-
selected={selected}
1279+
selected={states.slice(0, 1)}
12741280
/>
12751281
);
12761282

12771283
screen.getByRole('button').click();
12781284

12791285
expect(onChange).toHaveBeenCalledTimes(1);
1280-
expect(onInputChange).toHaveBeenCalledTimes(0);
1286+
expect(onInputChange).toHaveBeenCalledTimes(1);
1287+
expect(value).toBe('');
1288+
expect(event).toBeDefined();
12811289
});
12821290

12831291
it('calls `onInputChange` when text is entered in the input', () => {

src/core/Typeahead.js

+17-1
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,21 @@ export function toggleMenu(state: TypeaheadState, props: Props) {
290290
return state.showMenu ? hideMenu(state, props) : { showMenu: true };
291291
}
292292

293+
/**
294+
* Manually trigger the input's change event.
295+
* https://stackoverflow.com/questions/23892547/what-is-the-best-way-to-trigger-onchange-event-in-react-js/46012210#46012210
296+
*/
297+
function triggerInputChange(input: HTMLInputElement, value: string) {
298+
const inputValue = Object.getOwnPropertyDescriptor(
299+
window.HTMLInputElement.prototype,
300+
'value'
301+
);
302+
303+
inputValue && inputValue.set && inputValue.set.call(input, value);
304+
const e = new Event('input', { bubbles: true });
305+
input.dispatchEvent(e);
306+
}
307+
293308
class Typeahead extends React.Component<Props, TypeaheadState> {
294309
static propTypes = propTypes;
295310
static defaultProps = defaultProps;
@@ -453,7 +468,8 @@ class Typeahead extends React.Component<Props, TypeaheadState> {
453468
}
454469

455470
_handleClear = () => {
456-
this.setState(clearTypeahead, () => this._handleChange([]));
471+
this.inputNode && triggerInputChange(this.inputNode, '');
472+
this.setState(clearTypeahead);
457473
}
458474

459475
_handleFocus = (e: SyntheticEvent<HTMLInputElement>) => {

0 commit comments

Comments
 (0)