3

It's a little duplicated Event for click outside a div or element to close it on Blazor, but no right answers.

(And I didn't find anything on my topic in Google)

In JS I just use "window.onclick" and "!event.target.matches('class')", and what can Blazor offer? Is it possible to implement it short and concisely, like in JS? Or is it useless?

Just in case - I want to do it in C#, but if the solution turns out to be "not so rosy", then I'll take JS.

Thanks to answers!

5 Answers5

8

I use this in my modal repo:

    <div class="modal-outer" @onclick="OnBackgroundClicked">
        <div class="modal-inner" @onclick:stopPropagation="true">
            @ModalService.ModalFragment
        </div>
    </div>
Brian Parker
  • 11,946
  • 2
  • 31
  • 41
3

I use the following Tailwind trick to accomplish this behaviour without js.

<div class="fixed inset-0 transition-opacity" @onclick=@HideDatePicker></div>
<div class="transform">
@*clicking on and arround this div is not affected.*@
</div>
Taco
  • 181
  • 1
  • 12
2

You can use pure JS to do this as you normally would, with just a little interop. In this case, though, you can use a parent element's Blazor @onclick to toggle your hideable element, and the child element's vanilla onclick event to prevent clicks on it from reaching the parent.

<div style="width:500px;height:500px; background-color:pink" @onclick="()=>IsClosed=true">
    @if(!IsClosed)
    {
        <div style="width:300px; height: 300px; background-color: black; color:white" 
                onclick="event.stopPropagation();">Click outside to close me.</div>
    }
</div>
@code {
    bool IsClosed;
} 
Bennyboy1973
  • 3,413
  • 2
  • 11
  • 16
1

There are three scenarios in this:

  1. The element can have 'focus' (eg. text box). In that case, simply use onblur html event
  2. The element does not have focus but its container can detect a mouseclick. In that case, use onclick event on the container.
  3. Neither the element nor its container can have useful onclick (eg, they have some other action associated with the click). In that case treat the whole thing as a modal. i.e. container on a backdrop that has sufficiently high z-index. Register the method to hide the backdrop with the onclick event of the container.
Mayur Ekbote
  • 1,700
  • 1
  • 11
  • 14
1

Thanks all for answers, but I have bad news — https://github.com/dotnet/aspnetcore/issues/28820

They don't plan to do this in the near future, so there's no need to “crutch” in C#, I'll just use JS.

In JS code it will look like this:

window.onclick = function(event) {
    var dropdowns = document.getElementsByClassName("Class__name");

if (!event.target.matches('.js-close')) {
    for (i = 0; i < dropdowns.length; i++) {
        var openDropdown = dropdowns[i];
        if (openDropdown.classList.contains('show')) {
            openDropdown.classList.remove('show');
        }
    }
}
christopher.online
  • 2,614
  • 3
  • 28
  • 52
  • 1
    Um. . . I gave a working sample that does what you want in Blazor. Why are you choosing to use JS instead? – Bennyboy1973 Dec 01 '21 at 21:33
  • 1
    @Bennyboy1973 Your answer is not bad, but it only works with (@onclick), and I need it globally, and JS can do that. It may be a matter of experience, but I think so for now. – Naked Snake Dec 02 '21 at 19:33
  • 1
    For beginners would it be possible to show how you integrated this JS code into your razor component code file? – Musaffar Patel Nov 12 '22 at 20:33