Megabit / Blazorise

Blazorise is a component library built on top of Blazor with support for CSS frameworks like Bootstrap, Tailwind, Bulma, AntDesign, and Material.
https://blazorise.com/
Other
3.26k stars 529 forks source link

Add a TriState feature to the indeterminate checkbox #1917

Closed Jinjinov closed 3 years ago

Jinjinov commented 3 years ago

Is your feature request related to a problem? Please describe.

Now that #1467 is done, I would like for the checkbox to cycle trough unchecked, checked, indeterminate on mouse click

Describe the solution you'd like

Enable three states:

Overwrite @onchange so that bool? goes from false to true and then to null on mouse click

Additional context

Working example: https://blazor.radzen.com/checkbox

stsrki commented 3 years ago

I'm not sure about this feature. It's not really how the native checkbox is working. And if you inspect the Radzen checkbox you will see it is just a custom div with some styling, not a regular input element.

Jinjinov commented 3 years ago

I agree that this is not how a checkbox works, but it is a really useful feature if you want to make an "advanced search with filters" on your website, for example:

search should include all Action movies, it can be a Comedy or not, but exclude any Drama

It doesn't have to be a checkbox, but a control like this can be very useful.

David-Moreira commented 3 years ago

@stsrki this one's already custom right? Maybe we could add it to this one? The indeterminate would be the dot just sitting in the middle of the bar, I think it could actually look quite cool. And then you would have a bridge to also change the style to a custom checkbox if you really wanted I'm guessing. Does this make sense?

image

David-Moreira commented 3 years ago

Also to answer @Jinjinov question, I guess you have two immediate options to solve your problem:

EDIT: I am dumb, disregard the first option. You want to click and be able to set the indeterminate. But if you really need a solution immedtialy, I guess you can still take the second option and see if you can override and implement it yourself I'm guessing. :X

EDIT2: With the second option... maybe try with tracking the last known state and setting the IsIndeterminate flag to true at the correct times. This should theoretically work, right @stsrki ?

stsrki commented 3 years ago

The switch is just a regular checkbox with custom styles. And switching between true, false, and null is not so easy like it seems. We use @onchange which gives you only true or false. And somehow we would need to intercept that event and convert it to null in some cases. And we would also need to intercept a value coming from Parameter when check box is changed from outside. A lot of magic for my taste...

stsrki commented 3 years ago

EDIT2: With the second option... maybe try with tracking the last known state and setting the IsIndeterminate flag to true at the correct times. This should theoretically work, right @stsrki ?

In theory yes. The problem is that the native checkbox has only two states, and on top of that indeterminate overrides everything.

<Check TValue="bool?"
       Checked="true"
       Indeterminate="false">
    1
</Check>
<Check TValue="bool?"
       Checked="false"
       Indeterminate="false">
    2
</Check>
<Check TValue="bool?"
       Checked="true"
       Indeterminate="true">
    3
</Check>
<Check TValue="bool?"
       Checked="false"
       Indeterminate="true">
    4
</Check>

image

I don't think it can be done with a custom component.

David-Moreira commented 3 years ago

I might be wrong but I actually think you can or I am just not seeing the whole picture yet. I'll see if I have time later today to test it out.

Jinjinov commented 3 years ago

I made my own component, for now it will be useful: https://stackoverflow.com/a/66370265/4675770

I am already using it in my project and it is working just as I wanted.

David-Moreira commented 3 years ago

Oh glad you got it working then. :) I was trying something with wrapping the Blazorise Check with an internal queue that tracks the next value and basically just looking at every possible choice, but this block here looks simpler:

Checked = Checked switch
{
    false => true,
    true => null,
    null => false,
};

I don't think the code on that thread handles the Parameter Checked being mutated from outside though. Maybe it should have a custom setter, but you might not need it for your use case eitherway. :)

Jinjinov commented 3 years ago

Yes, doing something like this in Blazorise would be more difficult. Thanks for taking the time to check! :)