Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ListComponentBase] maintain consistency between SelectedOption and Value #1149

Merged
merged 2 commits into from
Dec 18, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading