Skip to content
This repository has been archived by the owner on Jul 10, 2024. It is now read-only.

Column Hiding #190

Merged
merged 3 commits into from
Nov 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/BlazorTable.Sample.Shared/NavMenu.razor
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@
<span class="oi oi-home" aria-hidden="true"></span> Dynamic Columns
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="ToggleColumnVisibility" Match="NavLinkMatch.All">
<span class="oi oi-eye" aria-hidden="true"></span> Column Visibility
</NavLink>
</li>
</ul>
</div>

Expand Down
69 changes: 69 additions & 0 deletions src/BlazorTable.Sample.Shared/Pages/ToggleColumnVisibility.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
@page "/ToggleColumnVisibility"
@inject HttpClient Http
@using BlazorTable
@using System.ComponentModel

<h1>Toggle Column Visibility</h1>

<button class="btn btn-primary mb-2" @onclick="@(_ => showSearchBar = !showSearchBar)">Toggle Search Bar</button>

<Table TableItem="PersonData" Items="data" PageSize="15" ColumnReorder="true" ShowSearchBar="showSearchBar">
<Column Hideable="true" TableItem="PersonData" Title="Id" Field="@(x => x.id)" Sortable="true" Filterable="true" Width="10%" DefaultSortColumn="true" />
<Column Hideable="true" TableItem="PersonData" Title="Full Name" Field="@(x => x.full_name)" Sortable="true" Filterable="true" Width="20%" />
<Column Hideable="true" TableItem="PersonData" Title="Email" Field="@(x => x.email)" Sortable="true" Filterable="true" Width="20%">
<Template>
<a href="mailto:@context.email">@context.email</a>
</Template>
</Column>
<Column TableItem="PersonData" Title="Paid" Field="@(x => x.paid)" Sortable="true" Filterable="true" Width="10%">
<Template>
@context.paid.ToString()
</Template>
</Column>
<Column Hideable="true" TableItem="PersonData" Title="Price" Field="@(x => x.price)" Sortable="true" Filterable="true" Width="10%" Format="C" Align="Align.Right" />
<Column TableItem="PersonData" Title="Created Date" Field="@(x => x.created_date)" Sortable="true" Filterable="true" Width="10%">
<Template>
@(context.created_date.HasValue ? context.created_date.Value.ToShortDateString() : string.Empty)
</Template>
</Column>
<Column Hideable="true" TableItem="PersonData" Title="Enum" Field="@(x => x.cc_type)" Sortable="true" Filterable="true" Width="10%">
<Template>
@context.cc_type
</Template>
</Column>
<Pager ShowPageNumber="true" ShowTotalCount="true" />
</Table>

@code
{
[Inject]
private HttpClient httpClient { get; set; }

private PersonData[] data;

private bool showSearchBar;

protected override async Task OnInitializedAsync()
{
data = await httpClient.GetFromJsonAsync<PersonData[]>("sample-data/MOCK_DATA.json");
}

public class PersonData
{
public int? id { get; set; }
public string full_name { get; set; }
public string email { get; set; }
public bool? paid { get; set; }
public decimal? price { get; set; }
public CreditCard? cc_type { get; set; }
public DateTime? created_date { get; set; }
}

public enum CreditCard
{
none = 0,
[Description("MasterCard")]
MasterCard = 1,
Visa = 2
}
}
22 changes: 22 additions & 0 deletions src/BlazorTable/Components/Column.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ public string Title
[Parameter]
public bool Filterable { get; set; }

/// <summary>
/// Column can be hidden
/// </summary>
[Parameter]
public bool Hideable { get; set; }

/// <summary>
/// Normal Item Template
/// </summary>
Expand Down Expand Up @@ -142,6 +148,22 @@ public string Title
/// </summary>
public bool FilterOpen { get; private set; }

private bool _visible = true;

/// <summary>
/// Column visibility
/// True if current column is visible else false.
/// </summary>
public bool Visible
{
get { return _visible; }
set
{
_visible = value;
Table.Refresh();
}
}

/// <summary>
/// Column Data Type
/// </summary>
Expand Down
171 changes: 113 additions & 58 deletions src/BlazorTable/Components/Table.razor
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,51 @@

<div class="table-responsive">
<table aria-readonly="@(IsEditMode ? "false" : "true")" role="grid" class="@TableClass" @attributes="UnknownParameters">
@if (ShowSearchBar)
@if (ShowSearchBar || Columns.Exists(column => !column.Visible))
{
<thead role="search">
<tr>
<th colspan="@columnCount"><input type="text" class="form-control form-control-sm float-right" style="width:33%" value="@GlobalSearch" @onchange="@(x => { GlobalSearch = x.Value.ToString(); Update(); })" placeholder="@Localization["GlobalSearch"]" /></th>
<th colspan="@columnCount">
@if (ShowSearchBar)
{
<th colspan="@columnCount"><input type="text" class="form-control form-control-sm float-right" style="width:33%" value="@GlobalSearch" @onchange="@(x => { GlobalSearch = x.Value.ToString(); Update(); })" placeholder="@Localization["GlobalSearch"]" /></th>
}
@if (Columns.Exists(column => !column.Visible))
{
<div class="float-right" @onclick="@(_ => VisibilityMenuOpen = !VisibilityMenuOpen)">
<a href="javascript:;" @ref="VisibilityMenuIconRef">
<span aria-hidden="true">
<img src="_content/BlazorTable/images/plus.png" />
</span>
</a>
</div>
<Popover IsOpen="@VisibilityMenuOpen" Placement="Placement.Bottom" DismissOnNextClick="false" Reference="VisibilityMenuIconRef">
<h3 class="popover-header">Column Visibility</h3>
<div class="popover-body">
<table class="table table-sm table-borderless">
@foreach (IColumn<TableItem> column in Columns.Where(column => !column.Visible))
{
<tr>
<td>
@(column.Title)
</td>
<td>
<div class="float-right" @onclick="@(_ => { column.Visible = true; if (!Columns.Exists(column => !column.Visible)) VisibilityMenuOpen = false;})">
<span aria-hidden="true">
<img src="_content/BlazorTable/images/plus.png" />
</span>
</div>
</td>
</tr>
}
</table>
<button class="btn btn-sm btn-danger" @onclick="@(_ => VisibilityMenuOpen = false)">
Close
</button>
</div>
</Popover>
}
</th>
</tr>
</thead>
}
Expand All @@ -25,56 +65,68 @@
}
@foreach (IColumn<TableItem> column in Columns)
{
<th scope="col" style="@(!string.IsNullOrEmpty(column.Width) ? $"width:{column.Width};" : "") user-select: none"
@ondrop="@(() => HandleDrop(column))"
@ondragstart="@(() => HandleDragStart(column))"
ondragover="event.preventDefault();"
draggable="@(ColumnReorder.ToString())"
@key="column"
aria-sort="@column.AriaSort"
class="@(column.Class)">
@if (column.Visible)
{
<th scope="col" style="@(!string.IsNullOrEmpty(column.Width) ? $"width:{column.Width};" : "") user-select: none"
@ondrop="@(() => HandleDrop(column))"
@ondragstart="@(() => HandleDragStart(column))"
ondragover="event.preventDefault();"
draggable="@(ColumnReorder.ToString())"
@key="column"
aria-sort="@column.AriaSort"
class="@(column.Class)">

<div @onclick="@(() => column.SortBy())">
<span>@column.Title</span>
<div @onclick="@(() => column.SortBy())">
<span>@column.Title</span>

@if (column.SortColumn)
{
if (column.SortDescending)
{ <span aria-hidden="true"><img src="_content/BlazorTable/images/sort-desc.png" /></span> }
else
{ <span aria-hidden="true"><img src="_content/BlazorTable/images/sort-asc.png" /></span> }
}
@if (column.SortColumn)
{
if (column.SortDescending)
{ <span aria-hidden="true"><img src="_content/BlazorTable/images/sort-desc.png" /></span> }
else
{ <span aria-hidden="true"><img src="_content/BlazorTable/images/sort-asc.png" /></span> }
}

@if (column.Filterable)
{
<div class="float-right" @onclick="@((x) => column.ToggleFilter())" @onclick:stopPropagation>
<a href="javascript:;" @ref="column.FilterRef" aria-expanded="@(column.FilterOpen ? "true" : "false")" style="text-decoration: none" aria-label="@(column.Filter == null ? "unfiltered" : "filtered")">
<span aria-hidden="true" style="@(column.Filter == null ? "opacity: 0.2;" : string.Empty)">
<img src="_content/BlazorTable/images/filter.png" />
@if (column.Filterable)
{
<div class="float-right" @onclick="@(_ => column.ToggleFilter())" @onclick:stopPropagation>
<a href="javascript:;" @ref="column.FilterRef" aria-expanded="@(column.FilterOpen ? "true" : "false")" style="text-decoration: none" aria-label="@(column.Filter == null ? "unfiltered" : "filtered")">
<span aria-hidden="true" style="@(column.Filter == null ? "opacity: 0.2;" : string.Empty)">
<img src="_content/BlazorTable/images/filter.png" />
</span>
</a>
</div>
<CascadingValue Value="column" Name="Column">
<Popover Reference="@column.FilterRef" IsOpen="@column.FilterOpen" Placement="Placement.Bottom" DismissOnNextClick="false">
<h3 class="popover-header">Filter</h3>
<div class="popover-body">
<FilterManager TableItem="TableItem">
<StringFilter TableItem="TableItem" />
<BooleanFilter TableItem="TableItem" />
<NumberFilter TableItem="TableItem" />
<DateFilter TableItem="TableItem" />
<EnumFilter TableItem="TableItem" />
@if (column.CustomIFilters != null)
{
@column.CustomIFilters(column)
}
</FilterManager>
</div>
</Popover>
</CascadingValue>
}

@if (column.Hideable)
{
<div class="float-right mr-1" @onclick="@(_ => column.Visible = false)" @onclick:stopPropagation>
<span aria-hidden="true">
<img src="_content/BlazorTable/images/minus.png" />
</span>
</a>
</div>
<CascadingValue Value="column" Name="Column">
<Popover Reference="@column.FilterRef" IsOpen="@column.FilterOpen" Placement="Placement.Bottom" DismissOnNextClick="false">
<h3 class="popover-header">Filter</h3>
<div class="popover-body">
<FilterManager TableItem="TableItem">
<StringFilter TableItem="TableItem" />
<BooleanFilter TableItem="TableItem" />
<NumberFilter TableItem="TableItem" />
<DateFilter TableItem="TableItem" />
<EnumFilter TableItem="TableItem" />
@if (column.CustomIFilters != null)
{
@column.CustomIFilters(column)
}
</FilterManager>
</div>
</Popover>
</CascadingValue>
}
</div>
</th>
</div>
}
</div>
</th>
}
}
</tr>
</thead>
Expand Down Expand Up @@ -107,17 +159,20 @@

@foreach (IColumn<TableItem> column in Columns)
{
<td @key="column"
style="@(column.Align > 0 ? $"text-align: {column.Align};" : "")"
class="@(column.Class)">
@if (column.Visible)
{
<td @key="column"
style="@(column.Align > 0 ? $"text-align: {column.Align};" : "")"
class="@(column.Class)">

@if (IsEditMode && column.EditTemplate != null)
@column.EditTemplate(item)
else if (column.Template == null)
@column.Render(item)
else
@column.Template(item)
</td>
@if (IsEditMode && column.EditTemplate != null)
@column.EditTemplate(item)
else if (column.Template == null)
@column.Render(item)
else
@column.Template(item)
</td>
}
}
</tr>

Expand Down
10 changes: 10 additions & 0 deletions src/BlazorTable/Components/Table.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ public partial class Table<TableItem> : ITable<TableItem>
[Inject]
private ILogger<ITable<TableItem>> Logger { get; set; }

/// <summary>
/// Ref to visibility menu icon for popover display
/// </summary>
private ElementReference VisibilityMenuIconRef { get; set; }

/// <summary>
/// True if visibility menu is open otherwise false
/// </summary>
private bool VisibilityMenuOpen { get; set; }

/// <summary>
/// Collection of filtered items
/// </summary>
Expand Down
11 changes: 11 additions & 0 deletions src/BlazorTable/Interfaces/IColumn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ public interface IColumn<TableItem>
/// </summary>
bool Filterable { get; set; }

/// <summary>
/// Column can be hidden
/// </summary>
bool Hideable { get; set; }

/// <summary>
/// Set the format for values if no template
/// </summary>
Expand All @@ -45,6 +50,12 @@ public interface IColumn<TableItem>
/// </summary>
bool FilterOpen { get; }

/// <summary>
/// Column visibility
/// True if current column is visible else false.
/// </summary>
bool Visible { get; set; }

/// <summary>
/// Opens/Closes the Filter Panel
/// </summary>
Expand Down