0

Trying to use mouse to select multiple elements inside specific HTML element similar to how users can select multiple files and folders in Windows Explorer. Tested several libraries. In general, they work, but the tricky part is that each selectable element has a checkbox inside of it.

<div class="container">
  <div class="selectable"><input type="checkbox" /></div>
  <div class="selectable"><input type="checkbox" /></div>
  <div class="selectable"><input type="checkbox" /></div>
</div>

To select elements with the mouse, each library adds mousedown, mousemove, mouseup event handlers to the container and it still works as displayed in the codepen below, mousedown on container normally co-exists with click on checkbox.

https://codepen.io/artemiusgreat/pen/eYWzrQb

Apparently, it's not the case for Blazor, because I have the same markup as in the codepen above, the same events, but once I add mousedown event to the container using JS interop, all checkboxes inside container stop working. With or without onclick, checkboxes appear dead and non-clickable.

<!-- Checkbox outside of container works fine -->
<input type="checkbox" @onclick=@(e => SelectCollection(e)) />

<div class="container"> <!-- Inner checkboxes work only if container doesn't have "mousedown" handler -->

  <!-- Checkbox inside of container with Blazor "onclick" does NOT work -->
  <input type="checkbox" @onclick=@(e => SelectCollection(e)) />

  <!-- Checkbox inside of container does NOT work even if it doesn't have any handlers -->
  <input type="checkbox" />
  
</div>

Why???

Anonymous
  • 1,823
  • 2
  • 35
  • 74
  • I'm not a programmer, but I think programming is easy-peasy. There was another man shouting "Why???", hundreds years ago, and he's still waiting for an answer. – enet Jul 09 '21 at 06:19

2 Answers2

1

Here's your code working...I guess the main reason why it did not work for you is that you're using the click event, but you should use the change event.

@page "/"


<!-- Checkbox outside of container works fine -->
<input type="checkbox"  @onchange="@((args) => SelectCollection(args))" />

<div class="container" @onmousedown="@(() => message2 = "Down with the mouse: " + count++.ToString())"> <!-- Inner checkboxes work only if container doesn't have "mousedown" handler -->

  <!-- Checkbox inside of container with Blazor "onclick" does NOT work -->
  <input type="checkbox" @onchange="@((args) => SelectCollection(args))" />

  <!-- Checkbox inside of container does NOT work even if it doesn't have any handlers -->
  <input type="checkbox" />
  
</div>


<p>@message</p>
<p>@message2</p>
@code
{
    private string message;
    private string message2;
    private int count;

    protected async Task SelectCollection(ChangeEventArgs args)
    {
        message = args.Value.ToString();
        await Task.Yield();
    }
}
enet
  • 41,195
  • 5
  • 76
  • 113
  • Thanks for trying to help, although you're cheating and adding `mousedown` from Blazor, not from JS. Nevertheless, your answer made me experiment with some simpler pieces of code and I found the real issue. When I start dragging the mouse, I create a dynamic DIV in HTML that reflects area selected with the mouse move. This dynamic DIV is positioned on top of all other elements and when the selected area start on top of checkbox, it intercepts all clicks before they get to the checkbox. – Anonymous Jul 09 '21 at 14:07
  • At the same time, this issue is not reproducible in plain JS. I can either click mouse down / up on any checkbox or can press left mouse button and start moving it to the right selecting red boxes, so there still may be some issue with Blazor itself. https://codepen.io/artemiusgreat/pen/eYWzrQb – Anonymous Jul 09 '21 at 14:09
  • You think enet is "cheating" because he's using. . . Blazor events in Blazor? The nerve of that guy! – Bennyboy1973 Jul 09 '21 at 14:35
  • Thank you for your kindness, Bennyboy1973, but I don't think he meant any harm... – enet Jul 09 '21 at 18:25
0

Enet's answer was correct, but I will add this a separate answer to describe the root cause.

As I mentioned in the comment, every mouse selection script has to create a dynamic DIV that shows the selected area. For some reason when I start selection from the place where checkbox is placed, the blue area gets created BEFORE checkbox detects the click event. As a result, this dynamic DIV intercepts all mouse events before they get to the checkbox.

In order to fix this behavior, when I create DIV for the selected area, I increase start position of the DIV by 10 pixels, so if mouse click happened on top of checkbox with coordinates { x: 5, y: 20 }, then the position of the DIV should be shifted to { x: 15, y: 30 }. In this case, blue area on the screenshot doesn't intercept mouse events and checkboxes work as expected.

enter image description here

Anonymous
  • 1,823
  • 2
  • 35
  • 74
  • 1
    If you have an issue with divs "hiding" each other, then that's not really a Blazor problem: https://stackoverflow.com/questions/3680429/click-through-div-to-underlying-elements – Bennyboy1973 Jul 09 '21 at 19:24