Skip to content

Commit

Permalink
DataGrid column reorder (#191)
Browse files Browse the repository at this point in the history
* DataGrid columns reorder added

* Columns reorder demo updated

* ColumnReordered event added to demo
  • Loading branch information
enchev committed Aug 6, 2021
1 parent db0252d commit 90edd71
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 4 deletions.
7 changes: 7 additions & 0 deletions Radzen.Blazor/Common.cs
Expand Up @@ -316,6 +316,13 @@ public class DataGridColumnResizedEventArgs<T>
public double Width { get; internal set; }
}

public class DataGridColumnReorderedEventArgs<T>
{
public RadzenDataGridColumn<T> Column { get; internal set; }
public int OldIndex { get; internal set; }
public int NewIndex { get; internal set; }
}

public class ColumnResizedEventArgs<T>
{
public RadzenGridColumn<T> Column { get; internal set; }
Expand Down
51 changes: 47 additions & 4 deletions Radzen.Blazor/RadzenDataGrid.razor
Expand Up @@ -44,9 +44,16 @@
}
@foreach (var column in visibleColumns)
{
var columnIndex = visibleColumns.IndexOf(column);
var sortableClass = AllowSorting && column.Sortable ? "rz-sortable-column" : "";
<th class="@($"rz-unselectable-text {sortableClass} {column.HeaderCssClass} {getFrozenColumnClass(column, visibleColumns)}")" scope="col" style="@column.GetStyle(true, true)">
<th class="@($"rz-unselectable-text {sortableClass} {column.HeaderCssClass} {getFrozenColumnClass(column, visibleColumns)}")" scope="col" style="@column.GetStyle(true, true)" @onmouseup=@(args => EndColumnReorder(args, columnIndex))>
<div @onclick='@((args) => OnSort(args, column))' style="width:100%">
@if (AllowColumnReorder && column.Reorderable)
{
<span id="@getColumnResizerId(columnIndex)" class="rz-column-drag"
@onclick:preventDefault="true" @onclick:stopPropagation="true"
@onmousedown=@(args => StartColumnReorder(args, columnIndex))>&nbsp;</span>
}
<span class="rz-column-title">
@if (column.HeaderTemplate != null)
{
Expand All @@ -72,9 +79,8 @@
<span class="rz-sortable-column-icon rzi-grid-sort rzi-sort"></span>
}
}
@if (AllowColumnResize)
@if (AllowColumnResize && column.Resizable)
{
var columnIndex = visibleColumns.IndexOf(column);
<div id="@getColumnResizerId(columnIndex)" style="cursor:col-resize;float:right;"
@onclick:preventDefault="true" @onclick:stopPropagation="true"
@onmousedown=@(args => StartColumnResize(args, columnIndex))>&nbsp;</div>
Expand Down Expand Up @@ -325,7 +331,7 @@
}

@code {
#if NET5
#if NET5
internal void SetAllowVirtualization(bool allowVirtualization)
{
AllowVirtualization = allowVirtualization;
Expand Down Expand Up @@ -795,6 +801,9 @@
[Parameter]
public bool AllowColumnResize { get; set; }

[Parameter]
public bool AllowColumnReorder { get; set; }

internal string getColumnResizerId(int columnIndex)
{
return string.Join("", $"{UniqueID}".Split('.')) + columnIndex;
Expand All @@ -805,6 +814,37 @@
await JSRuntime.InvokeVoidAsync("Radzen.startColumnResize", getColumnResizerId(columnIndex), Reference, columnIndex, args.ClientX);
}

int? indexOfColumnToReoder;

internal async Task StartColumnReorder(MouseEventArgs args, int columnIndex)
{
indexOfColumnToReoder = columnIndex;
await JSRuntime.InvokeVoidAsync("Radzen.startColumnReorder", getColumnResizerId(columnIndex));
}

internal async Task EndColumnReorder(MouseEventArgs args, int columnIndex)
{
if(indexOfColumnToReoder != null)
{
var columnToReorder = columns.Where(c => c.Visible).ElementAtOrDefault(indexOfColumnToReoder.Value);

if(columnToReorder != null)
{
columns.Remove(columnToReorder);
columns.Insert(columnIndex, columnToReorder);

await ColumnReordered.InvokeAsync(new DataGridColumnReorderedEventArgs<TItem>
{
Column = columnToReorder,
OldIndex = indexOfColumnToReoder.Value,
NewIndex = columnIndex
});
}

indexOfColumnToReoder = null;
}
}

[JSInvokable("RadzenGrid.OnColumnResized")]
public async Task OnColumnResized(int columnIndex, double value)
{
Expand All @@ -825,6 +865,9 @@
[Parameter]
public EventCallback<DataGridColumnResizedEventArgs<TItem>> ColumnResized { get; set; }

[Parameter]
public EventCallback<DataGridColumnReorderedEventArgs<TItem>> ColumnReordered { get; set; }

public override IQueryable<TItem> View
{
get
Expand Down
6 changes: 6 additions & 0 deletions Radzen.Blazor/RadzenDataGridColumn.razor
Expand Up @@ -84,6 +84,12 @@
[Parameter]
public bool Frozen { get; set; }

[Parameter]
public bool Resizable { get; set; } = true;

[Parameter]
public bool Reorderable { get; set; } = true;

[Parameter]
public TextAlign TextAlign { get; set; } = TextAlign.Left;

Expand Down
19 changes: 19 additions & 0 deletions Radzen.Blazor/themes/components/blazor/_grid.scss
Expand Up @@ -778,3 +778,22 @@ $grid-button-line-height: $grid-button-height !default;
.rz-grid-table tbody > div {
display: table-row;
}

.rz-column-drag {
@extend .rzi;

cursor: grab;
font-size: small;

&:after {
content: 'more_vert';
}

&:active {
cursor: grabbing;
}
}

.rz-column-draggable {
background-color: $grid-header-background-color;
}
37 changes: 37 additions & 0 deletions Radzen.Blazor/wwwroot/Radzen.Blazor.js
Expand Up @@ -1174,6 +1174,43 @@ window.Radzen = {
document.removeEventListener('touchmove', ref.touchMoveHandler)
document.removeEventListener('touchend', ref.mouseUpHandler);
},
startColumnReorder: function(id) {
var el = document.getElementById(id);
var cell = el.parentNode.parentNode;
var visual = document.createElement("th");
visual.className = cell.className + ' rz-column-draggable';
visual.style = cell.style;
visual.style.display = 'none';
visual.style.position = 'absolute';
visual.style.height = cell.offsetHeight + 'px';
visual.style.width = cell.offsetWidth + 'px';
visual.style.zIndex = 2000;
visual.innerHTML = cell.innerHTML;
visual.id = id + 'visual';
document.body.appendChild(visual);

Radzen[id + 'end'] = function (e) {
var el = document.getElementById(id + 'visual');
if (el) {
document.body.removeChild(el);
Radzen[id + 'end'] = null;
Radzen[id + 'move'] = null;
}
}
document.removeEventListener('click', Radzen[id + 'end']);
document.addEventListener('click', Radzen[id + 'end']);

Radzen[id + 'move'] = function (e) {
var el = document.getElementById(id + 'visual');
if (el) {
el.style.display = 'block';
el.style.top = e.clientY + 10 + 'px';
el.style.left = e.clientX + 10 + 'px';
}
}
document.removeEventListener('mousemove', Radzen[id + 'move']);
document.addEventListener('mousemove', Radzen[id + 'move']);
},
startColumnResize: function(id, grid, columnIndex, clientX) {
var el = document.getElementById(id);
var cell = el.parentNode.parentNode;
Expand Down
58 changes: 58 additions & 0 deletions RadzenBlazorDemos/Pages/DataGridColumnReoderPage.razor
@@ -0,0 +1,58 @@
@page "/datagrid-column-reorder"

@using RadzenBlazorDemos.Data
@using RadzenBlazorDemos.Models.Northwind
@using Microsoft.EntityFrameworkCore

@inject NorthwindContext dbContext

<h1>DataGrid</h1>

<p>Enable column reorder by setting the AllowColumnReorder property to true.</p

<RadzenExample Name="DataGrid" Heading="false" Documentation="false">
<RadzenButton Text="Change page state" Click="@((args) => { StateHasChanged(); })" Style="margin-bottom:20px" />
<RadzenDataGrid AllowColumnReorder="true" ColumnReordered="@OnColumnReordered"
AllowFiltering="true" AllowColumnResize="true" FilterMode="FilterMode.Advanced" PageSize="5" AllowPaging="true" AllowSorting="true" Data="@employees" TItem="Employee" ColumnWidth="300px" LogicalFilterOperator="LogicalFilterOperator.Or">
<Columns>
<RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Filterable="false" Title="ID" Frozen="true" Width="50px" TextAlign="TextAlign.Center" Reorderable="false" Resizable="false" />
<RadzenDataGridColumn TItem="Employee" Title="Photo" Sortable="false" Filterable="false" Width="200px" >
<Template Context="data">
<RadzenImage Path="@data.Photo" style="width: 40px; height: 40px; border-radius: 8px;" />
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="First Name" />
<RadzenDataGridColumn TItem="Employee" Property="LastName" Title="Last Name" Width="150px"/>
<RadzenDataGridColumn TItem="Employee" Property="Title" Title="Title" />
<RadzenDataGridColumn TItem="Employee" Property="TitleOfCourtesy" Title="Title Of Courtesy" />
<RadzenDataGridColumn TItem="Employee" Property="BirthDate" Title="Birth Date" FormatString="{0:d}" />
<RadzenDataGridColumn TItem="Employee" Property="HireDate" Title="Hire Date" FormatString="{0:d}" />
<RadzenDataGridColumn TItem="Employee" Property="Address" Title="Address" />
<RadzenDataGridColumn TItem="Employee" Property="City" Title="City" />
<RadzenDataGridColumn TItem="Employee" Property="Region" Title="Region" />
<RadzenDataGridColumn TItem="Employee" Property="PostalCode" Title="Postal Code" />
<RadzenDataGridColumn TItem="Employee" Property="Country" Title="Country" />
<RadzenDataGridColumn TItem="Employee" Property="HomePhone" Title="Home Phone" />
<RadzenDataGridColumn TItem="Employee" Property="Extension" Title="Extension" />
<RadzenDataGridColumn TItem="Employee" Property="Notes" Title="Notes" />
</Columns>
</RadzenDataGrid>
</RadzenExample>

<EventConsole @ref=@console />

@code {
EventConsole console;

IEnumerable<Employee> employees;

protected override void OnInitialized()
{
employees = dbContext.Employees;
}

void OnColumnReordered(DataGridColumnReorderedEventArgs<Employee> args)
{
console.Log($"Reordered {args.Column.Title}. Old index: {args.OldIndex}, New index: {args.NewIndex}");
}
}
7 changes: 7 additions & 0 deletions RadzenBlazorDemos/Services/ExampleService.cs
Expand Up @@ -117,6 +117,13 @@ public class ExampleService
Tags = new [] { "column", "resizing", "grid", "datagrid", "table"}
},
new Example
{
Name = "Reorder",
Path = "datagrid-column-reorder",
Title = "Blazor DataGrid column reorder",
Tags = new [] { "column", "reorder", "grid", "datagrid", "table"}
},
new Example
{
Name = "Footer Totals",
Path = "datagrid-footer-totals",
Expand Down

0 comments on commit 90edd71

Please sign in to comment.