asp.net-coreblazorcolor-picker

Close dialog when clicked outside or using close button


I have color palette dialog appear on click of a button. I am trying to make the color palette close with close button or when clicked anywhere outside the color palette dialog. As there is currently no option to close the palette unless we select one of the colors.

I want the palette to close even if no color is selected 1) either through a close button or 2) When clicked anywhere outside of the dialog.

Color picker code below:


@foreach(var picker in _pickers)
{
     <button class="btn btn-primary me-2" @onclick="() => this.OnOpen(picker)">
        <div style="background-color:@picker.Color" class="buttonColor">&nbsp;</div>
        @picker.Title
    </button>

    <ColorPicker IsOpened="picker.IsOpen" MyColor="@picker.Color" Closed="(value) => this.OnClose(picker, value)"  />
}

@code{
    private List<ColorPickerData> _pickers = new();

    protected override Task OnInitializedAsync()
    {
        _pickers.Add(new() { Title="Picker 1" });
        _pickers.Add(new() { Title="Picker 2" });
        _pickers.Add(new() { Title = "Picker 3" });
        return Task.CompletedTask;
    }

    private Task OnClose(ColorPickerData data, string value)
    {
        data.IsOpen = false;
        data.Color = value;
        return Task.CompletedTask;
    }

    private Task OnOpen(ColorPickerData data)
    {
        data.IsOpen = true;
        return Task.CompletedTask;
    }

    public class ColorPickerData
    { 
        public string Title { get; set; } = "Color Picker";
        public bool IsOpen { get; set; }
        public string Color { get; set; } = "#000000";
    }
}

I tried incorporating @onfocusout="@(() => picker.IsOpen = false;)" in my existing code. But could not get to work. Your input will be helpful. Thank you.


Solution

  • You could try following code to let it close when click empty area:

        @foreach (var picker in _pickers)
        {
            <button class="btn btn-primary me-2" @onclick="() => this.OnOpen(picker)">
                <div style="background-color:@picker.Color" class="buttonColor">&nbsp;</div>
                @picker.Title
            </button>
        <mytag @onclick="()=>this.Close(picker)">
            <BlazorColorPicker.ColorPicker IsOpened="picker.IsOpen" MyColor="@picker.Color" Closed="(value) => this.OnClose(picker, value)" />
        </mytag>
        }
    @code {
    
         ...
    
    
        private Task Close(ColorPickerData data)
        {
            data.IsOpen = false;
            return Task.CompletedTask;
        }
    }
    

    I used BlazorColorPicker.ColorPicker for test. Actually it make the component to close the selector on every click. But it doesn't have negative impact on the normal function.