Blazor 그리드 검색 필터
Blazor Grid의 Ignite UI for Blazor Search Filter 기능은 데이터 컬렉션에서 값을 찾는 프로세스를 가능하게 합니다. 이 기능을 설정하는 것을 더 쉽게 만들었으며 검색 입력 상자, 버튼, 키보드 탐색 및 기타 유용한 기능으로 구현하여 더욱 나은 사용자 경험을 제공할 수 있습니다. 브라우저는 기본적으로 콘텐츠 검색 기능을 제공하지만 대부분의 경우 IgbGrid
보기에서 벗어난 열과 행을 가상화합니다. 이러한 경우 네이티브 브라우저 검색은 DOM의 일부가 아니기 때문에 가상화된 셀에서 데이터를 검색할 수 없습니다. Blazor Material 테이블 기반 그리드를 확장했습니다. 검색 API 이를 통해 검색할 수 있습니다. 가상화된 콘텐츠 의 IgbGrid
.
すぐに使用できる機能のフルセット は、ページング、ソート、フィルタリング、編集、グループ化から行と列の仮想化まで、あらゆる機能をカバーします。.NET 開発者には制限はありません。
Blazor Search Example
다음 예는 모든 열과 행을 검색할 수 있는 검색 입력 상자와 각 열에 대한 특정 필터링 옵션이 있는 IgbGrid
나타냅니다.
EXAMPLE
MODULES
DATA
RAZOR
CSS
using System;
using System.Net.Http;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Text;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using IgniteUI.Blazor.Controls;
namespace Infragistics.Samples
{
public class Program
{
public static async Task Main (string [] args )
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app" );
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddIgniteUIBlazor(
typeof (IgbGridModule),
typeof (IgbGridColumnOptionsModule),
typeof (IgbInputModule),
typeof (IgbIconButtonModule),
typeof (IgbIconModule)
);
await builder.Build().RunAsync();
}
}
}
cs コピー using System;
using System.Collections;
using System.Collections.Generic;
namespace Infragistics.Samples
{
public class MarketRecord
{
public string IndustryGroup { get ; set ; }
public string IndustrySector { get ; set ; }
public string SectorType { get ; set ; }
public double KRD { get ; set ; }
public double MarketNotion { get ; set ; }
public string Date { get ; set ; }
}
public class MarketData
{
public static List<MarketRecord> GetData ( )
{
var data = new List<MarketRecord>() {
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Airlines" ,
IndustrySector = "Consumer" ,
KRD = 6E-05 ,
MarketNotion = 47338486.0 ,
SectorType = "PUBLIC"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Insurance" ,
IndustrySector = "Financial" ,
KRD = 1.46433 ,
MarketNotion = 42605156.0 ,
SectorType = "PUBLIC"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Insurance" ,
IndustrySector = "Financial" ,
KRD = 0.0 ,
MarketNotion = 41030865.0 ,
SectorType = "PUBLIC"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Banks" ,
IndustrySector = "Financial" ,
KRD = 6E-05 ,
MarketNotion = 30346443.0 ,
SectorType = "PUBLIC"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Retail" ,
IndustrySector = "Consumer, Cyclical" ,
KRD = 0.20296 ,
MarketNotion = 25111160.0 ,
SectorType = "PUBLIC"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Sovereign" ,
IndustrySector = "Government" ,
KRD = 0.05421 ,
MarketNotion = 23189929.0 ,
SectorType = "US GOVERNMENT"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Municipal" ,
IndustrySector = "Government" ,
KRD = 0.00031 ,
MarketNotion = 19365191.0 ,
SectorType = "FIXED"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Municipal" ,
IndustrySector = "Government" ,
KRD = 0.0 ,
MarketNotion = 16235303.0 ,
SectorType = "FIXED"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Engineering&Construction" ,
IndustrySector = "Industrial" ,
KRD = 0.00087 ,
MarketNotion = 11072448.0 ,
SectorType = "GLOBAL"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Engineering&Construction" ,
IndustrySector = "Industrial" ,
KRD = -0.00063 ,
MarketNotion = 7550053.0 ,
SectorType = "GLOBAL"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Municipal" ,
IndustrySector = "Government" ,
KRD = -1E-05 ,
MarketNotion = 6372222.0 ,
SectorType = "ADJUSTABLE"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Municipal" ,
IndustrySector = "Government" ,
KRD = 0.0 ,
MarketNotion = 5990939.0 ,
SectorType = "FIXED, OID"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Banks" ,
IndustrySector = "Financial" ,
KRD = 2E-05 ,
MarketNotion = 5809637.0 ,
SectorType = "EURO-DOLLAR"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Banks" ,
IndustrySector = "Financial" ,
KRD = 0.00377 ,
MarketNotion = 1435870.0 ,
SectorType = "GLOBAL"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Airlines" ,
IndustrySector = "Consumer" ,
KRD = 6E-05 ,
MarketNotion = 47338486.0 ,
SectorType = "PUBLIC"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Insurance" ,
IndustrySector = "Financial" ,
KRD = 1.46433 ,
MarketNotion = 42605156.0 ,
SectorType = "PUBLIC"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Insurance" ,
IndustrySector = "Financial" ,
KRD = 0.0 ,
MarketNotion = 41030865.0 ,
SectorType = "PUBLIC"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Banks" ,
IndustrySector = "Financial" ,
KRD = 6E-05 ,
MarketNotion = 30346443.0 ,
SectorType = "PUBLIC"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Retail" ,
IndustrySector = "Consumer, Cyclical" ,
KRD = 0.20296 ,
MarketNotion = 25111160.0 ,
SectorType = "PUBLIC"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Sovereign" ,
IndustrySector = "Government" ,
KRD = 0.05421 ,
MarketNotion = 23189929.0 ,
SectorType = "US GOVERNMENT"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Municipal" ,
IndustrySector = "Government" ,
KRD = 0.00031 ,
MarketNotion = 19365191.0 ,
SectorType = "FIXED"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Municipal" ,
IndustrySector = "Government" ,
KRD = 0.0 ,
MarketNotion = 16235303.0 ,
SectorType = "FIXED"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Engineering&Construction" ,
IndustrySector = "Industrial" ,
KRD = 0.00087 ,
MarketNotion = 11072448.0 ,
SectorType = "GLOBAL"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Engineering&Construction" ,
IndustrySector = "Industrial" ,
KRD = -0.00063 ,
MarketNotion = 7550053.0 ,
SectorType = "GLOBAL"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Municipal" ,
IndustrySector = "Government" ,
KRD = -1E-05 ,
MarketNotion = 6372222.0 ,
SectorType = "ADJUSTABLE"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Municipal" ,
IndustrySector = "Government" ,
KRD = 0.0 ,
MarketNotion = 5990939.0 ,
SectorType = "FIXED, OID"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Banks" ,
IndustrySector = "Financial" ,
KRD = 2E-05 ,
MarketNotion = 5809637.0 ,
SectorType = "EURO-DOLLAR"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Banks" ,
IndustrySector = "Financial" ,
KRD = 0.00377 ,
MarketNotion = 1435870.0 ,
SectorType = "GLOBAL"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Airlines" ,
IndustrySector = "Consumer" ,
KRD = 6E-05 ,
MarketNotion = 47338486.0 ,
SectorType = "PUBLIC"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Insurance" ,
IndustrySector = "Financial" ,
KRD = 1.46433 ,
MarketNotion = 42605156.0 ,
SectorType = "PUBLIC"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Insurance" ,
IndustrySector = "Financial" ,
KRD = 0.0 ,
MarketNotion = 41030865.0 ,
SectorType = "PUBLIC"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Banks" ,
IndustrySector = "Financial" ,
KRD = 6E-05 ,
MarketNotion = 30346443.0 ,
SectorType = "PUBLIC"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Retail" ,
IndustrySector = "Consumer, Cyclical" ,
KRD = 0.20296 ,
MarketNotion = 25111160.0 ,
SectorType = "PUBLIC"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Sovereign" ,
IndustrySector = "Government" ,
KRD = 0.05421 ,
MarketNotion = 23189929.0 ,
SectorType = "US GOVERNMENT"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Municipal" ,
IndustrySector = "Government" ,
KRD = 0.00031 ,
MarketNotion = 19365191.0 ,
SectorType = "FIXED"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Municipal" ,
IndustrySector = "Government" ,
KRD = 0.0 ,
MarketNotion = 16235303.0 ,
SectorType = "FIXED"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Engineering&Construction" ,
IndustrySector = "Industrial" ,
KRD = 0.00087 ,
MarketNotion = 11072448.0 ,
SectorType = "GLOBAL"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Engineering&Construction" ,
IndustrySector = "Industrial" ,
KRD = -0.00063 ,
MarketNotion = 7550053.0 ,
SectorType = "GLOBAL"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Municipal" ,
IndustrySector = "Government" ,
KRD = -1E-05 ,
MarketNotion = 6372222.0 ,
SectorType = "ADJUSTABLE"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Municipal" ,
IndustrySector = "Government" ,
KRD = 0.0 ,
MarketNotion = 5990939.0 ,
SectorType = "FIXED, OID"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Banks" ,
IndustrySector = "Financial" ,
KRD = 2E-05 ,
MarketNotion = 5809637.0 ,
SectorType = "EURO-DOLLAR"
},
new MarketRecord() {
Date = "new" ,
IndustryGroup = "Banks" ,
IndustrySector = "Financial" ,
KRD = 0.00377 ,
MarketNotion = 1435870.0 ,
SectorType = "GLOBAL"
}
};
return data;
}
}
}
cs コピー
@using IgniteUI.Blazor.Controls
<style >
.gridSize {
--ig-size: var (--ig-size-small);
}
</style >
<div class ="container vertical" >
@ if (marketData != null )
{
<div style ="margin-bottom: 1rem" >
<IgbInput ValueChanging ="OnValueChanging" Value ="@ searchText " @onkeydown ="OnSearchKeyDown" >
@ if (searchText.Length == 0 )
{
<IgbIcon @ref ="searchIconRef" slot ="prefix" IconName ="search" Collection ="material" / >
}
@ if (searchText.Length > 0 )
{
<IgbIcon slot ="prefix" IconName ="clear" Collection ="material" @onclick ="ClearSearch" / >
}
<div class ="chips" slot ="suffix" >
<IgbChip Selectable =true SelectedChanged ="UpdateCase" >
Case Sensitive
</IgbChip >
<IgbChip Selectable =true SelectedChanged ="UpdateExactSearch" >
Exact Match
</IgbChip >
</div >
<div class ="searchButtons" slot ="suffix" >
<IgbIconButton Variant ="IconButtonVariant.Flat" @onclick ="PrevSearch" >
<IgbIcon IconName ="prev" Collection ="material" / >
</IgbIconButton >
<IgbIconButton Variant ="IconButtonVariant.Flat" @onclick ="NextSearch" >
<IgbIcon IconName ="next" Collection ="material" />
</IgbIconButton >
</div >
</IgbInput >
</div >
<div class ="container vertical" >
<IgbGrid @ref =grid Class ="gridSize" Width ="100%" Height ="100%" AllowFiltering =true AutoGenerate =false Data =marketData >
<IgbColumn Field ="IndustrySector" Header ="Industry Sector" DataType ="GridColumnDataType.String" Sortable =true > </IgbColumn >
<IgbColumn Field ="IndustryGroup" Header ="Industry Group" DataType ="GridColumnDataType.String" Sortable =true > </IgbColumn >
<IgbColumn Field ="SectorType" Header ="Sector Type" DataType ="GridColumnDataType.String" Sortable =true > </IgbColumn >
<IgbColumn Field ="KRD" DataType ="GridColumnDataType.Number" Sortable =true > </IgbColumn >
<IgbColumn Field ="MarketNotion" Header ="Market Notion" DataType ="GridColumnDataType.Number" Sortable =true > </IgbColumn >
</IgbGrid >
</div >
}
</div >
@code {
private List <MarketRecord > marketData;
private IgbGrid grid;
public bool caseSensitive = false ;
public bool exactMatch = false ;
public string searchText = "" ;
private IgbIcon searchIconRef { get ; set ; }
const string searchIcon = " <svg width ='24' height ='24' viewBox ='0 0 24 24' > <path d ='M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z' /> </svg > " ;
const string prevIcon = " <svg width ='24' height ='24' viewBox ='0 0 24 24' > <path d ='M15.41 7.41 14 6l-6 6 6 6 1.41-1.41L10.83 12z' > </path > </svg > " ;
const string nextIcon = " <svg width ='24' height ='24' viewBox ='0 0 24 24' > <path d ='M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z' > </path > </svg > " ;
const string clearIcon = " <svg width ='24' height ='24' viewBox ='0 0 24 24' title ='Clear' > <path d ='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z' > </path > </svg > " ;
protected override void OnInitialized ( )
{
this .marketData = MarketData.GetData();
}
protected override void OnAfterRender (bool firstRender )
{
if (this .searchIconRef != null && firstRender)
{
this .searchIconRef.EnsureReady().ContinueWith(new Action<Task>((e) =>
{
this .searchIconRef.RegisterIconFromTextAsync("search" , searchIcon, "material" );
this .searchIconRef.RegisterIconFromTextAsync("prev" , prevIcon, "material" );
this .searchIconRef.RegisterIconFromTextAsync("next" , nextIcon, "material" );
this .searchIconRef.RegisterIconFromTextAsync("clear" , clearIcon, "material" );
}));
}
}
private void OnSearchKeyDown (KeyboardEventArgs evt )
{
if (evt.Key == "Enter" && !evt.ShiftKey) {
this .grid.FindNextAsync(this .searchText, this .caseSensitive, this .exactMatch);
} else if (evt.Key == "Enter" ) {
this .grid.FindPrevAsync(this .searchText, this .caseSensitive, this .exactMatch);
}
}
public void OnValueChanging (string newValue )
{
this .searchText = newValue;
this .grid.FindNextAsync(this .searchText, this .caseSensitive, this .exactMatch);
}
public void PrevSearch ( )
{
this .grid.FindPrevAsync(this .searchText, this .caseSensitive, this .exactMatch);
}
public void NextSearch ( )
{
this .grid.FindNextAsync(this .searchText, this .caseSensitive, this .exactMatch);
}
public void ClearSearch ( )
{
this .searchText = "" ;
this .grid.ClearSearchAsync();
}
public void UpdateCase (bool selected ) {
this .caseSensitive = selected;
this .grid.FindNextAsync(this .searchText, this .caseSensitive, this .exactMatch);
}
public void UpdateExactSearch (bool selected ) {
this .exactMatch = selected;
this .grid.FindNextAsync(this .searchText, this .caseSensitive, this .exactMatch);
}
}
razor コピー
.gridSize {
--ig-size: var (--ig-size-small);
}
css コピー
Like this sample? Get access to our complete Ignite UI for Blazor toolkit and start building your own apps in minutes. Download it for free.
Blazor Search Usage
Grid Setup
그리드를 생성하고 이를 데이터에 바인딩하는 것부터 시작해 보겠습니다. 또한 우리가 사용할 구성 요소에 대한 몇 가지 사용자 정의 스타일을 추가할 것입니다!
.gridSize {
--ig-size: var (--ig-size-small);
}
css
<IgbGrid @ref =grid Class ="gridSize" Width ="100%" Height ="480px" AllowFiltering =true AutoGenerate =false Data =marketData >
<IgbColumn Field ="IndustrySector" DataType ="GridColumnDataType.String" Sortable =true > </IgbColumn >
<IgbColumn Field ="IndustryGroup" DataType ="GridColumnDataType.String" Sortable =true > </IgbColumn >
<IgbColumn Field ="SectorType" DataType ="GridColumnDataType.String" Sortable =true > </IgbColumn >
<IgbColumn Field ="KRD" DataType ="GridColumnDataType.Number" Sortable =true > </IgbColumn >
<IgbColumn Field ="MarketNotion" DataType ="GridColumnDataType.Number" Sortable =true > </IgbColumn >
</IgbGrid >
@code {
protected override void OnInitialized ( )
{
base .OnInitialized();
this .marketData = MarketData.GetData();
}
}
razor
좋습니다. 이제 IgbGrid
의 검색 API를 준비하겠습니다! 현재 검색된 텍스트를 저장하고 검색이 대소문자를 구분하는지 및/또는 정확한 일치를 기준으로 하는지 여부를 저장하는 데 사용할 수 있는 몇 가지 속성을 만들 수 있습니다.
public string searchText = "";
public bool caseSensitive = false;
public bool exactMatch = false;
razor
이제 검색 입력을 만들어 보겠습니다! SearchText
를 새로 생성된 입력의 Value
속성에 바인딩하고 ValueChanging
이벤트를 구독하면 사용자가 SearchText
수정하는 모든 것을 감지할 수 있습니다. 이를 통해 IgbGrid
의 FindNext
및 FindPrev
메서드를 사용하여 SearchText
의 모든 항목을 강조 표시하고 다음/이전 항목으로 스크롤할 수 있습니다(호출한 메서드에 따라 다름).
FindNext
및 FindPrev
메서드에는 모두 세 가지 인수가 있습니다.
Text
: string (검색하려는 텍스트)
(선택 사항) CaseSensitive
: 부울 (검색 시 대소문자를 구분해야 하는지 여부, 기본값은 false입니다.)
(선택 사항) ExactMatch
: 부울 (정확한 일치로 검색해야 하는지 여부, 기본값은 false입니다.)
정확한 일치로 검색할 때 검색 API는 대소문자 구분도 고려하여 SearchText
와 완전히 일치하는 셀 값만 결과로 강조 표시합니다. 예를 들어 'software ' 및 'Software ' 문자열은 대소문자 구분을 무시하고 정확히 일치합니다.
위의 메소드는 숫자 값(IgbGrid
에 지정된 문자열이 포함된 횟수)을 반환합니다.
<IgbInput ValueChanging ="valueChanging" Value ="@ searchText " />
razor
검색 결과를 자유롭게 검색하고 탐색하기 위해 버튼의 각 클릭 이벤트 핸들러 내에서 FindNext
및 FindPrev
메서드를 호출하여 두 개의 버튼을 만들어 보겠습니다.
<IgbIconButton Variant ="IconButtonVariant.Flat" @onclick ="PrevSearch" >
<IgbIcon IconName ="prev" Collection ="material" / >
</IgbIconButton >
<IgbIconButton Variant ="IconButtonVariant.Flat" @onclick ="NextSearch" >
<IgbIcon IconName ="next" Collection ="material" />
</IgbIconButton >
@code {
private IgbGrid grid;
public void PrevSearch ( )
{
this .grid.FindPrevAsync(this .searchText, this .caseSensitive, this .exactMatch);
}
public void NextSearch ( )
{
this .grid.FindNextAsync(this .searchText, this .caseSensitive, this .exactMatch);
}
}
razor
Add Keyboard Search
또한 사용자가 키보드의 화살표 키와 입력하다 열쇠. 이를 달성하기 위해 우리는 다음을 처리할 수 있습니다. 키다운 입력의 기본 캐럿 이동을 방지하여 검색 입력 이벤트 PreventDefault
메소드를 호출하고 FindNext
/ FindPrev
사용자가 어떤 키를 눌렀는지에 따라 방법이 달라집니다.
또한 사용자가 키보드의 키를 사용하여 결과를 탐색하도록 허용할 수도 있습니다. 입력하다 열쇠. 이를 달성하기 위해 우리는 다음을 처리할 수 있습니다. 키다운 검색 이벤트를 호출하고 FindNext
/ FindPrev
사용자가 눌렀는지 여부에 따른 메서드 옮기다 그것도 아니면 아니지.
<IgbInput ValueChanging ="valueChanging" Value ="@ searchText " @onkeydown ="OnSearchKeyDown" / >
@code {
private void OnSearchKeyDown (KeyboardEventArgs evt )
{
if (evt.Key == "Enter" && !evt.ShiftKey) {
this .grid.FindNextAsync(this .searchText, this .caseSensitive, this .exactMatch);
} else if (evt.Key == "Enter" ) {
this .grid.FindPrevAsync(this .searchText, this .caseSensitive, this .exactMatch);
}
}
}
razor
Case Sensitive and Exact Match
이제 사용자가 검색에서 대소문자를 구분할지 또는 정확히 일치할지 여부를 선택할 수 있도록 하겠습니다. 이를 위해 간단한 선택 가능 Chips
사용하고 SelectedChanged
이벤트에 바인딩하여 사용자가 칩과 상호 작용하는 시기를 결정할 수 있습니다.
<IgbChip Selectable =true SelectedChanged ="UpdateCase" >
Case Sensitive
</IgbChip >
<IgbChip Selectable =true SelectedChanged ="UpdateExactSearch" >
Exact Match
</IgbChip >
@code {
public void UpdateCase (bool selected ) {
this .caseSensitive = selected;
this .grid.FindNextAsync(this .searchText, this .caseSensitive, this .exactMatch);
}
public void UpdateExactSearch (bool selected ) {
this .exactMatch = selected;
this .grid.FindNextAsync(this .searchText, this .caseSensitive, this .exactMatch);
}
}
razor
Persistence
IgbGrid
를 필터링 및 정렬하거나 레코드를 추가 및 제거하려면 어떻게 해야 합니까? 이러한 작업 후에는 현재 검색의 하이라이트가 자동으로 업데이트되어 SearchText
와 일치하는 모든 텍스트에 대해 지속됩니다! 또한 검색은 페이징과 함께 작동하며 IgbGrid
의 PerPage
속성을 변경하여 강조 표시를 유지합니다.
Adding icons
다른 구성 요소 중 일부를 사용하면 풍부한 사용자 인터페이스를 만들고 전체 검색 창의 전반적인 디자인을 개선할 수 있습니다! 검색 입력 왼쪽에는 멋진 검색 또는 삭제 아이콘이 있고, 검색 옵션을 위한 몇 가지 칩이 있으며, 오른쪽에는 탐색을 위한 멋진 잔물결 스타일 버튼과 결합된 일부 머티리얼 디자인 아이콘이 있습니다. 보다 세련된 디자인을 위해 이러한 구성 요소를 입력 그룹 내에 래핑할 수 있습니다.
이를 위해 IgbInput
, IgbIcon
, IgbIconButton
및 IgbChip
모듈을 가져와 보겠습니다.
// eg. Program.cs register the following:
builder.Services.AddIgniteUIBlazor(
typeof(IgbGridModule),
typeof(IgbInputModule),
typeof(IgbIconButtonModule),
typeof(IgbIconModule)
);
razor
@code {
private IgbIcon searchIconRef { get ; set ; }
const string searchIcon = " <svg width ='24' height ='24' viewBox ='0 0 24 24' > <path d ='M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z' /> </svg > " ;
const string prevIcon = " <svg width ='24' height ='24' viewBox ='0 0 24 24' > <path d ='M15.41 7.41 14 6l-6 6 6 6 1.41-1.41L10.83 12z' > </path > </svg > " ;
const string nextIcon = " <svg width ='24' height ='24' viewBox ='0 0 24 24' > <path d ='M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z' > </path > </svg > " ;
const string clearIcon = " <svg width ='24' height ='24' viewBox ='0 0 24 24' title ='Clear' > <path d ='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z' > </path > </svg > " ;
protected override void OnAfterRender (bool firstRender )
{
if (this .searchIconRef != null && firstRender)
{
this .searchIconRef.EnsureReady().ContinueWith(new Action<Task>((e) =>
{
this .searchIconRef.RegisterIconFromTextAsync("search" , searchIcon, "material" );
this .searchIconRef.RegisterIconFromTextAsync("prev" , prevIcon, "material" );
this .searchIconRef.RegisterIconFromTextAsync("next" , nextIcon, "material" );
this .searchIconRef.RegisterIconFromTextAsync("clear" , clearIcon, "material" );
}));
}
}
}
razor
마지막으로 템플릿을 새로운 구성요소로 업데이트해 보겠습니다.
모든 구성요소를 IgbInput
내부에 래핑하겠습니다. 왼쪽에서는 검색과 삭제/지우기 아이콘 사이를 전환합니다(검색 입력이 비어 있는지 여부에 따라). 중앙에는 입력 자체를 배치합니다. 또한 삭제 아이콘을 클릭할 때마다 SearchText
업데이트하고 IgbGrid
의 ClearSearch
메서드를 호출하여 하이라이트를 지웁니다.
<IgbInput ValueChanging ="OnValueChanging" Value ="@ searchText " @onkeydown ="OnSearchKeyDown" >
@ if (searchText.Length == 0 )
{
<IgbIcon @ref ="searchIconRef" slot ="prefix" IconName ="search" Collection ="material" / >
}
@ if (searchText.Length > 0 )
{
<IgbIcon slot ="prefix" IconName ="clear" Collection ="material" @onclick ="ClearSearch" / >
}
<div class ="chips" slot ="suffix" >
<IgbChip Selectable =true SelectedChanged ="UpdateCase" >
Case Sensitive
</IgbChip >
<IgbChip Selectable =true SelectedChanged ="UpdateExactSearch" >
Exact Match
</IgbChip >
</div >
<div class ="searchButtons" slot ="suffix" >
<IgbIconButton Variant ="IconButtonVariant.Flat" @onclick ="PrevSearch" >
<IgbIcon IconName ="prev" Collection ="material" / >
</IgbIconButton >
<IgbIconButton Variant ="IconButtonVariant.Flat" @onclick ="NextSearch" >
<IgbIcon IconName ="next" Collection ="material" />
</IgbIconButton >
</div >
</IgbInput >
@code {
public void clearSearch ( )
{
this .searchText = "" ;
this .grid.ClearSearchAsync();
}
}
razor
입력 그룹 오른쪽에 다음 목적을 가진 세 개의 별도 컨테이너를 만들어 보겠습니다.
CaseSensitive
및 ExactMatch
속성을 전환하는 몇 가지 칩을 표시합니다. 우리는 체크박스를 이러한 속성에 따라 색상을 변경하는 두 개의 세련된 칩으로 대체했습니다. 칩을 클릭할 때마다 해당 핸들러를 호출합니다.
<div class ="chips" slot ="suffix" >
<IgbChip Selectable =true SelectedChanged ="UpdateCase" >
Case Sensitive
</IgbChip >
<IgbChip Selectable =true SelectedChanged ="UpdateExactSearch" >
Exact Match
</IgbChip >
</div >
@code {
public void UpdateCase (bool selected ) {
this .caseSensitive = selected;
this .grid.FindNextAsync(this .searchText, this .caseSensitive, this .exactMatch);
}
public void UpdateExactSearch (bool selected ) {
this .exactMatch = selected;
this .grid.FindNextAsync(this .searchText, this .caseSensitive, this .exactMatch);
}
}
razor
검색 탐색 버튼의 경우 입력을 머티리얼 아이콘이 있는 잔물결 스타일 버튼으로 변환했습니다. 클릭 이벤트에 대한 핸들러는 동일하게 유지됩니다. 즉, FindNext
/ FindPrev
메소드를 호출합니다.
<div class ="searchButtons" slot ="suffix" >
<IgbIconButton Variant ="IconButtonVariant.Flat" @onclick ="PrevSearch" >
<IgbIcon IconName ="prev" Collection ="material" / >
</IgbIconButton >
<IgbIconButton Variant ="IconButtonVariant.Flat" @onclick ="NextSearch" >
<IgbIcon IconName ="next" Collection ="material" />
</IgbIconButton >
</div >
@code {
public void PrevSearch ( )
{
this .grid.FindPrevAsync(this .searchText, this .caseSensitive, this .exactMatch);
}
public void NextSearch ( )
{
this .grid.FindNextAsync(this .searchText, this .caseSensitive, this .exactMatch);
}
}
razor
Known Limitations
한정
설명
템플릿을 사용하여 셀에서 검색
검색 기능 강조 표시는 기본 셀 템플릿에서만 작동합니다. 사용자 정의 셀 템플릿이 포함된 열이 있는 경우 강조 표시가 작동하지 않으므로 열 포맷터와 같은 대체 접근 방식을 사용하거나Searchable
열의 속성을 false로 설정합니다.
원격 가상화
원격 가상화를 사용하면 검색이 제대로 작동하지 않습니다.
텍스트가 잘린 셀
셀의 텍스트가 너무 커서 맞지 않고 찾고 있는 텍스트가 줄임표로 잘려도 셀로 스크롤하여 일치 횟수에 포함시키지만 아무것도 강조 표시되지 않습니다.
API References
이 글에서는 검색 결과 간을 탐색할 때 추가 기능이 있는 IgbGrid
용 자체 검색 창을 구현했습니다. 또한 아이콘, 칩, 입력과 같은 Ignite UI for Blazor도 사용했습니다. 검색 API는 아래에 나와 있습니다.
IgbGrid
methods:
IgbColumn
properties:
사용된 관련 API가 포함된 추가 구성요소:
Additional Resources
우리 커뮤니티는 활동적이며 항상 새로운 아이디어를 환영합니다.