2020-06-14 18:54:14 +08:00
|
|
|
|
using System;
|
2020-11-27 13:13:26 +08:00
|
|
|
|
using System.Linq;
|
2020-06-14 18:54:14 +08:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Microsoft.AspNetCore.Components;
|
2020-11-27 13:13:26 +08:00
|
|
|
|
using AntDesign.Select.Internal;
|
2021-02-04 23:40:47 +08:00
|
|
|
|
using System.Globalization;
|
2020-06-14 18:54:14 +08:00
|
|
|
|
|
|
|
|
|
namespace AntDesign
|
|
|
|
|
{
|
2020-11-27 13:13:26 +08:00
|
|
|
|
public partial class SelectOption<TItemValue, TItem>
|
2020-06-14 18:54:14 +08:00
|
|
|
|
{
|
2020-11-27 13:13:26 +08:00
|
|
|
|
private const string ClassPrefix = "ant-select-item-option";
|
2020-09-09 22:12:12 +08:00
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
# region Parameters
|
2021-07-28 22:40:37 +08:00
|
|
|
|
[CascadingParameter(Name = "InternalId")] internal Guid InternalId { get; set; }
|
2020-11-27 13:13:26 +08:00
|
|
|
|
[CascadingParameter(Name = "ItemTemplate")] internal RenderFragment<TItem> ItemTemplate { get; set; }
|
2021-07-28 22:40:37 +08:00
|
|
|
|
[CascadingParameter(Name = "Model")] internal SelectOptionItem<TItemValue, TItem> Model { get; set; }
|
2020-11-27 13:13:26 +08:00
|
|
|
|
[CascadingParameter] internal Select<TItemValue, TItem> SelectParent { get; set; }
|
2020-11-28 10:02:35 +08:00
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
/// <summary>
|
2021-07-28 22:40:37 +08:00
|
|
|
|
/// Disable this option
|
2020-11-27 13:13:26 +08:00
|
|
|
|
/// The parameter should only be used if the SelectOption was created directly.
|
|
|
|
|
/// </summary>
|
2020-11-28 10:02:35 +08:00
|
|
|
|
[Parameter]
|
2021-07-28 22:40:37 +08:00
|
|
|
|
public bool Disabled
|
2020-11-27 13:13:26 +08:00
|
|
|
|
{
|
2021-07-28 22:40:37 +08:00
|
|
|
|
get => _disabled;
|
2020-11-27 13:13:26 +08:00
|
|
|
|
set
|
|
|
|
|
{
|
2021-07-28 22:40:37 +08:00
|
|
|
|
if (_disabled != value)
|
2020-11-27 13:13:26 +08:00
|
|
|
|
{
|
2021-07-28 22:40:37 +08:00
|
|
|
|
_disabled = value;
|
|
|
|
|
|
|
|
|
|
if (Model != null)
|
|
|
|
|
Model.IsDisabled = value;
|
2020-11-27 13:13:26 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-09 22:12:12 +08:00
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
/// <summary>
|
2021-07-28 22:40:37 +08:00
|
|
|
|
/// Label of Select after selecting this Option
|
2020-11-27 13:13:26 +08:00
|
|
|
|
/// The parameter should only be used if the SelectOption was created directly.
|
|
|
|
|
/// </summary>
|
2020-11-28 10:02:35 +08:00
|
|
|
|
[Parameter]
|
2021-07-28 22:40:37 +08:00
|
|
|
|
public string Label
|
2020-11-27 13:13:26 +08:00
|
|
|
|
{
|
2021-07-28 22:40:37 +08:00
|
|
|
|
get => _label;
|
2020-11-27 13:13:26 +08:00
|
|
|
|
set
|
|
|
|
|
{
|
2021-07-28 22:40:37 +08:00
|
|
|
|
if (_label != value)
|
2020-11-27 13:13:26 +08:00
|
|
|
|
{
|
2021-07-28 22:40:37 +08:00
|
|
|
|
_label = value;
|
|
|
|
|
StateHasChanged();
|
2020-11-27 13:13:26 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-09 22:12:12 +08:00
|
|
|
|
|
2021-07-28 22:40:37 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Value of Select after selecting this Option
|
|
|
|
|
/// The parameter should only be used if the SelectOption was created directly.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Parameter] public TItemValue Value { get; set; }
|
|
|
|
|
|
2020-09-09 22:12:12 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
# region Properties
|
|
|
|
|
private string _label = string.Empty;
|
|
|
|
|
private bool _disabled;
|
2021-02-04 23:40:47 +08:00
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
private bool _isSelected;
|
2020-11-28 10:02:35 +08:00
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
internal bool IsSelected
|
2020-06-14 18:54:14 +08:00
|
|
|
|
{
|
2020-11-27 13:13:26 +08:00
|
|
|
|
get => _isSelected;
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (_isSelected != value)
|
|
|
|
|
{
|
|
|
|
|
_isSelected = value;
|
|
|
|
|
StateHasChanged();
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-06-14 18:54:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
private bool _isDisabled;
|
2020-11-28 10:02:35 +08:00
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
internal bool IsDisabled
|
|
|
|
|
{
|
|
|
|
|
get => _isDisabled;
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (_isDisabled != value)
|
|
|
|
|
{
|
|
|
|
|
_isDisabled = value;
|
|
|
|
|
StateHasChanged();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-10-25 14:59:10 +08:00
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
private bool _isHidden;
|
2020-11-28 10:02:35 +08:00
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
internal bool IsHidden
|
2020-06-14 18:54:14 +08:00
|
|
|
|
{
|
2020-11-27 13:13:26 +08:00
|
|
|
|
get => _isHidden;
|
|
|
|
|
set
|
2020-06-14 18:54:14 +08:00
|
|
|
|
{
|
2020-11-27 13:13:26 +08:00
|
|
|
|
if (_isHidden != value)
|
2020-06-14 18:54:14 +08:00
|
|
|
|
{
|
2020-11-27 13:13:26 +08:00
|
|
|
|
_isHidden = value;
|
|
|
|
|
StateHasChanged();
|
2020-06-14 18:54:14 +08:00
|
|
|
|
}
|
2020-11-27 13:13:26 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-10-25 14:59:10 +08:00
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
private bool _isActive;
|
2020-11-28 10:02:35 +08:00
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
internal bool IsActive
|
|
|
|
|
{
|
|
|
|
|
get => _isActive;
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (_isActive != value)
|
2020-06-14 18:54:14 +08:00
|
|
|
|
{
|
2020-11-27 13:13:26 +08:00
|
|
|
|
_isActive = value;
|
|
|
|
|
StateHasChanged();
|
2020-06-14 18:54:14 +08:00
|
|
|
|
}
|
2020-11-27 13:13:26 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-10-25 14:59:10 +08:00
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
private string _internalLabel = string.Empty;
|
2020-11-28 10:02:35 +08:00
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
internal string InternalLabel
|
|
|
|
|
{
|
|
|
|
|
get => _internalLabel;
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (_internalLabel != value)
|
|
|
|
|
{
|
|
|
|
|
_internalLabel = value;
|
|
|
|
|
StateHasChanged();
|
|
|
|
|
}
|
2020-06-14 18:54:14 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
private string _groupName = string.Empty;
|
2020-11-28 10:02:35 +08:00
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
internal string GroupName
|
2020-07-21 23:48:43 +08:00
|
|
|
|
{
|
2020-11-27 13:13:26 +08:00
|
|
|
|
get => _groupName;
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (_groupName != value)
|
|
|
|
|
{
|
|
|
|
|
_groupName = value;
|
|
|
|
|
StateHasChanged();
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-07-21 23:48:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
2020-09-09 22:12:12 +08:00
|
|
|
|
protected override async Task OnInitializedAsync()
|
2020-06-14 18:54:14 +08:00
|
|
|
|
{
|
2021-09-05 18:13:38 +08:00
|
|
|
|
bool isAlreadySelected = false;
|
2020-11-27 13:13:26 +08:00
|
|
|
|
if (SelectParent.SelectOptions == null)
|
|
|
|
|
{
|
2020-11-28 10:02:35 +08:00
|
|
|
|
// The SelectOptionItem was already created, now only the SelectOption has to be
|
2020-11-27 13:13:26 +08:00
|
|
|
|
// bound to the SelectOptionItem.
|
|
|
|
|
var item = SelectParent.SelectOptionItems.First(x => x.InternalId == InternalId);
|
|
|
|
|
item.ChildComponent = this;
|
|
|
|
|
}
|
2021-02-04 23:40:47 +08:00
|
|
|
|
else if (Model is not null)
|
|
|
|
|
{
|
|
|
|
|
InternalId = Model.InternalId;
|
|
|
|
|
Label = Model.Label;
|
|
|
|
|
IsDisabled = Model.IsDisabled;
|
|
|
|
|
GroupName = Model.GroupName;
|
|
|
|
|
Value = Model.Value;
|
|
|
|
|
Model.ChildComponent = this;
|
2021-09-05 18:13:38 +08:00
|
|
|
|
isAlreadySelected = IsAlreadySelected(Model);
|
2021-02-04 23:40:47 +08:00
|
|
|
|
}
|
2021-09-05 18:13:38 +08:00
|
|
|
|
else
|
2020-11-27 13:13:26 +08:00
|
|
|
|
{
|
|
|
|
|
// The SelectOption was not created by using a DataSource, a SelectOptionItem must be created.
|
|
|
|
|
InternalId = Guid.NewGuid();
|
|
|
|
|
|
|
|
|
|
var newSelectOptionItem = new SelectOptionItem<TItemValue, TItem>()
|
|
|
|
|
{
|
|
|
|
|
InternalId = InternalId,
|
|
|
|
|
Label = Label,
|
|
|
|
|
IsDisabled = Disabled,
|
|
|
|
|
GroupName = _groupName,
|
|
|
|
|
Value = Value,
|
2021-05-06 13:00:16 +08:00
|
|
|
|
Item = THelper.ChangeType<TItem>(Value, CultureInfo.CurrentCulture),
|
2020-11-27 13:13:26 +08:00
|
|
|
|
ChildComponent = this
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
SelectParent.SelectOptionItems.Add(newSelectOptionItem);
|
2021-09-05 18:13:38 +08:00
|
|
|
|
isAlreadySelected = IsAlreadySelected(newSelectOptionItem);
|
2020-11-27 13:13:26 +08:00
|
|
|
|
}
|
2020-09-09 22:12:12 +08:00
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
SetClassMap();
|
2020-09-09 22:12:12 +08:00
|
|
|
|
await base.OnInitializedAsync();
|
2021-09-05 18:13:38 +08:00
|
|
|
|
if (isAlreadySelected)
|
|
|
|
|
{
|
|
|
|
|
await SelectParent.ProcessSelectedSelectOptions();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool IsAlreadySelected(SelectOptionItem<TItemValue, TItem> selectOption)
|
|
|
|
|
{
|
|
|
|
|
if (SelectParent.Mode == "default")
|
|
|
|
|
{
|
|
|
|
|
return selectOption.Value.Equals(SelectParent.Value) || selectOption.Value.Equals(SelectParent.LastValueBeforeReset);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return SelectParent.Values is null || SelectParent.Values.Contains(selectOption.Value);
|
|
|
|
|
}
|
2020-09-09 22:12:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
protected void SetClassMap()
|
2020-09-09 22:12:12 +08:00
|
|
|
|
{
|
2020-11-27 13:13:26 +08:00
|
|
|
|
ClassMapper.Clear()
|
|
|
|
|
.Add("ant-select-item")
|
|
|
|
|
.Add(ClassPrefix)
|
|
|
|
|
.If($"{ClassPrefix}-disabled", () => IsDisabled)
|
|
|
|
|
.If($"{ClassPrefix}-selected", () => IsSelected)
|
|
|
|
|
.If($"{ClassPrefix}-active", () => IsActive)
|
|
|
|
|
.If($"{ClassPrefix}-grouped", () => SelectParent.IsGroupingEnabled);
|
|
|
|
|
|
|
|
|
|
StateHasChanged();
|
2020-06-14 18:54:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
protected string InnerStyle
|
2020-06-14 18:54:14 +08:00
|
|
|
|
{
|
2020-11-27 13:13:26 +08:00
|
|
|
|
get
|
2020-06-14 18:54:14 +08:00
|
|
|
|
{
|
2020-11-27 13:13:26 +08:00
|
|
|
|
if (!IsHidden)
|
|
|
|
|
return Style;
|
|
|
|
|
|
|
|
|
|
return Style + ";display:none";
|
2020-06-14 18:54:14 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
protected async Task OnClick(EventArgs _)
|
2020-06-14 18:54:14 +08:00
|
|
|
|
{
|
2020-11-27 13:13:26 +08:00
|
|
|
|
if (!IsDisabled)
|
2020-06-14 18:54:14 +08:00
|
|
|
|
{
|
2020-11-27 13:13:26 +08:00
|
|
|
|
await SelectParent.SetValueAsync(Model);
|
2020-09-09 22:12:12 +08:00
|
|
|
|
|
|
|
|
|
if (SelectParent.SelectMode == SelectMode.Default)
|
|
|
|
|
{
|
2020-11-27 13:13:26 +08:00
|
|
|
|
await SelectParent.CloseAsync();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
await SelectParent.UpdateOverlayPositionAsync();
|
2020-09-09 22:12:12 +08:00
|
|
|
|
}
|
2020-06-14 18:54:14 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
protected void OnMouseEnter()
|
2020-06-14 18:54:14 +08:00
|
|
|
|
{
|
2021-02-04 23:40:47 +08:00
|
|
|
|
SelectParent.ActiveOption = Model;
|
2020-06-14 18:54:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
protected override void Dispose(bool disposing)
|
2020-09-09 22:12:12 +08:00
|
|
|
|
{
|
2020-11-28 10:02:35 +08:00
|
|
|
|
if (SelectParent?.SelectOptions != null)
|
2020-09-09 22:12:12 +08:00
|
|
|
|
{
|
2021-07-23 22:48:14 +08:00
|
|
|
|
// The SelectOptionItem must be explicitly removed if the SelectOption was not created using the DataSource .
|
|
|
|
|
var selectOptionItem = SelectParent.SelectOptionItems
|
|
|
|
|
.FirstOrDefault(x => x.InternalId == InternalId && !x.IsSelected);
|
2021-02-04 23:40:47 +08:00
|
|
|
|
if (selectOptionItem is not null)
|
|
|
|
|
SelectParent.SelectOptionItems.Remove(selectOptionItem);
|
2020-09-09 22:12:12 +08:00
|
|
|
|
}
|
2020-06-14 18:54:14 +08:00
|
|
|
|
|
2020-11-27 13:13:26 +08:00
|
|
|
|
base.Dispose(disposing);
|
2020-09-09 22:12:12 +08:00
|
|
|
|
}
|
2020-06-14 18:54:14 +08:00
|
|
|
|
}
|
|
|
|
|
}
|