-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Enable control over event propagation and default actions #5545
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
Comments
IMO both are independant and required:
Usage <button onclick=@MyHandler
onclick-stop-propagation
onclick-prevent-default /> |
Please read this comment: |
What about use Attributes on the target method |
Instead of:
Alternative vue-inspired syntax:
|
+1 this is really needed indeed, thinking of individual cells on tabels, other use cases etc.. |
Yes, for me this feature is also very important. |
I haven't been using Blazor very long, it may be something that's been covered and isn't possible. I think these button onclick.prevent.stop=@MyHandler button onclick.prevent.stop=@MyHandler are both undesirable formats. My preference would be a parameter list, something like this <button onclick=(@handler, prevent-default, no-propagation) /> less clutter, no changes to well known events, doesn't look like xaml . |
Blazor 0.6 is coming with new wonderful features and I think it is time to schedule this issue for Blazor 0.7. It is a showstopper for all component creators. Please read #1293, #1063, #988, #951, #902, #803, #715. Please note, that sometimes we have to decide at runtime what to do. Simple example is here: https://github.com/aspnet/Blazor/issues/715#issuecomment-403171755 |
I have just updated my comment here https://github.com/aspnet/Blazor/issues/715#issuecomment-403171755 with an example which (I believe) can be implemented in Blazor using async API. |
Add this to the 0.7 release please. |
We'll take a look at getting this into 0.7.0. |
Hi, For my testing, I just went with a simple attribute "bl-preventdefault" which contains a list of events you want to enable preventDefault on.
What do you think of using a simple fix like this for now? |
@SteveSandersonMS , @danroth27 some time ago this was scheduled for Blazor 0.7. Any chance to reconsider for 0.8? |
as a workaround, i'm currently using js interop to register event handlers instead of the native event binding. dynamic input handling is really necessary for complex components, even if it doesn't fit nicely into the async/worker-thread model. even simple buttons and fields need a plethora of weird special cases when you're handling touch input, different browers, history state etc. |
OK, I've been reading through everything that's ever been written about this, and am formulating it into a proposed design. Scenarios
Constraint: SynchronyThe big limitation, which we've discussed many times, is that for this to work within the Razor Components programming model, we need to know in advance whether you want to cancel bubbling or We can't have some .NET API for controlling this after the user has triggered the event, because code running on the server receives it later, and the browser APIs are synchronous. Nor can we have some system like suggested here where we block bubbling by default, but then re-raise the event asynchronously if the .NET code says we should - that doesn't work because many browser events can't be simulated from script (e.g., typing), nor are events treated the same if they are triggered asynchronously (e.g., attempting to open a popup). I know people want a way to do this, but there just isn't a way, so we have to come up with a nice design around it. DesignControlling propagation of bubbling events Bubbling events propagate by default, so all we have to do is create a way to say if you don't want a certain event to bubble up from a certain element. <div onclick-stop-propagation="true">...</div> <!-- Or any other event --> Note that we have to phrase it positively. We can't have it as "onsomeevent-bubble=false", because in Razor, a false bool attribute is shorthand for not emitting the attribute at all. The use of If you need to use event-time logic to decide whether to bubble (e.g., whether the user is holding "shift" or not), your scenario is advanced and you can implement it with JS. Example: <div onclick="conditionallyStopPropagation(event)">...</div>
// Separately, in a `.js` file:
function conditionallyStopPropagation(event) {
if (!event.shiftKey) {
event.stopPropagation();
}
} It's not unreasonable to use JS for advanced scenarios like this, and given the synchrony limitation, is the only way you're going to be able to put in totally arbitrary logic that run synchronously. Implementation note: Our Control over default actions Currently, our behavior is that we automatically We can make it possible to prevent default in a similar way to preventing event propagation: <input type="checkbox" onclick="@DoSomething" onclick-prevent-default="true" /> Again, As with above, it's only possible to prevent default based on information that exists prior to the event. You can't use .NET logic to prevent default conditionally after the event has started, because of the synchrony limitation. If you really do need conditional logic, this is an advanced scenario and you'll solve it via JS interop. Example: <input bind="@SomeString" onkeydown="blockDigits(event)" />
// Separately, in a `.js` file:
function blockDigits(event) {
if (event.keyCode >= 48 && event.keyCode <= 57) {
event.preventDefault();
}
} Again, it's not unreasonable to use JS for advanced and uncommon scenarios like this. Non-scenarios Controlling event capture: In JS, it's possible to register event listeners that fire during the "capture" phase of event handling, instead of during the "bubble" phase. However with Razor Components we don't expose that distinction - we use a mixture of capturing and bubbling handlers, depending on the event type, to produce the desired behaviors. If, one day, we have a way of changing your listener to be capturing, then we would also want something like Avoiding |
This seems to be just what I expected 👍 concise and orthonogonal to other features. One small nitpick - it should also be possible to write these examples with a minimized attribute, and maybe that's the preferred style.
It's obvious that there has to be some runtime component to this, do you imagine that there's a compiler/tooling angle as well? |
@danieldegtyarev Could you please let me know about this issue's estimated arrival time? |
@kameshrajandran .NET Core 3.1, which is scheduled for Nov/Dec of this year. |
The runtime part of this is now done and was merged in #14509 The tooling part is going to happen in 3.1.0-preview2, so assigning to @ajaybhargavb for the remaining work. |
In fact we have a different issue tracking the tooling work for this (#14517), so closing this one. |
Was this finally added to the released Blazor 3.0? |
Unfortunately it didn't make it into 3.0, but it has now been implemented for 3.1. We will have a preview of the functionality it a couple of weeks. |
Awesome. :) I just started fiddling with Blazor and ran into this requirement for drag and drop functionality. |
It's unfortunate JS won't let us decide asynchronously. I tried cancelling and then emulating mouse events but some browsers just wouldn't allow it. A tricky problem indeed. |
WPF has the same issue. You have to mark |
I wonder if the Blazor team has considered handling bubbling through the Blazor framework itself and bypassing Javascript event bubbling? Or would that just be too overwhelming for every DOM element to trigger an event in C# just for the possibility of bubbling it up to a parent? |
There are lots of scenarios where this is needed. See descriptions in aspnet/blazor#715.
Since we don't want to rely on synchronous APIs, the solution will probably be a variation on event registration syntax, e.g.,
We still need to design what terminology to use (e.g., "propagation" vs "bubbling") and what features to include (e.g., whether there is also control over "preventDefault").
The text was updated successfully, but these errors were encountered: