Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I have a fix for React input text 'onChange' events not firing. I need to know where to put it in the code #1336

Open
eldrgeek opened this issue Mar 15, 2017 · 3 comments · May be fixed by #1693

Comments

@eldrgeek
Copy link

Issue details

When React applications are synced across browsers, most things update properly. But input box onChange events do not trigger properly in the synced instances. The data in the input box is synced, which is great, but 'onChange` is not triggered.

This is because onChange is a synthetic event. If the code programmatically changes the input box by el.value = 'some value' the event is not triggered. It will only trigger if the change comes from within the React framework.

BrowserSync has the necessary information to cause the event to trigger because it delivers correct content to the input element. What it does not do is trigger the synthetic events.

I've created a project on glitch.com here that demonstrates the problem and implements a hackish solution. A description of how to run my hack is below.

The proven solution is to deliver an 'input' event to the input box. I do this on a timer tick:
const event = new Event('input', { bubbles: true }); input.dispatchEvent(event);
After demonstrating that this fixed the bug, I hooked the browser-sync socket and found that browser-sync sends this message on the text change:
[ 'input:text', 9:22 PM { tagName: 'INPUT', index: 0, value: 'f', url: '/' } ]

So a better solution is to watch for this event and then dispatch the above event when it is seen (or after a delay, if there is a race condition).

The best solution is to make this same fix in the 'right place' in browser-sync. But I do not know where that is. I am using the current version. If you advise me where to make the fix, I will prepare a PR with the fix.

Thanks.

For reference:

The method for the fix is from this StackOverflow post

Instructions for running my example:

Steps to reproduce/test case

I've created an example in this gomix.com project. To run it, do the following:

  1. Open this link in two different devices.

  2. You can confirm that scrolling, navigation, clicks in the side panel all sync properly.

  3. If you type (for example) an 'f' in the input box in a browser, it will filter the list of items in that browser. An 'f' reduces the list to just 'football.' The input box in the synced browser will get the changed value, but it does not trigger the onChange handler which causes the update.

  4. If you click the button labeled "Hack?" it will change (in both browsers) to "Hack!" and set up a timer loop that checks the contents of the input box every two seconds; if the input has changed since the last call to the onChange handler, then it will fire the onChange handler. In the browser in which a change is made, the handler will have fired normally, so the hack will have no effect. In the synced browser, the values will be different, so the update routine will run, and the list will be filtered.

I set the timeout to two seconds so that the effect would be clear. I could use something like this with a faster timer as a hack to work around the problem. The better solution would be to deliver the 'input' event to the target of the message from browsersync that updates the input box.

@abhi608
Copy link

abhi608 commented Jun 22, 2017

Hey! Did you integrate your fix with BrowserSync?

@eldrgeek
Copy link
Author

No. You are the only person to reply.
I don't know the BrowserSync code enough to know where to insert my change.
I notice that I did not include a link to my hack. Here it is

@joacim-boive
Copy link

This would be extremly sweet to have implemented as the benefit of using Browsersync with forms in a React app is quite limited now... :(

@eric1iu eric1iu linked a pull request May 24, 2019 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants