Skip to content

Commit

Permalink
ListComponentBase<TOption>, maintain consistency between SelectedOpti…
Browse files Browse the repository at this point in the history
…on and Value when Multiple is false (#1149)

This commit ensures that `SelectedOption` and `Value` consistently reflect each other. When `SelectedOption` is updated, `Value` is adjusted to maintain coherence, and conversely, changes to `Value` are reflected in the corresponding adjustment of `SelectedOption`.
This fixes #983

Co-authored-by: La Minh Phuc <[email protected]>
Co-authored-by: Vincent Baaij <[email protected]>
  • Loading branch information
3 people authored Dec 18, 2023
1 parent 940efee commit b7ad573
Showing 1 changed file with 78 additions and 2 deletions.
80 changes: 78 additions & 2 deletions src/Core/Components/List/ListComponentBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public abstract class ListComponentBase<TOption> : FluentComponentBase where TOp
{
private bool _multiple = false;
private List<TOption> _selectedOptions = [];
private TOption? _currentSelectedOption;

// We cascade the InternalListContext to descendants, which in turn call it to add themselves to the options list
internal InternalListContext<TOption> _internalListContext;
Expand Down Expand Up @@ -203,6 +204,81 @@ public ListComponentBase()
OptionValue = (item) => OptionText.Invoke(item) ?? item?.ToString() ?? null;
}

public override async Task SetParametersAsync(ParameterView parameters)
{
parameters.SetParameterProperties(this);

if (!Multiple)
{
bool isSetSelectedOption = false, isSetValue = false;
TOption? newSelectedOption = default;
string? newValue = null;

foreach (var parameter in parameters)
{
switch (parameter.Name)
{
case nameof(SelectedOption):
isSetSelectedOption = true;
newSelectedOption = (TOption?)parameter.Value;
break;
case nameof(Value):
isSetValue = true;
newValue = (string?)parameter.Value;
break;
default:
break;
}
}

if (isSetSelectedOption && !Equals(_currentSelectedOption, newSelectedOption))
{
if (Items != null)
{
if (Items.Contains(newSelectedOption))
{
_currentSelectedOption = newSelectedOption;
}
else
{
// If the selected option is not in the list of items, reset the selected option
_currentSelectedOption = SelectedOption = default;
await SelectedOptionChanged.InvokeAsync(SelectedOption);
}
}
else
{
// If Items is null, we don't know if the selected option is in the list of items, so we just set it
_currentSelectedOption = newSelectedOption;
}

Value = GetOptionValue(_currentSelectedOption);
await ValueChanged.InvokeAsync(Value);
}
else if (isSetValue && Items != null && GetOptionValue(_currentSelectedOption) != newValue)
{
newSelectedOption = Items.FirstOrDefault(item => GetOptionValue(item) == newValue);

if (newSelectedOption != null)
{
_currentSelectedOption = SelectedOption = newSelectedOption;
}
else
{
// If the selected option is not in the list of items, reset the selected option
_currentSelectedOption = SelectedOption = default;
Value = null;
await ValueChanged.InvokeAsync(Value);
}

await SelectedOptionChanged.InvokeAsync(SelectedOption);

}
}

await base.SetParametersAsync(ParameterView.Empty);
}

protected override void OnInitialized()
{
if (_multiple != Multiple)
Expand Down Expand Up @@ -261,7 +337,7 @@ protected override void OnParametersSet()
}
}


}

/// <summary />
Expand Down Expand Up @@ -405,7 +481,7 @@ protected virtual async Task RaiseChangedEventsAsync()
}
if (ValueChanged.HasDelegate)
{
await ValueChanged.InvokeAsync(InternalValue);
await ValueChanged.InvokeAsync(InternalValue);
}
StateHasChanged();
}
Expand Down

0 comments on commit b7ad573

Please sign in to comment.