Skip to content

Commit

Permalink
Ensure both onchange and oninput callbacks are executes when typing (#…
Browse files Browse the repository at this point in the history
…3562)

* ensure both onchange and oninput callbacks are attached to the event listener

* remove custom hook and combiner callbacks in one

* update implementation and unit test

* remove only on tests and improve error handling

* cover scenario changing order

* allow uncaught error in unit test

* use event hook to trigger oncompatchange handler

* use oninputCapture rather than oninput when both callbacks are defined

Co-authored-by: Jovi De Croock <decroockjovi@gmail.com>
  • Loading branch information
marconi1992 and JoviDeCroock committed Jun 14, 2022
1 parent 0b9a927 commit c746ecf
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 0 deletions.
9 changes: 9 additions & 0 deletions compat/src/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,15 @@ options.vnode = vnode => {
value = undefined;
}

// Add support for onInput and onChange, see #3561
// if we have an oninput prop already change it to oninputCapture
if (/^oninput/i.test(i)) {
i = i.toLowerCase();
if (normalizedProps[i]) {
i = 'oninputCapture';
}
}

normalizedProps[i] = value;
}

Expand Down
23 changes: 23 additions & 0 deletions compat/test/browser/render.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,29 @@ describe('compat render', () => {
expect(scratch.firstElementChild.value).to.equal('0');
});

it('should call onChange and onInput when input event is dispatched', () => {
const onChange = sinon.spy();
const onInput = sinon.spy();

render(<input onChange={onChange} onInput={onInput} />, scratch);

scratch.firstChild.dispatchEvent(createEvent('input'));

expect(onChange).to.be.calledOnce;
expect(onInput).to.be.calledOnce;

onChange.resetHistory();
onInput.resetHistory();

// change props order
render(<input onInput={onInput} onChange={onChange} />, scratch);

scratch.firstChild.dispatchEvent(createEvent('input'));

expect(onChange).to.be.calledOnce;
expect(onInput).to.be.calledOnce;
});

it('should keep value of uncontrolled inputs using defaultValue', () => {
// See https://github.com/preactjs/preact/issues/2391

Expand Down

0 comments on commit c746ecf

Please sign in to comment.