dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.32k stars 9.97k forks source link

[Blazor] @onkeydown:preventDefault not working on Android browsers #42836

Closed daniel-p-tech closed 2 years ago

daniel-p-tech commented 2 years ago

Is there an existing issue for this?

Describe the bug

I created a fairly complex mask component that relies heavily on @onkeydown:preventDefault="m_preventDefaultKeyDown" logic to suppress the user from entering invalid characters etc. This works great in all desktop browsers and when emulating mobile devices using developer tools, but when running the same (WASM) app on mobile browsers (Chrome and Firefox on Android), I am able to enter any characters as if preventDefault was not set to true.

I can easily reproduce this issue using a very simple input element:

<input type="text" class="form-control"
    @onkeydown:preventDefault
    @onchange:preventDefault />

I tried adding preventDefault and stopPropagation flags to all onxyz events just in case with no success.

What is going on? This seems to be a major bug in Blazor and I suspect by now all 3rd party component vendors would have issues with this, so maybe I'm doing something incorrectly?

Thank you.

Expected Behavior

Explained above.

Steps To Reproduce

<input type="text" class="form-control"
    @onkeydown:preventDefault
    @onchange:preventDefault />

Exceptions (if any)

No response

.NET Version

6.0.107

Anything else?

Tested on Chrome 103.0.5060.71 running on Android 10; SM-G960U

daniel-p-tech commented 2 years ago

Out of curiosity I ran a demo of DevExpress MaskedInput component on Chrome (Android) and was able to immediately break it. I suspect they use Blazor server and I know nothing further about the implementation details of their component but it's possibly related to the same problem that I'm running into with my own component.

https://demos.devexpress.com/blazor/MaskedInput

daniel-p-tech commented 2 years ago

@mkArtakMSFT I see that this issue has been assigned to a milestone - can you explain what this means? Is this a confirmed bug that will be fixed in https://github.com/dotnet/aspnetcore/milestone/218?

daniel-p-tech commented 2 years ago

Hi, is there any update on this? It has been two weeks without any feedback.

SteveSandersonMS commented 2 years ago

@daniel-p-tech Is it possible you're just running into an Android browser limitation? I see there are StackOverflow posts about this exact kind of thing, not involving Blazor: https://stackoverflow.com/questions/42011740/event-preventdefault-not-working-for-android-chrome. It might be that you need to preventDefault on the input event instead of keydown.

I did try the following repro: https://blazorrepl.telerik.com/mGEjubvk53gTKnFt09. On iOS Safari it behaves as expected, preventing characters from being typed.

ghost commented 2 years ago

Hi @daniel-p-tech. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

ghost commented 2 years ago

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. If it is closed, feel free to comment when you are able to provide the additional information and we will re-investigate.

See our Issue Management Policies for more information.

daniel-p-tech commented 2 years ago

I don't see how I can rewrite my code to use oninput since I need to be able to acquire the actual key:

// good reference: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values
if (args.Key == "ArrowLeft" || args.Key == "ArrowRight" ||
    args.Key == "ArrowDown" || args.Key == "ArrowUp" ||
    args.Key == "Home" || args.Key == "End")
{
    // enable default browser behaviour
    m_preventDefaultKeyDown = false;
}
else if (args.Key == "Delete")
{
}
else if (args.Key == "Backspace")
{
...
}
else
{
...
}

Also, the demo that you linked to does not work on Android mobile - I was able to enter everything I typed.

Thank you.

SteveSandersonMS commented 2 years ago

@daniel-p-tech As far as I can tell this is just an Android browser limitation. I tried https://jsfiddle.net/4thnxmjw/ (which doesn't involve Blazor at all) and on PC browsers it prevents all keys except a (as designed), whereas on Chrome for Android it doesn't prevent any keys - I was able to type anything.

If you have any reason to think this is a Blazor issue, please provide details.

ghost commented 2 years ago

Hi @daniel-p-tech. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

daniel-p-tech commented 2 years ago

Do you have any suggestions on how to implement a proper mask component that would work on all browsers? As I previously mentioned, oninput event does not provide the necessary key code. I put two weeks worth of work into this. Maybe one of the interns can look into implementing a true cross-browser mask component (which virtually every app requires) and share it with the world now that you have a basic grid component?

Thanks!

SteveSandersonMS commented 2 years ago

I'm afraid I don't have a specific suggestion but since this isn't a Blazor-specific limitation, it should be possible to look at any JavaScript component that does what you want and follow the same approach.

Closing this as an external issue - sorry we didn't have an easy solution for you!