[Blazor] Telerik Grid Filter Customizing (2) - Checkbox List 필터 만들기
[Blazor] Telerik Grid Filter Customizing (1) - Data 컬럼에 최근 1일, 1주, 1달 필터 추가하기
이런 식으로 최근 하루, 최근 1주, 최근1달의 필터를 만드는 것이 이번 포스팅의 목표. 최근 1일을 체크하고 Filter를 적용하면 최근 하루 이내에 만들어진 데이터만 필터되고, 최근 1주는 1주일 이
hyokye0ng.tistory.com
지난 포스팅에서 Grid에 최근 1 일/주/달 filter를 추가해보았다.
이번에는 Checkbox List 필터를 만들어보겠다.
checkbox list filter는 바로 이렇게 데이터의 List를 출력하고, 그 중에서 내가 선택한 값만 보여주는 filter를 만드는 것이다.
마치 excel의 filter와 같은 형식이랄까,,
아무튼 데이터의 중복되지 않는 값을 이용한 filter 구현하기 시작해보자 ~
참고로, 만약 그리드의 전체 컬럼에 대해 checkbox list filter를 적용할 것이라면
그냥 grid 속성에 FilterMenuType만 지정해주면 된다.
<TelerikGrid Data="@GridData"
Height="@Height"
FilterMode="@GridFilterMode.FilterMenu"
FilterMenuType="@FilterMenuType.CheckBoxList" //Checkboxlist filter Type
Pageable="true"
PageSize="@PageSize">
<GridColumns>
<GridColumn Width="200px" Field=@nameof(ProductDto.ProductName) Title="Product Name" />
<GridColumn Width="100px" Field=@nameof(ProductDto.ProductId) Title="Product Id" />
</GridColumns>
</TelerikGrid>
<reference>
Blazor DataGrid Demos - Filter CheckBoxList | Telerik UI for Blazor
The grid can take the Distinct values of the column and put them in a list of checkboxes for the user to select. This lets them chose values without prior knowledge of the data in a familiar Excel-like fashion. To enable this mode, set the FilterMenuType p
demos.telerik.com
하지만 나는 특정 컬럼에 대해서만 checkboxlist filter를 적용해야 하기 때문에
이렇게 간단하게 구현할 수 없었다.
1. TelerikGrid 만들기
<TelerikGrid>
<GridColumns>
<GridColumn Field="@nameof(V_PART.MSG)" Title="Message" Lockable="true">
</GridColumn>
</GridColumns>
</TelerikGrid>
우선 간단하게 filter를 구현한 컬럼인 Message 컬럼만 만들어줬다.
2. Grid 데이터 & MSG 컬럼의 filter List 가져오기
@code
{
public List<V_PART> GridData { get; set; }
public List<V_PART> SourceData { get; set; }
public int Total { get; set; } = 0;
public List<string> MSGList { get; set; }
protected async override void OnInitialized()
{
SourceData = await EnvironmentService.GetPart(); //전체 데이터 GET
MSGList = SourceData.Select(x => x.MSG).Distinct().ToList(); //전체 데이터에 대해 MSG 컬럼만 DISTICNT로 뽑아냄
}
protected void ReadItems(GridReadEventArgs args) // Grid에서 현재 페이지에 출력될 데이터만 가져옴 -> 성능 향상
{
var datasourceResult = (SourceData.OrderByDescending(f => f.DCN_NO).ThenBy(f => f.DCT_NO).ThenBy(f => f.S_PART_NO)).ToDataSourceResult(args.Request);
GridData = (datasourceResult.Data as IEnumerable<V_PART>).ToList();
Total = datasourceResult.Total;
StateHasChanged();
}
}
OnInitialized 메소드는 말 그대로 초기화될 때 실행되는 메소드이고,
ReadItems 메소드는 Grid의 총 데이터가 아주 많을 때 performance를 고려하여,
현재 페이지에 보여질 데이터만을 다루는 메소드이다.
OnInitialized 메소드에서 MSGList에 총 데이터의 MSG 컬럼을 distinct하여 저장했다.
3. filter 다루는 메소드 추가
@code
{
public List<string> CheckedMSG { get; set; } = new List<string>();
public FilterMenuTemplateContext CheckboxMSGFilterContext { get; set; }
public bool IsCheckboxInCurrentFilter_MSG(CompositeFilterDescriptor filterDescriptor, string msg)
{
if (msg == null)
{
foreach (FilterDescriptor item in filterDescriptor.FilterDescriptors)
{
if (item.Operator == FilterOperator.IsNull)
{
return true;
}
}
return false;
}
return filterDescriptor.FilterDescriptors.Select(f => (f as FilterDescriptor).Value?.ToString()).ToList().Contains(msg);
}
public void UpDateCheckedFilter_MSG(bool value, string itemValue)
{
var IsMSGChecked = CheckedMSG.Contains(itemValue);
if (value && !IsMSGChecked)
{
CheckedMSG.Add(itemValue);
}
if (!value && IsMSGChecked)
{
CheckedMSG.Remove(itemValue);
}
var filterDescriptor = CheckboxMSGFilterContext.FilterDescriptor;
filterDescriptor.FilterDescriptors.Clear();
filterDescriptor.LogicalOperator = FilterCompositionLogicalOperator.Or;
CheckedMSG.ForEach(s =>
{
FilterDescriptor fd = new FilterDescriptor("MSG", FilterOperator.IsEqualTo, s);
fd.MemberType = typeof(string);
if (s == null)
{
fd.Operator = FilterOperator.IsNull;
}
filterDescriptor.FilterDescriptors.Add(fd);
});
if (!filterDescriptor.FilterDescriptors.Any())
{
filterDescriptor.FilterDescriptors.Add(new FilterDescriptor());
}
}
}
4. Telerik Grid MSG Column 수정
<TelerikGrid>
<GridColumns>
<GridColumn Field="@nameof(V_PART.MSG)" Title="Message" Lockable="true">
<FilterMenuTemplate>
@{ CheckboxMSGFilterContext = context; }
<div class="filter-values-container">
@foreach (var msg in MSGList)
{
CheckedMSG.Clear();
<div>
<TelerikCheckBox Value="@(IsCheckboxInCurrentFilter_MSG(context.FilterDescriptor, msg))"
ValueChanged="@((bool value) => UpDateCheckedFilter_MSG(value, msg))"
Id="@($"msg_{msg}")">
</TelerikCheckBox>
<label for="@($"msg_{msg}")"> @msg </label>
</div>
}
</div>
</FilterMenuTemplate>
</GridColumn>
</GridColumns>
</TelerikGrid>
<Reference>
Blazor DataGrid Demos - Custom Filter Menu | Telerik UI for Blazor
The First Name, Country and Hire Date columns use custom filters, the other columns use the built-in filters.
demos.telerik.com
( + 다른 컬럼에서 filter 건 후 MSG 컬럼에 Filter 걸기)
위의 방식대로 하면 MSG 컬럼 말고 다른 컬럼에 Filter를 건 후 MSG의 filter list를 살펴보면
전체 데이터를 기준으로 MSG의 filter list를 생성한다.
왜냐면 초기화 메소드에서 전체 데이터에 대해 MSG컬럼은 Distinct했기 때문이다.
filter가 걸린 데이터에 대해서만 MSG 컬럼의 filter list를 생성하는 방법은 다음과 같다.
@code
{
protected async override void OnInitialized()
{
SourceData = await EnvironmentService.GetPart();
FilterLogicalOperators = GetFilterLogicalOperators();
}
protected void ReadItems(GridReadEventArgs args)
{
var datasourceResult = (SourceData.OrderByDescending(f => f.DCN_NO).ThenBy(f => f.DCT_NO).ThenBy(f => f.S_PART_NO)).ToDataSourceResult(args.Request);
GridData = (datasourceResult.Data as IEnumerable<V_PART>).ToList();
Total = datasourceResult.Total;
var Req = new DataSourceRequest();
Req.Filters = new List<IFilterDescriptor>();
Req.Filters.AddRange(args.Request.Filters);
var Filtered_Data = ((SourceData.ToDataSourceResult(Req)).Data as IEnumerable<V_PART>).ToList();
MSGList = Filtered_Data.Select(x => x.MSG).Distinct().ToList();
StateHasChanged();
}
}
OnInitialized 메소드에서 전체 데이터를 대상으로 MSGList를 생성하던 코드를 지우고
ReadItems 메소드에서 MSGList를 생성한다.
Req의 Filters에 GridReadEventArgs의 Filters 속성을 추가하고
Req를 전체 데이터인 SourceData에 적용하여 Filtered_Data에 저장한다.
이후 Filtered_Data에서 MSG 컬럼을 Distinct로 뽑아내면 filter가 적용된 데이터에 한해서만 MSG List를 가져온다.
<Reference>
Accessing Filtered Data in Grid in UI for Blazor | Telerik Forums
www.telerik.com