feat(module: table): add on row and cell (#1175)

* fix(module:table): set selectedRows exception

* fix(module:table): set selectedRows exception

* fix(module: tree) selected highlight confusion

* Revert "fix(module: tree) selected highlight confusion"

This reverts commit 91300ac664f8dcebc20f1a96e21f8afc1fac079d.

* fix(module: tree): remove the IsFixed attribute

* feat(module: table): add table onrow method

* feat(module: table) add onrow method to table column

* feat(module: table) add onrow method to table column

* feat(module: table) add onheaderrow and onheadercell methods to table

* feat(module: table) fix doc encoding

* fix demo

Co-authored-by: James Yeung <shunjiey@hotmail.com>
This commit is contained in:
qinhuaihe 2021-03-01 23:47:16 +08:00 committed by GitHub
parent 5fe1e94f4d
commit cc4a7bbf13
9 changed files with 129 additions and 30 deletions

View File

@ -40,7 +40,9 @@ else if (IsHeader && HeaderColSpan != 0)
<th class="ant-table-cell ant-table-row-expand-icon-cell"></th>
}
<th class="@ClassMapper.Class" style="@FixedStyle @HeaderStyle" colspan="@HeaderColSpan" title="@(Ellipsis?HeaderTitle:"")">
var headerCellAttributes = OnHeaderCell?.Invoke();
<th class="@ClassMapper.Class" style="@FixedStyle @HeaderStyle" colspan="@HeaderColSpan" title="@(Ellipsis?HeaderTitle:"")" @attributes="headerCellAttributes">
@if (Sortable || Filters?.Any() == true)
{
@FilterToolTipSorter(this)
@ -72,7 +74,9 @@ else if (IsBody && RowSpan != 0 && ColSpan != 0)
</td>
}
<td class="@ClassMapper.Class" style="@FixedStyle @Style" rowspan="@RowSpan" colspan="@ColSpan" title="@(Ellipsis? fieldText:"")">
var cellAttributes = OnCell?.Invoke(RowData);
<td class="@ClassMapper.Class" style="@FixedStyle @Style" rowspan="@RowSpan" colspan="@ColSpan" title="@(Ellipsis? fieldText:"")" @attributes="cellAttributes">
@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>
@ -159,7 +163,7 @@ readonly RenderFragment<Column<TData>> FilterToolTipSorter = col =>
@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 )})">
<span class="ant-table-filter-column-title" @attributes="@(new Dictionary<string, object>() { ["onclick"]=_callbackFactory.Create(col, col.HandleSort )})">
@if (col.Sortable)
{
@col.ToolTipSorter(col)
@ -208,7 +212,9 @@ readonly RenderFragment<Column<TData>> FilterToolTipSorter = col =>
{
@if (col.Sortable)
{
@col.ToolTipSorter(col)
<div @attributes="@(new Dictionary<string, object>() { ["onclick"]=_callbackFactory.Create(col, col.HandleSort )})">
@col.ToolTipSorter(col)
</div>
}
else if (col.TitleTemplate != null)
{

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections.Generic;
using System.Linq.Expressions;
@ -50,6 +51,12 @@ namespace AntDesign
[Parameter]
public SortDirection DefaultSortOrder { get; set; }
[Parameter]
public Func<RowData, Dictionary<string, object>> OnCell { get; set; }
[Parameter]
public Func<Dictionary<string, object>> OnHeaderCell { get; set; }
[Parameter]
public IEnumerable<TableFilter<TData>> Filters { get; set; }
@ -134,7 +141,7 @@ namespace AntDesign
.If($"ant-table-column-sort", () => Sortable && SortModel != null && SortModel.SortDirection.IsIn(SortDirection.Ascending, SortDirection.Descending));
}
private void HandelHeaderClick()
private void HandleSort()
{
if (Sortable)
{

View File

@ -107,8 +107,11 @@
{
RenderFragment<Table<TItem>> header = table =>
@<Template>
@{
var headerRowAttributes = table.OnHeaderRow?.Invoke();
}
<thead class="ant-table-thead">
<tr>
<tr @attributes="headerRowAttributes">
<CascadingValue Name="IsHeader" Value="true" IsFixed>
@table.ChildContent(_fieldModel)
</CascadingValue>
@ -170,8 +173,10 @@ RenderFragment<(Table<TItem> table, IEnumerable<TItem> showItems, int level)> bo
currentRowData.Level = level;
currentRowData.HasChildren = hasChildren;
<tr @attributes="@(new Dictionary<string,object> { {"onclick", _callbackFactory.Create(table, () => table.RowClick(currentRowData)) } })"
data-row-key="@(rowIndex-1)" class="ant-table-row ant-table-row-level-@level @(currentRowData.Selected ? "ant-table-row-selected" : "") @table.RowClassName(currentRowData)">
var rowAttributes = table.OnRow?.Invoke(currentRowData);
<tr @attributes="rowAttributes"
data-row-key="@(rowIndex-1)" class="ant-table-row ant-table-row-level-@level @(currentRowData.Selected ? "ant-table-row-selected" : "") @table.RowClassName(currentRowData) @rowAttributes?.GetValueOrDefault("class")">
<CascadingValue Value="currentRowData" Name="RowData" IsFixed>
<CascadingValue Value="true" Name="IsBody" IsFixed>
@table.ChildContent(data)
@ -194,4 +199,4 @@ RenderFragment<(Table<TItem> table, IEnumerable<TItem> showItems, int level)> bo
}
}
</Template>;
}
}

View File

@ -53,7 +53,10 @@ namespace AntDesign
public EventCallback<QueryModel<TItem>> OnChange { get; set; }
[Parameter]
public EventCallback<RowData<TItem>> OnRowClick { get; set; }
public Func<RowData<TItem>, Dictionary<string, object>> OnRow { get; set; }
[Parameter]
public Func<Dictionary<string, object>> OnHeaderRow { get; set; }
[Parameter]
public bool Loading { get; set; }
@ -345,14 +348,6 @@ namespace AntDesign
protected override bool ShouldRender() => this._shouldRender;
private void RowClick(RowData<TItem> item)
{
if (OnRowClick.HasDelegate)
{
OnRowClick.InvokeAsync(item);
}
}
void ITable.HasFixLeft() => _hasFixLeft = true;
void ITable.HasFixRight() => _hasFixRight = true;

View File

@ -1,7 +1,6 @@
@using System.ComponentModel
@using AntDesign.TableModels
<Table TItem="Data" DataSource="@data" OnRowClick="OnRowClick">
<Table TItem="Data" DataSource="@data">
<Column @bind-Field="@context.Name">
<a>@context.Name</a>
</Column>
@ -80,9 +79,4 @@
[DisplayName("Tags")]
public string[] Tags { get; set; }
}
void OnRowClick(RowData<Data> row)
{
Console.WriteLine($"row {row.Data.Key} was clicked");
}
}

View File

@ -1,7 +1,7 @@
@using System.ComponentModel
@using AntDesign.TableModels
<Table TItem="Data" DataSource="@data" OnRowClick="OnRowClick" RowClassName="@(x => x.Data.RowClass)">
<Table TItem="Data" DataSource="@data" OnRow="OnRow" RowClassName="@(x => x.Data.RowClass)">
<Column @bind-Field="@context.Name">
<a>@context.Name</a>
</Column>
@ -35,7 +35,7 @@
Name = "Joe Black",
Score = 65,
}
};
};
public class Data
{
@ -51,8 +51,16 @@
public string RowClass => Score < 70 ? "danger" : "";
}
void OnRowClick(RowData<Data> row)
Dictionary<string, object> OnRow(RowData<Data> row)
{
Console.WriteLine($"row {row.Data.Key} was clicked");
Action<MouseEventArgs> OnClick = args =>
{
Console.WriteLine($"row {row.Data.Key} was clicked");
};
return new Dictionary<string, object>
{
{ "onclick", OnClick },
};
}
}

View File

@ -0,0 +1,65 @@
@using System.ComponentModel
@using AntDesign.TableModels
<Table TItem="Data" DataSource="@data" OnRow="OnRow" OnHeaderRow="OnHeaderRow">
<Column DataIndex="@nameof(context.Name)" TData="string" OnCell="OnCell" OnHeaderCell="OnHeaderCell">
<a>@context.Name</a>
</Column>
<Column DataIndex="@nameof(context.Age)" TData="int"></Column>
<Column Title="Address" TData="string">
<TitleTemplate>
<span> <Icon Type="environment" /> Address </span>
</TitleTemplate>
</Column>
<Column Title="Tag" TData="string">
@foreach (var tag in context.Tags)
{
<Tag Color="@(tag == "loser" ? "volcano" : tag.Length > 5 ? "geekblue" : "green")">@tag</Tag>
}
</Column>
</Table>
@code{
record Data(string Key, string Name, int Age, string Address, string[] Tags);
Data[] data = new Data[]
{
new("1", "John Brown",32, "New York No. 1 Lake Park",new[] {"nice", "developer"}),
new("2", "Jim Green",42, "London No. 1 Lake Park",new[] { "loser"}),
new("3", "Joe Black",32, "Sidney No. 1 Lake Park",new[] { "cool", "teacher" }),
};
Dictionary<string, object> OnRow(RowData<Data> row) => new()
{
["id"] = row.Data.Key,
["onclick"] = ((Action)delegate
{
Console.WriteLine($"row {row.Data.Key} was clicked");
})
};
Dictionary<string, object> OnHeaderRow() => new()
{
["id"] = "header-row",
["onclick"] = ((Action)delegate
{
Console.WriteLine("header row was clicked");
})
};
Dictionary<string, object> OnCell(RowData rowData) => new()
{
["onclick"] = ((Action)delegate
{
Console.WriteLine($"cell { ((RowData<Data>)rowData).Data.Name} was clicked");
}),
};
Dictionary<string, object> OnHeaderCell() => new()
{
["onclick"] = ((Action)delegate
{
Console.WriteLine("header cell was clicked");
}),
};
}

View File

@ -0,0 +1,20 @@
---
order: 1
title:
en-US: Set props on per row
zh-CN: 设置行属性
---
## zh-CN
可通过传入一个返回字典的委托,来给行或者单元格设置任意属性。如 `onclick`、`style`、`class` 等。
适用于 `OnRow` `OnHeaderRow` `OnCell` `OnHeaderCell`
对于返回字典的要求,请参加官方文档[【属性展开和任意参数】](https://docs.microsoft.com/zh-cn/aspnet/core/blazor/components/?view=aspnetcore-5.0&WT.mc_id=DT-MVP-5003987#attribute-splatting-and-arbitrary-parameters) 一节。
## en-US
You can set any property to a row or cell by passing in a delegate that returns the dictionary. Such as 'onclick', 'style', 'class' and so on.
Same as `OnRow` `OnHeaderRow` `OnCell` `OnHeaderCell`.
For the rules for returning dictionaries, please refer to the official documentation [[Attribute splatting and arbitrary parameters]](https://docs.microsoft.com/en-us/aspnet/core/blazor/components/?view=aspnetcore-5.0&WT.mc_id=DT-MVP-5003987#attribute-splatting-and-arbitrary-parameters).

View File

@ -16,4 +16,3 @@ A table displays rows of data.
## How To Use
Specify `dataSource` of Table as an array of data.