Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
box-shadow: var(--bb-layout-button-shadow);
transition: opacity .3s linear;
position: fixed;
z-index: 45;
z-index: 1001;
}

::deep .btn-fade:hover {
Expand Down
2 changes: 1 addition & 1 deletion src/BootstrapBlazor.Server/Components/Pages/Coms.razor
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<div class="coms-search">
<div class="row">
<div class="col-12">
<Search @bind-Value="@SearchText" PlaceHolder="@Localizer["Search"]" IsOnInputTrigger="true" IsAutoFocus="true" OnSearch="@OnSearch"></Search>
<Search @bind-Value="@SearchText" PlaceHolder="@Localizer["Search"]" IsTriggerSearchByInput="true" IsAutoFocus="true" OnSearch="@OnSearch"></Search>
</div>
</div>
<div class="coms-search-filter">
Expand Down
21 changes: 17 additions & 4 deletions src/BootstrapBlazor.Server/Components/Samples/Searches.razor
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
@page "/search"
@inject IStringLocalizer<Searches> Localizer
@inject IStringLocalizer<Foo> LocalizerFoo
@inject IOptionsMonitor<WebsiteOptions> WebsiteOption

<h3>@Localizer["SearchesTitle"]</h3>

Expand Down Expand Up @@ -39,10 +41,21 @@
Introduction="@Localizer["SearchesItemTemplateIntro"]"
Name="ItemTemplate">
<Search PlaceHolder="@Localizer["SearchesPlaceHolder"]"
OnGetDisplayText="OnGetDisplayText"
OnSearch="@OnSearchFoo">
<ItemTemplate>
<div>@context.Name</div>
<div>@context.Address</div>
<div class="search-result">
<div class="search-result-avatar">
<img src="@WebsiteOption.CurrentValue.GetAvatarUrl(context.Id)" alt="avatar" />
</div>
<div class="search-result-main">
<div class="search-result-name">@context.Name</div>
<div class="search-result-address">@context.Address</div>
</div>
<div class="search-result-circle">
<Circle Value="@context.Count" Color="Color.Info" StrokeWidth="4" Width="60" />
</div>
</div>
</ItemTemplate>
</Search>
</DemoBlock>
Expand All @@ -51,7 +64,7 @@
Introduction="@Localizer["SearchesKeyboardsIntro"]"
Name="keyboards">
<Search PlaceHolder="@Localizer["SearchesPlaceHolder"]"
IsOnInputTrigger="false"
IsTriggerSearchByInput="false"
OnSearch="@OnKeyboardSearch" />
<ConsoleLogger @ref="KeyboardLogger" />
</DemoBlock>
Expand All @@ -60,7 +73,7 @@
Introduction="@Localizer["SearchesValidateFormIntro"]"
Name="ValidateForm">
<ValidateForm Model="@Model">
<Search IsOnInputTrigger="true" @bind-Value="Model.Name" />
<Search @bind-Value="Model.Name" />
</ValidateForm>
</DemoBlock>

Expand Down
48 changes: 14 additions & 34 deletions src/BootstrapBlazor.Server/Components/Samples/Searches.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,21 @@ private Task<IEnumerable<string>> OnKeyboardSearch(string searchText)
return Task.FromResult<IEnumerable<string>>([$"{searchText}1", $"{searchText}12", $"{searchText}123"]);
}

private Foo Model { get; set; } = new Foo() { Name = "" };
private Foo Model { get; } = new() { Name = "" };

private static async Task<IEnumerable<Foo>> OnSearchFoo(string searchText)
private string? OnGetDisplayText(Foo foo) => foo.Name;

private async Task<IEnumerable<Foo>> OnSearchFoo(string searchText)
{
// 模拟异步延时
await Task.Delay(100);
return Enumerable.Range(1, 10).Select(i => new Foo() { Name = $"{searchText}-{i}", Address = $"Address - 10{i}" }).ToList();
return Enumerable.Range(1, 10).Select(i => new Foo()
{
Id = i,
Name = LocalizerFoo["Foo.Name", $"{i:d4}"],
Address = LocalizerFoo["Foo.Address", $"{Random.Shared.Next(1000, 2000)}"],
Count = Random.Shared.Next(1, 100)
}).ToList();
}

/// <summary>
Expand All @@ -66,20 +75,6 @@ private static async Task<IEnumerable<Foo>> OnSearchFoo(string searchText)
/// <returns></returns>
private AttributeItem[] GetAttributes() =>
[
new() {
Name = "ChildContent",
Description = Localizer["SearchesChildContent"],
Type = "RenderFragment",
ValueList = " — ",
DefaultValue = " — "
},
new() {
Name = "Items",
Description = Localizer["SearchesItems"],
Type = "IEnumerable<string>",
ValueList = " — ",
DefaultValue = " — "
},
new() {
Name = "NoDataTip",
Description = Localizer["SearchesNoDataTip"],
Expand Down Expand Up @@ -123,13 +118,6 @@ private AttributeItem[] GetAttributes() =>
ValueList = " — ",
DefaultValue = "Primary"
},
new() {
Name = "IsLikeMatch",
Description = Localizer["SearchesIsLikeMatch"],
Type = "bool",
ValueList = "true|false",
DefaultValue = "false"
},
new() {
Name = "IsAutoFocus",
Description = Localizer["SearchesIsAutoFocus"],
Expand All @@ -145,21 +133,13 @@ private AttributeItem[] GetAttributes() =>
DefaultValue = "false"
},
new() {
Name = "IsOnInputTrigger",
Description = Localizer["SearchesIsOnInputTrigger"],
Name = "IsTriggerSearchByInput",
Description = Localizer["SearchesIsTriggerSearchByInput"],
Type = "bool",
ValueList = "true|false",
DefaultValue = "false"
},
new()
{
Name = "IgnoreCase",
Description = Localizer["SearchesIgnoreCase"],
Type = "bool",
ValueList = "true|false",
DefaultValue = "true"
},
new()
{
Name = "ShowClearButton",
Description = Localizer["SearchesShowClearButton"],
Expand Down
31 changes: 31 additions & 0 deletions src/BootstrapBlazor.Server/Components/Samples/Searches.razor.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.search-result {
border: solid 1px var(--bs-boder-color);
display: flex;
border-radius: 10px;
padding: .5rem;
border: 1px dashed var(--bs-border-color);
}

.search-result-avatar {
flex-basis: 60px;
border-radius: 10px;
border: 2px solid var(--bb-primary-color);
overflow: hidden;
margin-inline-end: 1rem;
}

.search-result-avatar img {
width: 100%;
}

.search-result-main {
flex-grow: 1;
width: 1%;
min-width: 0;
}

.search-result-address {
margin-top: .25rem;
font-size: 86%;
color: #c0c4cc;
}
12 changes: 5 additions & 7 deletions src/BootstrapBlazor.Server/Locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -4182,26 +4182,24 @@
"SearchesDisplayButtonTitle": "The Empty button is displayed",
"SearchesDisplayButtonIntro": "Control whether the Empty button is displayed by setting the <code>ShowClearButton</code> parameter",
"SearchesKeyboardsTitle": "Keyboard input instant search",
"SearchesKeyboardsIntro": "Control whether search operations are performed in real time by setting <code>the IsOnInputTrigger</code> parameter",
"SearchesKeyboardsIntro": "Control whether search operations are performed in real time by setting <code>IsTriggerSearchByInput</code> parameter",
"SearchesValidateFormTitle": "ValidateForm",
"SearchesValidateFormIntro": "Inside <code>ValidateForm</code>",
"SearchesChildContent": "Content",
"SearchesItems": "Data source",
"SearchesNoDataTip": "Auto-complete data prompts when there is no match",
"SearchesNoDataTipDefaultValue": "No matching data",
"SearchesButtonLoadingIcon": "Searching for button icon",
"SearchesClearButtonIcon": "Clear the button color",
"SearchesClearButtonText": "Empty the button text",
"SearchesClearButtonColor": "Clear the button color",
"SearchesButtonColor": "Search for button color",
"SearchesIsLikeMatch": "Whether fuzzy matching is turned on",
"SearchesIsAutoFocus": "Whether to get the focus automatically",
"SearchesIsAutoClearAfterSearch": "Click Search to automatically empty the search box",
"SearchesIsOnInputTrigger": "Whether the search mode is triggered by input, it is triggered by clicking the search button by default",
"SearchesIgnoreCase": "Whether case is ignored when matching",
"SearchesIsTriggerSearchByInput": "Whether the search mode is triggered by input, it is triggered by clicking the search button by default",
"SearchesShowClearButton": "Whether the Clear button is displayed",
"SearchesOnSearch": "Call back this delegate when you click Search",
"SearchesOnClear": "Click Recall this order when emptying"
"SearchesOnClear": "Click Recall this order when emptying",
"SearchesItemTemplateTitle": "Item Template",
"SearchesItemTemplateIntro": "By setting <code>ItemTemplate</code> and matching generic data, you can achieve any desired effect. In this example, by searching for any keyword, the backend calls any third-party search results and displays them. After selecting the search item, you can handle it yourself through the <code>OnSelectedItemChanged</code> callback method"
},
"BootstrapBlazor.Server.Components.Samples.Titles": {
"Title": "Title",
Expand Down
12 changes: 5 additions & 7 deletions src/BootstrapBlazor.Server/Locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -4182,26 +4182,24 @@
"SearchesDisplayButtonTitle": "显示清空按钮",
"SearchesDisplayButtonIntro": "通过设置 <code>ShowClearButton</code> 参数控制是否显示清空按钮",
"SearchesKeyboardsTitle": "键盘输入即时搜索",
"SearchesKeyboardsIntro": "通过设置 <code>IsOnInputTrigger</code> 参数控制是否实时进行搜索操作",
"SearchesKeyboardsIntro": "通过设置 <code>IsTriggerSearchByInput</code> 参数控制是否实时进行搜索操作",
"SearchesValidateFormTitle": "验证表单内使用",
"SearchesValidateFormIntro": "内置于 <code>ValidateForm</code> 使用,输入中文时不会多次触发搜索功能",
"SearchesChildContent": "内容",
"SearchesItems": "数据源",
"SearchesNoDataTip": "自动完成数据无匹配项时提示信息",
"SearchesNoDataTipDefaultValue": "无匹配数据",
"SearchesButtonLoadingIcon": "正在搜索按钮图标",
"SearchesClearButtonIcon": "清空按钮颜色",
"SearchesClearButtonText": "清空按钮文本",
"SearchesClearButtonColor": "清空按钮颜色",
"SearchesButtonColor": "搜索按钮颜色",
"SearchesIsLikeMatch": "是否开启模糊匹配",
"SearchesIsAutoFocus": "是否自动获得焦点",
"SearchesIsAutoClearAfterSearch": "点击搜索后是否自动清空搜索框",
"SearchesIsOnInputTrigger": "搜索模式是否为输入即触发,默认点击搜索按钮触发",
"SearchesIgnoreCase": "匹配时是否忽略大小写",
"SearchesIsTriggerSearchByInput": "搜索模式是否为输入即触发,默认点击搜索按钮触发",
"SearchesShowClearButton": "是否显示清除按钮",
"SearchesOnSearch": "点击搜索时回调此委托",
"SearchesOnClear": "点击清空时回调此委托"
"SearchesOnClear": "点击清空时回调此委托",
"SearchesItemTemplateTitle": "模板",
"SearchesItemTemplateIntro": "通过设置 <code>ItemTemplate</code> 配合泛型数据可以做出自己想要的任何效果,本例中通过搜索任意关键字,后台调用任意第三方搜索结果并且进行展示,选中搜索项后通过 <code>OnSelectedItemChanged</code> 回调方法可以自行处理"
},
"BootstrapBlazor.Server.Components.Samples.Titles": {
"Title": "Title 网站标题",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ public partial class AutoComplete
[Parameter]
public bool ShowDropdownListOnFocus { get; set; } = true;

/// <summary>
/// 获得/设置 是否显示无匹配数据选项 默认 true 显示
/// </summary>
[Parameter]
public bool ShowNoDataTip { get; set; } = true;

/// <summary>
/// IStringLocalizer 服务实例
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export function init(id, invoke) {
}

el.classList.add('is-loading');
await invoke.invokeMethodAsync('TriggerOnChange', v, useInput);
await invoke.invokeMethodAsync('TriggerOnChange', v);
el.classList.remove('is-loading');
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,6 @@ public abstract class PopoverCompleteBase<TValue> : BootstrapInputBase<TValue>,
[NotNull]
public string? NoDataTip { get; set; }

/// <summary>
/// 获得/设置 是否显示无匹配数据选项 默认 true 显示
/// </summary>
[Parameter]
[NotNull]
public bool ShowNoDataTip { get; set; } = true;

/// <summary>
/// <inheritdoc/>
/// </summary>
Expand Down
6 changes: 6 additions & 0 deletions src/BootstrapBlazor/Components/AutoFill/AutoFill.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ public partial class AutoFill<TValue>
[Parameter]
public Func<string, Task<IEnumerable<TValue>>>? OnCustomFilter { get; set; }

/// <summary>
/// 获得/设置 是否显示无匹配数据选项 默认 true 显示
/// </summary>
[Parameter]
public bool ShowNoDataTip { get; set; } = true;

/// <summary>
/// 获得/设置 候选项模板 默认 null
/// </summary>
Expand Down
11 changes: 6 additions & 5 deletions src/BootstrapBlazor/Components/Search/Search.razor
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,22 @@
<input @attributes="AdditionalAttributes" id="@InputId" class="@ClassName" autocomplete="off" type="text"
data-bs-toggle="@ToggleString" data-bs-placement="@PlacementString"
data-bs-offset="@OffsetString" data-bs-custom-class="@CustomClassString"
data-bb-auto-dropdown-focus="@ShowDropdownListOnFocusString"
data-bb-skip-esc="@SkipEscString" data-bb-skip-enter="@SkipEnterString"
data-bb-scroll-behavior="@ScrollIntoViewBehaviorString"
data-bb-input="@UseInputString"
value="@CurrentValueAsString"
value="@_displayText"
placeholder="@PlaceHolder" disabled="@Disabled" @ref="FocusElement" />
@if (ShowClearButton)
{
<Button Color="ClearButtonColor" Text="@ClearButtonText" Icon="@ClearButtonIcon" OnClick="OnClearClick" aria-label="Clear" />
<Button Color="ClearButtonColor" Text="@ClearButtonText" Icon="@ClearButtonIcon" OnClick="OnClearClick" aria-label="Clear"></Button>
}
<Button Color="SearchButtonColor" Text="@SearchButtonText" Icon="@ButtonIcon" OnClick="OnSearchClick" aria-label="Search" />
<Button Color="SearchButtonColor" Text="@SearchButtonText" Icon="@ButtonIcon" OnClick="OnSearchClick" aria-label="Search"></Button>
</div>
<ul class="dropdown-menu">
@foreach (var item in FilterItems)
{
<li class="dropdown-item">
<li class="dropdown-item" @onclick="() => OnClickItem(item)">
@if (ItemTemplate != null)
{
@ItemTemplate(item)
Expand All @@ -32,7 +33,7 @@
}
</li>
}
@if (ShowNoDataTip && FilterItems.Count == 0)
@if (FilterItems.Count == 0)
{
<li class="dropdown-item">@NoDataTip</li>
}
Expand Down
Loading
Loading