ant-design-blazor/components/table/Column.razor
James Yeung 4065869806 feat(module: table): add filters (#1178)
* feat: add table filter

* add filter buttons

* fix filter menu

* make filter work

* support multiple filters

* delete the old files

* support single select
2021-02-27 23:55:48 +08:00

224 lines
8.6 KiB
C#

@namespace AntDesign
@inherits ColumnBase
@using AntDesign.Core.Helpers
@using AntDesign.TableModels
@typeparam TData
@if (IsInitialize)
{
return;
}
else if (IsPlaceholder)
{
<td style="padding: 0px; border: 0px; height: 0px;"></td>
}
else if (IsMeasure)
{
<td style="padding: 0px; border: 0px; height: 0px;"><div style="height: 0px; overflow: hidden;">&nbsp;</div></td>
}
else if (IsColGroup)
{
@if (AppendExpandColumn)
{
<col class="ant-table-expand-icon-col">
}
if (Width != null)
{
<col style="width: @((CssSizeLength)Width); min-width: @((CssSizeLength)Width);">
}
else
{
<col />
}
}
else if (IsHeader && HeaderColSpan != 0)
{
@if (AppendExpandColumn)
{
<th class="ant-table-cell ant-table-row-expand-icon-cell"></th>
}
<th class="@ClassMapper.Class" style="@FixedStyle @HeaderStyle" colspan="@HeaderColSpan" title="@(Ellipsis?HeaderTitle:"")">
@if (Sortable || Filters?.Any() == true)
{
@FilterToolTipSorter(this)
}
else if (TitleTemplate != null)
{
@TitleTemplate
}
else
{
@HeaderTitle
}
</th>
}
else if (IsBody && RowSpan != 0 && ColSpan != 0)
{
var fieldText = !string.IsNullOrWhiteSpace(Format) ? Formatter<TData>.Format(Field, Format) : Field?.ToString();
@if (AppendExpandColumn)
{
<td class="ant-table-cell ant-table-row-expand-icon-cell">
@if (Table.RowExpandable(RowData) && (!Table.TreeMode || !RowData.HasChildren))
{
<button type="button" @onclick="()=> RowData.Expanded = !RowData.Expanded"
class="ant-table-row-expand-icon @(RowData.Expanded?"ant-table-row-expand-icon-expanded":"ant-table-row-expand-icon-collapsed")"
aria-label="@(RowData.Expanded?Table.Locale.Collapse:Table.Locale.Expand)"></button>
}
</td>
}
<td class="@ClassMapper.Class" style="@FixedStyle @Style" rowspan="@RowSpan" colspan="@ColSpan" title="@(Ellipsis? fieldText:"")">
@if (ColIndex == Table.TreeExpandIconColumnIndex && Table.TreeMode)
{
<span class="ant-table-row-indent indent-level-@RowData.Level" style="padding-left: @((CssSizeLength)(RowData.Level * Table.IndentSize));"></span>
@if (RowData.HasChildren)
{
<button type="button" @onclick="ToggleTreeNode" class="ant-table-row-expand-icon @(RowData?.Expanded==true?"ant-table-row-expand-icon-expanded":"ant-table-row-expand-icon-collapsed")" aria-label="@(RowData?.Expanded==true?Table.Locale.Collapse:Table.Locale.Expand)"></button>
}
else
{
<button type="button" class="ant-table-row-expand-icon ant-table-row-expand-icon-spaced" aria-label="@Table.Locale.Expand"></button>
}
}
@if (CellRender != null)
{
@CellRender(Field)
}
else if (ChildContent != null)
{
@ChildContent
}
else
{
if (!string.IsNullOrWhiteSpace(Format))
{
@(Formatter<TData>.Format(GetValue != null ? GetValue(RowData) : Field, Format))
}
else
{
@(GetValue != null ? GetValue(RowData) : Field)
}
}
</td>
}
@code
{
string HeaderTitle => Title ?? DisplayName ?? FieldName ?? DataIndex;
readonly RenderFragment<Column<TData>> SortHeader = col =>
@<div class="ant-table-column-sorters">
<span>
@if (col.TitleTemplate != null)@col.TitleTemplate else @col.HeaderTitle
</span>
@{
bool hasDescendingSorter = SortDirection.Descending.IsIn(col.SortDirections);
bool hasAscendingSorter = SortDirection.Ascending.IsIn(col.SortDirections);
}
<span class="ant-table-column-sorter @(hasDescendingSorter && hasAscendingSorter?"ant-table-column-sorter-full":"")">
<span class="ant-table-column-sorter-inner">
@if (hasAscendingSorter)
{
<Icon Type="caret-up" Class=@($"ant-table-column-sorter-up {(col._sortDirection == SortDirection.Ascending? "active":"")}") />
}
@if (hasDescendingSorter)
{
<Icon Type="caret-down" Class=@($"ant-table-column-sorter-down {(col._sortDirection == SortDirection.Descending ? "active" : "")}") />
}
</span>
</span>
</div>;
readonly RenderFragment<Column<TData>> ToolTipSorter = col =>
@<Template>
@if (col.ShowSorterTooltip)
{
<Tooltip Title="@col.SorterTooltip">
<Unbound>
<div class="ant-table-column-sorters-with-tooltip" @ref="context.Current">
@col.SortHeader(col)
</div>
</Unbound>
</Tooltip>
}
else
{
@col.SortHeader(col)
}
</Template>;
readonly RenderFragment<Column<TData>> FilterToolTipSorter = col =>
@<Template>
@if (col.Filters?.Any() == true)
{
<div class="ant-table-filter-column">
<span class="ant-table-filter-column-title" @attributes="@(new Dictionary<string, object>() { ["onclick"]=_callbackFactory.Create(col, col.HandelHeaderClick )})">
@if (col.Sortable)
{
@col.ToolTipSorter(col)
}
</span>
<Dropdown Trigger="new[] { TriggerType.Click }" Visible="col._filterOpened" Placement="PlacementType.BottomRight" TriggerReference="col._filterTriggerRef">
<Unbound>
<span @ref="@col._filterTriggerRef" class="ant-table-filter-trigger-container @(col._filterOpened?" ant-table-filter-trigger-container-open":"")">
<span role="button" tabindex="-1" class="ant-dropdown-trigger ant-table-filter-trigger @(col._hasFilterSelected?"active":"")"
@attributes="@(new Dictionary<string, object>() { ["onclick"] = _callbackFactory.Create<MouseEventArgs>(col, () => col._filterOpened = !col._filterOpened )})">
<Icon Type="filter" Theme="fill" />
</span>
</span>
</Unbound>
<Overlay>
<div class="ant-table-filter-dropdown">
<Menu AutoCloseDropdown="false" SelectedKeys="col._selectedFilterValues">
@foreach (var filter in col.Filters)
{
<MenuItem Key="@filter.Value.ToString()" @attributes="@(new Dictionary<string, object>() { ["OnClick"] = _callbackFactory.Create<MouseEventArgs>(col, () => col.FilterSelected(filter))})">
@if (col.FilterMultiple)
{
<Checkbox Value="filter.Selected" @attributes="@(new Dictionary<string, object>() { ["ValueChanged"] = _callbackFactory.Create<bool>(col, value => col.FilterSelected(filter)) })">@filter.Text</Checkbox>
}
else
{
<Radio TValue="bool" Checked="filter.Selected" @attributes="@(new Dictionary<string, object>() { ["CheckedChanged"] = _callbackFactory.Create<bool>(col, value => col.FilterSelected(filter))})">@filter.Text</Radio>
}
</MenuItem>
}
</Menu>
<div class="ant-table-filter-dropdown-btns">
<Button Size="small" Type="link" @attributes="@(new Dictionary<string, object>() { ["OnClick"] = _callbackFactory.Create<MouseEventArgs>(col, ()=> col.FilterReset()) })">
@col.Table?.Locale.FilterReset
</Button>
<Button Size="small" Type="primary" @attributes="@(new Dictionary<string, object>() { ["OnClick"] = _callbackFactory.Create<MouseEventArgs>(col, ()=> col.FilterConfirm()) })">
@col.Table?.Locale.FilterConfirm
</Button>
</div>
</div>
</Overlay>
</Dropdown>
</div>
}
else
{
@if (col.Sortable)
{
@col.ToolTipSorter(col)
}
else if (col.TitleTemplate != null)
{
@col.TitleTemplate
}
else
{
@col.HeaderTitle
}
}
</Template>;
}