Skip to content
Merged
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<Version>9.0.2</Version>
<Version>9.0.3</Version>
</PropertyGroup>

<PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ public partial class SelectCity
[Parameter]
public bool IsMultiple { get; set; }

private string? InputId => $"{Id}_input";

private string? ClassString => CssBuilder.Default("select bb-city")
.AddClass("disabled", IsDisabled)
.AddClassFromAttributes(AdditionalAttributes)
Expand All @@ -42,30 +40,22 @@ private async Task OnClearValue()

private void OnSelectProvince(string province)
{
if (IsMultiple)
if (!IsMultiple)
{
HashSet<string> cities;
if (province == "直辖市")
{
cities = Municipalities;
}
else if (province == "特别行政区")
{
cities = SpecialAdministrativeRegions;
}
else
{
cities = GetCities(province);
}
foreach (var city in cities)
{
if (!_values.Remove(city))
{
_values.Add(city);
}
}
CurrentValue = string.Join(",", _values);
return;
}

HashSet<string> cities = province switch
{
"直辖市" => Municipalities,
"特别行政区" => SpecialAdministrativeRegions,
_ => GetCities(province)
};
foreach (var city in cities.Where(city => !_values.Remove(city)))
{
_values.Add(city);
Comment thread
ArgoZhang marked this conversation as resolved.
Comment thread
ArgoZhang marked this conversation as resolved.
}
CurrentValue = string.Join(",", _values);
}

private void OnSelectCity(string item)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
}

[data-bs-theme="dark"] .dropdown-menu {
--bb-region-body-color: #ddd;
--bb-region-body-color: #c0c4cc;
--bb-region-body-hover-color: #fff;
--bb-region-body-active-color: #fff;
--bb-region-body-hover-bg-color: #495057;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@namespace BootstrapBlazor.Components
@inherits SelectRegionBase
@attribute [JSModuleAutoLoader("./_content/BootstrapBlazor.Region/Components/SelectRegion.razor.js")]

@if (IsShowLabel)
{
<BootstrapLabel required="@Required" for="@InputId" ShowLabelTooltip="ShowLabelTooltip" Value="@DisplayText" />
}
<div @attributes="AdditionalAttributes" id="@Id" class="@ClassString">
<div class="dropdown-toggle" data-bs-toggle="bb.dropdown" data-bs-placement="@PlacementString" data-bs-offset="@OffsetString" data-bs-custom-class="@CustomClassString">
<input type="text" id="@InputId" disabled="@Disabled" readonly placeholder="@PlaceHolder" class="@InputClassString" value="@CurrentValueAsString" />
<span class="@AppendClassString"><i class="@DropdownIcon"></i></span>
</div>
@if (!IsDisabled)
{
<span class="@ClearClassString" @onclick="OnClearValue"><i class="@ClearIcon"></i></span>
}
<div class="dropdown-menu bb-region-body">
<ul>
@foreach (var item in GetProvinces())
{
<li class="@GetActiveClass(item)" @onclick="() => OnSelectProvince(item)">@item</li>
}
</ul>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (c) BootstrapBlazor & Argo Zhang (argo@live.ca). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

namespace BootstrapBlazor.Components;

/// <summary>
/// SelectProvince 组件
/// </summary>
public partial class SelectProvince
{
/// <summary>
/// 获得/设置 是否可多选 默认 false 单选
/// </summary>
[Parameter]
public bool IsMultiple { get; set; }

private string? ClassString => CssBuilder.Default("select bb-province")
.AddClass("disabled", IsDisabled)
.AddClassFromAttributes(AdditionalAttributes)
.Build();

private readonly HashSet<string> _values = [];

private string? GetActiveClass(string item) => _values.Contains(item) || CurrentValue == item ? "active" : null;

private async Task OnClearValue()
{
if (IsMultiple)
{
_values.Clear();
}
CurrentValue = "";

if (OnClearAsync != null)
{
await OnClearAsync();
}
}

private void OnSelectProvince(string item)
{
if (IsMultiple)
{
if (!_values.Remove(item))
{
_values.Add(item);
}
CurrentValue = string.Join(",", _values);
}
else
{
CurrentValue = item;
}
}

private HashSet<string> GetProvinces() => RegionService.GetProvinces();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
.bb-province {
position: relative;
}

.bb-province:not(.disabled):hover .form-select-append {
display: none;
}

.dropdown-menu {
--bs-dropdown-padding-y: 0;
--bb-region-body-color: #495057;
--bb-region-body-hover-bg-color: #e9ecef;
--bb-region-body-active-bg-color: #dee2e6;
--bb-region-body-hover-color: #000;
--bb-region-body-active-color: #000;
--bb-region-body-width: 400px;
--bb-region-body-padding: .5rem;
--bb-region-body-item-padding: 3px 12px;
--bb-region-body-gap: 5px;
}

.dropdown-menu ul {
margin: 0;
padding: 0;
}

.dropdown-menu li {
list-style: none;
transition: background-color .3s linear, color .3s linear;
}

[data-bs-theme="dark"] .dropdown-menu {
--bb-region-body-color: #c0c4cc;
--bb-region-body-hover-color: #fff;
--bb-region-body-active-color: #fff;
--bb-region-body-hover-bg-color: #495057;
--bb-region-body-active-bg-color: #6c757d;
}

.bb-region-body {
padding: var(--bb-region-body-padding);
width: var(--bb-region-body-width);
}

.bb-region-body ul {
display: flex;
flex-wrap: wrap;
gap: var(--bb-region-body-gap);
}

.bb-region-body ul li {
padding: var(--bb-region-body-item-padding);
border-radius: var(--bs-border-radius);
color: var(--bb-region-body-color);
cursor: pointer;
}

.bb-region-body ul li:hover {
background-color: var(--bb-region-body-hover-bg-color);
color: var(--bb-region-body-hover-color);
}

.bb-region-body ul li.active {
background-color: var(--bb-region-body-active-bg-color);
color: var(--bb-region-body-active-color);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ namespace BootstrapBlazor.Components;
/// </summary>
public partial class SelectRegion
{
private string? InputId => $"{Id}_input";

private string? ClassString => CssBuilder.Default("select bb-region")
.AddClass("disabled", IsDisabled)
.AddClassFromAttributes(AdditionalAttributes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
[data-bs-theme="dark"] .dropdown-menu {
--bb-region-header-hover-bg-color: #495057;
--bb-region-header-active-bg-color: #6c757d;
--bb-region-body-color: #ddd;
--bb-region-body-color: #c0c4cc;
--bb-region-body-hover-color: #fff;
--bb-region-body-active-color: #fff;
--bb-region-body-hover-bg-color: #495057;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ public abstract class SelectRegionBase : PopoverSelectBase<string>
.AddClass($"text-danger", IsValid.HasValue && !IsValid.Value)
.Build();

/// <summary>
/// 获得 选择框组件 Id
/// </summary>
protected string InputId => $"{Id}_input";

/// <summary>
/// <inheritdoc/>
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,35 @@ namespace BootstrapBlazor.Components;

class DefaultRegionService : IRegionService
{
private static readonly ConcurrentDictionary<string, HashSet<string>> _citiesCache = new();
private static readonly ConcurrentDictionary<string, HashSet<CountyItem>> _countiesCache = new();
private static readonly ConcurrentDictionary<string, HashSet<string>> _detailCache = new();
private static readonly ConcurrentDictionary<string, HashSet<string>> CitiesCache = new();
private static readonly ConcurrentDictionary<string, HashSet<CountyItem>> CountiesCache = new();
private static readonly ConcurrentDictionary<string, HashSet<string>> DetailCache = new();

private static bool _initialized = false;
private static bool _initialized;

#if NET9_0_OR_GREATER
private static readonly Lock _lock = new();
private static readonly Lock Lock = new();
#else
private static readonly object _lock = new();
#endif

#if NET9_0_OR_GREATER
private static readonly Lock _lockDetail = new();
#else
private static readonly object _lockDetail = new();
private static readonly object Lock = new();
#endif

public HashSet<string> GetProvinces() => Provinces;

public HashSet<string> GetCities(string province)
{
LoadCityData();
return _citiesCache.TryGetValue(province, out var cities) ? cities : [];
return CitiesCache.TryGetValue(province, out var cities) ? cities : [];
}

public HashSet<CountyItem> GetCounties(string city)
{
LoadCityData();
return _countiesCache.TryGetValue(city, out var counties) ? counties : [];
return CountiesCache.TryGetValue(city, out var counties) ? counties : [];
}

public HashSet<string> GetDetails(string countyCode)
{
return _detailCache.GetOrAdd(countyCode, LoadDetailData);
return DetailCache.GetOrAdd(countyCode, LoadDetailData);
}

private static HashSet<string> LoadDetailData(string countyCode)
Expand All @@ -71,7 +65,7 @@ private static void LoadCityData()
{
if (!_initialized)
{
lock (_lock)
lock (Lock)
{
if (!_initialized)
{
Expand Down Expand Up @@ -105,7 +99,7 @@ private static void LoadDataCore(Stream data)

var mem = content.AsMemory();
var code = Trim(mem[0..index].ToString());
var value = Trim(mem[(index + 1)..(mem.Length - 1)].ToString());
var value = Trim(mem[(index + 1)..^1].ToString());

if (code[2..] == "0000")
{
Expand All @@ -117,7 +111,7 @@ private static void LoadDataCore(Stream data)
cities.Add(value);
}

_citiesCache.TryAdd(value, cities);
CitiesCache.TryAdd(value, cities);
counties = null;
continue;
}
Expand All @@ -126,14 +120,14 @@ private static void LoadDataCore(Stream data)
{
cities.Add(value);
counties = [];
_countiesCache.TryAdd(value, counties);
CountiesCache.TryAdd(value, counties);
continue;
}

if (counties == null)
{
counties = [];
_countiesCache.TryAdd(city, counties);
CountiesCache.TryAdd(city, counties);
}

counties.Add(new CountyItem() { Name = value, Code = code });
Expand Down