mirror of
https://github.com/radzenhq/radzen-blazor.git
synced 2026-02-04 05:35:44 +00:00
Compare commits
176 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4608f9465 | ||
|
|
6828ee95d7 | ||
|
|
3cecde7c50 | ||
|
|
1aec2dbfb4 | ||
|
|
ba3f28cd5b | ||
|
|
b8b6a749ce | ||
|
|
1d1c64119d | ||
|
|
e93e4d03a1 | ||
|
|
1ddbb1b197 | ||
|
|
3632c3b19e | ||
|
|
25651d84dd | ||
|
|
5a59b245ce | ||
|
|
cf33f8bf74 | ||
|
|
bfb86a67da | ||
|
|
c076f7641d | ||
|
|
ff6efc7681 | ||
|
|
30a0583aab | ||
|
|
ea27a1802d | ||
|
|
9c23bbd309 | ||
|
|
a0680ffa8f | ||
|
|
94c4b723ad | ||
|
|
23ee6c2bb1 | ||
|
|
02058e523f | ||
|
|
e1951f3637 | ||
|
|
7039478ebc | ||
|
|
ff566466c8 | ||
|
|
3dae1aac2d | ||
|
|
43dad21cad | ||
|
|
9f07373e33 | ||
|
|
b09e4f3b6a | ||
|
|
be66132498 | ||
|
|
a6a70cc88e | ||
|
|
63d04b7734 | ||
|
|
90edd71274 | ||
|
|
db0252dc2c | ||
|
|
8b3e13ecba | ||
|
|
5ac96dd852 | ||
|
|
cf1ad22af1 | ||
|
|
4cf7e6888b | ||
|
|
1aa4e8bbb2 | ||
|
|
d9db327ffa | ||
|
|
6f484766ac | ||
|
|
9b6468c0b4 | ||
|
|
c5880c9096 | ||
|
|
4d588b62cb | ||
|
|
f6d2ab2e0e | ||
|
|
c52636a6e8 | ||
|
|
a24fb43ae8 | ||
|
|
8f7ead0687 | ||
|
|
39e6cc64a2 | ||
|
|
4f985776e1 | ||
|
|
b9e992f118 | ||
|
|
39e5f969e8 | ||
|
|
ee79ce4bf6 | ||
|
|
20e7a98395 | ||
|
|
c66be99be7 | ||
|
|
0bb5873fc5 | ||
|
|
50bf0b4a3b | ||
|
|
d664652b53 | ||
|
|
77d500235b | ||
|
|
a7811d9425 | ||
|
|
6c6d9d507f | ||
|
|
36ebc21d3e | ||
|
|
12f900cb6c | ||
|
|
e515bb4933 | ||
|
|
d93f46f4d6 | ||
|
|
1d4aaf04fd | ||
|
|
65469210b1 | ||
|
|
88a8bf2769 | ||
|
|
8429ff3150 | ||
|
|
890d352a65 | ||
|
|
acb85071f0 | ||
|
|
e41a60613c | ||
|
|
9001668e1b | ||
|
|
7b78f22fcc | ||
|
|
b614e6c1a4 | ||
|
|
187abcbcdf | ||
|
|
5a3a755f1a | ||
|
|
386e539148 | ||
|
|
d05375447b | ||
|
|
0fc5791b8e | ||
|
|
0e4f851098 | ||
|
|
2488378099 | ||
|
|
b906890de1 | ||
|
|
feb0236d50 | ||
|
|
22104a9bdb | ||
|
|
d0ccd9d77a | ||
|
|
dc6a7cf712 | ||
|
|
795d6bdab6 | ||
|
|
a2b41531a0 | ||
|
|
6ed4301ba4 | ||
|
|
7abab63049 | ||
|
|
b29fdd841b | ||
|
|
7e73f6f074 | ||
|
|
efc1efdfe1 | ||
|
|
11fdff952c | ||
|
|
14f90b66f2 | ||
|
|
a8d1676156 | ||
|
|
951f588a31 | ||
|
|
7081627776 | ||
|
|
391576f080 | ||
|
|
8cca3b9ef6 | ||
|
|
47c5f14eda | ||
|
|
a757b3b326 | ||
|
|
1e1475c0e9 | ||
|
|
fa68a17ea3 | ||
|
|
dc1bb0e2c1 | ||
|
|
656cfb62ff | ||
|
|
65b26a25ea | ||
|
|
6a03246234 | ||
|
|
53289b8616 | ||
|
|
349eb433ce | ||
|
|
9a98e0db24 | ||
|
|
b89e8baba0 | ||
|
|
773f276a78 | ||
|
|
1085923163 | ||
|
|
6b3ffed3e4 | ||
|
|
16a142c3c4 | ||
|
|
2b660c4d45 | ||
|
|
6283987323 | ||
|
|
fd778b0fa8 | ||
|
|
8f03d92f5b | ||
|
|
2ca624e9e2 | ||
|
|
514b00f7af | ||
|
|
05b7f6dbe9 | ||
|
|
d22eb9c85a | ||
|
|
4bd60c04a5 | ||
|
|
f361e61ce9 | ||
|
|
1e5807c585 | ||
|
|
8239b130bf | ||
|
|
09acf97c8d | ||
|
|
6e72d0bb14 | ||
|
|
34c6659703 | ||
|
|
42a067a32a | ||
|
|
f2a995ccdc | ||
|
|
463f064919 | ||
|
|
bec20e7e5d | ||
|
|
da18b35d68 | ||
|
|
842d7f453c | ||
|
|
74e63fd176 | ||
|
|
c8ec229629 | ||
|
|
d955e09268 | ||
|
|
106dfd8d47 | ||
|
|
aa4ff53d62 | ||
|
|
2a9e9932f6 | ||
|
|
df853d9867 | ||
|
|
bcd185e508 | ||
|
|
2032c30a4d | ||
|
|
2b8e217459 | ||
|
|
29948c246d | ||
|
|
901d0effe7 | ||
|
|
6a21f98d14 | ||
|
|
6eb05ce9b4 | ||
|
|
cae3414ddb | ||
|
|
3e067c9ea5 | ||
|
|
12316e8611 | ||
|
|
bf3370fad1 | ||
|
|
2cb2868d47 | ||
|
|
6ab33ba06c | ||
|
|
f826575567 | ||
|
|
498879a235 | ||
|
|
0283c5204f | ||
|
|
5bb7fea3ca | ||
|
|
593f0e7a18 | ||
|
|
1158c43430 | ||
|
|
041d53c434 | ||
|
|
1e60b41226 | ||
|
|
855d831c33 | ||
|
|
425efa412f | ||
|
|
0b5a284ceb | ||
|
|
75f1e6e569 | ||
|
|
0258316d21 | ||
|
|
b55cd42aaf | ||
|
|
8781a53f21 | ||
|
|
75a2b47abf | ||
|
|
9b531f83a6 |
47
Radzen.Blazor.Tests/BadgeTests.cs
Normal file
47
Radzen.Blazor.Tests/BadgeTests.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using Bunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Radzen.Blazor.Tests
|
||||
{
|
||||
public class BadgeTests
|
||||
{
|
||||
[Fact]
|
||||
public void Badge_Renders_TextParameter()
|
||||
{
|
||||
using var ctx = new TestContext();
|
||||
|
||||
var component = ctx.RenderComponent<RadzenBadge>();
|
||||
|
||||
var text = "Test";
|
||||
|
||||
component.SetParametersAndRender(parameters => parameters.Add(p => p.Text, text));
|
||||
|
||||
Assert.Contains(text, component.Markup);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Badge_Renders_ChildContent()
|
||||
{
|
||||
using var ctx = new TestContext();
|
||||
|
||||
var component = ctx.RenderComponent<RadzenBadge>();
|
||||
|
||||
component.SetParametersAndRender(parameters => parameters.AddChildContent("SomeContent"));
|
||||
|
||||
Assert.Contains(@$"SomeContent", component.Markup);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Badge_Renders_BadgeStyle()
|
||||
{
|
||||
var badgeStyle = BadgeStyle.Danger;
|
||||
|
||||
using var ctx = new TestContext();
|
||||
|
||||
var component = ctx.RenderComponent<RadzenBadge>();
|
||||
component.SetParametersAndRender(parameters => parameters.Add(p => p.BadgeStyle, badgeStyle));
|
||||
|
||||
Assert.Contains($"badge-{badgeStyle.ToString().ToLower()}", component.Markup);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ namespace Radzen.Blazor.Tests
|
||||
Assert.DoesNotContain(@$"<i class=""rz-button-icon-left rzi"">{icon}</i>", component.Markup);
|
||||
|
||||
// renders the icon with busy spin animation
|
||||
Assert.Contains(@"<i style=""animation: button-icon-spin", component.Markup);
|
||||
Assert.Contains(@"<i style=""animation: rotation", component.Markup);
|
||||
Assert.Contains(">refresh</i>", component.Markup);
|
||||
}
|
||||
|
||||
|
||||
98
Radzen.Blazor.Tests/DataGridColumnTests.cs
Normal file
98
Radzen.Blazor.Tests/DataGridColumnTests.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Radzen.Blazor.Tests
|
||||
{
|
||||
public class DataGridColumnTests
|
||||
{
|
||||
class TestModel
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public int Age { get; set; }
|
||||
}
|
||||
class Testable : RadzenDataGridColumn<TestModel>
|
||||
{
|
||||
public Testable()
|
||||
{
|
||||
Grid = new RadzenDataGrid<TestModel>();
|
||||
}
|
||||
public void PublicMorozov_OnInitialized()
|
||||
{
|
||||
OnInitialized();
|
||||
}
|
||||
public Type PublicMorozov_FilterPropertyType()
|
||||
{
|
||||
var propertyInfo = this.GetType()
|
||||
.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
|
||||
.FirstOrDefault(x => x.Name == "FilterPropertyType");
|
||||
|
||||
return propertyInfo?.GetValue(this) as Type;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FilterPropertyType_Assigned_From_Type_Parameter()
|
||||
{
|
||||
var column = new Testable()
|
||||
{
|
||||
Property = nameof(TestModel.Id),
|
||||
Type = typeof(string),
|
||||
FilterProperty = null
|
||||
};
|
||||
|
||||
column.PublicMorozov_OnInitialized();
|
||||
|
||||
Assert.Equal(typeof(string), column.PublicMorozov_FilterPropertyType());
|
||||
Assert.Equal(FilterOperator.Contains, column.FilterOperator);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FilterPropertyType_Assigned_From_FilterProperty_Parameter()
|
||||
{
|
||||
var column = new Testable()
|
||||
{
|
||||
Property = nameof(TestModel.Id),
|
||||
Type = null,
|
||||
FilterProperty = nameof(TestModel.Name)
|
||||
};
|
||||
|
||||
column.PublicMorozov_OnInitialized();
|
||||
|
||||
Assert.Equal(typeof(string), column.PublicMorozov_FilterPropertyType());
|
||||
Assert.Equal(FilterOperator.Contains, column.FilterOperator);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FilterPropertyType_Assigned_From_ColumnType()
|
||||
{
|
||||
var column = new Testable()
|
||||
{
|
||||
Property = nameof(TestModel.Id),
|
||||
Type = null,
|
||||
FilterProperty = null
|
||||
};
|
||||
|
||||
column.PublicMorozov_OnInitialized();
|
||||
|
||||
Assert.Equal(typeof(Guid), column.PublicMorozov_FilterPropertyType());
|
||||
Assert.Equal(FilterOperator.Equals, column.FilterOperator);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FilterPropertyType_Assigned_From_Type_If_FilterProperty_Is_Fake_Field()
|
||||
{
|
||||
var column = new Testable()
|
||||
{
|
||||
Property = nameof(TestModel.Id),
|
||||
Type = typeof(decimal),
|
||||
FilterProperty = "NotExistsField"
|
||||
};
|
||||
|
||||
column.PublicMorozov_OnInitialized();
|
||||
|
||||
Assert.Equal(typeof(decimal), column.PublicMorozov_FilterPropertyType());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,7 @@ using AngleSharp.Dom;
|
||||
using Bunit;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Rendering;
|
||||
using Radzen.Blazor.Rendering;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
@@ -22,9 +20,11 @@ namespace Radzen.Blazor.Tests
|
||||
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
|
||||
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
|
||||
|
||||
var component = ctx.RenderComponent<RadzenGrid<dynamic>>(parameterBuilder => {
|
||||
var component = ctx.RenderComponent<RadzenGrid<dynamic>>(parameterBuilder =>
|
||||
{
|
||||
parameterBuilder.Add<IEnumerable<dynamic>>(p => p.Data, new[] { new { Id = 1 }, new { Id = 2 }, new { Id = 3 } });
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder => {
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder =>
|
||||
{
|
||||
builder.OpenComponent(0, typeof(RadzenGridColumn<dynamic>));
|
||||
builder.AddAttribute(1, "Property", "Id");
|
||||
builder.CloseComponent();
|
||||
@@ -63,9 +63,11 @@ namespace Radzen.Blazor.Tests
|
||||
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
|
||||
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
|
||||
|
||||
var component = ctx.RenderComponent<RadzenGrid<dynamic>>(parameterBuilder => {
|
||||
parameterBuilder.Add<IEnumerable<dynamic>>(p => p.Data, new[] { new { Id = 1}, new { Id = 2 }, new { Id = 3 } });
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder => {
|
||||
var component = ctx.RenderComponent<RadzenGrid<dynamic>>(parameterBuilder =>
|
||||
{
|
||||
parameterBuilder.Add<IEnumerable<dynamic>>(p => p.Data, new[] { new { Id = 1 }, new { Id = 2 }, new { Id = 3 } });
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder =>
|
||||
{
|
||||
builder.OpenComponent(0, typeof(RadzenGridColumn<dynamic>));
|
||||
builder.AddAttribute(1, "Property", "Id");
|
||||
builder.CloseComponent();
|
||||
@@ -86,9 +88,11 @@ namespace Radzen.Blazor.Tests
|
||||
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
|
||||
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
|
||||
|
||||
var component = ctx.RenderComponent<RadzenGrid<dynamic>>(parameterBuilder => {
|
||||
var component = ctx.RenderComponent<RadzenGrid<dynamic>>(parameterBuilder =>
|
||||
{
|
||||
parameterBuilder.Add<IEnumerable<dynamic>>(p => p.Data, new[] { new { Id = 1 }, new { Id = 2 }, new { Id = 3 } });
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder => {
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder =>
|
||||
{
|
||||
builder.OpenComponent(0, typeof(RadzenGridColumn<dynamic>));
|
||||
builder.AddAttribute(1, "Title", "MyId");
|
||||
builder.CloseComponent();
|
||||
@@ -107,20 +111,23 @@ namespace Radzen.Blazor.Tests
|
||||
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
|
||||
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
|
||||
|
||||
var component = ctx.RenderComponent<RadzenGrid<dynamic>>(parameterBuilder => {
|
||||
var component = ctx.RenderComponent<RadzenGrid<dynamic>>(parameterBuilder =>
|
||||
{
|
||||
parameterBuilder.Add<IEnumerable<dynamic>>(p => p.Data, new[] { new { Id = 1 }, new { Id = 2 }, new { Id = 3 } });
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder => {
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder =>
|
||||
{
|
||||
builder.OpenComponent(0, typeof(RadzenGridColumn<dynamic>));
|
||||
builder.AddAttribute(1, "Property", "Id");
|
||||
builder.AddAttribute(2, "Title", "Id");
|
||||
builder.CloseComponent();
|
||||
});
|
||||
parameterBuilder.Add<bool>(p => p.AllowSorting, true) ;
|
||||
parameterBuilder.Add<bool>(p => p.AllowSorting, true);
|
||||
});
|
||||
|
||||
Assert.Contains(@$"rz-sortable-column", component.Markup);
|
||||
|
||||
component.SetParametersAndRender(parameters => {
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<bool>(p => p.AllowSorting, false);
|
||||
});
|
||||
|
||||
@@ -134,9 +141,11 @@ namespace Radzen.Blazor.Tests
|
||||
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
|
||||
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
|
||||
|
||||
var component = ctx.RenderComponent<RadzenGrid<dynamic>>(parameterBuilder => {
|
||||
var component = ctx.RenderComponent<RadzenGrid<dynamic>>(parameterBuilder =>
|
||||
{
|
||||
parameterBuilder.Add<IEnumerable<dynamic>>(p => p.Data, new[] { new { Id = 1 }, new { Id = 2 }, new { Id = 3 } });
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder => {
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder =>
|
||||
{
|
||||
builder.OpenComponent(0, typeof(RadzenGridColumn<dynamic>));
|
||||
builder.AddAttribute(1, "Property", "Id");
|
||||
builder.AddAttribute(2, "Title", "Id");
|
||||
@@ -156,9 +165,11 @@ namespace Radzen.Blazor.Tests
|
||||
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
|
||||
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
|
||||
|
||||
var component = ctx.RenderComponent<RadzenGrid<dynamic>>(parameterBuilder => {
|
||||
var component = ctx.RenderComponent<RadzenGrid<dynamic>>(parameterBuilder =>
|
||||
{
|
||||
parameterBuilder.Add<IEnumerable<dynamic>>(p => p.Data, new[] { new { Id = 1 }, new { Id = 2 }, new { Id = 3 } });
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder => {
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder =>
|
||||
{
|
||||
builder.OpenComponent(0, typeof(RadzenGridColumn<dynamic>));
|
||||
builder.AddAttribute(1, "Property", "Id");
|
||||
builder.AddAttribute(2, "Title", "Id");
|
||||
@@ -169,7 +180,8 @@ namespace Radzen.Blazor.Tests
|
||||
|
||||
Assert.Contains(@$"rz-cell-filter", component.Markup);
|
||||
|
||||
component.SetParametersAndRender(parameters => {
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<bool>(p => p.AllowFiltering, false);
|
||||
});
|
||||
|
||||
@@ -183,9 +195,11 @@ namespace Radzen.Blazor.Tests
|
||||
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
|
||||
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
|
||||
|
||||
var component = ctx.RenderComponent<RadzenGrid<dynamic>>(parameterBuilder => {
|
||||
var component = ctx.RenderComponent<RadzenGrid<dynamic>>(parameterBuilder =>
|
||||
{
|
||||
parameterBuilder.Add<IEnumerable<dynamic>>(p => p.Data, new[] { new { Id = 1 }, new { Id = 2 }, new { Id = 3 } });
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder => {
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder =>
|
||||
{
|
||||
builder.OpenComponent(0, typeof(RadzenGridColumn<dynamic>));
|
||||
builder.AddAttribute(1, "Property", "Id");
|
||||
builder.AddAttribute(2, "Title", "Id");
|
||||
@@ -205,9 +219,11 @@ namespace Radzen.Blazor.Tests
|
||||
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
|
||||
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
|
||||
|
||||
var component = ctx.RenderComponent<RadzenGrid<dynamic>>(parameterBuilder => {
|
||||
var component = ctx.RenderComponent<RadzenGrid<dynamic>>(parameterBuilder =>
|
||||
{
|
||||
parameterBuilder.Add<IEnumerable<dynamic>>(p => p.Data, new[] { new { Id = 1 }, new { Id = 2 }, new { Id = 3 } });
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder => {
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder =>
|
||||
{
|
||||
builder.OpenComponent(0, typeof(RadzenGridColumn<dynamic>));
|
||||
builder.AddAttribute(1, "Property", "Id");
|
||||
builder.AddAttribute(2, "Title", "Id");
|
||||
@@ -219,7 +235,8 @@ namespace Radzen.Blazor.Tests
|
||||
|
||||
Assert.Contains(@$"rz-grid-filter", component.Markup);
|
||||
|
||||
component.SetParametersAndRender(parameters => {
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<FilterMode>(p => p.FilterMode, FilterMode.Simple);
|
||||
});
|
||||
|
||||
@@ -233,9 +250,11 @@ namespace Radzen.Blazor.Tests
|
||||
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
|
||||
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
|
||||
|
||||
var component = ctx.RenderComponent<RadzenGrid<int>>(parameterBuilder => {
|
||||
var component = ctx.RenderComponent<RadzenGrid<int>>(parameterBuilder =>
|
||||
{
|
||||
parameterBuilder.Add<IEnumerable<int>>(p => p.Data, new[] { 1, 2, 3 });
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder => {
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder =>
|
||||
{
|
||||
builder.OpenComponent(0, typeof(RadzenGridColumn<int>));
|
||||
|
||||
builder.AddAttribute(1, "HeaderTemplate", (RenderFragment)delegate (RenderTreeBuilder b)
|
||||
@@ -257,9 +276,11 @@ namespace Radzen.Blazor.Tests
|
||||
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
|
||||
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
|
||||
|
||||
var component = ctx.RenderComponent<RadzenGrid<int>>(parameterBuilder => {
|
||||
var component = ctx.RenderComponent<RadzenGrid<int>>(parameterBuilder =>
|
||||
{
|
||||
parameterBuilder.Add<IEnumerable<int>>(p => p.Data, new[] { 1, 2, 3 });
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder => {
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder =>
|
||||
{
|
||||
builder.OpenComponent(0, typeof(RadzenGridColumn<int>));
|
||||
|
||||
builder.AddAttribute(1, "FooterTemplate", (RenderFragment)delegate (RenderTreeBuilder b)
|
||||
@@ -284,9 +305,11 @@ namespace Radzen.Blazor.Tests
|
||||
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
|
||||
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
|
||||
|
||||
var component = ctx.RenderComponent<RadzenGrid<dynamic>>(parameterBuilder => {
|
||||
var component = ctx.RenderComponent<RadzenGrid<dynamic>>(parameterBuilder =>
|
||||
{
|
||||
parameterBuilder.Add<IEnumerable<dynamic>>(p => p.Data, Enumerable.Range(0, 100).Select(i => new { Id = i }));
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder => {
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder =>
|
||||
{
|
||||
builder.OpenComponent(0, typeof(RadzenGridColumn<dynamic>));
|
||||
builder.AddAttribute(1, "Property", "Id");
|
||||
builder.AddAttribute(2, "Title", "Id");
|
||||
@@ -328,9 +351,10 @@ namespace Radzen.Blazor.Tests
|
||||
|
||||
var component = ctx.RenderComponent<RadzenGrid<int>>(parameterBuilder => parameterBuilder.Add<IEnumerable<int>>(p => p.Data, Enumerable.Range(0, 100)));
|
||||
|
||||
component.SetParametersAndRender(parameters => {
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<bool>(p => p.AllowPaging, true);
|
||||
parameters.Add<PagerPosition>(p => p.PagerPosition, PagerPosition.Top);
|
||||
parameters.Add<PagerPosition>(p => p.PagerPosition, PagerPosition.Top);
|
||||
});
|
||||
|
||||
Assert.Contains(@$"rz-paginator", component.Markup);
|
||||
@@ -346,7 +370,8 @@ namespace Radzen.Blazor.Tests
|
||||
|
||||
var component = ctx.RenderComponent<RadzenGrid<int>>(parameterBuilder => parameterBuilder.Add<IEnumerable<int>>(p => p.Data, Enumerable.Range(0, 100)));
|
||||
|
||||
component.SetParametersAndRender(parameters => {
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<bool>(p => p.AllowPaging, true);
|
||||
parameters.Add<PagerPosition>(p => p.PagerPosition, PagerPosition.TopAndBottom);
|
||||
});
|
||||
@@ -355,6 +380,57 @@ namespace Radzen.Blazor.Tests
|
||||
Assert.Contains(@$"rz-paginator-bottom", component.Markup);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DataGrid_Renders_DefaultEmptyText()
|
||||
{
|
||||
using var ctx = new TestContext();
|
||||
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
|
||||
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
|
||||
|
||||
var component = ctx.RenderComponent<RadzenGrid<int>>(parameterBuilder => parameterBuilder.Add<IEnumerable<int>>(p => p.Data, Array.Empty<int>()));
|
||||
component.Render();
|
||||
|
||||
Assert.Contains("No records to display.", component.Markup);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DataGrid_Renders_EmptyText()
|
||||
{
|
||||
string emptyText = "Lorem Ipsum";
|
||||
using var ctx = new TestContext();
|
||||
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
|
||||
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
|
||||
|
||||
var component = ctx.RenderComponent<RadzenGrid<int>>(parameterBuilder => parameterBuilder.Add<IEnumerable<int>>(p => p.Data, Array.Empty<int>()));
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add(p => p.EmptyText, emptyText);
|
||||
});
|
||||
|
||||
Assert.Contains(emptyText, component.Markup);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DataGrid_Renders_EmptyTemplate()
|
||||
{
|
||||
using var ctx = new TestContext();
|
||||
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
|
||||
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
|
||||
|
||||
var component = ctx.RenderComponent<RadzenGrid<int>>(parameterBuilder => parameterBuilder.Add<IEnumerable<int>>(p => p.Data, Array.Empty<int>()));
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<RenderFragment>(p => p.EmptyTemplate, builder =>
|
||||
{
|
||||
builder.OpenElement(0, "p");
|
||||
builder.AddContent(0, "Lorem Ipsum");
|
||||
builder.CloseElement();
|
||||
});
|
||||
});
|
||||
|
||||
Assert.Contains("<p>Lorem Ipsum</p>", component.Markup);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DataGrid_Raises_LoadDataEventOnNextPageClick()
|
||||
{
|
||||
@@ -367,7 +443,8 @@ namespace Radzen.Blazor.Tests
|
||||
var raised = false;
|
||||
LoadDataArgs newArgs = null;
|
||||
|
||||
component.SetParametersAndRender(parameters => {
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<bool>(p => p.AllowPaging, true);
|
||||
parameters.Add<LoadDataArgs>(p => p.LoadData, args => { raised = true; newArgs = args; });
|
||||
});
|
||||
@@ -391,7 +468,8 @@ namespace Radzen.Blazor.Tests
|
||||
var raised = false;
|
||||
LoadDataArgs newArgs = null;
|
||||
|
||||
component.SetParametersAndRender(parameters => {
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<bool>(p => p.AllowPaging, true);
|
||||
parameters.Add<LoadDataArgs>(p => p.LoadData, args => { raised = true; newArgs = args; });
|
||||
});
|
||||
@@ -415,7 +493,8 @@ namespace Radzen.Blazor.Tests
|
||||
var raised = false;
|
||||
LoadDataArgs newArgs = null;
|
||||
|
||||
component.SetParametersAndRender(parameters => {
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<bool>(p => p.AllowPaging, true);
|
||||
parameters.Add<LoadDataArgs>(p => p.LoadData, args => { raised = true; newArgs = args; });
|
||||
});
|
||||
@@ -440,7 +519,8 @@ namespace Radzen.Blazor.Tests
|
||||
var raised = false;
|
||||
LoadDataArgs newArgs = null;
|
||||
|
||||
component.SetParametersAndRender(parameters => {
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<bool>(p => p.AllowPaging, true);
|
||||
parameters.Add<LoadDataArgs>(p => p.LoadData, args => { raised = true; newArgs = args; });
|
||||
});
|
||||
@@ -464,7 +544,8 @@ namespace Radzen.Blazor.Tests
|
||||
|
||||
var raised = false;
|
||||
|
||||
component.SetParametersAndRender(parameters => {
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<bool>(p => p.AllowPaging, true);
|
||||
parameters.Add<LoadDataArgs>(p => p.LoadData, args => { raised = true; });
|
||||
});
|
||||
@@ -485,7 +566,8 @@ namespace Radzen.Blazor.Tests
|
||||
|
||||
var raised = false;
|
||||
|
||||
component.SetParametersAndRender(parameters => {
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<bool>(p => p.AllowPaging, true);
|
||||
parameters.Add<LoadDataArgs>(p => p.LoadData, args => { raised = true; });
|
||||
});
|
||||
@@ -506,13 +588,15 @@ namespace Radzen.Blazor.Tests
|
||||
|
||||
var raised = false;
|
||||
|
||||
component.SetParametersAndRender(parameters => {
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<bool>(p => p.AllowPaging, true);
|
||||
});
|
||||
|
||||
component.Find(".rz-paginator-last").Click();
|
||||
|
||||
component.SetParametersAndRender(parameters => {
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<LoadDataArgs>(p => p.LoadData, args => { raised = true; });
|
||||
});
|
||||
|
||||
@@ -532,13 +616,15 @@ namespace Radzen.Blazor.Tests
|
||||
|
||||
var raised = false;
|
||||
|
||||
component.SetParametersAndRender(parameters => {
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<bool>(p => p.AllowPaging, true);
|
||||
});
|
||||
|
||||
component.Find(".rz-paginator-last").Click();
|
||||
|
||||
component.SetParametersAndRender(parameters => {
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<LoadDataArgs>(p => p.LoadData, args => { raised = true; });
|
||||
});
|
||||
|
||||
@@ -559,7 +645,8 @@ namespace Radzen.Blazor.Tests
|
||||
var raised = false;
|
||||
LoadDataArgs newArgs = null;
|
||||
|
||||
component.SetParametersAndRender(parameters => {
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<bool>(p => p.AllowPaging, true);
|
||||
parameters.Add<int>(p => p.PageSize, 20);
|
||||
parameters.Add<LoadDataArgs>(p => p.LoadData, args => { raised = true; newArgs = args; });
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Bunit;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Radzen.Blazor.Tests
|
||||
@@ -145,7 +147,8 @@ namespace Radzen.Blazor.Tests
|
||||
|
||||
var raised = false;
|
||||
|
||||
component.SetParametersAndRender(parameters => {
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<bool>(p => p.AllowCollapse, true);
|
||||
parameters.Add(p => p.Collapse, args => { raised = true; });
|
||||
});
|
||||
@@ -160,5 +163,57 @@ namespace Radzen.Blazor.Tests
|
||||
|
||||
component.Find("a").Click();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Fieldset_Renders_SummaryWhenCollapsed()
|
||||
{
|
||||
using var ctx = new TestContext();
|
||||
var component = ctx.RenderComponent<RadzenFieldset>();
|
||||
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<bool>(p => p.AllowCollapse, true);
|
||||
parameters.Add<bool>(p => p.Collapsed, true);
|
||||
parameters.Add<RenderFragment>(p => p.SummaryTemplate, builder =>
|
||||
{
|
||||
builder.OpenElement(0, "p");
|
||||
builder.AddContent(0, "SummaryContent");
|
||||
builder.CloseElement();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Assert.Contains("SummaryContent", component.Markup);
|
||||
Assert.Equal(
|
||||
"",
|
||||
component.Find(".rz-fieldset-content-summary").ParentElement.Attributes.First(attr => attr.Name == "style").Value
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Fieldset_DontRenders_SummaryWhenOpen()
|
||||
{
|
||||
using var ctx = new TestContext();
|
||||
var component = ctx.RenderComponent<RadzenFieldset>();
|
||||
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<bool>(p => p.AllowCollapse, true);
|
||||
parameters.Add<bool>(p => p.Collapsed, false);
|
||||
parameters.Add<RenderFragment>(p => p.SummaryTemplate, builder =>
|
||||
{
|
||||
builder.OpenElement(0, "p");
|
||||
builder.AddContent(0, "SummaryContent");
|
||||
builder.CloseElement();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Assert.Contains("SummaryContent", component.Markup);
|
||||
Assert.Equal(
|
||||
"display: none",
|
||||
component.Find(".rz-fieldset-content-summary").ParentElement.Attributes.First(attr => attr.Name == "style").Value
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Radzen.Blazor.Tests
|
||||
|
||||
var component = ctx.RenderComponent<RadzenLogin>();
|
||||
|
||||
Assert.Contains(@$"<input name=""userName"" class=""rz-textbox""", component.Markup);
|
||||
Assert.Contains(@$"<input name=""Username""", component.Markup);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -89,30 +89,6 @@ namespace Radzen.Blazor.Tests
|
||||
Assert.True(!clicked);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Login_Validates_UsernameParameter()
|
||||
{
|
||||
using var ctx = new TestContext();
|
||||
|
||||
var component = ctx.RenderComponent<RadzenLogin>();
|
||||
|
||||
component.Find("button").Click();
|
||||
|
||||
Assert.Contains(@$"Username is required", component.Markup);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Login_Validates_PasswordParameter()
|
||||
{
|
||||
using var ctx = new TestContext();
|
||||
|
||||
var component = ctx.RenderComponent<RadzenLogin>();
|
||||
|
||||
component.Find("button").Click();
|
||||
|
||||
Assert.Contains(@$"Password is required", component.Markup);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Login_Renders_LoginTextParameter()
|
||||
{
|
||||
@@ -214,7 +190,7 @@ namespace Radzen.Blazor.Tests
|
||||
parameters.Add(p => p.Register, args => { clicked = true; });
|
||||
});
|
||||
|
||||
component.Find(".btn-secondary").Click();
|
||||
component.Find(".register > button").Click();
|
||||
|
||||
Assert.True(clicked);
|
||||
}
|
||||
@@ -257,17 +233,5 @@ namespace Radzen.Blazor.Tests
|
||||
|
||||
Assert.True(!clicked);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Login_Validates_UsernameParameter_OnResetPasswordEvent()
|
||||
{
|
||||
using var ctx = new TestContext();
|
||||
|
||||
var component = ctx.RenderComponent<RadzenLogin>();
|
||||
|
||||
component.Find("a").Click();
|
||||
|
||||
Assert.Contains(@$"Username is required", component.Markup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
57
Radzen.Blazor.Tests/PagerTests.cs
Normal file
57
Radzen.Blazor.Tests/PagerTests.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using Bunit;
|
||||
using Bunit.JSInterop;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Xunit;
|
||||
|
||||
namespace Radzen.Blazor.Tests
|
||||
{
|
||||
public class PagerTests
|
||||
{
|
||||
[Fact]
|
||||
public void RadzenPager_AutoHide_If_Count_Is_Less_Than_PageSize()
|
||||
{
|
||||
using var ctx = new TestContext();
|
||||
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
|
||||
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
|
||||
|
||||
var component = ctx.RenderComponent<RadzenPager>(parameters =>
|
||||
{
|
||||
parameters.Add<int>(p => p.PageSize, 20);
|
||||
parameters.Add<int>(p => p.Count, 100);
|
||||
});
|
||||
|
||||
component.Render();
|
||||
|
||||
Assert.Contains(@$"rz-paginator", component.Markup);
|
||||
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<int>(p => p.PageSize, 101);
|
||||
parameters.Add<int>(p => p.Count, 100);
|
||||
});
|
||||
Assert.DoesNotContain(@$"rz-paginator", component.Markup);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RadzenPager_Dont_AutoHide_If_PageSizeOptions_Specified()
|
||||
{
|
||||
using var ctx = new TestContext();
|
||||
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
|
||||
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
|
||||
|
||||
var component = ctx.RenderComponent<RadzenPager>(parameters =>
|
||||
{
|
||||
parameters.Add<int>(p => p.PageSize, 101);
|
||||
parameters.Add<int>(p => p.Count, 100);
|
||||
parameters.Add<IEnumerable<int>>(p => p.PageSizeOptions, new int[] { 3, 7, 15 });
|
||||
});
|
||||
|
||||
component.Render();
|
||||
|
||||
Assert.Contains(@$"rz-paginator", component.Markup);
|
||||
Assert.Contains(@$"rz-dropdown-trigger", component.Markup);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using Bunit;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Radzen.Blazor.Tests
|
||||
@@ -159,7 +161,8 @@ namespace Radzen.Blazor.Tests
|
||||
|
||||
var raised = false;
|
||||
|
||||
component.SetParametersAndRender(parameters => {
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<bool>(p => p.AllowCollapse, true);
|
||||
parameters.Add(p => p.Collapse, args => { raised = true; });
|
||||
});
|
||||
@@ -174,5 +177,57 @@ namespace Radzen.Blazor.Tests
|
||||
|
||||
component.Find("a").Click();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Panel_Renders_SummaryWhenCollapsed()
|
||||
{
|
||||
using var ctx = new TestContext();
|
||||
var component = ctx.RenderComponent<RadzenPanel>();
|
||||
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<bool>(p => p.AllowCollapse, true);
|
||||
parameters.Add<bool>(p => p.Collapsed, true);
|
||||
parameters.Add<RenderFragment>(p => p.SummaryTemplate, builder =>
|
||||
{
|
||||
builder.OpenElement(0, "p");
|
||||
builder.AddContent(0, "SummaryContent");
|
||||
builder.CloseElement();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Assert.Contains("SummaryContent", component.Markup);
|
||||
Assert.Equal(
|
||||
"display: block",
|
||||
component.Find(".rz-panel-content-summary").ParentElement.Attributes.First(attr => attr.Name == "style").Value
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Panel_DontRenders_SummaryWhenOpen()
|
||||
{
|
||||
using var ctx = new TestContext();
|
||||
var component = ctx.RenderComponent<RadzenPanel>();
|
||||
|
||||
component.SetParametersAndRender(parameters =>
|
||||
{
|
||||
parameters.Add<bool>(p => p.AllowCollapse, true);
|
||||
parameters.Add<bool>(p => p.Collapsed, false);
|
||||
parameters.Add<RenderFragment>(p => p.SummaryTemplate, builder =>
|
||||
{
|
||||
builder.OpenElement(0, "p");
|
||||
builder.AddContent(0, "SummaryContent");
|
||||
builder.CloseElement();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Assert.Contains("SummaryContent", component.Markup);
|
||||
Assert.Equal(
|
||||
"display: none",
|
||||
component.Find(".rz-panel-content-summary").ParentElement.Attributes.First(attr => attr.Name == "style").Value
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,6 +250,7 @@ namespace Radzen.Blazor
|
||||
}
|
||||
|
||||
Chart.Refresh(false);
|
||||
Chart.DisplayTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using System.Linq.Dynamic.Core;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Forms;
|
||||
using Radzen.Blazor;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Dynamic.Core;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace Radzen
|
||||
{
|
||||
@@ -173,6 +172,12 @@ namespace Radzen
|
||||
}
|
||||
}
|
||||
|
||||
public enum TabRenderMode
|
||||
{
|
||||
Server,
|
||||
Client
|
||||
}
|
||||
|
||||
public enum PagerPosition
|
||||
{
|
||||
Top,
|
||||
@@ -283,7 +288,8 @@ namespace Radzen
|
||||
GreaterThanOrEquals,
|
||||
Contains,
|
||||
StartsWith,
|
||||
EndsWith
|
||||
EndsWith,
|
||||
DoesNotContain
|
||||
}
|
||||
|
||||
public enum TextAlign
|
||||
@@ -293,14 +299,32 @@ namespace Radzen
|
||||
Center
|
||||
}
|
||||
|
||||
public enum BadgeStyle
|
||||
{
|
||||
Primary,
|
||||
Secondary,
|
||||
Light,
|
||||
Success,
|
||||
Danger,
|
||||
Warning,
|
||||
Info
|
||||
}
|
||||
|
||||
public class DataGridColumnResizedEventArgs<T>
|
||||
{
|
||||
public RadzenDataGridColumn<T> Column { get; internal set; }
|
||||
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; }
|
||||
public double Width { get; internal set; }
|
||||
}
|
||||
@@ -317,7 +341,25 @@ namespace Radzen
|
||||
public class SortDescriptor
|
||||
{
|
||||
public string Property { get; set; }
|
||||
public SortOrder SortOrder { get; set; }
|
||||
public SortOrder? SortOrder { get; set; }
|
||||
}
|
||||
|
||||
public class GroupDescriptor
|
||||
{
|
||||
public string Property { get; set; }
|
||||
public string Title { get; set; }
|
||||
|
||||
public string GetTitle()
|
||||
{
|
||||
return !string.IsNullOrEmpty(Title) ? Title : Property;
|
||||
}
|
||||
}
|
||||
|
||||
public class Group
|
||||
{
|
||||
public GroupResult Data { get; set; }
|
||||
public GroupDescriptor GroupDescriptor { get; set; }
|
||||
public int Level { get; set; }
|
||||
}
|
||||
|
||||
public class LoadDataArgs
|
||||
@@ -462,6 +504,7 @@ namespace Radzen
|
||||
|
||||
public static bool IsDate(Type source)
|
||||
{
|
||||
if (source == null) return false;
|
||||
var type = source.IsGenericType ? source.GetGenericArguments()[0] : source;
|
||||
|
||||
if (type == typeof(DateTime) || type == typeof(DateTimeOffset))
|
||||
@@ -726,4 +769,16 @@ namespace Radzen
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public class RadzenSplitterEventArgs
|
||||
{
|
||||
public int PaneIndex { get; set; }
|
||||
public RadzenSplitterPane Pane { get; set; }
|
||||
public bool Cancel { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class RadzenSplitterResizeEventArgs:RadzenSplitterEventArgs
|
||||
{
|
||||
public double NewSize { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,35 +92,26 @@ namespace Radzen
|
||||
ShowClose = options != null ? options.ShowClose : true,
|
||||
ChildContent = options?.ChildContent,
|
||||
Style = options != null ? options.Style : "",
|
||||
AutoFocusFirstElement = options != null ? options.AutoFocusFirstElement : true
|
||||
});
|
||||
}
|
||||
|
||||
private object closingDialog = null;
|
||||
|
||||
public void Close(dynamic result = null)
|
||||
{
|
||||
if (closingDialog == null)
|
||||
var dialog = dialogs.LastOrDefault();
|
||||
|
||||
if (dialog != null)
|
||||
{
|
||||
closingDialog = dialogs.LastOrDefault();
|
||||
|
||||
if (closingDialog != null)
|
||||
{
|
||||
OnClose?.Invoke(result);
|
||||
dialogs.Remove(closingDialog);
|
||||
}
|
||||
|
||||
var task = tasks.LastOrDefault();
|
||||
if (task != null && task.Task != null && !task.Task.IsCompleted)
|
||||
{
|
||||
task.SetResult(result);
|
||||
tasks.Remove(task);
|
||||
}
|
||||
OnClose?.Invoke(result);
|
||||
dialogs.Remove(dialog);
|
||||
}
|
||||
}
|
||||
|
||||
internal void DidCloseDialog()
|
||||
{
|
||||
closingDialog = null;
|
||||
var task = tasks.LastOrDefault();
|
||||
if (task != null && task.Task != null && !task.Task.IsCompleted)
|
||||
{
|
||||
tasks.Remove(task);
|
||||
task.SetResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
@@ -186,6 +177,7 @@ namespace Radzen
|
||||
public string Height { get; set; }
|
||||
public string Style { get; set; }
|
||||
public RenderFragment<DialogService> ChildContent { get; set; }
|
||||
public bool AutoFocusFirstElement { get; set; } = true;
|
||||
}
|
||||
|
||||
public class ConfirmOptions : DialogOptions
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Linq.Dynamic.Core;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Rendering;
|
||||
using Microsoft.JSInterop;
|
||||
using Radzen.Blazor;
|
||||
|
||||
@@ -13,6 +14,84 @@ namespace Radzen
|
||||
{
|
||||
public class DropDownBase<T> : DataBoundFormComponent<T>
|
||||
{
|
||||
#if NET5
|
||||
internal Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize<object> virtualize;
|
||||
|
||||
private async ValueTask<Microsoft.AspNetCore.Components.Web.Virtualization.ItemsProviderResult<object>> LoadItems(Microsoft.AspNetCore.Components.Web.Virtualization.ItemsProviderRequest request)
|
||||
{
|
||||
var data = Data != null ? Data.Cast<object>() : Enumerable.Empty<object>();
|
||||
var view = (LoadData.HasDelegate ? data : View).Cast<object>().AsQueryable();
|
||||
var totalItemsCount = LoadData.HasDelegate ? Count : view.Count();
|
||||
var top = Math.Min(request.Count, totalItemsCount - request.StartIndex);
|
||||
|
||||
if (LoadData.HasDelegate)
|
||||
{
|
||||
await LoadData.InvokeAsync(new Radzen.LoadDataArgs() { Skip = request.StartIndex, Top = top, Filter = await JSRuntime.InvokeAsync<string>("Radzen.getInputValue", search) });
|
||||
}
|
||||
|
||||
return new Microsoft.AspNetCore.Components.Web.Virtualization.ItemsProviderResult<object>(LoadData.HasDelegate ? Data.Cast<object>() : view.Skip(request.StartIndex).Take(top), totalItemsCount);
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public int Count { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool AllowVirtualization { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public int PageSize { get; set; } = 5;
|
||||
#endif
|
||||
internal bool IsVirtualizationAllowed()
|
||||
{
|
||||
#if NET5
|
||||
return AllowVirtualization;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
internal virtual RenderFragment RenderItems()
|
||||
{
|
||||
return new RenderFragment(builder =>
|
||||
{
|
||||
#if NET5
|
||||
if (AllowVirtualization)
|
||||
{
|
||||
builder.OpenComponent(0, typeof(Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize<object>));
|
||||
builder.AddAttribute(1, "ItemsProvider", new Microsoft.AspNetCore.Components.Web.Virtualization.ItemsProviderDelegate<object>(LoadItems));
|
||||
builder.AddAttribute(2, "ChildContent", (RenderFragment<object>)((context) =>
|
||||
{
|
||||
return (RenderFragment)((b) =>
|
||||
{
|
||||
RenderItem(b, context);
|
||||
});
|
||||
}));
|
||||
|
||||
builder.AddComponentReferenceCapture(7, c => { virtualize = (Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize<object>)c; });
|
||||
|
||||
builder.CloseComponent();
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var item in LoadData.HasDelegate ? Data : View)
|
||||
{
|
||||
RenderItem(builder, item);
|
||||
}
|
||||
}
|
||||
#else
|
||||
foreach (var item in LoadData.HasDelegate ? Data : View)
|
||||
{
|
||||
RenderItem(builder, item);
|
||||
}
|
||||
#endif
|
||||
});
|
||||
}
|
||||
|
||||
internal virtual void RenderItem(RenderTreeBuilder builder, object item)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public virtual bool AllowFiltering { get; set; }
|
||||
|
||||
@@ -189,7 +268,7 @@ namespace Radzen
|
||||
if (Disabled)
|
||||
return;
|
||||
|
||||
var items = (LoadData.HasDelegate ? Data != null ? Data : Enumerable.Empty<object>() : (View != null ? View : Enumerable.Empty<object>())).OfType<object>();
|
||||
var items = (LoadData.HasDelegate ? Data != null ? Data : Enumerable.Empty<object>() : (View != null ? View : Enumerable.Empty<object>())).Cast<object>();
|
||||
|
||||
var key = args.Code != null ? args.Code : args.Key;
|
||||
|
||||
@@ -240,6 +319,11 @@ namespace Radzen
|
||||
selectedIndex = -1;
|
||||
await OnSelectItem(null, true);
|
||||
}
|
||||
|
||||
if (AllowFiltering && isFilter)
|
||||
{
|
||||
Debounce(DebounceFilter, FilterDelay);
|
||||
}
|
||||
}
|
||||
else if(AllowFiltering && isFilter)
|
||||
{
|
||||
@@ -258,12 +342,40 @@ namespace Radzen
|
||||
{
|
||||
searchText = await JSRuntime.InvokeAsync<string>("Radzen.getInputValue", search);
|
||||
_view = null;
|
||||
await InvokeAsync(() => { StateHasChanged(); });
|
||||
if (IsVirtualizationAllowed())
|
||||
{
|
||||
#if NET5
|
||||
if (virtualize != null)
|
||||
{
|
||||
await virtualize.RefreshDataAsync();
|
||||
}
|
||||
await InvokeAsync(() => { StateHasChanged(); });
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
await InvokeAsync(() => { StateHasChanged(); });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await LoadData.InvokeAsync(new Radzen.LoadDataArgs() { Filter = await JSRuntime.InvokeAsync<string>("Radzen.getInputValue", search) });
|
||||
if (IsVirtualizationAllowed())
|
||||
{
|
||||
#if NET5
|
||||
if (virtualize != null)
|
||||
{
|
||||
await InvokeAsync(virtualize.RefreshDataAsync);
|
||||
}
|
||||
await InvokeAsync(() => { StateHasChanged(); });
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
await LoadData.InvokeAsync(await GetLoadDataArgs());
|
||||
}
|
||||
}
|
||||
|
||||
await JSRuntime.InvokeAsync<string>("Radzen.repositionPopup", Element, PopupID);
|
||||
}
|
||||
|
||||
protected async System.Threading.Tasks.Task OnKeyPress(Microsoft.AspNetCore.Components.Web.KeyboardEventArgs args)
|
||||
@@ -278,16 +390,23 @@ namespace Radzen
|
||||
|
||||
protected virtual async System.Threading.Tasks.Task OnFilter(ChangeEventArgs args)
|
||||
{
|
||||
if (!LoadData.HasDelegate)
|
||||
await DebounceFilter();
|
||||
}
|
||||
|
||||
internal virtual async System.Threading.Tasks.Task<LoadDataArgs> GetLoadDataArgs()
|
||||
{
|
||||
#if NET5
|
||||
if (AllowVirtualization)
|
||||
{
|
||||
searchText = await JSRuntime.InvokeAsync<string>("Radzen.getInputValue", search);
|
||||
_view = null;
|
||||
StateHasChanged();
|
||||
return new Radzen.LoadDataArgs() { Skip = 0, Top = PageSize, Filter = await JSRuntime.InvokeAsync<string>("Radzen.getInputValue", search) };
|
||||
}
|
||||
else
|
||||
{
|
||||
await LoadData.InvokeAsync(new Radzen.LoadDataArgs() { Filter = await JSRuntime.InvokeAsync<string>("Radzen.getInputValue", search) });
|
||||
return new Radzen.LoadDataArgs() { Filter = await JSRuntime.InvokeAsync<string>("Radzen.getInputValue", search) };
|
||||
}
|
||||
#else
|
||||
return new Radzen.LoadDataArgs() { Filter = await JSRuntime.InvokeAsync<string>("Radzen.getInputValue", search) };
|
||||
#endif
|
||||
}
|
||||
|
||||
private bool firstRender = true;
|
||||
@@ -301,6 +420,13 @@ namespace Radzen
|
||||
|
||||
public override async Task SetParametersAsync(ParameterView parameters)
|
||||
{
|
||||
#if NET5
|
||||
var pageSize = parameters.GetValueOrDefault<int>(nameof(PageSize));
|
||||
if(pageSize != default(int))
|
||||
{
|
||||
PageSize = pageSize;
|
||||
}
|
||||
#endif
|
||||
var shouldClose = false;
|
||||
|
||||
if (parameters.DidParameterChange(nameof(Visible), Visible))
|
||||
@@ -339,7 +465,7 @@ namespace Radzen
|
||||
Value = args.Value;
|
||||
}
|
||||
|
||||
protected bool isSelected(object item)
|
||||
internal bool isSelected(object item)
|
||||
{
|
||||
if (Multiple)
|
||||
{
|
||||
@@ -372,7 +498,55 @@ namespace Radzen
|
||||
{
|
||||
get
|
||||
{
|
||||
return (LoadData.HasDelegate ? Data != null ? Data : Enumerable.Empty<object>() : (View != null ? View : Enumerable.Empty<object>())).OfType<object>();
|
||||
return (LoadData.HasDelegate ? Data != null ? Data : Enumerable.Empty<object>() : (View != null ? View : Enumerable.Empty<object>())).Cast<object>();
|
||||
}
|
||||
}
|
||||
|
||||
protected override IEnumerable View
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_view == null && Query != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(searchText))
|
||||
{
|
||||
var ignoreCase = FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive;
|
||||
|
||||
var query = new List<string>();
|
||||
|
||||
if (!string.IsNullOrEmpty(TextProperty))
|
||||
{
|
||||
query.Add(TextProperty);
|
||||
}
|
||||
|
||||
if (typeof(EnumerableQuery).IsAssignableFrom(Query.GetType()))
|
||||
{
|
||||
query.Add("ToString()");
|
||||
}
|
||||
|
||||
if (ignoreCase)
|
||||
{
|
||||
query.Add("ToLower()");
|
||||
}
|
||||
|
||||
query.Add($"{Enum.GetName(typeof(StringFilterOperator), FilterOperator)}(@0)");
|
||||
|
||||
_view = Query.Where(String.Join(".", query), ignoreCase ? searchText.ToLower() : searchText);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsVirtualizationAllowed())
|
||||
{
|
||||
_view = Query;
|
||||
}
|
||||
else
|
||||
{
|
||||
_view = (typeof(IQueryable).IsAssignableFrom(Data.GetType())) ? Query.Cast<object>().ToList().AsQueryable() : Query;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _view;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -380,10 +554,13 @@ namespace Radzen
|
||||
{
|
||||
if (selectedItem != null)
|
||||
{
|
||||
var result = Items.Select((x, i) => new { Item = x, Index = i }).FirstOrDefault(itemWithIndex => object.Equals(itemWithIndex.Item, selectedItem));
|
||||
if (result != null)
|
||||
if (typeof(EnumerableQuery).IsAssignableFrom(View.GetType()))
|
||||
{
|
||||
selectedIndex = result.Index;
|
||||
var result = Items.Select((x, i) => new { Item = x, Index = i }).FirstOrDefault(itemWithIndex => object.Equals(itemWithIndex.Item, selectedItem));
|
||||
if (result != null)
|
||||
{
|
||||
selectedIndex = result.Index;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -392,6 +569,11 @@ namespace Radzen
|
||||
}
|
||||
}
|
||||
|
||||
internal async System.Threading.Tasks.Task SelectItemInternal(object item, bool raiseChange = true)
|
||||
{
|
||||
await SelectItem(item, raiseChange);
|
||||
}
|
||||
|
||||
protected async System.Threading.Tasks.Task SelectItem(object item, bool raiseChange = true)
|
||||
{
|
||||
if (!Multiple)
|
||||
@@ -498,7 +680,7 @@ namespace Radzen
|
||||
item = View.AsQueryable().Where($@"{ValueProperty} == @0", v).FirstOrDefault();
|
||||
}
|
||||
|
||||
if (item != null && selectedItems.IndexOf(item) == -1)
|
||||
if (!object.Equals(item, null) && selectedItems.IndexOf(item) == -1)
|
||||
{
|
||||
selectedItems.Add(item);
|
||||
}
|
||||
|
||||
@@ -49,6 +49,9 @@ namespace Radzen
|
||||
}
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public IEnumerable<int> PageSizeOptions { get; set; }
|
||||
|
||||
protected IQueryable<T> _view = null;
|
||||
public virtual IQueryable<T> PagedView
|
||||
{
|
||||
@@ -56,7 +59,7 @@ namespace Radzen
|
||||
{
|
||||
if (_view == null)
|
||||
{
|
||||
_view = (AllowPaging ? View.Skip(skip).Take(PageSize) : View).ToList().AsQueryable();
|
||||
_view = (AllowPaging && !LoadData.HasDelegate ? View.Skip(skip).Take(PageSize) : View).ToList().AsQueryable();
|
||||
}
|
||||
return _view;
|
||||
}
|
||||
@@ -97,6 +100,18 @@ namespace Radzen
|
||||
|
||||
}
|
||||
|
||||
public override async Task SetParametersAsync(ParameterView parameters)
|
||||
{
|
||||
bool pageSizeChanged = parameters.DidParameterChange(nameof(PageSize), PageSize);
|
||||
|
||||
await base.SetParametersAsync(parameters);
|
||||
|
||||
if (pageSizeChanged && !firstRender)
|
||||
{
|
||||
await InvokeAsync(Reload);
|
||||
}
|
||||
}
|
||||
|
||||
protected override Task OnParametersSetAsync()
|
||||
{
|
||||
if (Visible && !LoadData.HasDelegate)
|
||||
@@ -111,8 +126,10 @@ namespace Radzen
|
||||
return base.OnParametersSetAsync();
|
||||
}
|
||||
|
||||
bool firstRender = true;
|
||||
protected override Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
this.firstRender = firstRender;
|
||||
if (firstRender && Visible && (LoadData.HasDelegate && Data == null))
|
||||
{
|
||||
InvokeAsync(Reload);
|
||||
@@ -134,15 +151,23 @@ namespace Radzen
|
||||
await InvokeAsync(Reload);
|
||||
}
|
||||
|
||||
protected async Task OnPageSizeChanged(int value)
|
||||
{
|
||||
PageSize = value;
|
||||
await InvokeAsync(Reload);
|
||||
}
|
||||
|
||||
protected void CalculatePager()
|
||||
{
|
||||
if (topPager != null)
|
||||
{
|
||||
bottomPager.SetCount(Count);
|
||||
topPager.SetCurrentPage(CurrentPage);
|
||||
}
|
||||
|
||||
if (bottomPager != null)
|
||||
{
|
||||
bottomPager.SetCount(Count);
|
||||
bottomPager.SetCurrentPage(CurrentPage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,8 @@ namespace Radzen
|
||||
{"ge", ">="},
|
||||
{"startswith", "StartsWith"},
|
||||
{"endswith", "EndsWith"},
|
||||
{"contains", "Contains"}
|
||||
{"contains", "Contains"},
|
||||
{"DoesNotContain", "Contains"}
|
||||
};
|
||||
|
||||
internal static readonly IDictionary<FilterOperator, string> LinqFilterOperators = new Dictionary<FilterOperator, string>
|
||||
@@ -32,7 +33,8 @@ namespace Radzen
|
||||
{FilterOperator.GreaterThanOrEquals, ">="},
|
||||
{FilterOperator.StartsWith, "StartsWith"},
|
||||
{FilterOperator.EndsWith, "EndsWith"},
|
||||
{FilterOperator.Contains, "Contains"}
|
||||
{FilterOperator.Contains, "Contains"},
|
||||
{FilterOperator.DoesNotContain, "DoesNotContain"}
|
||||
};
|
||||
|
||||
internal static readonly IDictionary<FilterOperator, string> ODataFilterOperators = new Dictionary<FilterOperator, string>
|
||||
@@ -45,7 +47,8 @@ namespace Radzen
|
||||
{FilterOperator.GreaterThanOrEquals, "ge"},
|
||||
{FilterOperator.StartsWith, "startswith"},
|
||||
{FilterOperator.EndsWith, "endswith"},
|
||||
{FilterOperator.Contains, "contains"}
|
||||
{FilterOperator.Contains, "contains"},
|
||||
{FilterOperator.DoesNotContain, "DoesNotContain"}
|
||||
};
|
||||
|
||||
public static IList ToList(IQueryable query)
|
||||
@@ -114,8 +117,27 @@ namespace Radzen
|
||||
var whereList = new List<string>();
|
||||
foreach (var column in columns.Where(canFilter))
|
||||
{
|
||||
var value = (string)Convert.ChangeType(column.GetFilterValue(), typeof(string));
|
||||
var secondValue = (string)Convert.ChangeType(column.GetSecondFilterValue(), typeof(string));
|
||||
string value = "";
|
||||
string secondValue = "";
|
||||
|
||||
if (PropertyAccess.IsDate(column.FilterPropertyType))
|
||||
{
|
||||
var v = column.GetFilterValue();
|
||||
var sv = column.GetSecondFilterValue();
|
||||
if (v != null)
|
||||
{
|
||||
value = v is DateTime ? ((DateTime)v).ToString("yyyy-MM-ddTHH:mm:ss.fffZ") : v is DateTimeOffset ? ((DateTimeOffset)v).UtcDateTime.ToString("yyyy-MM-ddTHH:mm:ss.fffZ") : "";
|
||||
}
|
||||
if (sv != null)
|
||||
{
|
||||
secondValue = sv is DateTime ? ((DateTime)sv).ToString("yyyy-MM-ddTHH:mm:ss.fffZ") : sv is DateTimeOffset ? ((DateTimeOffset)sv).UtcDateTime.ToString("yyyy-MM-ddTHH:mm:ss.fffZ") : "";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value = (string)Convert.ChangeType(column.GetFilterValue(), typeof(string));
|
||||
secondValue = (string)Convert.ChangeType(column.GetSecondFilterValue(), typeof(string));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
@@ -129,11 +151,11 @@ namespace Radzen
|
||||
|
||||
if (string.IsNullOrEmpty(secondValue))
|
||||
{
|
||||
whereList.Add(GetColumnFilter(column));
|
||||
whereList.Add(GetColumnFilter(column, value));
|
||||
}
|
||||
else
|
||||
{
|
||||
whereList.Add($"({GetColumnFilter(column)} {booleanOperator} {GetColumnFilter(column, true)})");
|
||||
whereList.Add($"({GetColumnFilter(column, value)} {booleanOperator} {GetColumnFilter(column, secondValue, true)})");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,6 +218,10 @@ namespace Radzen
|
||||
{
|
||||
return $@"({property} == null ? """" : {property}){filterCaseSensitivityOperator}.Contains(""{value}""{filterCaseSensitivityOperator})";
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == "DoesNotContain")
|
||||
{
|
||||
return $@"({property} == null ? """" : !{property}){filterCaseSensitivityOperator}.Contains(""{value}""{filterCaseSensitivityOperator})";
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == "startswith")
|
||||
{
|
||||
return $@"({property} == null ? """" : {property}){filterCaseSensitivityOperator}.StartsWith(""{value}""{filterCaseSensitivityOperator})";
|
||||
@@ -206,7 +232,11 @@ namespace Radzen
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == "eq")
|
||||
{
|
||||
return $@"{property} == null ? """" : {property}{filterCaseSensitivityOperator} == {value}{filterCaseSensitivityOperator}";
|
||||
return $@"({property} == null ? """" : {property}){filterCaseSensitivityOperator} == ""{value}""{filterCaseSensitivityOperator}";
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == "ne")
|
||||
{
|
||||
return $@"({property} == null ? """" : {property}){filterCaseSensitivityOperator} != ""{value}""{filterCaseSensitivityOperator}";
|
||||
}
|
||||
}
|
||||
else if (columnType == "number" || columnType == "integer")
|
||||
@@ -221,7 +251,7 @@ namespace Radzen
|
||||
return "";
|
||||
}
|
||||
|
||||
private static string GetColumnFilter<T>(RadzenDataGridColumn<T> column, bool second = false)
|
||||
private static string GetColumnFilter<T>(RadzenDataGridColumn<T> column, string value, bool second = false)
|
||||
{
|
||||
var property = PropertyAccess.GetProperty(column.GetFilterProperty());
|
||||
|
||||
@@ -230,11 +260,6 @@ namespace Radzen
|
||||
property = $"({property})";
|
||||
}
|
||||
|
||||
if (column.FilterPropertyType == typeof(string))
|
||||
{
|
||||
property = $@"({property} == null ? """" : {property})";
|
||||
}
|
||||
|
||||
var columnFilterOperator = !second ? column.GetFilterOperator() : column.GetSecondFilterOperator();
|
||||
|
||||
var linqOperator = LinqFilterOperators[columnFilterOperator];
|
||||
@@ -243,9 +268,6 @@ namespace Radzen
|
||||
linqOperator = "==";
|
||||
}
|
||||
|
||||
var value = !second ? (string)Convert.ChangeType(column.GetFilterValue(), typeof(string)) :
|
||||
(string)Convert.ChangeType(column.GetSecondFilterValue(), typeof(string));
|
||||
|
||||
if (column.FilterPropertyType == typeof(string))
|
||||
{
|
||||
string filterCaseSensitivityOperator = column.Grid.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ? ".ToLower()" : "";
|
||||
@@ -254,6 +276,10 @@ namespace Radzen
|
||||
{
|
||||
return $@"({property} == null ? """" : {property}){filterCaseSensitivityOperator}.Contains(""{value}""{filterCaseSensitivityOperator})";
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == FilterOperator.DoesNotContain)
|
||||
{
|
||||
return $@"!({property} == null ? """" : {property}){filterCaseSensitivityOperator}.Contains(""{value}""{filterCaseSensitivityOperator})";
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == FilterOperator.StartsWith)
|
||||
{
|
||||
return $@"({property} == null ? """" : {property}){filterCaseSensitivityOperator}.StartsWith(""{value}""{filterCaseSensitivityOperator})";
|
||||
@@ -264,7 +290,11 @@ namespace Radzen
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == FilterOperator.Equals)
|
||||
{
|
||||
return $@"{property} == null ? """" : {property}{filterCaseSensitivityOperator} == {value}{filterCaseSensitivityOperator}";
|
||||
return $@"({property} == null ? """" : {property}){filterCaseSensitivityOperator} == ""{value}""{filterCaseSensitivityOperator}";
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == FilterOperator.NotEquals)
|
||||
{
|
||||
return $@"({property} == null ? """" : {property}){filterCaseSensitivityOperator} != ""{value}""{filterCaseSensitivityOperator}";
|
||||
}
|
||||
}
|
||||
else if (PropertyAccess.IsNumeric(column.FilterPropertyType))
|
||||
@@ -279,8 +309,9 @@ namespace Radzen
|
||||
var dateTimeValue = DateTime.Parse(value, null, System.Globalization.DateTimeStyles.RoundtripKind);
|
||||
var finalDate = dateTimeValue.TimeOfDay == TimeSpan.Zero ? dateTimeValue.Date : dateTimeValue;
|
||||
var dateFormat = dateTimeValue.TimeOfDay == TimeSpan.Zero ? "yyyy-MM-dd" : "yyyy-MM-ddTHH:mm:ssZ";
|
||||
var dateFunction = column.FilterPropertyType == typeof(DateTimeOffset) || column.FilterPropertyType == typeof(DateTimeOffset?) ? "DateTimeOffset" : "DateTime";
|
||||
|
||||
return $@"{property} {linqOperator} DateTime(""{finalDate.ToString(dateFormat)}"")";
|
||||
return $@"{property} {linqOperator} {dateFunction}(""{finalDate.ToString(dateFormat)}"")";
|
||||
}
|
||||
else if (column.FilterPropertyType == typeof(bool) || column.FilterPropertyType == typeof(bool?))
|
||||
{
|
||||
@@ -331,6 +362,12 @@ namespace Radzen
|
||||
$"contains({property}, tolower('{value}'))" :
|
||||
$"contains({property}, '{value}')";
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == "DoesNotContain")
|
||||
{
|
||||
return column.Grid.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ?
|
||||
$"not(contains({property}, tolower('{value}')))" :
|
||||
$"not(contains({property}, '{value}'))";
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == "startswith")
|
||||
{
|
||||
return column.Grid.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ?
|
||||
@@ -345,7 +382,15 @@ namespace Radzen
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == "eq")
|
||||
{
|
||||
return $"{property} eq {value}";
|
||||
return column.Grid.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ?
|
||||
$"{property} eq tolower('{value}')" :
|
||||
$"{property} eq '{value}'";
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == "ne")
|
||||
{
|
||||
return column.Grid.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ?
|
||||
$"{property} ne tolower('{value}')" :
|
||||
$"{property} ne '{value}'";
|
||||
}
|
||||
}
|
||||
else if (columnType == "number" || columnType == "integer")
|
||||
@@ -382,6 +427,12 @@ namespace Radzen
|
||||
$"contains({property}, tolower('{value}'))" :
|
||||
$"contains({property}, '{value}')";
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == FilterOperator.DoesNotContain)
|
||||
{
|
||||
return column.Grid.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ?
|
||||
$"not(contains({property}, tolower('{value}')))" :
|
||||
$"not(contains({property}, '{value}'))";
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == FilterOperator.StartsWith)
|
||||
{
|
||||
return column.Grid.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ?
|
||||
@@ -396,7 +447,15 @@ namespace Radzen
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == FilterOperator.Equals)
|
||||
{
|
||||
return $"{property} eq {value}";
|
||||
return column.Grid.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ?
|
||||
$"{property} eq tolower('{value}')" :
|
||||
$"{property} eq '{value}'";
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == FilterOperator.NotEquals)
|
||||
{
|
||||
return column.Grid.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ?
|
||||
$"{property} ne tolower('{value}')" :
|
||||
$"{property} ne '{value}'";
|
||||
}
|
||||
}
|
||||
else if (PropertyAccess.IsNumeric(column.FilterPropertyType))
|
||||
@@ -555,6 +614,11 @@ namespace Radzen
|
||||
whereList.Add($@"{property}{filterCaseSensitivityOperator}.{comparison}(@{index}{filterCaseSensitivityOperator})", new object[] { column.FilterValue });
|
||||
index++;
|
||||
}
|
||||
else if (comparison == "DoesNotContain")
|
||||
{
|
||||
whereList.Add($@"!{property}{filterCaseSensitivityOperator}.Contains(@{index}{filterCaseSensitivityOperator})", new object[] { column.FilterValue });
|
||||
index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
whereList.Add($@"{property}{filterCaseSensitivityOperator} {comparison} @{index}{filterCaseSensitivityOperator}", new object[] { column.FilterValue });
|
||||
@@ -565,12 +629,14 @@ namespace Radzen
|
||||
{
|
||||
var firstFilter = comparison == "StartsWith" || comparison == "EndsWith" || comparison == "Contains" ?
|
||||
$@"{property}{filterCaseSensitivityOperator}.{comparison}(@{index}{filterCaseSensitivityOperator})" :
|
||||
comparison == "DoesNotContain" ? $@"!{property}{filterCaseSensitivityOperator}.Contains(@{index}{filterCaseSensitivityOperator})" :
|
||||
$@"{property}{filterCaseSensitivityOperator} {comparison} @{index}{filterCaseSensitivityOperator}";
|
||||
index++;
|
||||
|
||||
var secondComparison = FilterOperators[column.SecondFilterOperator];
|
||||
var secondFilter = secondComparison == "StartsWith" || secondComparison == "EndsWith" || secondComparison == "Contains" ?
|
||||
$@"{property}{filterCaseSensitivityOperator}.{secondComparison}(@{index}{filterCaseSensitivityOperator})" :
|
||||
secondComparison == "DoesNotContain" ? $@"!{property}{filterCaseSensitivityOperator}.Contains(@{index}{filterCaseSensitivityOperator})" :
|
||||
$@"{property}{filterCaseSensitivityOperator} {secondComparison} @{index}{filterCaseSensitivityOperator}";
|
||||
index++;
|
||||
|
||||
@@ -624,6 +690,11 @@ namespace Radzen
|
||||
whereList.Add($@"{property}{filterCaseSensitivityOperator}.{comparison}(@{index}{filterCaseSensitivityOperator})", new object[] { column.GetFilterValue() });
|
||||
index++;
|
||||
}
|
||||
else if (comparison == "DoesNotContain")
|
||||
{
|
||||
whereList.Add($@"!{property}{filterCaseSensitivityOperator}.Contains(@{index}{filterCaseSensitivityOperator})", new object[] { column.GetFilterValue() });
|
||||
index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
whereList.Add($@"{property}{filterCaseSensitivityOperator} {comparison} @{index}{filterCaseSensitivityOperator}", new object[] { column.GetFilterValue() });
|
||||
@@ -634,12 +705,14 @@ namespace Radzen
|
||||
{
|
||||
var firstFilter = comparison == "StartsWith" || comparison == "EndsWith" || comparison == "Contains" ?
|
||||
$@"{property}{filterCaseSensitivityOperator}.{comparison}(@{index}{filterCaseSensitivityOperator})" :
|
||||
comparison == "DoesNotContain" ? $@"!{property}{filterCaseSensitivityOperator}.Contains(@{index}{filterCaseSensitivityOperator})" :
|
||||
$@"{property}{filterCaseSensitivityOperator} {comparison} @{index}{filterCaseSensitivityOperator}";
|
||||
index++;
|
||||
|
||||
var secondComparison = LinqFilterOperators[column.GetSecondFilterOperator()];
|
||||
var secondFilter = secondComparison == "StartsWith" || secondComparison == "EndsWith" || secondComparison == "Contains" ?
|
||||
$@"{property}{filterCaseSensitivityOperator}.{secondComparison}(@{index}{filterCaseSensitivityOperator})" :
|
||||
secondComparison == "DoesNotContain" ? $@"!{property}{filterCaseSensitivityOperator}.Contains(@{index}{filterCaseSensitivityOperator})" :
|
||||
$@"{property}{filterCaseSensitivityOperator} {secondComparison} @{index}{filterCaseSensitivityOperator}";
|
||||
index++;
|
||||
|
||||
@@ -657,5 +730,15 @@ namespace Radzen
|
||||
{
|
||||
return new ODataEnumerable<T>(source);
|
||||
}
|
||||
|
||||
public static IEnumerable<T> SelectManyRecursive<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> selector)
|
||||
{
|
||||
var result = source.SelectMany(selector);
|
||||
if (!result.Any())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return result.Concat(result.SelectManyRecursive(selector));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<IsPackable>true</IsPackable>
|
||||
<PackageId>Radzen.Blazor</PackageId>
|
||||
<Product>Radzen.Blazor</Product>
|
||||
<Version>3.3.2</Version>
|
||||
<Version>3.9.4</Version>
|
||||
<Copyright>Radzen Ltd.</Copyright>
|
||||
<Authors>Radzen Ltd.</Authors>
|
||||
<Description>Native Blazor UI components by Radzen Ltd.</Description>
|
||||
|
||||
@@ -191,7 +191,10 @@
|
||||
{
|
||||
base.Dispose();
|
||||
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", PopupID);
|
||||
if (IsJSRuntimeAvailable)
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", PopupID);
|
||||
}
|
||||
}
|
||||
|
||||
private bool firstRender = true;
|
||||
|
||||
42
Radzen.Blazor/RadzenBadge.razor
Normal file
42
Radzen.Blazor/RadzenBadge.razor
Normal file
@@ -0,0 +1,42 @@
|
||||
@inherits RadzenComponent
|
||||
@if (Visible)
|
||||
{
|
||||
<span @ref="@Element" style="@Style" @attributes="Attributes" class="@GetCssClass()" id="@GetId()">
|
||||
@if (ChildContent != null)
|
||||
{
|
||||
@ChildContent
|
||||
}
|
||||
else
|
||||
{
|
||||
@Text
|
||||
}
|
||||
</span>
|
||||
}
|
||||
@code {
|
||||
protected override string GetComponentCssClass()
|
||||
{
|
||||
var classList = new List<string>();
|
||||
|
||||
classList.Add("rz-badge");
|
||||
classList.Add($"rz-badge-{BadgeStyle.ToString().ToLower()}");
|
||||
|
||||
if (IsPill)
|
||||
{
|
||||
classList.Add("rz-badge-pill");
|
||||
}
|
||||
|
||||
return string.Join(" ", classList);
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Text { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public BadgeStyle BadgeStyle { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool IsPill { get; set; }
|
||||
}
|
||||
@@ -245,17 +245,27 @@
|
||||
|
||||
RenderFragment tooltip;
|
||||
object tooltipData;
|
||||
double mouseX;
|
||||
double mouseY;
|
||||
|
||||
[JSInvokable]
|
||||
public void MouseMove(double x, double y)
|
||||
{
|
||||
mouseX = x;
|
||||
mouseY = y;
|
||||
|
||||
DisplayTooltip();
|
||||
}
|
||||
|
||||
internal void DisplayTooltip()
|
||||
{
|
||||
if (Tooltip.Visible)
|
||||
{
|
||||
foreach (var series in Series)
|
||||
{
|
||||
if (series.Visible && series.Contains(x - MarginLeft, y - MarginTop))
|
||||
if (series.Visible && series.Contains(mouseX - MarginLeft, mouseY - MarginTop))
|
||||
{
|
||||
var data = series.DataAt(x - MarginLeft, y - MarginTop);
|
||||
var data = series.DataAt(mouseX - MarginLeft, mouseY - MarginTop);
|
||||
|
||||
if (data != tooltipData)
|
||||
{
|
||||
@@ -301,6 +311,8 @@
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
await base.OnAfterRenderAsync(firstRender);
|
||||
|
||||
this.firstRender = firstRender;
|
||||
|
||||
if (firstRender || visibleChanged)
|
||||
@@ -417,7 +429,7 @@
|
||||
{
|
||||
base.Dispose();
|
||||
|
||||
if (Visible)
|
||||
if (Visible && IsJSRuntimeAvailable)
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyChart", Element);
|
||||
}
|
||||
|
||||
@@ -420,8 +420,12 @@
|
||||
SaturationHandleTop = 1 - HSV.Value;
|
||||
HSV.Saturation = 1;
|
||||
HSV.Value = 1;
|
||||
|
||||
HueHandleLeft = HSV.Hue;
|
||||
|
||||
if (value.StartsWith("rgba"))
|
||||
{
|
||||
AlphaHandleLeft = HSV.Alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,8 @@ namespace Radzen
|
||||
|
||||
[Inject]
|
||||
protected IJSRuntime JSRuntime { get; set; }
|
||||
|
||||
protected bool IsJSRuntimeAvailable { get; set; }
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
@@ -120,6 +122,8 @@ namespace Radzen
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
IsJSRuntimeAvailable = true;
|
||||
|
||||
this.firstRender = firstRender;
|
||||
|
||||
if (firstRender || visibleChanged)
|
||||
@@ -178,19 +182,22 @@ namespace Radzen
|
||||
reference?.Dispose();
|
||||
reference = null;
|
||||
|
||||
if (ContextMenu.HasDelegate)
|
||||
if (IsJSRuntimeAvailable)
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.removeContextMenu", UniqueID);
|
||||
}
|
||||
if (ContextMenu.HasDelegate)
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.removeContextMenu", UniqueID);
|
||||
}
|
||||
|
||||
if (MouseEnter.HasDelegate)
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.removeMouseEnter", UniqueID);
|
||||
}
|
||||
if (MouseEnter.HasDelegate)
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.removeMouseEnter", UniqueID);
|
||||
}
|
||||
|
||||
if (MouseLeave.HasDelegate)
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.removeMouseLeave", UniqueID);
|
||||
if (MouseLeave.HasDelegate)
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.removeMouseLeave", UniqueID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,8 +40,12 @@
|
||||
await InvokeAsync(() => { StateHasChanged(); });
|
||||
}
|
||||
|
||||
private bool IsJSRuntimeAvailable { get; set; }
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
IsJSRuntimeAvailable = true;
|
||||
|
||||
var menu = menus.LastOrDefault();
|
||||
if (menu != null)
|
||||
{
|
||||
@@ -66,7 +70,10 @@
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", UniqueID);
|
||||
if (IsJSRuntimeAvailable)
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", UniqueID);
|
||||
}
|
||||
|
||||
Service.OnOpen -= OnOpen;
|
||||
Service.OnClose -= OnClose;
|
||||
|
||||
@@ -16,15 +16,41 @@
|
||||
{
|
||||
var visibleColumns = columns.Where(c => c.Visible).ToList();
|
||||
|
||||
<div style="@Style" @attributes="Attributes" class="rz-data-grid @GetCssClass()" id="@GetId()">
|
||||
<div @ref=@Element style="@Style" @attributes="Attributes" class="rz-data-grid @GetCssClass()" id="@GetId()">
|
||||
@if(AllowGrouping)
|
||||
{
|
||||
<div class="rz-group-header" @onmouseup=@(args => EndColumnDropToGroup())>
|
||||
@if(groups.Any())
|
||||
{
|
||||
@foreach(var gd in groups)
|
||||
{
|
||||
<div class="rz-group-header-item">
|
||||
<span class="rz-group-header-item-title">@gd.GetTitle()</span>
|
||||
<a href="javascript:void(0)" @onclick=@(args => { groups.Remove(gd); _groupedPagedView = null; }) role="button" class="rz-dialog-titlebar-icon rz-dialog-titlebar-close">
|
||||
<span class="rzi rzi-times"></span>
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="rz-group-header-drop">@GroupPanelText</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (AllowPaging && (PagerPosition == PagerPosition.Top || PagerPosition == PagerPosition.TopAndBottom))
|
||||
{
|
||||
<RadzenPager @ref="topPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@OnPageChanged" />
|
||||
<RadzenPager @ref="topPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@OnPageChanged" PageSizeChanged="@OnPageSizeChanged" PageSizeOptions="@PageSizeOptions" />
|
||||
}
|
||||
|
||||
<div class="rz-data-grid-data">
|
||||
<table class="rz-grid-table rz-grid-table-fixed">
|
||||
<colgroup>
|
||||
@foreach(var g in groups)
|
||||
{
|
||||
<col>
|
||||
}
|
||||
@if (Template != null)
|
||||
{
|
||||
<col>
|
||||
@@ -36,6 +62,12 @@
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
@foreach(var g in groups)
|
||||
{
|
||||
<th class="rz-col-icon rz-unselectable-text" scope="col">
|
||||
<span class="rz-column-title"></span>
|
||||
</th>
|
||||
}
|
||||
@if (Template != null)
|
||||
{
|
||||
<th class="rz-col-icon rz-unselectable-text" scope="col">
|
||||
@@ -44,9 +76,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 || AllowGrouping)
|
||||
{
|
||||
<span id="@getColumnResizerId(columnIndex)" class="rz-column-drag"
|
||||
@onclick:preventDefault="true" @onclick:stopPropagation="true"
|
||||
@onmousedown=@(args => StartColumnReorder(args, columnIndex))> </span>
|
||||
}
|
||||
<span class="rz-column-title">
|
||||
@if (column.HeaderTemplate != null)
|
||||
{
|
||||
@@ -72,9 +111,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))> </div>
|
||||
@@ -99,8 +137,7 @@
|
||||
{
|
||||
@(DrawNumericFilter(column, false))
|
||||
}
|
||||
else if (column.FilterPropertyType == typeof(DateTime) || column.FilterPropertyType == typeof(DateTime?) ||
|
||||
column.FilterPropertyType == typeof(DateTimeOffset) || column.FilterPropertyType == typeof(DateTimeOffset?))
|
||||
else if (PropertyAccess.IsDate(column.FilterPropertyType))
|
||||
{
|
||||
<RadzenDatePicker TValue="@object" ShowTime="true" ShowTimeOkButton="true" DateFormat="@getFilterDateFormat(column)"
|
||||
Value="@column.GetFilterValue()" Change="@(args => column.SetFilterValue(args.Value))" />
|
||||
@@ -108,7 +145,7 @@
|
||||
}
|
||||
else if (column.FilterPropertyType == typeof(bool) || column.FilterPropertyType == typeof(bool?))
|
||||
{
|
||||
<RadzenCheckBox TriState="true" TValue="@object" Value="@column.GetFilterValue()" Change="@((args) => OnFilter(new ChangeEventArgs() { Value = args }, column))" />
|
||||
<RadzenCheckBox TriState="true" TValue="@object" Value="@column.GetFilterValue()" Change="@(args => column.SetFilterValue(args))" />
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -123,8 +160,7 @@
|
||||
{
|
||||
@(DrawNumericFilter(column, false, false))
|
||||
}
|
||||
else if (column.FilterPropertyType == typeof(DateTime) || column.FilterPropertyType == typeof(DateTime?) ||
|
||||
column.FilterPropertyType == typeof(DateTimeOffset) || column.FilterPropertyType == typeof(DateTimeOffset?))
|
||||
else if (PropertyAccess.IsDate(column.FilterPropertyType))
|
||||
{
|
||||
<RadzenDatePicker TValue="@object"
|
||||
ShowTime="true" ShowTimeOkButton="true" DateFormat="@getFilterDateFormat(column)"
|
||||
@@ -133,7 +169,7 @@
|
||||
}
|
||||
else if (column.FilterPropertyType == typeof(bool) || column.FilterPropertyType == typeof(bool?))
|
||||
{
|
||||
<RadzenCheckBox TriState="true" TValue="@object" Value="@column.GetSecondFilterValue()" Change="@((args) => OnFilter(new ChangeEventArgs() { Value = args }, column, false))" />
|
||||
<RadzenCheckBox TriState="true" TValue="@object" Value="@column.GetSecondFilterValue()" Change="@(args => column.SetFilterValue(args, false))"/>
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -157,6 +193,12 @@
|
||||
@if (AllowFiltering && FilterMode == FilterMode.Simple && columns.Where(column => column.Filterable && (!string.IsNullOrEmpty(column.GetFilterProperty()) || column.FilterTemplate != null)).Any())
|
||||
{
|
||||
<tr>
|
||||
@foreach(var g in groups)
|
||||
{
|
||||
<th class="rz-col-icon rz-unselectable-text" scope="col">
|
||||
<span class="rz-column-title"></span>
|
||||
</th>
|
||||
}
|
||||
@if (Template != null)
|
||||
{
|
||||
<th class="rz-col-icon rz-unselectable-text" scope="col">
|
||||
@@ -241,7 +283,9 @@
|
||||
}
|
||||
else if (column.FilterPropertyType == typeof(bool) || column.FilterPropertyType == typeof(bool?))
|
||||
{
|
||||
<div style="@(column.TextAlign == TextAlign.Center ? "width:100%;text-align:center" : column.TextAlign == TextAlign.Right ? "width:100%;text-align:right" : "")">
|
||||
<RadzenCheckBox TriState="true" TValue="@object" Value="@column.GetFilterValue()" Change="@((args) => OnFilter(new ChangeEventArgs() { Value = args }, column))" />
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -269,7 +313,14 @@
|
||||
{
|
||||
<tr class=" rz-datatable-emptymessage-row">
|
||||
<td class="rz-datatable-emptymessage" colspan="@visibleColumns.Count">
|
||||
<span>@EmptyText</span>
|
||||
@if (EmptyTemplate != null)
|
||||
{
|
||||
@EmptyTemplate
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>@EmptyText</span>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@@ -279,6 +330,12 @@
|
||||
{
|
||||
<tfoot class="rz-datatable-tfoot">
|
||||
<tr class="">
|
||||
@foreach(var g in groups)
|
||||
{
|
||||
<td class="rz-col-icon rz-unselectable-text" scope="col">
|
||||
<span class="rz-column-title"></span>
|
||||
</td>
|
||||
}
|
||||
@if (Template != null)
|
||||
{
|
||||
<td class="rz-col-icon rz-unselectable-text" scope="col">
|
||||
@@ -312,20 +369,30 @@
|
||||
|
||||
@if (AllowPaging && (PagerPosition == PagerPosition.Bottom || PagerPosition == PagerPosition.TopAndBottom))
|
||||
{
|
||||
<RadzenPager @ref="topPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@OnPageChanged" />
|
||||
<RadzenPager @ref="bottomPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@OnPageChanged" PageSizeChanged="@OnPageSizeChanged" PageSizeOptions="@PageSizeOptions" />
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@code {
|
||||
#if NET5
|
||||
Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize<TItem> virtualize;
|
||||
#if NET5
|
||||
internal void SetAllowVirtualization(bool allowVirtualization)
|
||||
{
|
||||
AllowVirtualization = allowVirtualization;
|
||||
}
|
||||
|
||||
internal Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize<TItem> virtualize;
|
||||
|
||||
private async ValueTask<Microsoft.AspNetCore.Components.Web.Virtualization.ItemsProviderResult<TItem>> LoadItems(Microsoft.AspNetCore.Components.Web.Virtualization.ItemsProviderRequest request)
|
||||
{
|
||||
var view = AllowPaging ? PagedView : View;
|
||||
var totalItemsCount = LoadData.HasDelegate ? Count : view.Count();
|
||||
var top = Math.Min(request.Count, totalItemsCount - request.StartIndex);
|
||||
var top = totalItemsCount > request.Count ? Math.Min(request.Count, totalItemsCount - request.StartIndex) : PageSize;
|
||||
|
||||
if(top <= 0)
|
||||
{
|
||||
top = PageSize;
|
||||
}
|
||||
|
||||
if (LoadData.HasDelegate)
|
||||
{
|
||||
@@ -341,7 +408,7 @@
|
||||
await LoadData.InvokeAsync(new Radzen.LoadDataArgs() { Skip = request.StartIndex, Top = top, OrderBy = orderBy, Filter = IsOData() ? columns.ToODataFilterString<TItem>() : filterString });
|
||||
}
|
||||
|
||||
return new Microsoft.AspNetCore.Components.Web.Virtualization.ItemsProviderResult<TItem>(LoadData.HasDelegate ? Data : view.Skip(request.StartIndex).Take(top), totalItemsCount);
|
||||
return new Microsoft.AspNetCore.Components.Web.Virtualization.ItemsProviderResult<TItem>(LoadData.HasDelegate ? Data : itemToInsert != null ? (new[] { itemToInsert }).Concat(view.Skip(request.StartIndex).Take(top)) : view.Skip(request.StartIndex).Take(top), totalItemsCount);
|
||||
}
|
||||
#endif
|
||||
RenderFragment DrawRows(IList<RadzenDataGridColumn<TItem>> visibleColumns)
|
||||
@@ -363,6 +430,12 @@
|
||||
b.AddAttribute(6, "TItem", typeof(TItem));
|
||||
b.AddAttribute(7, "Item", context);
|
||||
b.AddAttribute(8, "InEditMode", IsRowInEditMode(context));
|
||||
|
||||
if (editContexts.ContainsKey(context))
|
||||
{
|
||||
b.AddAttribute(9, nameof(RadzenDataGridRow<TItem>.EditContext), editContexts[context]);
|
||||
}
|
||||
|
||||
b.SetKey(context);
|
||||
b.CloseComponent();
|
||||
});
|
||||
@@ -374,35 +447,63 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var item in LoadData.HasDelegate ? Data : PagedView)
|
||||
{
|
||||
builder.OpenComponent(0, typeof(RadzenDataGridRow<TItem>));
|
||||
builder.AddAttribute(1, "Columns", visibleColumns);
|
||||
builder.AddAttribute(2, "Index", i);
|
||||
builder.AddAttribute(3, "Grid", this);
|
||||
builder.AddAttribute(4, "TItem", typeof(TItem));
|
||||
builder.AddAttribute(5, "Item", item);
|
||||
builder.AddAttribute(6, "InEditMode", IsRowInEditMode(item));
|
||||
builder.CloseComponent();
|
||||
i++;
|
||||
}
|
||||
DrawGroupOrDataRows(builder, visibleColumns);
|
||||
}
|
||||
#else
|
||||
int i = 0;
|
||||
foreach (var item in LoadData.HasDelegate ? Data : PagedView)
|
||||
DrawGroupOrDataRows(builder, visibleColumns);
|
||||
#endif
|
||||
});
|
||||
}
|
||||
|
||||
internal void DrawGroupOrDataRows(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder, IList<RadzenDataGridColumn<TItem>> visibleColumns)
|
||||
{
|
||||
if (groups.Any())
|
||||
{
|
||||
foreach (var group in GroupedPagedView)
|
||||
{
|
||||
builder.OpenComponent(0, typeof(RadzenDataGridRow<TItem>));
|
||||
builder.OpenComponent(0, typeof(RadzenDataGridGroupRow<TItem>));
|
||||
builder.AddAttribute(1, "Columns", visibleColumns);
|
||||
builder.AddAttribute(3, "Grid", this);
|
||||
builder.AddAttribute(5, "GroupResult", group);
|
||||
builder.AddAttribute(6, "Builder", builder);
|
||||
builder.CloseComponent();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var item in PagedView)
|
||||
{
|
||||
builder.OpenComponent<RadzenDataGridRow<TItem>>(0);
|
||||
builder.AddAttribute(1, "Columns", visibleColumns);
|
||||
builder.AddAttribute(2, "Index", i);
|
||||
builder.AddAttribute(3, "Grid", this);
|
||||
builder.AddAttribute(4, "TItem", typeof(TItem));
|
||||
builder.AddAttribute(5, "Item", item);
|
||||
builder.AddAttribute(6, "InEditMode", IsRowInEditMode(item));
|
||||
|
||||
if (editContexts.ContainsKey(item))
|
||||
{
|
||||
builder.AddAttribute(7, nameof(RadzenDataGridRow<TItem>.EditContext), editContexts[item]);
|
||||
}
|
||||
|
||||
builder.CloseComponent();
|
||||
i++;
|
||||
}
|
||||
#endif
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<GroupResult> _groupedPagedView;
|
||||
public IEnumerable<GroupResult> GroupedPagedView
|
||||
{
|
||||
get
|
||||
{
|
||||
if(_groupedPagedView == null)
|
||||
{
|
||||
_groupedPagedView = PagedView.GroupByMany(groups.Select(g => g.Property).ToArray()).ToList();
|
||||
}
|
||||
return _groupedPagedView;
|
||||
}
|
||||
}
|
||||
|
||||
internal string getFrozenColumnClass(RadzenDataGridColumn<TItem> column, IList<RadzenDataGridColumn<TItem>> visibleColumns)
|
||||
@@ -446,6 +547,13 @@
|
||||
if (!columns.Contains(column))
|
||||
{
|
||||
columns.Add(column);
|
||||
|
||||
var descriptor = sorts.Where(d => d.Property == column?.GetSortProperty()).FirstOrDefault();
|
||||
if (descriptor == null && column.SortOrder.HasValue)
|
||||
{
|
||||
descriptor = new SortDescriptor() { Property = column.Property, SortOrder = column.SortOrder.Value };
|
||||
sorts.Add(descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -535,6 +643,14 @@
|
||||
builder.AddAttribute(3, "Change", eventCallbackGenericCreate.Invoke(this,
|
||||
new object[] { this, eventCallbackGenericAction.Invoke(this, new object[] { action }) }));
|
||||
|
||||
if(FilterMode == FilterMode.Advanced)
|
||||
{
|
||||
builder.AddAttribute(4, "oninput", EventCallback.Factory.Create<ChangeEventArgs>(this, args => {
|
||||
var value = $"{args.Value}";
|
||||
column.SetFilterValue(!string.IsNullOrWhiteSpace(value) ? Convert.ChangeType(value, Nullable.GetUnderlyingType(type)) : null, isFirst);
|
||||
} ));
|
||||
}
|
||||
|
||||
builder.CloseComponent();
|
||||
});
|
||||
}
|
||||
@@ -694,6 +810,9 @@
|
||||
[Parameter]
|
||||
public string ContainsText { get; set; } = "Contains";
|
||||
|
||||
[Parameter]
|
||||
public string DoesNotContainText { get; set; } = "Does not contain";
|
||||
|
||||
[Parameter]
|
||||
public string StartsWithText { get; set; } = "Starts with";
|
||||
|
||||
@@ -733,10 +852,13 @@
|
||||
{
|
||||
_emptyText = value;
|
||||
|
||||
ChangeState();
|
||||
ChangeState().Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment EmptyTemplate { get; set; }
|
||||
#if NET5
|
||||
[Parameter]
|
||||
public bool AllowVirtualization { get; set; }
|
||||
@@ -756,6 +878,18 @@
|
||||
[Parameter]
|
||||
public bool AllowColumnResize { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool AllowColumnReorder { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool AllowGrouping { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment<Group> GroupHeaderTemplate { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string GroupPanelText { get; set; } = "Drag a column header here and drop it to group by that column";
|
||||
|
||||
internal string getColumnResizerId(int columnIndex)
|
||||
{
|
||||
return string.Join("", $"{UniqueID}".Split('.')) + columnIndex;
|
||||
@@ -766,6 +900,40 @@
|
||||
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 visibleColumns = columns.Where(c => c.Visible).ToList();
|
||||
var columnToReorder = visibleColumns.ElementAtOrDefault(indexOfColumnToReoder.Value);
|
||||
var columnToReorderTo = visibleColumns.ElementAtOrDefault(columnIndex);
|
||||
|
||||
if (columnToReorder != null && columnToReorderTo != null)
|
||||
{
|
||||
var actualColumnIndex = columns.IndexOf(columnToReorderTo);
|
||||
columns.Remove(columnToReorder);
|
||||
columns.Insert(actualColumnIndex, columnToReorder);
|
||||
|
||||
await ColumnReordered.InvokeAsync(new DataGridColumnReorderedEventArgs<TItem>
|
||||
{
|
||||
Column = columnToReorder,
|
||||
OldIndex = indexOfColumnToReoder.Value,
|
||||
NewIndex = actualColumnIndex
|
||||
});
|
||||
}
|
||||
|
||||
indexOfColumnToReoder = null;
|
||||
}
|
||||
}
|
||||
|
||||
[JSInvokable("RadzenGrid.OnColumnResized")]
|
||||
public async Task OnColumnResized(int columnIndex, double value)
|
||||
{
|
||||
@@ -780,12 +948,15 @@
|
||||
|
||||
internal string GetOrderBy()
|
||||
{
|
||||
return string.Join(",", columns.Where(c => c.GetSortOrder() != null).Select(c => c.GetSortOrderAsString(IsOData())));
|
||||
return string.Join(",", sorts.Select(d => columns.Where(c => c.GetSortProperty() == d.Property).FirstOrDefault()).Where(c => c != null).Select(c => c.GetSortOrderAsString(IsOData())));
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<DataGridColumnResizedEventArgs<TItem>> ColumnResized { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<DataGridColumnReorderedEventArgs<TItem>> ColumnReordered { get; set; }
|
||||
|
||||
public override IQueryable<TItem> View
|
||||
{
|
||||
get
|
||||
@@ -815,6 +986,12 @@
|
||||
if (count != Count)
|
||||
{
|
||||
Count = count;
|
||||
|
||||
if (skip >= Count && Count > PageSize)
|
||||
{
|
||||
skip = Count - PageSize;
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
@@ -883,8 +1060,9 @@
|
||||
Reset(!IsOData() && !LoadData.HasDelegate);
|
||||
}
|
||||
|
||||
public void Reset(bool resetColumnFilters = true, bool resetRowState = false)
|
||||
public void Reset(bool resetColumnState = true, bool resetRowState = false)
|
||||
{
|
||||
_groupedPagedView = null;
|
||||
_view = null;
|
||||
_value = new List<TItem>();
|
||||
|
||||
@@ -894,14 +1072,17 @@
|
||||
expandedItems.Clear();
|
||||
}
|
||||
|
||||
if (resetColumnFilters)
|
||||
if (resetColumnState)
|
||||
{
|
||||
columns.ForEach(c => { c.SetFilterValue(null); c.SetSecondFilterOperator(FilterOperator.Equals); });
|
||||
}
|
||||
columns.ForEach(c => { c.ResetSortOrder(); });
|
||||
sorts.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public async override Task Reload()
|
||||
{
|
||||
_groupedPagedView = null;
|
||||
_view = null;
|
||||
|
||||
if (Data != null && !LoadData.HasDelegate)
|
||||
@@ -909,9 +1090,16 @@
|
||||
Count = 1;
|
||||
}
|
||||
#if NET5
|
||||
if (AllowVirtualization && virtualize != null && !LoadData.HasDelegate)
|
||||
if (AllowVirtualization && virtualize != null)
|
||||
{
|
||||
await virtualize.RefreshDataAsync();
|
||||
if(!LoadData.HasDelegate)
|
||||
{
|
||||
await virtualize.RefreshDataAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
Data = null;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
var orderBy = GetOrderBy();
|
||||
@@ -940,21 +1128,28 @@
|
||||
SecondFilterOperator = c.GetSecondFilterOperator(),
|
||||
LogicalFilterOperator = c.GetLogicalFilterOperator()
|
||||
}),
|
||||
Sorts = columns.Where(c => c.Sortable && c.Visible && c.GetSortOrder() != null).Select(c => new SortDescriptor()
|
||||
{
|
||||
Property = c.GetSortProperty(),
|
||||
SortOrder = c.GetSortOrder().Value,
|
||||
})
|
||||
Sorts = sorts
|
||||
}); ;
|
||||
}
|
||||
|
||||
var v = PagedView;
|
||||
|
||||
CalculatePager();
|
||||
|
||||
if (!LoadData.HasDelegate)
|
||||
{
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if NET5
|
||||
if (AllowVirtualization && virtualize != null)
|
||||
{
|
||||
await virtualize.RefreshDataAsync();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task ChangeState()
|
||||
{
|
||||
@@ -975,6 +1170,16 @@
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
internal Dictionary<Group, bool> collapsedGroupItems = new Dictionary<Group, bool>();
|
||||
internal string ExpandedGroupItemStyle(Group item)
|
||||
{
|
||||
return collapsedGroupItems.Keys.Contains(item) ? "rz-row-toggler rzi-grid-sort rzi-chevron-circle-right" : "rz-row-toggler rzi-grid-sort rzi-chevron-circle-down";
|
||||
}
|
||||
|
||||
internal bool IsGroupItemExpanded(Group item)
|
||||
{
|
||||
return !collapsedGroupItems.Keys.Contains(item) ;
|
||||
}
|
||||
|
||||
internal Dictionary<TItem, bool> expandedItems = new Dictionary<TItem, bool>();
|
||||
internal string ExpandedItemStyle(TItem item)
|
||||
@@ -1094,6 +1299,22 @@
|
||||
expandedItems.Remove(item);
|
||||
await RowCollapse.InvokeAsync(item);
|
||||
}
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
internal async System.Threading.Tasks.Task ExpandGroupItem(Group item)
|
||||
{
|
||||
if (!collapsedGroupItems.Keys.Contains(item))
|
||||
{
|
||||
collapsedGroupItems.Add(item, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
collapsedGroupItems.Remove(item);
|
||||
}
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
@@ -1183,6 +1404,16 @@
|
||||
internal Dictionary<TItem, EditContext> editContexts = new Dictionary<TItem, EditContext>();
|
||||
|
||||
public async System.Threading.Tasks.Task EditRow(TItem item)
|
||||
{
|
||||
if(itemToInsert != null)
|
||||
{
|
||||
CancelEditRow(itemToInsert);
|
||||
}
|
||||
|
||||
await EditRowInternal(item);
|
||||
}
|
||||
|
||||
async System.Threading.Tasks.Task EditRowInternal(TItem item)
|
||||
{
|
||||
if (EditMode == DataGridEditMode.Single && editedItems.Keys.Any())
|
||||
{
|
||||
@@ -1237,12 +1468,25 @@
|
||||
{
|
||||
if (object.Equals(itemToInsert, item))
|
||||
{
|
||||
var list = this.PagedView.ToList();
|
||||
list.Remove(item);
|
||||
this._view = list.AsQueryable();
|
||||
this.Count = this.View.Count();
|
||||
itemToInsert = default(TItem);
|
||||
StateHasChanged();
|
||||
if(!IsVirtualizationAllowed())
|
||||
{
|
||||
var list = this.PagedView.ToList();
|
||||
list.Remove(item);
|
||||
this._view = list.AsQueryable();
|
||||
this.Count--;
|
||||
itemToInsert = default(TItem);
|
||||
StateHasChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
#if NET5
|
||||
itemToInsert = default(TItem);
|
||||
if (virtualize != null)
|
||||
{
|
||||
virtualize.RefreshDataAsync();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1267,18 +1511,38 @@
|
||||
public async System.Threading.Tasks.Task InsertRow(TItem item)
|
||||
{
|
||||
itemToInsert = item;
|
||||
var list = this.PagedView.ToList();
|
||||
list.Insert(0, item);
|
||||
this._view = list.AsQueryable();
|
||||
this.Count = this._view.Count();
|
||||
await EditRow(item);
|
||||
if(!IsVirtualizationAllowed())
|
||||
{
|
||||
var list = this.PagedView.ToList();
|
||||
list.Insert(0, item);
|
||||
this._view = list.AsQueryable();
|
||||
this.Count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if NET5
|
||||
if (virtualize != null)
|
||||
{
|
||||
await virtualize.RefreshDataAsync();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
await EditRowInternal(item);
|
||||
}
|
||||
|
||||
bool? isOData;
|
||||
internal bool IsOData()
|
||||
{
|
||||
return Data != null && typeof(ODataEnumerable<TItem>).IsAssignableFrom(Data.GetType());
|
||||
if(isOData == null && Data != null)
|
||||
{
|
||||
isOData = typeof(ODataEnumerable<TItem>).IsAssignableFrom(Data.GetType());
|
||||
}
|
||||
|
||||
return isOData != null ? isOData.Value : false;
|
||||
}
|
||||
|
||||
internal List<SortDescriptor> sorts = new List<SortDescriptor>();
|
||||
internal void SetColumnSortOrder(RadzenDataGridColumn<TItem> column)
|
||||
{
|
||||
if (!AllowMultiColumnSorting)
|
||||
@@ -1287,20 +1551,74 @@
|
||||
{
|
||||
c.SetSortOrder(null);
|
||||
}
|
||||
sorts.Clear();
|
||||
}
|
||||
|
||||
var descriptor = sorts.Where(d => d.Property == column?.GetSortProperty()).FirstOrDefault();
|
||||
if (descriptor == null)
|
||||
{
|
||||
descriptor = new SortDescriptor() { Property = column.GetSortProperty() };
|
||||
}
|
||||
|
||||
if (column.GetSortOrder() == null)
|
||||
{
|
||||
column.SetSortOrder(SortOrder.Ascending);
|
||||
descriptor.SortOrder = SortOrder.Ascending;
|
||||
}
|
||||
else if (column.GetSortOrder() == SortOrder.Ascending)
|
||||
{
|
||||
column.SetSortOrder(SortOrder.Descending);
|
||||
descriptor.SortOrder = SortOrder.Descending;
|
||||
}
|
||||
else if (column.GetSortOrder() == SortOrder.Descending)
|
||||
{
|
||||
column.SetSortOrder(null);
|
||||
if (sorts.Where(d => d.Property == column?.GetSortProperty()).Any())
|
||||
{
|
||||
sorts.Remove(descriptor);
|
||||
}
|
||||
descriptor = null;
|
||||
}
|
||||
|
||||
if (descriptor != null && !sorts.Where(d => d.Property == column?.GetSortProperty()).Any())
|
||||
{
|
||||
sorts.Add(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
public List<GroupDescriptor> Groups
|
||||
{
|
||||
get
|
||||
{
|
||||
return groups;
|
||||
}
|
||||
set
|
||||
{
|
||||
groups = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal List<GroupDescriptor> groups = new List<GroupDescriptor>();
|
||||
internal void EndColumnDropToGroup()
|
||||
{
|
||||
if(indexOfColumnToReoder != null)
|
||||
{
|
||||
var column = columns.Where(c => c.Visible).ElementAtOrDefault(indexOfColumnToReoder.Value);
|
||||
|
||||
if(column != null && column.Groupable && !string.IsNullOrEmpty(column.GetGroupProperty()))
|
||||
{
|
||||
var descriptor = groups.Where(d => d.Property == column.GetGroupProperty()).FirstOrDefault();
|
||||
if (descriptor == null)
|
||||
{
|
||||
descriptor = new GroupDescriptor() { Property = column.GetGroupProperty(), Title = column.Title };
|
||||
groups.Add(descriptor);
|
||||
_groupedPagedView = null;
|
||||
}
|
||||
}
|
||||
|
||||
indexOfColumnToReoder = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void OrderBy(string property)
|
||||
@@ -1372,9 +1690,12 @@
|
||||
|
||||
disposed = true;
|
||||
|
||||
foreach (var column in columns.Where(c => c.Visible))
|
||||
if (IsJSRuntimeAvailable)
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", $"{PopupID}{column.GetFilterProperty()}");
|
||||
foreach (var column in columns.Where(c => c.Visible))
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", $"{PopupID}{column.GetFilterProperty()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@typeparam TItem
|
||||
<td style="@Style" @attributes="@Attributes" class="@GetCssClass()" @onclick="@OnClick" @ondblclick="@OnDblClick" >
|
||||
<td @attributes="@Attributes" style="@GetStyle()" class="@GetCssClass()" @onclick="@OnClick" @ondblclick="@OnDblClick" >
|
||||
<CascadingValue Value=this>
|
||||
@ChildContent
|
||||
</CascadingValue>
|
||||
@@ -118,6 +118,16 @@
|
||||
return $"{CssClass} {@class}".Trim();
|
||||
}
|
||||
|
||||
return CssClass;
|
||||
return String.IsNullOrWhiteSpace(CssClass) ? null : CssClass;
|
||||
}
|
||||
|
||||
string GetStyle()
|
||||
{
|
||||
if (Attributes != null && Attributes.TryGetValue("style", out var style) == true && !string.IsNullOrEmpty(Convert.ToString(style)))
|
||||
{
|
||||
return String.IsNullOrEmpty(Style) ? $"{style}" : $"{Style.TrimEnd(';')};{style}";
|
||||
}
|
||||
|
||||
return Style;
|
||||
}
|
||||
}
|
||||
@@ -10,25 +10,28 @@
|
||||
{
|
||||
Grid.AddColumn(this);
|
||||
|
||||
var property = GetFilterProperty();
|
||||
|
||||
if (!string.IsNullOrEmpty(property))
|
||||
if (!string.IsNullOrEmpty(FilterProperty) || Type == null)
|
||||
{
|
||||
_filterPropertyType = PropertyAccess.GetPropertyType(typeof(TItem), property);
|
||||
var property = GetFilterProperty();
|
||||
|
||||
if (_filterPropertyType == null)
|
||||
if (!string.IsNullOrEmpty(property))
|
||||
{
|
||||
_filterPropertyType = Type;
|
||||
}
|
||||
else
|
||||
{
|
||||
propertyValueGetter = PropertyAccess.Getter<TItem, object>(Property);
|
||||
_filterPropertyType = PropertyAccess.GetPropertyType(typeof(TItem), property);
|
||||
}
|
||||
}
|
||||
|
||||
if (_filterPropertyType == null)
|
||||
{
|
||||
_filterPropertyType = Type;
|
||||
}
|
||||
else
|
||||
{
|
||||
propertyValueGetter = PropertyAccess.Getter<TItem, object>(Property);
|
||||
}
|
||||
|
||||
if (_filterPropertyType == typeof(string))
|
||||
{
|
||||
FilterOperator = FilterOperator.Contains;
|
||||
}
|
||||
if (_filterPropertyType == typeof(string))
|
||||
{
|
||||
FilterOperator = FilterOperator.Contains;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,6 +51,9 @@
|
||||
[Parameter]
|
||||
public string SortProperty { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string GroupProperty { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string FilterProperty { get; set; }
|
||||
|
||||
@@ -81,6 +87,15 @@
|
||||
[Parameter]
|
||||
public bool Frozen { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool Resizable { get; set; } = true;
|
||||
|
||||
[Parameter]
|
||||
public bool Reorderable { get; set; } = true;
|
||||
|
||||
[Parameter]
|
||||
public bool Groupable { get; set; } = true;
|
||||
|
||||
[Parameter]
|
||||
public TextAlign TextAlign { get; set; } = TextAlign.Left;
|
||||
|
||||
@@ -109,7 +124,9 @@
|
||||
|
||||
public object GetValue(TItem item)
|
||||
{
|
||||
return propertyValueGetter != null ? propertyValueGetter(item) : !string.IsNullOrEmpty(Property) ? PropertyAccess.GetValue(item, Property) : "";
|
||||
var value = propertyValueGetter != null && !string.IsNullOrEmpty(Property) && !Property.Contains('.') ? propertyValueGetter(item) : !string.IsNullOrEmpty(Property) ? PropertyAccess.GetValue(item, Property) : "";
|
||||
|
||||
return !string.IsNullOrEmpty(FormatString) ? string.Format(FormatString, value) : value;
|
||||
}
|
||||
|
||||
internal object GetHeader()
|
||||
@@ -154,15 +171,20 @@
|
||||
.TakeWhile((c, i) => Grid.ColumnsCollection.IndexOf(this) > i && c.Frozen)
|
||||
.Sum(c => {
|
||||
var w = !string.IsNullOrEmpty(c.GetWidth()) ? c.GetWidth() : Grid.ColumnWidth;
|
||||
return !string.IsNullOrEmpty(w) && w.Contains("px") ? int.Parse(w.Replace("px", "")) : 200;
|
||||
var cw = 200;
|
||||
if (!string.IsNullOrEmpty(w) && w.Contains("px"))
|
||||
{
|
||||
int.TryParse(w.Replace("px", ""), out cw);
|
||||
}
|
||||
return cw;
|
||||
});
|
||||
|
||||
style.Add($"left:{left}px");
|
||||
}
|
||||
|
||||
if (isHeaderOrFooterCell && !Frozen && Grid.ColumnsCollection.Where(c => c.Visible && c.Frozen).Any())
|
||||
if ((isHeaderOrFooterCell && Frozen || isHeaderOrFooterCell && !Frozen || !isHeaderOrFooterCell && Frozen) && Grid.ColumnsCollection.Where(c => c.Visible && c.Frozen).Any())
|
||||
{
|
||||
style.Add("z-index:0");
|
||||
style.Add($"z-index:{(isHeaderOrFooterCell && Frozen ? 2 : 1)}");
|
||||
}
|
||||
|
||||
return string.Join(";", style);
|
||||
@@ -194,6 +216,24 @@
|
||||
sortOrder = new SortOrder?[] { order };
|
||||
}
|
||||
|
||||
internal void ResetSortOrder()
|
||||
{
|
||||
sortOrder = Enumerable.Empty<SortOrder?>();
|
||||
SortOrder = null;
|
||||
}
|
||||
|
||||
public string GetGroupProperty()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(GroupProperty))
|
||||
{
|
||||
return GroupProperty;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Property;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetFilterProperty()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(FilterProperty))
|
||||
@@ -236,7 +276,7 @@
|
||||
|
||||
if (parameters.DidParameterChange(nameof(SortOrder), SortOrder))
|
||||
{
|
||||
sortOrder = new SortOrder?[] { parameters.GetValueOrDefault<SortOrder>(nameof(SortOrder)) };
|
||||
sortOrder = new SortOrder?[] { parameters.GetValueOrDefault<SortOrder?>(nameof(SortOrder)) };
|
||||
}
|
||||
|
||||
if (parameters.DidParameterChange(nameof(FilterValue), FilterValue))
|
||||
@@ -299,7 +339,7 @@
|
||||
|
||||
internal void SetFilterValue(object value, bool isFirst = true)
|
||||
{
|
||||
if (FilterPropertyType == typeof(DateTimeOffset) && value != null && value is DateTime?)
|
||||
if ((FilterPropertyType == typeof(DateTimeOffset) || FilterPropertyType == typeof(DateTimeOffset?)) && value != null && value is DateTime?)
|
||||
{
|
||||
DateTimeOffset? offset = DateTime.SpecifyKind((DateTime)value, DateTimeKind.Utc);
|
||||
value = offset;
|
||||
@@ -350,7 +390,7 @@
|
||||
internal IEnumerable<FilterOperator> GetFilterOperators()
|
||||
{
|
||||
return Enum.GetValues(typeof(FilterOperator)).Cast<FilterOperator>().Where(o => {
|
||||
var isStringOperator = o == FilterOperator.Contains || o == FilterOperator.StartsWith || o == FilterOperator.EndsWith;
|
||||
var isStringOperator = o == FilterOperator.Contains || o == FilterOperator.DoesNotContain || o == FilterOperator.StartsWith || o == FilterOperator.EndsWith;
|
||||
return FilterPropertyType == typeof(string) ? isStringOperator || o == FilterOperator.Equals || o == FilterOperator.NotEquals : !isStringOperator;
|
||||
});
|
||||
}
|
||||
@@ -361,6 +401,8 @@
|
||||
{
|
||||
case FilterOperator.Contains:
|
||||
return Grid?.ContainsText;
|
||||
case FilterOperator.DoesNotContain:
|
||||
return Grid?.DoesNotContainText;
|
||||
case FilterOperator.EndsWith:
|
||||
return Grid?.EndsWithText;
|
||||
case FilterOperator.Equals:
|
||||
|
||||
121
Radzen.Blazor/RadzenDataGridGroupRow.razor
Normal file
121
Radzen.Blazor/RadzenDataGridGroupRow.razor
Normal file
@@ -0,0 +1,121 @@
|
||||
@typeparam TItem
|
||||
@using System.Linq.Dynamic.Core
|
||||
<tr>
|
||||
@for(var i = 0; i < GetLevel(); i++)
|
||||
{
|
||||
<td class="rz-col-icon">
|
||||
<span class="rz-column-title"></span>
|
||||
</td>
|
||||
}
|
||||
<td class="rz-col-icon">
|
||||
<span class="rz-column-title"></span>
|
||||
<a href="javascript:void(0)" @onclick="@(_ => Grid.ExpandGroupItem(Group))">
|
||||
<span class="@(Grid.ExpandedGroupItemStyle(Group))"></span>
|
||||
</a>
|
||||
</td>
|
||||
<td colspan="@(Columns.Count + Grid.groups.Count - 1 - Group.Level)">
|
||||
<span class="rz-cell-data">
|
||||
@if (Grid.GroupHeaderTemplate != null)
|
||||
{
|
||||
@Grid.GroupHeaderTemplate(Group)
|
||||
}
|
||||
else
|
||||
{
|
||||
@(Group.GroupDescriptor.GetTitle() + ": " + Group.Data.Key)
|
||||
}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
@if(Grid != null && Grid.IsGroupItemExpanded(Group))
|
||||
{
|
||||
@DrawDataRows()
|
||||
}
|
||||
@code {
|
||||
[Parameter]
|
||||
public IList<RadzenDataGridColumn<TItem>> Columns { get; set; }
|
||||
|
||||
GroupResult _groupResult;
|
||||
[Parameter]
|
||||
public GroupResult GroupResult
|
||||
{
|
||||
get
|
||||
{
|
||||
return _groupResult;
|
||||
}
|
||||
set
|
||||
{
|
||||
if(_groupResult != value)
|
||||
{
|
||||
_groupResult = value;
|
||||
|
||||
var level = GetLevel();
|
||||
Group = new Group()
|
||||
{
|
||||
Level = level,
|
||||
GroupDescriptor = Grid.groups[level],
|
||||
Data = _groupResult
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public RadzenDataGrid<TItem> Grid { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public RadzenDataGridGroupRow<TItem> Parent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder Builder { get; set; }
|
||||
|
||||
RenderFragment DrawDataRows()
|
||||
{
|
||||
return new RenderFragment(builder =>
|
||||
{
|
||||
if(GroupResult.Subgroups != null)
|
||||
{
|
||||
foreach(var g in GroupResult.Subgroups)
|
||||
{
|
||||
builder.OpenComponent(0, typeof(RadzenDataGridGroupRow<TItem>));
|
||||
builder.AddAttribute(1, "Columns", Columns);
|
||||
builder.AddAttribute(3, "Grid", Grid);
|
||||
builder.AddAttribute(3, "Parent", this);
|
||||
builder.AddAttribute(5, "GroupResult", g);
|
||||
builder.AddAttribute(6, "Builder", builder);
|
||||
builder.CloseComponent();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = 0;
|
||||
foreach(var item in GroupResult.Items)
|
||||
{
|
||||
builder.OpenComponent(0, typeof(RadzenDataGridRow<TItem>));
|
||||
builder.AddAttribute(1, "Columns", Columns);
|
||||
builder.AddAttribute(2, "Index", i);
|
||||
builder.AddAttribute(3, "Grid", Grid);
|
||||
builder.AddAttribute(4, "TItem", typeof(TItem));
|
||||
builder.AddAttribute(5, "Item", item);
|
||||
builder.AddAttribute(6, "InEditMode", Grid.IsRowInEditMode((TItem)item));
|
||||
builder.CloseComponent();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Group Group { get; set; }
|
||||
|
||||
int GetLevel()
|
||||
{
|
||||
int i = 0;
|
||||
var p = Parent;
|
||||
while(p != null)
|
||||
{
|
||||
p = p.Parent;
|
||||
i++;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,15 @@
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@typeparam TItem
|
||||
@implements IRadzenForm
|
||||
@implements IDisposable
|
||||
@{var rowArgs = Grid?.RowAttributes(Item); }
|
||||
<tr class="@(Grid.RowStyle(Item, Index))" @attributes="@rowArgs.Item2">
|
||||
|
||||
@foreach(var g in Grid.groups)
|
||||
{
|
||||
<td class="rz-col-icon">
|
||||
<span class="rz-column-title"></span>
|
||||
</td>
|
||||
}
|
||||
@if (Grid.Template != null)
|
||||
{
|
||||
<td class="rz-col-icon">
|
||||
@@ -15,6 +22,7 @@
|
||||
}
|
||||
</td>
|
||||
}
|
||||
<CascadingValue Value=@EditContext>
|
||||
<CascadingValue Value=this>
|
||||
@for (var j = 0; j < Columns.Count; j++)
|
||||
{
|
||||
@@ -51,62 +59,29 @@
|
||||
Grid.rowSpans.Add(j, (int)Convert.ChangeType(rowspan, TypeCode.Int32));
|
||||
}
|
||||
|
||||
if (Grid.IsRowInEditMode(Item))
|
||||
{
|
||||
<CascadingValue Value=Grid.editContexts[Item]>
|
||||
<td style="@column.GetStyle(true)" @attributes="@(cellAttr)" class="@Grid.getFrozenColumnClass(column, Columns)">
|
||||
<span class="rz-cell-data">
|
||||
@if (column.EditTemplate != null)
|
||||
{
|
||||
@column.EditTemplate(Item)
|
||||
}
|
||||
else if (column.Template != null)
|
||||
{
|
||||
@column.Template(Item)
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(column.Property))
|
||||
{
|
||||
@if (!string.IsNullOrEmpty(column.FormatString))
|
||||
{
|
||||
@(String.Format(column.FormatString, PropertyAccess.GetValue(Item, column.Property)));
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(column.Property))
|
||||
{
|
||||
@(PropertyAccess.GetValue(Item, column.Property));
|
||||
}
|
||||
}
|
||||
</span>
|
||||
</td>
|
||||
</CascadingValue>
|
||||
}
|
||||
else
|
||||
{
|
||||
<RadzenDataGridCell Grid="@this.Grid" Item="@Item"
|
||||
Style="@column.GetStyle(true)" CssClass="@(column.CssClass + " " + Grid.getFrozenColumnClass(column, Columns))" Attributes="@(cellAttr)">
|
||||
<span class="rz-cell-data">
|
||||
@if (Item != null)
|
||||
<RadzenDataGridCell Grid="@this.Grid" Item="@Item"
|
||||
Style="@column.GetStyle(true)" CssClass="@(column.CssClass + " " + Grid.getFrozenColumnClass(column, Columns))" Attributes="@(cellAttr)">
|
||||
<span class="rz-cell-data" title="@(column.Template == null ? column.GetValue(Item) : "")">
|
||||
@if (Item != null)
|
||||
{
|
||||
@if (Grid.IsRowInEditMode(Item) && column.EditTemplate != null)
|
||||
{
|
||||
@if (column.Template != null)
|
||||
{
|
||||
@column.Template(Item)
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(column.Property))
|
||||
{
|
||||
@if (!string.IsNullOrEmpty(column.FormatString))
|
||||
{
|
||||
@(String.Format(column.FormatString, PropertyAccess.GetValue(Item, column.Property)));
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(column.Property))
|
||||
{
|
||||
@(PropertyAccess.GetValue(Item, column.Property));
|
||||
}
|
||||
}
|
||||
@column.EditTemplate(Item)
|
||||
}
|
||||
else if (column.Template != null)
|
||||
{
|
||||
@column.Template(Item)
|
||||
}
|
||||
</span>
|
||||
</RadzenDataGridCell>
|
||||
}
|
||||
else
|
||||
{
|
||||
@column.GetValue(Item)
|
||||
}
|
||||
}
|
||||
</span>
|
||||
</RadzenDataGridCell>
|
||||
}
|
||||
</CascadingValue>
|
||||
</CascadingValue>
|
||||
</tr>
|
||||
@if (Grid.Template != null && Grid.expandedItems.Keys.Contains(Item))
|
||||
{
|
||||
@@ -143,6 +118,9 @@
|
||||
[Parameter]
|
||||
public bool InEditMode { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EditContext EditContext { get; set; }
|
||||
|
||||
List<IRadzenFormComponent> components;
|
||||
|
||||
public void AddComponent(IRadzenFormComponent component)
|
||||
@@ -175,11 +153,8 @@
|
||||
return components.Where(component => component.Name == name).FirstOrDefault();
|
||||
}
|
||||
|
||||
Tuple<Radzen.RowRenderEventArgs<TItem>, IReadOnlyDictionary<string, object>> rowArgs;
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
rowArgs = Grid.RowAttributes(Item);
|
||||
|
||||
if (Grid.IsVirtualizationAllowed() && Item != null)
|
||||
{
|
||||
Index = Grid.GetItemIndex(Item);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<div @ref="@Element" @attributes="Attributes" class="@GetCssClass()" style="@Style" id="@GetId()">
|
||||
@if (AllowPaging && (PagerPosition == PagerPosition.Top || PagerPosition == PagerPosition.TopAndBottom))
|
||||
{
|
||||
<RadzenPager @ref="topPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@OnPageChanged" />
|
||||
<RadzenPager @ref="topPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@OnPageChanged" PageSizeChanged="@OnPageSizeChanged" PageSizeOptions="@PageSizeOptions" />
|
||||
}
|
||||
@if (Data != null)
|
||||
{
|
||||
@@ -47,7 +47,7 @@
|
||||
}
|
||||
@if (AllowPaging && (PagerPosition == PagerPosition.Bottom || PagerPosition == PagerPosition.TopAndBottom))
|
||||
{
|
||||
<RadzenPager @ref="bottomPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@OnPageChanged" class="rz-paginator-bottom" />
|
||||
<RadzenPager @ref="bottomPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@OnPageChanged" PageSizeChanged="@OnPageSizeChanged" PageSizeOptions="@PageSizeOptions" class="rz-paginator-bottom" />
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
@if (!Inline)
|
||||
{
|
||||
<span class="@($"rz-calendar rz-calendar-w-btn{(Disabled ? " rz-state-disabled" : "")}")" style="width:100%">
|
||||
<input @ref="@input" disabled="@Disabled" readonly="@ReadOnly" value="@FormattedValue" tabindex="@TabIndex"
|
||||
<input @ref="@input" disabled="@Disabled" readonly="@IsReadonly" value="@FormattedValue" tabindex="@TabIndex"
|
||||
@onchange="@ParseDate" autocomplete="off" type="text"
|
||||
class="rz-inputtext" id="@Name" placeholder="@Placeholder" />
|
||||
<button onclick="@getOpenPopup()" class="@($"rz-datepicker-trigger rz-calendar-button rz-button rz-button-icon-only{(Disabled ? " rz-state-disabled" : "")}")" tabindex="-1" type="button">
|
||||
@@ -92,86 +92,30 @@
|
||||
@if (ShowTime)
|
||||
{
|
||||
<div class="rz-timepicker">
|
||||
<RadzenNumeric Disabled="@Disabled" Value="@(HourFormat == "12" ? ((CurrentDate.Hour + 11) % 12) + 1 : CurrentDate.Hour)" TValue="double" Step="@HoursStep"
|
||||
Change="@(async v => {
|
||||
var step = getStep(StepType.Hours);
|
||||
if (v == CurrentDate.Hour - step || v == CurrentDate.Hour + step)
|
||||
{
|
||||
if (v > CurrentDate.Hour)
|
||||
{
|
||||
Value = CurrentDate.AddHours(step);
|
||||
}
|
||||
else
|
||||
{
|
||||
Value = CurrentDate.AddHours(-step);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Value = CurrentDate.AddHours(v - CurrentDate.Hour);
|
||||
}
|
||||
|
||||
await OnChange();
|
||||
} )" class="rz-hour-picker" />
|
||||
<RadzenNumeric TValue="int" Disabled="@Disabled" Value="@(HourFormat == "12" ? ((CurrentDate.Hour + 11) % 12) + 1 : CurrentDate.Hour)"
|
||||
Min="@(HourFormat == "12" ? 1 : -1)" Max="@(HourFormat == "12" ? 12 : 24)" TValue="double" Step="@HoursStep"
|
||||
Change="@UpdateHour" class="rz-hour-picker" @oninput=@OnUpdateHourInput />
|
||||
<div class="rz-separator">
|
||||
<span>:</span>
|
||||
</div>
|
||||
<RadzenNumeric Disabled="@Disabled" Value="CurrentDate.Minute" TValue="double" Step="@MinutesStep"
|
||||
Change="@(async v => {
|
||||
var step = getStep(StepType.Minutes);
|
||||
if (v == CurrentDate.Minute - step || v == CurrentDate.Minute + step)
|
||||
{
|
||||
if (v > CurrentDate.Minute)
|
||||
{
|
||||
Value = CurrentDate.AddMinutes(step);
|
||||
}
|
||||
else
|
||||
{
|
||||
Value = CurrentDate.AddMinutes(-step);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Value = CurrentDate.AddMinutes(v - CurrentDate.Minute);
|
||||
}
|
||||
|
||||
await OnChange();
|
||||
} )" class="rz-minute-picker" />
|
||||
<RadzenNumeric TValue="int" Disabled="@Disabled" Value="CurrentDate.Minute" TValue="double" Step="@MinutesStep" Min="0" Max="59"
|
||||
Change="@UpdateMinutes" class="rz-minute-picker" @oninput=@OnUpdateHourMinutes />
|
||||
@if (ShowSeconds)
|
||||
{
|
||||
<div class="rz-separator">
|
||||
<span>:</span>
|
||||
</div>
|
||||
<RadzenNumeric Disabled="@Disabled" Value="CurrentDate.Second" TValue="double" Step="@SecondsStep"
|
||||
Change="@(async v => {
|
||||
var step = getStep(StepType.Seconds);
|
||||
if (v == CurrentDate.Second - step || v == CurrentDate.Second + step)
|
||||
{
|
||||
if (v > CurrentDate.Second)
|
||||
{
|
||||
Value = CurrentDate.AddSeconds(step);
|
||||
}
|
||||
else
|
||||
{
|
||||
Value = CurrentDate.AddSeconds(-step);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Value = CurrentDate.AddSeconds(v - CurrentDate.Second);
|
||||
}
|
||||
|
||||
await OnChange();
|
||||
} )" class="rz-second-picker" />
|
||||
<RadzenNumeric TValue="int" Disabled="@Disabled" Value="CurrentDate.Second" TValue="double" Step="@SecondsStep" Min="0" Max="59"
|
||||
Change="@UpdateSeconds" class="rz-second-picker" @oninput=@OnUpdateHourSeconds />
|
||||
}
|
||||
@if (HourFormat == "12")
|
||||
{
|
||||
<div class="rz-ampm-picker">
|
||||
<a href="javascript:void(0)" @onclick="@(async() => { if (amPm == "am" && !Disabled) { Value = CurrentDate.AddDays(1).AddHours(-12); amPm = "pm"; await OnChange(); } })">
|
||||
<a href="javascript:void(0)" @onclick="@AmToPm">
|
||||
<span class="rzi rzi-chevron-up"></span>
|
||||
</a>
|
||||
<span>@CurrentDate.ToString("tt")</span>
|
||||
<a href="javascript:void(0)" @onclick="@(async() => { if (amPm == "pm" && !Disabled) { Value = CurrentDate.AddDays(-1).AddHours(12); amPm = "am"; await OnChange(); } })">
|
||||
<a href="javascript:void(0)" @onclick="@PmToAm">
|
||||
<span class="rzi rzi-chevron-down"></span>
|
||||
</a>
|
||||
</div>
|
||||
@@ -179,7 +123,7 @@
|
||||
@if (ShowTimeOkButton)
|
||||
{
|
||||
<button type="button" class="rz-button rz-button-md btn-secondary" style="width:60px;padding:0px;margin-left:10px;"
|
||||
@onclick="@(async() => { if (!Disabled) { Value = CurrentDate; await OnChange(); await monthDropDown?.ClosePopup(); await yearDropDown?.ClosePopup(); } })"
|
||||
@onclick="@OkClick"
|
||||
onmouseup="@($"Radzen.closePopup('{PopupID}')")">
|
||||
<span class="rz-button-text">Ok</span>
|
||||
</button>
|
||||
@@ -193,6 +137,162 @@
|
||||
RadzenDropDown<int> monthDropDown;
|
||||
RadzenDropDown<int> yearDropDown;
|
||||
|
||||
async Task AmToPm()
|
||||
{
|
||||
if (amPm == "am" && !Disabled)
|
||||
{
|
||||
amPm = "pm";
|
||||
|
||||
var currentHour = ((CurrentDate.Hour + 11) % 12) + 1;
|
||||
|
||||
var newHour = currentHour - 12;
|
||||
|
||||
if(newHour < 1)
|
||||
{
|
||||
newHour = currentHour;
|
||||
}
|
||||
|
||||
var newValue = new DateTime(CurrentDate.Year, CurrentDate.Month, CurrentDate.Day, newHour, CurrentDate.Minute, CurrentDate.Second);
|
||||
|
||||
if(!object.Equals(newValue, Value))
|
||||
{
|
||||
Value = newValue;
|
||||
await OnChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async Task PmToAm()
|
||||
{
|
||||
if (amPm == "pm" && !Disabled)
|
||||
{
|
||||
amPm = "am";
|
||||
|
||||
var currentHour = ((CurrentDate.Hour + 11) % 12) + 1;
|
||||
|
||||
var newHour = currentHour + 12;
|
||||
|
||||
if(newHour > 23)
|
||||
{
|
||||
newHour = 0;
|
||||
}
|
||||
|
||||
var newValue = new DateTime(CurrentDate.Year, CurrentDate.Month, CurrentDate.Day, newHour, CurrentDate.Minute, CurrentDate.Second);
|
||||
|
||||
if(!object.Equals(newValue, Value))
|
||||
{
|
||||
Value = newValue;
|
||||
await OnChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int? hour;
|
||||
void OnUpdateHourInput(ChangeEventArgs args)
|
||||
{
|
||||
var value = $"{args.Value}";
|
||||
if(!string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
hour = (int)Convert.ChangeType(value, typeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
int? minutes;
|
||||
void OnUpdateHourMinutes(ChangeEventArgs args)
|
||||
{
|
||||
var value = $"{args.Value}";
|
||||
if(!string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
minutes = (int)Convert.ChangeType(value, typeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
int? seconds;
|
||||
void OnUpdateHourSeconds(ChangeEventArgs args)
|
||||
{
|
||||
var value = $"{args.Value}";
|
||||
if(!string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
seconds = (int)Convert.ChangeType(value, typeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
async Task UpdateHour(int v)
|
||||
{
|
||||
var newHour = HourFormat == "12" && CurrentDate.Hour > 12 ? v + 12 : v;
|
||||
|
||||
var newValue = new DateTime(CurrentDate.Year, CurrentDate.Month, CurrentDate.Day, newHour > 23 || newHour < 0 ? 0 : newHour, CurrentDate.Minute, CurrentDate.Second);
|
||||
|
||||
if(!object.Equals(newValue, Value))
|
||||
{
|
||||
hour = newValue.Hour;
|
||||
Value = newValue;
|
||||
await OnChange();
|
||||
}
|
||||
}
|
||||
|
||||
async Task UpdateMinutes(int v)
|
||||
{
|
||||
var newValue = new DateTime(CurrentDate.Year, CurrentDate.Month, CurrentDate.Day, CurrentDate.Hour, v, CurrentDate.Second);
|
||||
|
||||
if(!object.Equals(newValue, Value))
|
||||
{
|
||||
minutes = newValue.Minute;
|
||||
Value = newValue;
|
||||
await OnChange();
|
||||
}
|
||||
}
|
||||
|
||||
async Task UpdateSeconds(int v)
|
||||
{
|
||||
var newValue = new DateTime(CurrentDate.Year, CurrentDate.Month, CurrentDate.Day, CurrentDate.Hour, CurrentDate.Minute, v);
|
||||
|
||||
if(!object.Equals(newValue, Value))
|
||||
{
|
||||
seconds = newValue.Second;
|
||||
Value = newValue;
|
||||
await OnChange();
|
||||
}
|
||||
}
|
||||
|
||||
async Task OkClick()
|
||||
{
|
||||
if (!Disabled)
|
||||
{
|
||||
DateTime date = CurrentDate;
|
||||
|
||||
if(CurrentDate.Hour != hour && hour != null)
|
||||
{
|
||||
var newHour = HourFormat == "12" && CurrentDate.Hour > 12 ? hour.Value + 12 : hour.Value;
|
||||
date = new DateTime(CurrentDate.Year, CurrentDate.Month, CurrentDate.Day, newHour > 23 || newHour < 0 ? 0 : newHour, CurrentDate.Minute, CurrentDate.Second);
|
||||
}
|
||||
|
||||
if(CurrentDate.Minute != minutes && minutes != null)
|
||||
{
|
||||
date = new DateTime(CurrentDate.Year, CurrentDate.Month, CurrentDate.Day, CurrentDate.Hour, minutes.Value, CurrentDate.Second);
|
||||
}
|
||||
|
||||
if(CurrentDate.Second != seconds && seconds != null)
|
||||
{
|
||||
date = new DateTime(CurrentDate.Year, CurrentDate.Month, CurrentDate.Day, CurrentDate.Hour, CurrentDate.Minute, seconds.Value);
|
||||
}
|
||||
|
||||
Value = date;
|
||||
|
||||
await OnChange();
|
||||
|
||||
if(monthDropDown != null)
|
||||
{
|
||||
await monthDropDown.ClosePopup();
|
||||
}
|
||||
|
||||
if(yearDropDown != null)
|
||||
{
|
||||
await yearDropDown.ClosePopup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class NameValue
|
||||
{
|
||||
public string Name { get; set; }
|
||||
@@ -449,6 +549,11 @@
|
||||
[Parameter]
|
||||
public bool ReadOnly { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool AllowInput { get; set; } = true;
|
||||
|
||||
private bool IsReadonly => ReadOnly || !AllowInput;
|
||||
|
||||
[Parameter]
|
||||
public bool Disabled { get; set; }
|
||||
|
||||
@@ -689,7 +794,10 @@
|
||||
|
||||
Form?.RemoveComponent(this);
|
||||
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", PopupID);
|
||||
if (IsJSRuntimeAvailable)
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", PopupID);
|
||||
}
|
||||
}
|
||||
|
||||
public object GetValue()
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
await InvokeAsync(() => { StateHasChanged(); });
|
||||
|
||||
await JSRuntime.InvokeAsync<string>("Radzen.openDialog");
|
||||
await JSRuntime.InvokeAsync<string>("Radzen.openDialog", options);
|
||||
}
|
||||
|
||||
public async Task Close(dynamic result)
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
@using Radzen
|
||||
@using System.Linq
|
||||
@using System.Linq.Dynamic.Core
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.JSInterop
|
||||
@using Microsoft.AspNetCore.Components.Rendering
|
||||
@typeparam TValue
|
||||
@inherits DropDownBase<TValue>
|
||||
|
||||
@if (Visible)
|
||||
{
|
||||
<div @ref="@Element" @attributes="Attributes" class="@GetCssClass()" @onmousedown="@(args => OpenPopup("ArrowDown", false, true))" style="@Style" tabindex="@TabIndex"
|
||||
@onkeydown="@((args) => OnKeyPress(args))" id="@GetId()">
|
||||
<div @ref="@Element" @attributes="Attributes" class="@GetCssClass()" @onmousedown="@(args => OpenPopup("ArrowDown", false, true))" style="@Style" tabindex="@TabIndex"
|
||||
@onkeydown="@((args) => OnKeyPress(args))" id="@GetId()">
|
||||
<div class="rz-helper-hidden-accessible">
|
||||
<input disabled="@Disabled" style="width:100%" aria-haspopup="listbox" readonly="" type="text" tabindex="-1"
|
||||
name="@Name" value="@(Value != null ? Value : "")"
|
||||
name="@Name" value="@(Value != null ? Value : "")"
|
||||
aria-label="@(!Multiple && Value != null ? PropertyAccess.GetItemOrValueFromProperty(Value, TextProperty) : "")" />
|
||||
</div>
|
||||
|
||||
@@ -39,7 +41,7 @@
|
||||
else
|
||||
{
|
||||
foreach (var item in selectedItems)
|
||||
{
|
||||
{
|
||||
@Template(item)@(",")
|
||||
}
|
||||
}
|
||||
@@ -72,7 +74,7 @@
|
||||
@if (AllowFiltering && !Multiple)
|
||||
{
|
||||
<div class="rz-dropdown-filter-container">
|
||||
<input id="@SearchID" @ref="@search" tabindex="@TabIndex" class="rz-dropdown-filter rz-inputtext " autocomplete="off" type="text"
|
||||
<input id="@SearchID" @ref="@search" tabindex="@TabIndex" class="rz-dropdown-filter rz-inputtext " autocomplete="off" type="text"
|
||||
@onchange="@((ChangeEventArgs args) => OnFilter(args))" @onkeydown="@((args) => OnFilterKeyPress(args))" value="@searchText" />
|
||||
<span class="rz-dropdown-filter-icon rzi rzi-search"></span>
|
||||
</div>
|
||||
@@ -89,7 +91,7 @@
|
||||
</div>
|
||||
</div>
|
||||
@if (!AllowFiltering && !string.IsNullOrEmpty(SelectAllText))
|
||||
{
|
||||
{
|
||||
@SelectAllText
|
||||
}
|
||||
@if (AllowFiltering)
|
||||
@@ -111,45 +113,7 @@
|
||||
<ul @ref="list" class="@(Multiple ? "rz-multiselect-items rz-multiselect-list " : "rz-dropdown-items rz-dropdown-list ")" role="listbox">
|
||||
@if (View != null)
|
||||
{
|
||||
@foreach (var item in View)
|
||||
{
|
||||
@if (Multiple)
|
||||
{
|
||||
<li class="@(isSelected(item) ? "rz-multiselect-item rz-state-highlight" : "rz-multiselect-item ")"
|
||||
aria-label="@PropertyAccess.GetItemOrValueFromProperty(item, TextProperty)" style="display: block;white-space: nowrap;" @onclick:preventDefault @onclick="@(() => OnSelectItem(item))">
|
||||
<div class="rz-chkbox ">
|
||||
<div class="@(isSelected(item) ? "rz-chkbox-box rz-state-active" : "rz-chkbox-box ")">
|
||||
<span class="@(isSelected(item) ? "rz-chkbox-icon rzi rzi-check" : "rz-chkbox-icon ")"></span>
|
||||
</div>
|
||||
</div>
|
||||
<span>
|
||||
@if (Template != null)
|
||||
{
|
||||
@Template(item)
|
||||
}
|
||||
else
|
||||
{
|
||||
@PropertyAccess.GetItemOrValueFromProperty(item, TextProperty)
|
||||
}
|
||||
</span>
|
||||
</li>
|
||||
}
|
||||
else
|
||||
{
|
||||
<li role="option" class="@(isSelected(item) ? "rz-dropdown-item rz-state-highlight" : "rz-dropdown-item ")" aria-label=">@PropertyAccess.GetItemOrValueFromProperty(item, TextProperty)" @onclick:preventDefault @onclick="@(() => OnSelectItem(item))">
|
||||
<span>
|
||||
@if (Template != null)
|
||||
{
|
||||
@Template(item)
|
||||
}
|
||||
else
|
||||
{
|
||||
@PropertyAccess.GetItemOrValueFromProperty(item, TextProperty)
|
||||
}
|
||||
</span>
|
||||
</li>
|
||||
}
|
||||
}
|
||||
@RenderItems()
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
@@ -161,6 +125,15 @@
|
||||
</div>
|
||||
}
|
||||
@code {
|
||||
internal override void RenderItem(RenderTreeBuilder builder, object item)
|
||||
{
|
||||
builder.OpenComponent(0, typeof(RadzenDropDownItem<TValue>));
|
||||
builder.AddAttribute(1, "DropDown", this);
|
||||
builder.AddAttribute(2, "Item", item);
|
||||
builder.SetKey(item);
|
||||
builder.CloseComponent();
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public int MaxSelectedLabels { get; set; } = 4;
|
||||
|
||||
@@ -206,7 +179,7 @@
|
||||
bool reload = false;
|
||||
if (LoadData.HasDelegate && Data == null)
|
||||
{
|
||||
await LoadData.InvokeAsync(new Radzen.LoadDataArgs() { });
|
||||
await LoadData.InvokeAsync(await GetLoadDataArgs());
|
||||
reload = true;
|
||||
}
|
||||
|
||||
@@ -234,6 +207,11 @@
|
||||
await SelectItem(item);
|
||||
}
|
||||
|
||||
internal async System.Threading.Tasks.Task OnSelectItemInternal(object item, bool isFromKey = false)
|
||||
{
|
||||
await OnSelectItem(item, isFromKey);
|
||||
}
|
||||
|
||||
protected override string GetComponentCssClass()
|
||||
{
|
||||
var classList = new List<string>();
|
||||
@@ -272,7 +250,10 @@
|
||||
{
|
||||
base.Dispose();
|
||||
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", PopupID);
|
||||
if (IsJSRuntimeAvailable)
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", PopupID);
|
||||
}
|
||||
}
|
||||
|
||||
internal async System.Threading.Tasks.Task ClosePopup()
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
<div class="rz-dropdown-trigger rz-corner-right" onclick="@OpenPopupScript()">
|
||||
<span class="rz-dropdown-trigger-icon rzi rzi-chevron-down"></span>
|
||||
</div>
|
||||
<div id="@PopupID" class="@(Multiple ? "rz-multiselect-panel " : "rz-dropdown-panel ")"
|
||||
<div id="@PopupID" class="@(Multiple ? "rz-multiselect-panel" : "rz-dropdown-panel")"
|
||||
style="display:none;min-width:320px;padding:0px;">
|
||||
<div class="rz-lookup-panel">
|
||||
@if (AllowFiltering)
|
||||
@@ -92,33 +92,48 @@
|
||||
}
|
||||
@if (Template != null)
|
||||
{
|
||||
<RadzenGrid Responsive="@Responsive" ColumnWidth="@ColumnWidth" @ref="grid" Data="@(LoadData.HasDelegate ? (Data != null ? Data.Cast<object>() : Enumerable.Empty<object>()) : pagedData)" Count="@(LoadData.HasDelegate ? Count : count)" LoadData="@OnLoadData"
|
||||
TItem="object" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" AllowPaging="true" AllowSorting="@AllowSorting" RowSelect="@OnRowSelect">
|
||||
<RadzenDataGrid ColumnWidth="@ColumnWidth" @ref="grid" Data="@(LoadData.HasDelegate ? (Data != null ? Data.Cast<object>() : Enumerable.Empty<object>()) : pagedData)" Count="@(LoadData.HasDelegate ? Count : count)" LoadData="@OnLoadData"
|
||||
TItem="object" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" AllowPaging="@(!IsVirtualizationAllowed())" AllowSorting="@AllowSorting" RowSelect="@OnRowSelect" Style="@(IsVirtualizationAllowed() ? "height:285px" : "")">
|
||||
<Columns>
|
||||
<RadzenGridColumn TItem="object" Property="@TextProperty" Title="@TextProperty" Type="string">
|
||||
<RadzenDataGridColumn TItem="object" Property="@TextProperty" Title="@TextProperty" Type="typeof(string)">
|
||||
<Template>
|
||||
@Template(context)
|
||||
</Template>
|
||||
</RadzenGridColumn>
|
||||
</RadzenDataGridColumn>
|
||||
</Columns>
|
||||
</RadzenGrid>
|
||||
</RadzenDataGrid>
|
||||
}
|
||||
else
|
||||
{
|
||||
<RadzenGrid Responsive="@Responsive" ColumnWidth="@ColumnWidth" EmptyText="@EmptyText" @ref="grid" Data="@(LoadData.HasDelegate ? (Data != null ? Data.Cast<object>() : Enumerable.Empty<object>()) : pagedData)" Count="@(LoadData.HasDelegate ? Count : count)" LoadData="@OnLoadData"
|
||||
TItem="object" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" AllowPaging="true" AllowSorting="@AllowSorting" RowSelect="@OnRowSelect">
|
||||
<Columns>
|
||||
@if (Columns != null)
|
||||
{
|
||||
@Columns
|
||||
}
|
||||
else
|
||||
{
|
||||
<RadzenGridColumn TItem="object" Property="@TextProperty" Title="@TextProperty" Type="string">
|
||||
</RadzenGridColumn>
|
||||
}
|
||||
</Columns>
|
||||
</RadzenGrid>
|
||||
if (!string.IsNullOrEmpty(TextProperty) || Columns != null)
|
||||
{
|
||||
<RadzenDataGrid ColumnWidth="@ColumnWidth" EmptyText="@EmptyText" @ref="grid" Data="@(LoadData.HasDelegate ? (Data != null ? Data.Cast<object>() : Enumerable.Empty<object>()) : pagedData)" Count="@(LoadData.HasDelegate ? Count : count)" LoadData="@OnLoadData"
|
||||
TItem="object" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" AllowPaging="@(!IsVirtualizationAllowed())" AllowSorting="@AllowSorting" RowSelect="@OnRowSelect" Style="@(IsVirtualizationAllowed() ? "height:285px" : "")">
|
||||
<Columns>
|
||||
@if (Columns != null)
|
||||
{
|
||||
@Columns
|
||||
}
|
||||
else
|
||||
{
|
||||
<RadzenDataGridColumn TItem="object" Property="@TextProperty" Title="@TextProperty" Type="typeof(string)" />
|
||||
}
|
||||
</Columns>
|
||||
</RadzenDataGrid>
|
||||
}
|
||||
else
|
||||
{
|
||||
<RadzenDataGrid ColumnWidth="@ColumnWidth" EmptyText="@EmptyText" @ref="grid" Data="@(LoadData.HasDelegate ? (Data != null ? Data.Cast<object>() : Enumerable.Empty<object>()) : pagedData)" Count="@(LoadData.HasDelegate ? Count : count)" LoadData="@OnLoadData"
|
||||
TItem="object" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" AllowPaging="@(!IsVirtualizationAllowed())" AllowSorting="@AllowSorting" RowSelect="@OnRowSelect" Style="@(IsVirtualizationAllowed() ? "height:285px" : "")">
|
||||
<Columns>
|
||||
<RadzenDataGridColumn TItem="object" Property="it" Title="Item" Type="typeof(string)">
|
||||
<Template>
|
||||
@context
|
||||
</Template>
|
||||
</RadzenDataGridColumn>
|
||||
</Columns>
|
||||
</RadzenDataGrid>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -150,13 +165,10 @@
|
||||
[Parameter]
|
||||
public object SelectedValue { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public int Count { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment Columns { get; set; }
|
||||
|
||||
RadzenGrid<object> grid;
|
||||
RadzenDataGrid<object> grid;
|
||||
|
||||
IEnumerable<object> pagedData;
|
||||
int count;
|
||||
@@ -164,6 +176,14 @@
|
||||
[Parameter]
|
||||
public int MaxSelectedLabels { get; set; } = 4;
|
||||
|
||||
#if !NET5
|
||||
[Parameter]
|
||||
public int PageSize { get; set; } = 5;
|
||||
|
||||
[Parameter]
|
||||
public int Count { get; set; }
|
||||
#endif
|
||||
|
||||
[Parameter]
|
||||
public string SelectedItemsText { get; set; } = "items selected";
|
||||
|
||||
@@ -171,9 +191,19 @@
|
||||
|
||||
protected override Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender && Visible && (LoadData.HasDelegate && Data == null))
|
||||
if (firstRender)
|
||||
{
|
||||
LoadData.InvokeAsync(new Radzen.LoadDataArgs() { Skip = 0, Top = PageSize });
|
||||
#if NET5
|
||||
if (grid != null)
|
||||
{
|
||||
grid.SetAllowVirtualization(AllowVirtualization);
|
||||
}
|
||||
#endif
|
||||
if(Visible && LoadData.HasDelegate && Data == null)
|
||||
{
|
||||
LoadData.InvokeAsync(new Radzen.LoadDataArgs() { Skip = 0, Top = PageSize });
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
@@ -199,11 +229,15 @@
|
||||
|
||||
private string GetPropertyFilterExpression(string property, string filterCaseSensitivityOperator)
|
||||
{
|
||||
if (property == null)
|
||||
{
|
||||
property = "it";
|
||||
}
|
||||
var p = $@"({property} == null ? """" : {property})";
|
||||
return $"{p}{filterCaseSensitivityOperator}.{Enum.GetName(typeof(StringFilterOperator), FilterOperator)}(@0)";
|
||||
}
|
||||
|
||||
private bool IsColumnFilterPropertyTypeString(RadzenGridColumn<object> column)
|
||||
private bool IsColumnFilterPropertyTypeString(RadzenDataGridColumn<object> column)
|
||||
{
|
||||
var property = column.GetFilterProperty();
|
||||
var itemType = Data != null ? Data.AsQueryable().ElementType : typeof(object);
|
||||
@@ -247,7 +281,7 @@
|
||||
|
||||
count = query.Count();
|
||||
|
||||
pagedData = QueryableExtension.ToList(query.Skip(args.Skip.HasValue ? args.Skip.Value : 0).Take(PageSize)).Cast<object>();
|
||||
pagedData = QueryableExtension.ToList(query.Skip(args.Skip.HasValue ? args.Skip.Value : 0).Take(args.Top.HasValue ? args.Top.Value : PageSize)).Cast<object>();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -400,22 +434,35 @@
|
||||
|
||||
await InvokeAsync(() =>
|
||||
{
|
||||
StateHasChanged();
|
||||
grid.FirstPage(true).Wait();
|
||||
#if NET5
|
||||
if (grid?.virtualize != null)
|
||||
{
|
||||
if(string.IsNullOrEmpty(searchText))
|
||||
{
|
||||
if(LoadData.HasDelegate)
|
||||
{
|
||||
Data = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
pagedData = null;
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
grid.virtualize.RefreshDataAsync().Wait();
|
||||
}
|
||||
#endif
|
||||
StateHasChanged();
|
||||
grid.FirstPage(true).Wait();
|
||||
|
||||
JSRuntime.InvokeAsync<string>("Radzen.repositionPopup", Element, PopupID);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task OnFilter(ChangeEventArgs args)
|
||||
{
|
||||
searchText = await JSRuntime.InvokeAsync<string>("Radzen.getInputValue", search);
|
||||
if (searchText != previousSearch)
|
||||
{
|
||||
previousSearch = searchText;
|
||||
_view = null;
|
||||
StateHasChanged();
|
||||
await grid.FirstPage(true);
|
||||
}
|
||||
await DebounceFilter();
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
@@ -427,10 +474,6 @@
|
||||
[Parameter]
|
||||
public bool AllowFilteringByAllStringColumns { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public int PageSize { get; set; } = 5;
|
||||
|
||||
|
||||
async Task OnRowSelect(object item)
|
||||
{
|
||||
await SelectItem(item);
|
||||
@@ -468,6 +511,9 @@
|
||||
{
|
||||
base.Dispose();
|
||||
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", PopupID);
|
||||
if (IsJSRuntimeAvailable)
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", PopupID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
@inherits RadzenGridColumn<dynamic>
|
||||
@inherits RadzenDataGridColumn<dynamic>
|
||||
|
||||
49
Radzen.Blazor/RadzenDropDownItem.razor
Normal file
49
Radzen.Blazor/RadzenDropDownItem.razor
Normal file
@@ -0,0 +1,49 @@
|
||||
@using Radzen
|
||||
@using System.Linq.Dynamic.Core
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.JSInterop
|
||||
@typeparam TValue
|
||||
|
||||
@if (DropDown.Multiple)
|
||||
{
|
||||
<li class="@(DropDown.isSelected(Item) ? "rz-multiselect-item rz-state-highlight" : "rz-multiselect-item ")"
|
||||
aria-label="@PropertyAccess.GetItemOrValueFromProperty(Item, DropDown.TextProperty)" style="display: block;white-space: nowrap;" @onclick:preventDefault @onclick="@(() => DropDown.OnSelectItemInternal(Item))">
|
||||
<div class="rz-chkbox ">
|
||||
<div class="@(DropDown.isSelected(Item) ? "rz-chkbox-box rz-state-active" : "rz-chkbox-box ")">
|
||||
<span class="@(DropDown.isSelected(Item) ? "rz-chkbox-icon rzi rzi-check" : "rz-chkbox-icon ")"></span>
|
||||
</div>
|
||||
</div>
|
||||
<span>
|
||||
@if (DropDown.Template != null)
|
||||
{
|
||||
@DropDown.Template(Item)
|
||||
}
|
||||
else
|
||||
{
|
||||
@PropertyAccess.GetItemOrValueFromProperty(Item, DropDown.TextProperty)
|
||||
}
|
||||
</span>
|
||||
</li>
|
||||
}
|
||||
else
|
||||
{
|
||||
<li role="option" class="@(DropDown.isSelected(Item) ? "rz-dropdown-item rz-state-highlight" : "rz-dropdown-item ")" aria-label=">@PropertyAccess.GetItemOrValueFromProperty(Item, DropDown.TextProperty)" @onclick:preventDefault @onclick="@(() => DropDown.OnSelectItemInternal(Item))">
|
||||
<span>
|
||||
@if (DropDown.Template != null)
|
||||
{
|
||||
@DropDown.Template(Item)
|
||||
}
|
||||
else
|
||||
{
|
||||
@PropertyAccess.GetItemOrValueFromProperty(Item, DropDown.TextProperty)
|
||||
}
|
||||
</span>
|
||||
</li>
|
||||
}
|
||||
@code {
|
||||
[Parameter]
|
||||
public RadzenDropDown<TValue> DropDown { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public object Item { get; set; }
|
||||
}
|
||||
@@ -46,6 +46,14 @@
|
||||
@ChildContent
|
||||
</div>
|
||||
</div>
|
||||
@if (SummaryTemplate != null)
|
||||
{
|
||||
<div class="rz-fieldset-content-wrapper" role="region" aria-hidden="false" style="@summaryContentStyle">
|
||||
<div class="rz-fieldset-content rz-fieldset-content-summary">
|
||||
@SummaryTemplate
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</fieldset>
|
||||
}
|
||||
@code {
|
||||
@@ -73,6 +81,9 @@
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment SummaryTemplate { get; set; } = null;
|
||||
|
||||
[Parameter]
|
||||
public EventCallback Expand { get; set; }
|
||||
|
||||
@@ -80,11 +91,13 @@
|
||||
public EventCallback Collapse { get; set; }
|
||||
|
||||
string contentStyle = "";
|
||||
string summaryContentStyle = "display: none";
|
||||
|
||||
async System.Threading.Tasks.Task Toggle(EventArgs args)
|
||||
{
|
||||
collapsed = !collapsed;
|
||||
contentStyle = collapsed ? "display: none;" : "";
|
||||
summaryContentStyle = !collapsed ? "display: none" : "";
|
||||
|
||||
if (collapsed)
|
||||
{
|
||||
@@ -116,6 +129,7 @@
|
||||
protected override Task OnParametersSetAsync()
|
||||
{
|
||||
contentStyle = collapsed ? "display: none;" : "";
|
||||
summaryContentStyle = !collapsed ? "display: none" : "";
|
||||
|
||||
return base.OnParametersSetAsync();
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<div>
|
||||
@if (IsImage)
|
||||
{
|
||||
<img style="width:100px;" src="@Value">
|
||||
<img style="@ImageStyle" src="@Value">
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
@@ -152,4 +152,7 @@
|
||||
|
||||
[Parameter]
|
||||
public int MaxFileSize { get; set; } = 5 * 1024 * 1024;
|
||||
|
||||
[Parameter]
|
||||
public string ImageStyle { get; set; } = "width:100px;";
|
||||
}
|
||||
|
||||
@@ -75,6 +75,8 @@
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
await base.OnAfterRenderAsync(firstRender);
|
||||
|
||||
var data = Data != null ? Data : markers;
|
||||
|
||||
if (firstRender)
|
||||
@@ -93,6 +95,9 @@
|
||||
{
|
||||
base.Dispose();
|
||||
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyMap", UniqueID);
|
||||
if (IsJSRuntimeAvailable)
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyMap", UniqueID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
<div @ref="@Element" style="@Style" @attributes="Attributes" class="@GetCssClass()" id="@GetId()">
|
||||
@if (AllowPaging && (PagerPosition == PagerPosition.Top || PagerPosition == PagerPosition.TopAndBottom))
|
||||
{
|
||||
<RadzenPager @ref="topPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@OnPageChanged" />
|
||||
<RadzenPager @ref="topPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@OnPageChanged" PageSizeChanged="@OnPageSizeChanged" PageSizeOptions="@PageSizeOptions" />
|
||||
}
|
||||
<div class="rz-datatable-scrollable-wrapper rz-helper-clearfix" style="">
|
||||
<div class="rz-datatable-scrollable-view">
|
||||
@@ -64,11 +64,11 @@
|
||||
</span>
|
||||
@if (AllowSorting && column.Sortable)
|
||||
{
|
||||
@if (!string.IsNullOrEmpty(orderBy) && orderBy.Contains($"{column.GetSortProperty()} asc"))
|
||||
@if (column.SortOrder == SortOrder.Ascending)
|
||||
{
|
||||
<span class="rz-sortable-column-icon rzi-grid-sort rzi-sort rzi-sort-asc"></span>
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(orderBy) && orderBy.Contains($"{column.GetSortProperty()} desc"))
|
||||
else if (column.SortOrder == SortOrder.Descending)
|
||||
{
|
||||
<span class="rz-sortable-column-icon rzi-grid-sort rzi-sort rzi-sort-desc"></span>
|
||||
}
|
||||
@@ -423,7 +423,14 @@
|
||||
{
|
||||
<tr class=" rz-datatable-emptymessage-row">
|
||||
<td class="rz-datatable-emptymessage" colspan="@visibleColumns.Count">
|
||||
<span>@EmptyText</span>
|
||||
@if (EmptyTemplate != null)
|
||||
{
|
||||
@EmptyTemplate
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>@EmptyText</span>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@@ -477,7 +484,7 @@
|
||||
|
||||
@if (AllowPaging && (PagerPosition == PagerPosition.Bottom || PagerPosition == PagerPosition.TopAndBottom))
|
||||
{
|
||||
<RadzenPager @ref="bottomPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@OnPageChanged" class="rz-paginator-bottom" />
|
||||
<RadzenPager @ref="bottomPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@OnPageChanged" PageSizeChanged="@OnPageSizeChanged" PageSizeOptions="@PageSizeOptions" class="rz-paginator-bottom" />
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@@ -633,12 +640,14 @@
|
||||
if (value != _emptyText)
|
||||
{
|
||||
_emptyText = value;
|
||||
|
||||
ChangeState();
|
||||
ChangeState().Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment EmptyTemplate { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool AllowSorting { get; set; }
|
||||
|
||||
@@ -1106,6 +1115,16 @@
|
||||
Dictionary<TItem, EditContext> editContexts = new Dictionary<TItem, EditContext>();
|
||||
|
||||
public async System.Threading.Tasks.Task EditRow(TItem item)
|
||||
{
|
||||
if(itemToInsert != null)
|
||||
{
|
||||
CancelEditRow(itemToInsert);
|
||||
}
|
||||
|
||||
await EditRowInternal(item);
|
||||
}
|
||||
|
||||
async System.Threading.Tasks.Task EditRowInternal(TItem item)
|
||||
{
|
||||
if (EditMode == DataGridEditMode.Single && editedItems.Keys.Any())
|
||||
{
|
||||
@@ -1194,7 +1213,7 @@
|
||||
list.Insert(0, item);
|
||||
this._view = list.AsQueryable();
|
||||
this.Count = this._view.Count();
|
||||
await EditRow(item);
|
||||
await EditRowInternal(item);
|
||||
}
|
||||
|
||||
protected void OnSort(EventArgs args, RadzenGridColumn<TItem> column)
|
||||
@@ -1267,6 +1286,7 @@
|
||||
|
||||
public void OrderBy(string property)
|
||||
{
|
||||
SetColumnSortOrder(property);
|
||||
var p = IsOData() ? property.Replace('.', '/') : PropertyAccess.GetProperty(property);
|
||||
orderBy = orderBy == $"{p} desc" || orderBy == null || orderBy.IndexOf(p) == -1 ? $"{p} asc" : $"{p} desc";
|
||||
InvokeAsync(Reload);
|
||||
@@ -1274,11 +1294,32 @@
|
||||
|
||||
public void OrderByDescending(string property)
|
||||
{
|
||||
SetColumnSortOrder(property);
|
||||
var p = IsOData() ? property.Replace('.', '/') : PropertyAccess.GetProperty(property);
|
||||
orderBy = $"{p} desc";
|
||||
InvokeAsync(Reload);
|
||||
}
|
||||
|
||||
internal void SetColumnSortOrder(string property)
|
||||
{
|
||||
var column = columns.Where(c => c.GetSortProperty() == property).FirstOrDefault();
|
||||
if(column != null)
|
||||
{
|
||||
if (column.SortOrder == null)
|
||||
{
|
||||
column.SortOrder = SortOrder.Ascending;
|
||||
}
|
||||
else if (column.SortOrder == SortOrder.Ascending)
|
||||
{
|
||||
column.SortOrder = SortOrder.Descending;
|
||||
}
|
||||
else if (column.SortOrder == SortOrder.Descending)
|
||||
{
|
||||
column.SortOrder = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override string GetComponentCssClass()
|
||||
{
|
||||
var additionalClasses = new List<string>();
|
||||
|
||||
@@ -31,7 +31,9 @@
|
||||
_title = value;
|
||||
|
||||
if (Grid != null)
|
||||
Grid.ChangeState();
|
||||
{
|
||||
Grid.ChangeState().Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -279,6 +281,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
internal SortOrder? SortOrder { get; set; }
|
||||
|
||||
public string GetFilterProperty()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(FilterProperty))
|
||||
|
||||
@@ -138,6 +138,8 @@
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
await base.OnAfterRenderAsync(firstRender);
|
||||
|
||||
this.firstRender = firstRender;
|
||||
|
||||
if (firstRender || visibleChanged)
|
||||
@@ -214,7 +216,7 @@
|
||||
{
|
||||
base.Dispose();
|
||||
|
||||
if (Visible)
|
||||
if (Visible && IsJSRuntimeAvailable)
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyEditor", ContentEditable);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
@using System.Linq.Dynamic.Core
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.JSInterop
|
||||
@using Microsoft.AspNetCore.Components.Rendering
|
||||
@typeparam TValue
|
||||
@inherits DropDownBase<TValue>
|
||||
@if (Visible)
|
||||
@@ -24,7 +25,7 @@
|
||||
</div>
|
||||
</div>
|
||||
@if (!AllowFiltering && !string.IsNullOrEmpty(Placeholder))
|
||||
{
|
||||
{
|
||||
<label for="@($"{UniqueID}sa")" class="rz-dropdown-label rz-inputtext " style="width:100%;">@Placeholder</label>
|
||||
}
|
||||
}
|
||||
@@ -42,35 +43,23 @@
|
||||
{
|
||||
<div class="rz-listbox-list-wrapper">
|
||||
<ul @ref="list" class="rz-listbox-list">
|
||||
@foreach (var item in View)
|
||||
{
|
||||
<li class="@(isSelected(item) ? "rz-multiselect-item rz-state-highlight" : "rz-multiselect-item ")" aria-label="@PropertyAccess.GetItemOrValueFromProperty(item, TextProperty)" style="display: block;" @onclick="@(async () => { if (!Disabled) { await SelectItem(item); } })">
|
||||
@if (Multiple)
|
||||
{
|
||||
<div class="rz-chkbox ">
|
||||
<div class="@(isSelected(item) ? "rz-chkbox-box rz-state-active" : "rz-chkbox-box ")">
|
||||
<span class="@(isSelected(item) ? "rz-chkbox-icon rzi rzi-check" : "rz-chkbox-icon ")"></span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<span>
|
||||
@if (Template != null)
|
||||
{
|
||||
@Template(item)
|
||||
}
|
||||
else
|
||||
{
|
||||
@PropertyAccess.GetItemOrValueFromProperty(item, TextProperty)
|
||||
}
|
||||
</span>
|
||||
</li>
|
||||
}
|
||||
@RenderItems()
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@code {
|
||||
|
||||
internal override void RenderItem(RenderTreeBuilder builder, object item)
|
||||
{
|
||||
builder.OpenComponent(0, typeof(RadzenListBoxItem<TValue>));
|
||||
builder.AddAttribute(1, "ListBox", this);
|
||||
builder.AddAttribute(2, "Item", item);
|
||||
builder.SetKey(item);
|
||||
builder.CloseComponent();
|
||||
}
|
||||
|
||||
protected async System.Threading.Tasks.Task OnKeyDown(Microsoft.AspNetCore.Components.Web.KeyboardEventArgs args)
|
||||
{
|
||||
if (Disabled)
|
||||
@@ -123,7 +112,7 @@
|
||||
bool reload = false;
|
||||
if (LoadData.HasDelegate && Data == null)
|
||||
{
|
||||
await LoadData.InvokeAsync(new Radzen.LoadDataArgs() { });
|
||||
await LoadData.InvokeAsync(await GetLoadDataArgs());
|
||||
reload = true;
|
||||
}
|
||||
|
||||
|
||||
34
Radzen.Blazor/RadzenListBoxItem.razor
Normal file
34
Radzen.Blazor/RadzenListBoxItem.razor
Normal file
@@ -0,0 +1,34 @@
|
||||
@using Radzen
|
||||
@using System.Linq.Dynamic.Core
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.JSInterop
|
||||
@typeparam TValue
|
||||
|
||||
<li class="@(ListBox.isSelected(Item) ? "rz-multiselect-item rz-state-highlight" : "rz-multiselect-item ")" aria-label="@PropertyAccess.GetItemOrValueFromProperty(Item, ListBox.TextProperty)" style="display: block;" @onclick="@(async () => { if (!ListBox.Disabled) { await ListBox.SelectItemInternal(Item); } })">
|
||||
@if (ListBox.Multiple)
|
||||
{
|
||||
<div class="rz-chkbox ">
|
||||
<div class="@(ListBox.isSelected(Item) ? "rz-chkbox-box rz-state-active" : "rz-chkbox-box ")">
|
||||
<span class="@(ListBox.isSelected(Item) ? "rz-chkbox-icon rzi rzi-check" : "rz-chkbox-icon ")"></span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<span>
|
||||
@if (ListBox.Template != null)
|
||||
{
|
||||
@ListBox.Template(Item)
|
||||
}
|
||||
else
|
||||
{
|
||||
@PropertyAccess.GetItemOrValueFromProperty(Item, ListBox.TextProperty)
|
||||
}
|
||||
</span>
|
||||
</li>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public RadzenListBox<TValue> ListBox { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public object Item { get; set; }
|
||||
}
|
||||
@@ -7,14 +7,14 @@
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-3 col-form-label" for="username">@UserText</label>
|
||||
<div class="col">
|
||||
<RadzenTextBox style="display: block" Name="Username" @bind-Value=@Username />
|
||||
<RadzenTextBox AutoComplete=@AutoComplete style="display: block" Name="Username" @bind-Value=@Username />
|
||||
<RadzenRequiredValidator Component="Username" Text=@UserRequired style="position: absolute" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-3 col-form-label" for="password">@PasswordText</label>
|
||||
<div class="col">
|
||||
<RadzenPassword style="display: block" Name="Password" @bind-Value=@Password />
|
||||
<RadzenPassword AutoComplete=@AutoComplete style="display: block" Name="Password" @bind-Value=@Password />
|
||||
<RadzenRequiredValidator Component="Password" Text=@PasswordRequired style="position: absolute" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -37,7 +37,10 @@
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@code {
|
||||
@code {
|
||||
[Parameter]
|
||||
public bool AutoComplete { get; set; } = true;
|
||||
|
||||
protected override string GetComponentCssClass()
|
||||
{
|
||||
return "login";
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
{
|
||||
<input @ref="@Element" disabled="@Disabled" readonly="@ReadOnly" name="@Name" style="@Style" @attributes="Attributes" class="@GetCssClass()" tabindex="@TabIndex"
|
||||
placeholder="@Placeholder" maxlength="@MaxLength" autocomplete="@(AutoComplete ? "on" : "off")" value="@Value" @onchange="@OnChange" id="@GetId()"
|
||||
onkeyup="Radzen.mask('@GetId()', '@Mask', '@Pattern')"/>
|
||||
oninput="Radzen.mask('@GetId()', '@Mask', '@Pattern')"/>
|
||||
}
|
||||
@code {
|
||||
[Parameter]
|
||||
|
||||
@@ -15,7 +15,14 @@
|
||||
{
|
||||
<img class="rz-navigation-item-icon" src="@Image" />
|
||||
}
|
||||
<span class="rz-navigation-item-text">@Text</span>
|
||||
@if(Template != null)
|
||||
{
|
||||
@Template
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="rz-navigation-item-text">@Text</span>
|
||||
}
|
||||
@if (ChildContent != null)
|
||||
{
|
||||
<i class="rzi rz-navigation-item-icon-children">keyboard_arrow_down</i>
|
||||
@@ -33,7 +40,14 @@
|
||||
{
|
||||
<img class="rz-navigation-item-icon" src="@Image" />
|
||||
}
|
||||
<span class="rz-navigation-item-text">@Text</span>
|
||||
@if(Template != null)
|
||||
{
|
||||
@Template
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="rz-navigation-item-text">@Text</span>
|
||||
}
|
||||
@if (ChildContent != null)
|
||||
{
|
||||
<i class="rzi rz-navigation-item-icon-children">keyboard_arrow_down</i>
|
||||
@@ -73,6 +87,9 @@
|
||||
[Parameter]
|
||||
public string Image { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment Template { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
|
||||
@@ -152,10 +152,20 @@
|
||||
await InternalValueChanged(args.Value);
|
||||
}
|
||||
|
||||
private string RemoveNonNumericCharacters(object value)
|
||||
{
|
||||
string valueStr = value as string;
|
||||
if (valueStr == null)
|
||||
{
|
||||
valueStr = value.ToString();
|
||||
}
|
||||
return new string(valueStr.Where(c => char.IsDigit(c) || char.IsPunctuation(c)).ToArray());
|
||||
}
|
||||
|
||||
private async System.Threading.Tasks.Task InternalValueChanged(object value)
|
||||
{
|
||||
TValue newValue;
|
||||
BindConverter.TryConvertTo<TValue>($"{value}", System.Globalization.CultureInfo.CurrentCulture, out newValue);
|
||||
BindConverter.TryConvertTo<TValue>(RemoveNonNumericCharacters(value), System.Globalization.CultureInfo.CurrentCulture, out newValue);
|
||||
|
||||
decimal? newValueAsDecimal = newValue == null ? default(decimal?) : (decimal)ConvertType.ChangeType(newValue, typeof(decimal));
|
||||
|
||||
@@ -191,4 +201,30 @@
|
||||
|
||||
[Parameter]
|
||||
public decimal? Max { get; set; }
|
||||
|
||||
public override async Task SetParametersAsync(ParameterView parameters)
|
||||
{
|
||||
bool minChanged = parameters.DidParameterChange(nameof(Min), Min);
|
||||
bool maxChanged = parameters.DidParameterChange(nameof(Max), Max);
|
||||
|
||||
await base.SetParametersAsync(parameters);
|
||||
|
||||
if (minChanged && Min.HasValue && Value != null && IsJSRuntimeAvailable)
|
||||
{
|
||||
decimal decimalValue = (decimal)Convert.ChangeType(Value, typeof(decimal));
|
||||
if (decimalValue < Min.Value)
|
||||
{
|
||||
await InternalValueChanged(Min.Value);
|
||||
}
|
||||
}
|
||||
|
||||
if (maxChanged && Max.HasValue && Value != null && IsJSRuntimeAvailable)
|
||||
{
|
||||
decimal decimalValue = (decimal)Convert.ChangeType(Value, typeof(decimal));
|
||||
if (decimalValue > Max.Value)
|
||||
{
|
||||
await InternalValueChanged(Max.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,22 @@
|
||||
@inherits RadzenComponent
|
||||
@if (Visible && Count > PageSize)
|
||||
@if (GetVisible())
|
||||
{
|
||||
<div @ref="@Element" @attributes="Attributes" class="@GetCssClass()" style="@Style" id="@GetId()">
|
||||
@if (skip > 0)
|
||||
{
|
||||
<a class="rz-paginator-first rz-paginator-element" href="javascript:void(0)" tabindex="-1" @onclick="@(() => FirstPage())">
|
||||
<a class="rz-paginator-first rz-paginator-element" href="javascript:void(0)" tabindex="-1" @onclick:preventDefault="true" @onclick="@(() => FirstPage())">
|
||||
<span class="rz-paginator-icon rzi rzi-step-backward"></span>
|
||||
</a>
|
||||
<a class="rz-paginator-prev rz-paginator-element" href="javascript:void(0)" tabindex="-1" @onclick="@(() => PrevPage())">
|
||||
<a class="rz-paginator-prev rz-paginator-element" href="javascript:void(0)" tabindex="-1" @onclick:preventDefault="true" @onclick="@(() => PrevPage())">
|
||||
<span class="rz-paginator-icon rzi rzi-caret-left"></span>
|
||||
</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="rz-paginator-first rz-paginator-element rz-state-disabled" href="javascript:void(0)" tabindex="-1" @onclick="@(() => FirstPage())">
|
||||
<a class="rz-paginator-first rz-paginator-element rz-state-disabled" href="javascript:void(0)" tabindex="-1" @onclick:preventDefault="true" @onclick="@(() => FirstPage())">
|
||||
<span class="rz-paginator-icon rzi rzi-step-backward"></span>
|
||||
</a>
|
||||
<a class="rz-paginator-prev rz-paginator-element rz-state-disabled" href="javascript:void(0)" tabindex="-1" @onclick="@(() => PrevPage())">
|
||||
<a class="rz-paginator-prev rz-paginator-element rz-state-disabled" href="javascript:void(0)" tabindex="-1" @onclick:preventDefault="true" @onclick="@(() => PrevPage())">
|
||||
<span class="rz-paginator-icon rzi rzi-caret-left"></span>
|
||||
</a>
|
||||
}
|
||||
@@ -25,32 +25,36 @@
|
||||
{
|
||||
@if (i == CurrentPage)
|
||||
{
|
||||
<a class="rz-paginator-page rz-paginator-element rz-state-active" href="javascript:void(0)" @onclick="@(() => GoToPage(i))">@(i + 1)</a>
|
||||
<a class="rz-paginator-page rz-paginator-element rz-state-active" href="javascript:void(0)" @onclick:preventDefault="true" @onclick="@(() => GoToPage(i))">@(i + 1)</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="rz-paginator-page rz-paginator-element" href="javascript:void(0)" @onclick="@(() => GoToPage(i))">@(i + 1)</a>
|
||||
<a class="rz-paginator-page rz-paginator-element" href="javascript:void(0)" @onclick:preventDefault="true" @onclick="@(() => GoToPage(i))">@(i + 1)</a>
|
||||
}
|
||||
}
|
||||
</span>
|
||||
@if (CurrentPage != numberOfPages - 1)
|
||||
{
|
||||
<a class="rz-paginator-next rz-paginator-element" href="javascript:void(0)" tabindex="0" @onclick="@(() => NextPage())">
|
||||
<a class="rz-paginator-next rz-paginator-element" href="javascript:void(0)" tabindex="0" @onclick:preventDefault="true" @onclick="@(() => NextPage())">
|
||||
<span class="rz-paginator-icon rzi rzi-caret-right"></span>
|
||||
</a>
|
||||
<a class="rz-paginator-last rz-paginator-element" href="javascript:void(0)" tabindex="0" @onclick="@(() => LastPage())">
|
||||
<a class="rz-paginator-last rz-paginator-element" href="javascript:void(0)" tabindex="0" @onclick:preventDefault="true" @onclick="@(() => LastPage())">
|
||||
<span class="rz-paginator-icon rzi rzi-step-forward"></span>
|
||||
</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="rz-paginator-next rz-paginator-element rz-state-disabled" href="javascript:void(0)" tabindex="0" @onclick="@(() => NextPage())">
|
||||
<a class="rz-paginator-next rz-paginator-element rz-state-disabled" href="javascript:void(0)" tabindex="0" @onclick:preventDefault="true" @onclick="@(() => NextPage())">
|
||||
<span class="rz-paginator-icon rzi rzi-caret-right"></span>
|
||||
</a>
|
||||
<a class="rz-paginator-last rz-paginator-element rz-state-disabled" href="javascript:void(0)" tabindex="0" @onclick="@(() => LastPage())">
|
||||
<a class="rz-paginator-last rz-paginator-element rz-state-disabled" href="javascript:void(0)" tabindex="0" @onclick:preventDefault="true" @onclick="@(() => LastPage())">
|
||||
<span class="rz-paginator-icon rzi rzi-step-forward"></span>
|
||||
</a>
|
||||
}
|
||||
@if(PageSizeOptions != null && PageSizeOptions.Any())
|
||||
{
|
||||
<RadzenDropDown TValue="int" Data="@PageSizeOptions" Value="@PageSize" Change="@OnPageSizeChanged" />
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@code {
|
||||
@@ -62,6 +66,12 @@
|
||||
[Parameter]
|
||||
public int PageSize { get; set; } = 10;
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<int> PageSizeChanged { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public IEnumerable<int> PageSizeOptions { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public int PageNumbersCount { get; set; } = 5;
|
||||
|
||||
@@ -74,8 +84,13 @@
|
||||
{
|
||||
return GetPage();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected bool GetVisible()
|
||||
{
|
||||
return Visible && (Count > PageSize || (PageSizeOptions != null && PageSizeOptions.Any()));
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<PagerEventArgs> PageChanged { get; set; }
|
||||
|
||||
@@ -86,7 +101,7 @@
|
||||
|
||||
protected override Task OnParametersSetAsync()
|
||||
{
|
||||
if (Visible)
|
||||
if (GetVisible())
|
||||
{
|
||||
InvokeAsync(Reload);
|
||||
}
|
||||
@@ -94,6 +109,25 @@
|
||||
return base.OnParametersSetAsync();
|
||||
}
|
||||
|
||||
protected async Task OnPageSizeChanged(object value)
|
||||
{
|
||||
bool isFirstPage = CurrentPage == 0;
|
||||
bool isLastPage = CurrentPage == numberOfPages - 1;
|
||||
int prevSkip = skip;
|
||||
PageSize = (int)value;
|
||||
await InvokeAsync(Reload);
|
||||
await PageSizeChanged.InvokeAsync((int)value);
|
||||
if (isLastPage)
|
||||
{
|
||||
await LastPage();
|
||||
}
|
||||
else if (!isFirstPage)
|
||||
{
|
||||
int newPage = (int)Math.Floor((decimal)(prevSkip / (PageSize > 0 ? PageSize : 10)));
|
||||
await GoToPage(newPage, true);
|
||||
}
|
||||
}
|
||||
|
||||
protected int skip;
|
||||
protected int numberOfPageLinks = 5;
|
||||
protected int startPage;
|
||||
@@ -129,9 +163,9 @@
|
||||
return (int)Math.Floor((decimal)(skip / (PageSize > 0 ? PageSize : 10)));
|
||||
}
|
||||
|
||||
public async Task GoToPage(int page)
|
||||
public async Task GoToPage(int page, bool forceReload = false)
|
||||
{
|
||||
if (CurrentPage != page)
|
||||
if (CurrentPage != page || forceReload)
|
||||
{
|
||||
skip = page * PageSize;
|
||||
await InvokeAsync(Reload);
|
||||
@@ -139,7 +173,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
internal async void SetCurrentPage(int page)
|
||||
internal void SetCurrentPage(int page)
|
||||
{
|
||||
if (CurrentPage != page)
|
||||
{
|
||||
@@ -147,6 +181,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetCount(int count)
|
||||
{
|
||||
Count = count;
|
||||
CalculatePager();
|
||||
}
|
||||
|
||||
public async Task FirstPage(bool forceReload = false)
|
||||
{
|
||||
if (CurrentPage != 0 || forceReload)
|
||||
|
||||
@@ -38,6 +38,14 @@
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@if (SummaryTemplate != null)
|
||||
{
|
||||
<div class="rz-panel-content-wrapper" role="region" aria-hidden="false" style="@summaryContentStyle">
|
||||
<div class="rz-panel-content rz-panel-content-summary">
|
||||
@SummaryTemplate
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@code {
|
||||
@@ -63,6 +71,9 @@
|
||||
[Parameter]
|
||||
public RenderFragment HeaderTemplate { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment SummaryTemplate { get; set; } = null;
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment FooterTemplate { get; set; }
|
||||
|
||||
@@ -73,11 +84,13 @@
|
||||
public EventCallback Collapse { get; set; }
|
||||
|
||||
string contentStyle = "display: block;";
|
||||
string summaryContentStyle = "display: none";
|
||||
|
||||
async System.Threading.Tasks.Task Toggle(MouseEventArgs args)
|
||||
{
|
||||
collapsed = !collapsed;
|
||||
contentStyle = collapsed ? "display: none;" : "display: block;";
|
||||
summaryContentStyle = !collapsed ? "display: none" : "display: block";
|
||||
|
||||
if (collapsed)
|
||||
{
|
||||
@@ -109,6 +122,7 @@
|
||||
protected override Task OnParametersSetAsync()
|
||||
{
|
||||
contentStyle = collapsed ? "display: none;" : "display: block;";
|
||||
summaryContentStyle = !collapsed ? "display: none" : "display: block";
|
||||
|
||||
return base.OnParametersSetAsync();
|
||||
}
|
||||
|
||||
@@ -15,7 +15,14 @@
|
||||
{
|
||||
<img class="rz-navigation-item-icon" src="@Image" />
|
||||
}
|
||||
<span class="rz-navigation-item-text" @onclick="@Toggle">@Text</span>
|
||||
@if(Template != null)
|
||||
{
|
||||
@Template
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="rz-navigation-item-text" @onclick="@Toggle">@Text</span>
|
||||
}
|
||||
@if (items.Any())
|
||||
{
|
||||
<i class="rzi rz-navigation-item-icon-children" style="@getStyle()" @onclick="@Toggle">keyboard_arrow_down</i>
|
||||
@@ -33,7 +40,14 @@
|
||||
{
|
||||
<img class="rz-navigation-item-icon" src="@Image" />
|
||||
}
|
||||
<span class="rz-navigation-item-text">@Text</span>
|
||||
@if(Template != null)
|
||||
{
|
||||
@Template
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="rz-navigation-item-text">@Text</span>
|
||||
}
|
||||
@if (items.Any())
|
||||
{
|
||||
<i class="rzi rz-navigation-item-icon-children" style="@getStyle()">keyboard_arrow_down</i>
|
||||
@@ -78,6 +92,9 @@
|
||||
[Parameter]
|
||||
public string Image { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment Template { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool Expanded { get; set; } = false;
|
||||
|
||||
|
||||
@@ -3,73 +3,73 @@
|
||||
@inherits FormComponent<int>
|
||||
@if (Visible)
|
||||
{
|
||||
@if (Disabled)
|
||||
{
|
||||
<div @ref="@Element" @attributes="Attributes" class="@GetCssClass()" id="@GetId()">
|
||||
<a href="javascript:void(0)" class="rz-rating-cancel">
|
||||
<span class="rz-rating-icon rzi rzi-ban"></span>
|
||||
</a>
|
||||
@foreach (var index in Enumerable.Range(1, Stars))
|
||||
{
|
||||
@if (index <= Value)
|
||||
{
|
||||
<a href="javascript:void(0)">
|
||||
<span class="rz-rating-icon rzi rzi-star"></span>
|
||||
</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a href="javascript:void(0)">
|
||||
<span class="rz-rating-icon rzi rzi-star-o"></span>
|
||||
</a>
|
||||
}
|
||||
|
||||
}
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div @ref="@Element" @attributes="Attributes" class="@GetCssClass()" id="@GetId()">
|
||||
<div @ref="@Element" @attributes="Attributes" class="@GetCssClass()" id="@GetId()">
|
||||
@if (!ReadOnly)
|
||||
{
|
||||
<a href="javascript:void(0)" class="rz-rating-cancel" tabindex="@TabIndex" @onclick="@(args => SetValue(0))" @onkeypress="@(async args => { if (args.Code == "Space") { await SetValue(0); } })">
|
||||
<span class="rz-rating-icon rzi rzi-ban"></span>
|
||||
</a>
|
||||
@foreach (var index in Enumerable.Range(1, Stars))
|
||||
}
|
||||
@foreach (var index in Enumerable.Range(1, Stars))
|
||||
{
|
||||
|
||||
@if (index <= Value)
|
||||
{
|
||||
|
||||
@if (index <= Value)
|
||||
{
|
||||
<a href="javascript:void(0)" tabindex="@TabIndex" @onclick="@(args => SetValue(index))" @onkeypress="@(async args => { if (args.Code == "Space") { await SetValue(index); } })">
|
||||
<span class="rz-rating-icon rzi rzi-star"></span>
|
||||
</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a href="javascript:void(0)" tabindex="@TabIndex" @onclick="@(args => SetValue(index))" @onkeypress="@(async args => { if (args.Code == "Space") { await SetValue(index); } })">
|
||||
<span class="rz-rating-icon rzi rzi-star-o"></span>
|
||||
</a>
|
||||
}
|
||||
|
||||
<a href="javascript:void(0)" tabindex="@TabIndex" @onclick="@(args => SetValue(index))" @onkeypress="@(async args => { if (args.Code == "Space") { await SetValue(index); } })">
|
||||
<span class="rz-rating-icon rzi rzi-star"></span>
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a href="javascript:void(0)" tabindex="@TabIndex" @onclick="@(args => SetValue(index))" @onkeypress="@(async args => { if (args.Code == "Space") { await SetValue(index); } })">
|
||||
<span class="rz-rating-icon rzi rzi-star-o"></span>
|
||||
</a>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@code {
|
||||
protected override string GetComponentCssClass()
|
||||
{
|
||||
var fieldCssClass = FieldIdentifier.FieldName != null ? EditContext?.FieldCssClass(FieldIdentifier) : "";
|
||||
|
||||
return $"rz-rating {(Disabled ? "rz-state-disabled" : "")} {fieldCssClass}";
|
||||
var classList = new List<string>();
|
||||
|
||||
classList.Add("rz-rating");
|
||||
|
||||
if (Disabled)
|
||||
{
|
||||
classList.Add("rz-state-disabled");
|
||||
}
|
||||
|
||||
if (ReadOnly)
|
||||
{
|
||||
classList.Add("rz-state-readonly");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(fieldCssClass))
|
||||
{
|
||||
classList.Add(fieldCssClass);
|
||||
}
|
||||
|
||||
return string.Join(" ", classList);
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public int Stars { get; set; } = 5;
|
||||
|
||||
[Parameter]
|
||||
public bool ReadOnly { get; set; }
|
||||
|
||||
private async System.Threading.Tasks.Task SetValue(int value)
|
||||
{
|
||||
Value = value;
|
||||
if (!Disabled && !ReadOnly)
|
||||
{
|
||||
Value = value;
|
||||
|
||||
await ValueChanged.InvokeAsync(value);
|
||||
if (FieldIdentifier.FieldName != null) { EditContext?.NotifyFieldChanged(FieldIdentifier); }
|
||||
await Change.InvokeAsync(value);
|
||||
await ValueChanged.InvokeAsync(value);
|
||||
if (FieldIdentifier.FieldName != null) { EditContext?.NotifyFieldChanged(FieldIdentifier); }
|
||||
await Change.InvokeAsync(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,6 +307,8 @@
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
await base.OnAfterRenderAsync(firstRender);
|
||||
|
||||
if (firstRender)
|
||||
{
|
||||
var rect = await JSRuntime.InvokeAsync<Rect>("Radzen.createScheduler", Element, Reference);
|
||||
@@ -339,7 +341,11 @@
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyScheduler", Element);
|
||||
|
||||
if (IsJSRuntimeAvailable)
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyScheduler", Element);
|
||||
}
|
||||
}
|
||||
|
||||
private bool heightIsSet = false;
|
||||
|
||||
@@ -99,7 +99,11 @@
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroySlider", UniqueID, Element);
|
||||
|
||||
if (IsJSRuntimeAvailable)
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroySlider", UniqueID, Element);
|
||||
}
|
||||
}
|
||||
|
||||
[JSInvokable("RadzenSlider.OnValueChange")]
|
||||
|
||||
218
Radzen.Blazor/RadzenSplitter.razor
Normal file
218
Radzen.Blazor/RadzenSplitter.razor
Normal file
@@ -0,0 +1,218 @@
|
||||
@using Microsoft.JSInterop
|
||||
@using System.Globalization
|
||||
@inherits RadzenComponent
|
||||
|
||||
@if (Visible)
|
||||
{
|
||||
<div @ref="@Element" @attributes="Attributes" class="@GetCssClass()" id="@GetId()" style="@Style">
|
||||
<CascadingValue Value=this>
|
||||
@ChildContent
|
||||
</CascadingValue>
|
||||
</div>
|
||||
}
|
||||
|
||||
@code {
|
||||
private int _sizeautopanes = 0;
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public Orientation Orientation { get; set; } = Orientation.Horizontal;
|
||||
|
||||
internal List<RadzenSplitterPane> Panes = new List<RadzenSplitterPane>();
|
||||
|
||||
public void AddPane(RadzenSplitterPane pane)
|
||||
{
|
||||
if (Panes.IndexOf(pane) != -1 || !pane.Visible)
|
||||
return;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(pane.Size))
|
||||
{
|
||||
//no size defined
|
||||
pane.SizeAuto = true;
|
||||
_sizeautopanes++;
|
||||
}
|
||||
|
||||
pane.Index = Panes.Count;
|
||||
Panes.Add(pane);
|
||||
|
||||
foreach (var iPane in Panes)
|
||||
{
|
||||
if (!iPane.SizeAuto)
|
||||
continue;
|
||||
|
||||
iPane.SizeRuntine = (100 / _sizeautopanes) + "%";
|
||||
}
|
||||
}
|
||||
|
||||
public void RemovePane(RadzenSplitterPane pane)
|
||||
{
|
||||
if (Panes.Contains(pane))
|
||||
{
|
||||
Panes.Remove(pane);
|
||||
try
|
||||
{
|
||||
InvokeAsync(StateHasChanged);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
try
|
||||
{
|
||||
InvokeAsync(StateHasChanged);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
internal Task ResizeExec(MouseEventArgs args, int paneIndex)
|
||||
{
|
||||
var pane = Panes[paneIndex];
|
||||
if (!pane.Resizable)
|
||||
return Task.CompletedTask;
|
||||
|
||||
var paneNextResizable = Panes.Skip(paneIndex + 1).FirstOrDefault(o => o.Resizable && !o.Collapsed);
|
||||
|
||||
|
||||
return JSRuntime.InvokeVoidAsync("Radzen.startSplitterResize",
|
||||
UniqueID,
|
||||
Reference,
|
||||
pane.UniqueID,
|
||||
paneNextResizable?.UniqueID,
|
||||
Orientation.ToString(), Orientation == Orientation.Horizontal ? args.ClientX : args.ClientY,
|
||||
pane.Min,
|
||||
pane.Max,
|
||||
paneNextResizable?.Min,
|
||||
paneNextResizable?.Max).AsTask();
|
||||
}
|
||||
|
||||
[JSInvokable("RadzenSplitter.OnPaneResized")]
|
||||
public async Task OnPaneResized(int paneIndex, double sizeNew, int? paneNextIndex, double? sizeNextNew)
|
||||
{
|
||||
var pane = Panes[paneIndex];
|
||||
|
||||
if (Resize.HasDelegate)
|
||||
{
|
||||
var arg = new RadzenSplitterResizeEventArgs {PaneIndex = pane.Index, Pane = pane, NewSize = sizeNew};
|
||||
await Resize.InvokeAsync(arg);
|
||||
if (arg.Cancel)
|
||||
{
|
||||
var oldSize = pane.SizeRuntine;
|
||||
pane.SizeRuntine = "0";
|
||||
await InvokeAsync(StateHasChanged);
|
||||
pane.SizeRuntine = oldSize;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pane.SizeRuntine = sizeNew.ToString("0.##", CultureInfo.InvariantCulture) + "%";
|
||||
|
||||
if (paneNextIndex.HasValue)
|
||||
{
|
||||
var paneNext = Panes[paneNextIndex.Value];
|
||||
|
||||
if (Expand.HasDelegate)
|
||||
{
|
||||
var arg = new RadzenSplitterResizeEventArgs {PaneIndex = paneNext.Index, Pane = paneNext, NewSize = sizeNextNew.Value};
|
||||
await Resize.InvokeAsync(arg);
|
||||
//cancel omitted because it is managed by the parent panel
|
||||
}
|
||||
|
||||
paneNext.SizeRuntine = sizeNextNew.Value.ToString("0.##", CultureInfo.InvariantCulture) + "%";
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task CollapseExec(object args, int paneIndex, string paneId)
|
||||
{
|
||||
var pane = Panes[paneIndex];
|
||||
var paneNext = pane.Next();
|
||||
|
||||
if (paneNext != null && paneNext.Collapsible && paneNext.IsLast && paneNext.Collapsed)
|
||||
{
|
||||
if (Expand.HasDelegate)
|
||||
{
|
||||
var arg = new RadzenSplitterEventArgs {PaneIndex = paneNext.Index, Pane = paneNext};
|
||||
await Expand.InvokeAsync(arg);
|
||||
if (arg.Cancel)
|
||||
return;
|
||||
}
|
||||
|
||||
paneNext.Collapsed = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Collapse.HasDelegate)
|
||||
{
|
||||
var arg = new RadzenSplitterEventArgs {PaneIndex = pane.Index, Pane = pane};
|
||||
await Collapse.InvokeAsync(arg);
|
||||
if (arg.Cancel)
|
||||
return;
|
||||
}
|
||||
|
||||
pane.Collapsed = true;
|
||||
}
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
internal async Task ExpandExec(MouseEventArgs args, int paneIndex, string paneId)
|
||||
{
|
||||
var pane = Panes[paneIndex];
|
||||
var paneNext = pane.Next();
|
||||
|
||||
if (paneNext != null && paneNext.Collapsible && paneNext.IsLast && !pane.Collapsed)
|
||||
{
|
||||
if (Collapse.HasDelegate)
|
||||
{
|
||||
var arg = new RadzenSplitterEventArgs {PaneIndex = paneNext.Index, Pane = paneNext};
|
||||
await Collapse.InvokeAsync(arg);
|
||||
if (arg.Cancel)
|
||||
return;
|
||||
}
|
||||
|
||||
paneNext.Collapsed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Expand.HasDelegate)
|
||||
{
|
||||
var arg = new RadzenSplitterEventArgs {PaneIndex = pane.Index, Pane = pane};
|
||||
await Expand.InvokeAsync(arg);
|
||||
if (arg.Cancel)
|
||||
return;
|
||||
}
|
||||
|
||||
pane.Collapsed = false;
|
||||
}
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
|
||||
protected override string GetComponentCssClass()
|
||||
{
|
||||
return $"rz-splitter rz-splitter-{Enum.GetName(typeof(Orientation), Orientation).ToLower()}";
|
||||
}
|
||||
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<RadzenSplitterEventArgs> Collapse { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<RadzenSplitterEventArgs> Expand { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<RadzenSplitterResizeEventArgs> Resize { get; set; }
|
||||
|
||||
|
||||
|
||||
}
|
||||
188
Radzen.Blazor/RadzenSplitterPane.razor
Normal file
188
Radzen.Blazor/RadzenSplitterPane.razor
Normal file
@@ -0,0 +1,188 @@
|
||||
@using System.Diagnostics
|
||||
@inherits RadzenComponent
|
||||
|
||||
|
||||
@if (Visible)
|
||||
{
|
||||
<div id="@GetId()" class="@GetComponentCssClass()" style="flex-basis: @Size;" data-index="@Index">
|
||||
@ChildContent
|
||||
</div>
|
||||
|
||||
|
||||
@if (!IsLast)
|
||||
{
|
||||
<div class="@GetComponentBarCssClass()"
|
||||
@onclick:preventDefault="true"
|
||||
@onclick:stopPropagation="true"
|
||||
@onmousedown=@(args => Splitter.ResizeExec(args, Index))>
|
||||
|
||||
@if (IsCollapsible)
|
||||
{
|
||||
<span class="rz-collapse" @onmousedown:preventDefault="true" @onmousedown:stopPropagation="true" @onmousedown=@(args => Splitter.CollapseExec(args, Index, UniqueID))>
|
||||
</span>
|
||||
}
|
||||
|
||||
@if (IsResizable)
|
||||
{
|
||||
<span class="rz-resize">
|
||||
</span>
|
||||
}
|
||||
|
||||
@if (IsExpandable)
|
||||
{
|
||||
<span class="rz-expand" @onmousedown:preventDefault="true" @onmousedown:stopPropagation="true" @onmousedown=@(args => Splitter.ExpandExec(args, Index, UniqueID))>
|
||||
</span>
|
||||
}
|
||||
|
||||
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@code {
|
||||
RadzenSplitter _splitter;
|
||||
private string _size;
|
||||
|
||||
internal string SizeRuntine { get; set; }
|
||||
|
||||
internal bool SizeAuto { get; set; }
|
||||
|
||||
internal int Index { get; set; }
|
||||
|
||||
internal bool IsLastResizable
|
||||
{
|
||||
get { return Splitter.Panes.Last(o => o.Resizable && !o.Collapsed) == this; }
|
||||
}
|
||||
|
||||
internal bool IsLast => Splitter.Panes.Count - 1 == Index;
|
||||
|
||||
internal RadzenSplitterPane Next()
|
||||
{
|
||||
return Index <= Splitter.Panes.Count - 2
|
||||
? Splitter.Panes[Index + 1]
|
||||
: null;
|
||||
}
|
||||
|
||||
internal bool IsResizable
|
||||
{
|
||||
get
|
||||
{
|
||||
var paneNext = Next();
|
||||
|
||||
if (Collapsed
|
||||
|| (Index == Splitter.Panes.Count - 2 && !paneNext.IsResizable)
|
||||
|| (IsLastResizable && paneNext != null && paneNext.Collapsed)
|
||||
)
|
||||
return false;
|
||||
|
||||
|
||||
return Resizable;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsCollapsible
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Collapsible && !Collapsed)
|
||||
return true;
|
||||
|
||||
var paneNext = Next();
|
||||
if (paneNext == null)
|
||||
return false;
|
||||
|
||||
return paneNext.IsLast && paneNext.Collapsible && paneNext.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsExpandable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Collapsed)
|
||||
return true;
|
||||
|
||||
var paneNext = Next();
|
||||
if (paneNext == null)
|
||||
return false;
|
||||
|
||||
return paneNext.IsLast && paneNext.Collapsible && !paneNext.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
internal string ClassName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Collapsed)
|
||||
return "collapsed";
|
||||
|
||||
if (IsLastResizable)
|
||||
return "lastresizable";
|
||||
|
||||
if (IsResizable)
|
||||
return "resizable";
|
||||
|
||||
return "locked";
|
||||
}
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool Collapsible { get; set; } = true;
|
||||
|
||||
[Parameter]
|
||||
public bool Collapsed { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool Resizable { get; set; } = true;
|
||||
|
||||
[Parameter]
|
||||
public string Max { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Min { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Size
|
||||
{
|
||||
get => SizeRuntine ?? _size;
|
||||
set => _size = value;
|
||||
}
|
||||
|
||||
[CascadingParameter]
|
||||
public RadzenSplitter Splitter
|
||||
{
|
||||
get => _splitter;
|
||||
set
|
||||
{
|
||||
if (_splitter != value)
|
||||
{
|
||||
_splitter = value;
|
||||
_splitter.AddPane(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
Splitter?.RemovePane(this);
|
||||
}
|
||||
|
||||
protected override string GetComponentCssClass()
|
||||
{
|
||||
return $"rz-splitter-pane rz-splitter-pane-{ClassName}";
|
||||
}
|
||||
|
||||
protected string GetComponentBarCssClass()
|
||||
{
|
||||
return $"rz-splitter-bar rz-splitter-bar-{ClassName}";
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
@inherits FormComponent<bool>
|
||||
@if (Visible)
|
||||
{
|
||||
<div @ref="@Element" @attributes="Attributes" class="@GetCssClass()"
|
||||
<div @ref="@Element" @attributes="Attributes" class="@GetCssClass()" id="@GetId()"
|
||||
@onmouseup="@OnMouseUp" @onkeypress="@(async (args) => { if (args.Code == "Space") { await Toggle(); } })" style="outline: 0 none;@Style" tabindex="@TabIndex">
|
||||
<div class="rz-helper-hidden-accessible">
|
||||
<input type="checkbox" name="@Name" value="@Value" tabindex="-1">
|
||||
|
||||
@@ -9,11 +9,23 @@
|
||||
@Tabs
|
||||
</ul>
|
||||
<div class="rz-tabview-panels">
|
||||
@if (SelectedTab?.Visible == true)
|
||||
@if(RenderMode == TabRenderMode.Client)
|
||||
{
|
||||
<div class="rz-tabview-panel" role="tabpanel" id="@($"{Id}-tabpanel-{selectedIndex}")" aria-hidden="false" aria-labelledby="@($"{Id}-tabpanel-{selectedIndex}-label")">
|
||||
@SelectedTab.ChildContent
|
||||
</div>
|
||||
for (var i = 0; i < tabs.Count; i++)
|
||||
{
|
||||
<div class="rz-tabview-panel" role="tabpanel" id="@($"{Id}-tabpanel-{i}")" style="@(tabs[i] == SelectedTab ? "" : "display:none")" aria-hidden="@(tabs[i] == SelectedTab ? "false" : "true")" aria-labelledby="@($"{Id}-tabpanel-{i}-label")">
|
||||
@tabs[i].ChildContent
|
||||
</div>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (SelectedTab?.Visible == true)
|
||||
{
|
||||
<div class="rz-tabview-panel" role="tabpanel" id="@($"{Id}-tabpanel-{selectedIndex}")" aria-hidden="false" aria-labelledby="@($"{Id}-tabpanel-{selectedIndex}-label")">
|
||||
@SelectedTab.ChildContent
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -21,6 +33,9 @@
|
||||
</CascadingValue>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public TabRenderMode RenderMode { get; set; } = TabRenderMode.Server;
|
||||
|
||||
[Parameter]
|
||||
public int SelectedIndex { get; set; } = -1;
|
||||
|
||||
|
||||
@@ -40,13 +40,14 @@
|
||||
await InvokeAsync(() => { StateHasChanged(); });
|
||||
}
|
||||
|
||||
bool firstRender = true;
|
||||
bool IsJSRuntimeAvailable { get; set; }
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
this.firstRender = firstRender;
|
||||
IsJSRuntimeAvailable = true;
|
||||
|
||||
var tooltip = tooltips.LastOrDefault();
|
||||
|
||||
if (tooltip != null)
|
||||
{
|
||||
await JSRuntime.InvokeVoidAsync("Radzen.openTooltip",
|
||||
@@ -71,7 +72,7 @@
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!firstRender)
|
||||
if (IsJSRuntimeAvailable)
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", UniqueID);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,52 @@
|
||||
[Parameter]
|
||||
public EventCallback<object> ValueChanged { get; set; }
|
||||
|
||||
void RenderTreeItem(RenderTreeBuilder builder, object data, RenderFragment<RadzenTreeItem> template, Func<object,
|
||||
[Parameter]
|
||||
public bool AllowCheckBoxes { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool AllowCheckChildren { get; set; } = true;
|
||||
|
||||
[Parameter]
|
||||
public bool AllowCheckParents { get; set; } = true;
|
||||
|
||||
[Parameter]
|
||||
public IEnumerable<object> CheckedValues { get; set; } = Enumerable.Empty<object>();
|
||||
|
||||
internal List<RadzenTreeItem> items = new List<RadzenTreeItem>();
|
||||
|
||||
internal void AddItem(RadzenTreeItem item)
|
||||
{
|
||||
if (items.IndexOf(item) == -1)
|
||||
{
|
||||
items.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
internal void RemoveItem(RadzenTreeItem item)
|
||||
{
|
||||
if (items.IndexOf(item) != -1)
|
||||
{
|
||||
items.Remove(item);
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task SetCheckedValues(IEnumerable<object> values)
|
||||
{
|
||||
CheckedValues = values.ToList();
|
||||
await CheckedValuesChanged.InvokeAsync(CheckedValues);
|
||||
}
|
||||
|
||||
internal IEnumerable<object> UncheckedValues { get; set; } = Enumerable.Empty<object>();
|
||||
internal void SetUncheckedValues(IEnumerable<object> values)
|
||||
{
|
||||
UncheckedValues = values.ToList();
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<IEnumerable<object>> CheckedValuesChanged { get; set; }
|
||||
|
||||
void RenderTreeItem(RadzenTreeItem parent, RenderTreeBuilder builder, object data, RenderFragment<RadzenTreeItem> template, Func<object,
|
||||
string> text,
|
||||
Func<object, bool> hasChildren, Func<object, bool> expanded, Func<object, bool> selected)
|
||||
{
|
||||
@@ -59,6 +104,12 @@
|
||||
builder.AddAttribute(4, nameof(RadzenTreeItem.Template), template);
|
||||
builder.AddAttribute(5, nameof(RadzenTreeItem.Expanded), expanded(data));
|
||||
builder.AddAttribute(6, nameof(RadzenTreeItem.Selected), Value == data || selected(data));
|
||||
|
||||
if (parent != null)
|
||||
{
|
||||
builder.AddAttribute(7, nameof(RadzenTreeItem.ParentItem), parent);
|
||||
}
|
||||
|
||||
builder.SetKey(data);
|
||||
}
|
||||
|
||||
@@ -77,7 +128,7 @@
|
||||
text = level.Text ?? Getter<string>(data, level.TextProperty);
|
||||
}
|
||||
|
||||
RenderTreeItem(builder, data, level.Template, text, level.HasChildren, level.Expanded, level.Selected);
|
||||
RenderTreeItem(null, builder, data, level.Template, text, level.HasChildren, level.Expanded, level.Selected);
|
||||
|
||||
var hasChildren = level.HasChildren(data);
|
||||
|
||||
@@ -144,12 +195,24 @@
|
||||
text = children.Text ?? Getter<string>(data, children.TextProperty);
|
||||
}
|
||||
|
||||
RenderTreeItem(builder, data, children.Template, text, children.HasChildren, children.Expanded, children.Selected);
|
||||
RenderTreeItem(item, builder, data, children.Template, text, children.HasChildren, children.Expanded, children.Selected);
|
||||
builder.CloseComponent();
|
||||
}
|
||||
});
|
||||
|
||||
item.RenderChildContent(childContent);
|
||||
|
||||
if(AllowCheckBoxes && AllowCheckChildren && args.Children.Data != null)
|
||||
{
|
||||
if (CheckedValues != null && CheckedValues.Contains(item.Value))
|
||||
{
|
||||
await SetCheckedValues(CheckedValues.Union(args.Children.Data.Cast<object>().Except(UncheckedValues)));
|
||||
}
|
||||
else
|
||||
{
|
||||
await SetCheckedValues(CheckedValues.Except(args.Children.Data.Cast<object>()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
@using Radzen
|
||||
|
||||
@implements IDisposable
|
||||
<li class="rz-treenode">
|
||||
<div class="@($"rz-treenode-content {(selected ? "rz-treenode-content-selected" : "")}")" @onclick="@Select">
|
||||
@if (ChildContent != null || HasChildren)
|
||||
{
|
||||
<span class="@($"rz-tree-toggler rzi {(expanded ? "rzi-caret-down" : "rzi-caret-right")}")" @onclick="@Toggle" @onclick:stopPropagation></span>
|
||||
}
|
||||
@if(Tree != null && Tree.AllowCheckBoxes)
|
||||
{
|
||||
<RadzenCheckBox TValue="bool?" Value="@IsChecked()" Change="@CheckedChange" Style="@(ParentItem != null && !HasChildren ? "margin-left:25px;margin-right:5px;" : "margin-right:5px;")" />
|
||||
}
|
||||
@if (Template != null)
|
||||
{
|
||||
@Template(this)
|
||||
@@ -51,6 +55,59 @@
|
||||
[CascadingParameter]
|
||||
public RadzenTree Tree { get; set; }
|
||||
|
||||
RadzenTreeItem _parentItem;
|
||||
|
||||
[Parameter]
|
||||
public RadzenTreeItem ParentItem
|
||||
{
|
||||
get
|
||||
{
|
||||
return _parentItem;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_parentItem != value)
|
||||
{
|
||||
_parentItem = value;
|
||||
|
||||
if (_parentItem != null)
|
||||
{
|
||||
_parentItem.AddItem(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal List<RadzenTreeItem> items = new List<RadzenTreeItem>();
|
||||
|
||||
internal void AddItem(RadzenTreeItem item)
|
||||
{
|
||||
if (items.IndexOf(item) == -1)
|
||||
{
|
||||
items.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
internal void RemoveItem(RadzenTreeItem item)
|
||||
{
|
||||
if (items.IndexOf(item) != -1)
|
||||
{
|
||||
items.Remove(item);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (ParentItem != null)
|
||||
{
|
||||
ParentItem.RemoveItem(this);
|
||||
}
|
||||
else if(Tree != null)
|
||||
{
|
||||
Tree.RemoveItem(this);
|
||||
}
|
||||
}
|
||||
|
||||
async Task Toggle()
|
||||
{
|
||||
expanded = !expanded;
|
||||
@@ -93,6 +150,11 @@
|
||||
{
|
||||
Tree?.SelectItem(this);
|
||||
}
|
||||
|
||||
if (Tree != null && ParentItem == null)
|
||||
{
|
||||
Tree.AddItem(this);
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task SetParametersAsync(ParameterView parameters)
|
||||
@@ -130,4 +192,123 @@
|
||||
|
||||
await base.SetParametersAsync(parameters);
|
||||
}
|
||||
|
||||
async Task CheckedChange(bool? value)
|
||||
{
|
||||
if (Tree != null)
|
||||
{
|
||||
var checkedValues = GetCheckedValues();
|
||||
|
||||
if (Tree.AllowCheckChildren)
|
||||
{
|
||||
if (value == true)
|
||||
{
|
||||
var valueAndChildren = GetValueAndAllChildValues();
|
||||
checkedValues = checkedValues.Union(valueAndChildren);
|
||||
Tree.SetUncheckedValues(Tree.UncheckedValues.Except(valueAndChildren));
|
||||
}
|
||||
else
|
||||
{
|
||||
var valueAndChildren = GetValueAndAllChildValues();
|
||||
checkedValues = checkedValues.Except(valueAndChildren);
|
||||
Tree.SetUncheckedValues(valueAndChildren.Union(Tree.UncheckedValues));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value == true)
|
||||
{
|
||||
var valueWithoutChildren = new[] { Value };
|
||||
checkedValues = checkedValues.Union(valueWithoutChildren);
|
||||
Tree.SetUncheckedValues(Tree.UncheckedValues.Except(valueWithoutChildren));
|
||||
}
|
||||
else
|
||||
{
|
||||
var valueWithoutChildren = new[] { Value };
|
||||
checkedValues = checkedValues.Except(valueWithoutChildren);
|
||||
Tree.SetUncheckedValues(valueWithoutChildren.Union(Tree.UncheckedValues));
|
||||
}
|
||||
}
|
||||
|
||||
if (Tree.AllowCheckParents)
|
||||
{
|
||||
checkedValues = UpdateCheckedValuesWithParents(checkedValues, value);
|
||||
}
|
||||
|
||||
await Tree.SetCheckedValues(checkedValues);
|
||||
}
|
||||
}
|
||||
|
||||
bool? IsChecked()
|
||||
{
|
||||
var checkedValues = GetCheckedValues();
|
||||
|
||||
if(HasChildren && IsOneChildUnchecked() && IsOneChildChecked())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return checkedValues.Contains(Value);
|
||||
}
|
||||
|
||||
IEnumerable<object> GetCheckedValues()
|
||||
{
|
||||
return Tree.CheckedValues != null ? Tree.CheckedValues : Enumerable.Empty<object>();
|
||||
}
|
||||
|
||||
IEnumerable<object> GetAllChildValues(Func<object, bool> predicate = null)
|
||||
{
|
||||
var children = items.Concat(items.SelectManyRecursive(i => i.items)).Select(i => i.Value);
|
||||
|
||||
return predicate != null ? children.Where(predicate) : children;
|
||||
}
|
||||
|
||||
IEnumerable<object> GetValueAndAllChildValues()
|
||||
{
|
||||
return new object[] { Value }.Concat(GetAllChildValues());
|
||||
}
|
||||
|
||||
bool AreAllChildrenChecked(Func<object, bool> predicate = null)
|
||||
{
|
||||
var checkedValues = GetCheckedValues();
|
||||
return GetAllChildValues(predicate).All(i => checkedValues.Contains(i));
|
||||
}
|
||||
|
||||
bool AreAllChildrenUnchecked(Func<object, bool> predicate = null)
|
||||
{
|
||||
var checkedValues = GetCheckedValues();
|
||||
return GetAllChildValues(predicate).All(i => !checkedValues.Contains(i));
|
||||
}
|
||||
|
||||
bool IsOneChildUnchecked()
|
||||
{
|
||||
var checkedValues = GetCheckedValues();
|
||||
return GetAllChildValues().Any(i => !checkedValues.Contains(i));
|
||||
}
|
||||
|
||||
bool IsOneChildChecked()
|
||||
{
|
||||
var checkedValues = GetCheckedValues();
|
||||
return GetAllChildValues().Any(i => checkedValues.Contains(i));
|
||||
}
|
||||
|
||||
IEnumerable<object> UpdateCheckedValuesWithParents(IEnumerable<object> checkedValues, bool? value)
|
||||
{
|
||||
var p = ParentItem;
|
||||
while (p != null)
|
||||
{
|
||||
if (value == false && p.AreAllChildrenUnchecked(i => !object.Equals(i, Value)))
|
||||
{
|
||||
checkedValues = checkedValues.Except(new object[] { p.Value });
|
||||
}
|
||||
else if (value == true && p.AreAllChildrenChecked(i => !object.Equals(i, Value)))
|
||||
{
|
||||
checkedValues = checkedValues.Union(new object[] { p.Value });
|
||||
}
|
||||
|
||||
p = p.ParentItem;
|
||||
}
|
||||
|
||||
return checkedValues;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
<div class="rz-events">
|
||||
@{
|
||||
var eventGroups = AppointmentGroups();
|
||||
var lefts = new Dictionary<AppointmentData, double>();
|
||||
}
|
||||
@for (var date = StartDate; date < EndDate; date = date.AddMinutes(30))
|
||||
{
|
||||
@@ -11,11 +12,19 @@
|
||||
var end = start.AddMinutes(30);
|
||||
|
||||
var appointments = AppointmentsInSlot(start, end);
|
||||
var existingLefts = ExistingLefts(lefts, appointments);
|
||||
|
||||
@foreach (var item in appointments)
|
||||
{
|
||||
var width = 90.0 / appointments.Max(data => eventGroups[Appointments.IndexOf(data)]);
|
||||
var left = Array.IndexOf(appointments, item) * width;
|
||||
|
||||
if (!lefts.TryGetValue(item, out var left))
|
||||
{
|
||||
left = DetermineLeft(existingLefts, width);
|
||||
lefts.Add(item, left);
|
||||
existingLefts.Add(left);
|
||||
}
|
||||
|
||||
var eventStart = item.Start < StartDate ? StartDate : item.Start;
|
||||
var eventEnd = item.End > EndDate ? EndDate : item.End;
|
||||
var length = eventStart.Subtract(StartDate).TotalMinutes / 30;
|
||||
@@ -62,6 +71,32 @@
|
||||
return Appointments.Where(item => Scheduler.IsAppointmentInRange(item, start, end)).OrderBy(item => item.Start).ThenByDescending(item => item.End).ToArray();
|
||||
}
|
||||
|
||||
double DetermineLeft(HashSet<double> existingLefts, double width)
|
||||
{
|
||||
double left = 0;
|
||||
|
||||
while (existingLefts.Contains(left))
|
||||
{
|
||||
left += width;
|
||||
}
|
||||
|
||||
return left;
|
||||
}
|
||||
|
||||
HashSet<double> ExistingLefts(IDictionary<AppointmentData, double> lefts, IEnumerable<AppointmentData> appointments)
|
||||
{
|
||||
var existingLefts = new HashSet<double>();
|
||||
|
||||
foreach (var appointment in appointments)
|
||||
{
|
||||
if (lefts.TryGetValue(appointment, out var existingLeft))
|
||||
{
|
||||
existingLefts.Add(existingLeft);
|
||||
}
|
||||
}
|
||||
|
||||
return existingLefts;
|
||||
}
|
||||
private IDictionary<int, int> AppointmentGroups()
|
||||
{
|
||||
var groups = new Dictionary<int, int>();
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
@implements IDisposable
|
||||
|
||||
<div class="rz-dialog-wrapper">
|
||||
<div class="rz-dialog" role="dialog" aria-labelledby="rz-dialog-0-label" style=@Style>
|
||||
@if (Dialog.Options.ShowTitle)
|
||||
@@ -32,11 +30,6 @@
|
||||
[Parameter]
|
||||
public Dialog Dialog { get; set; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Service.DidCloseDialog();
|
||||
}
|
||||
|
||||
RenderFragment ChildContent => new RenderFragment(builder =>
|
||||
{
|
||||
builder.OpenComponent(0, Dialog.Type);
|
||||
|
||||
@@ -44,6 +44,9 @@
|
||||
{
|
||||
base.Dispose();
|
||||
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", GetId());
|
||||
if (IsJSRuntimeAvailable)
|
||||
{
|
||||
JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", GetId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
@import 'components/blazor/icons';
|
||||
@import 'components/blazor/common';
|
||||
@import 'components/blazor/button';
|
||||
@import 'components/blazor/badge';
|
||||
@import 'components/blazor/input';
|
||||
@import 'components/blazor/header';
|
||||
@import 'components/blazor/footer';
|
||||
@@ -56,4 +57,5 @@
|
||||
@import 'components/blazor/link';
|
||||
@import 'components/blazor/editor';
|
||||
@import 'components/blazor/colorpicker';
|
||||
@import 'components/blazor/splitter';
|
||||
|
||||
|
||||
57
Radzen.Blazor/themes/components/blazor/_badge.scss
Normal file
57
Radzen.Blazor/themes/components/blazor/_badge.scss
Normal file
@@ -0,0 +1,57 @@
|
||||
$badge-pill-border-radius: $border-radius !default;
|
||||
|
||||
$badge-styles: () !default;
|
||||
|
||||
$badge-styles: map-merge(
|
||||
(
|
||||
primary: (
|
||||
background-color: $primary
|
||||
),
|
||||
light: (
|
||||
background-color: $light,
|
||||
color: $charcoal-grey
|
||||
),
|
||||
secondary: (
|
||||
background-color: $secondary
|
||||
),
|
||||
info: (
|
||||
background-color: $info
|
||||
),
|
||||
warning: (
|
||||
background-color: $warning
|
||||
),
|
||||
error: (
|
||||
background-color: $danger
|
||||
),
|
||||
danger: (
|
||||
background-color: $danger
|
||||
),
|
||||
success: (
|
||||
background-color: $success
|
||||
)
|
||||
),
|
||||
$badge-styles
|
||||
);
|
||||
|
||||
.rz-badge {
|
||||
color: $white;
|
||||
display: inline-block;
|
||||
padding: .25em .4em;
|
||||
font-size: 75%;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@each $style, $badge in $badge-styles {
|
||||
.rz-badge-#{$style} {
|
||||
@each $name, $value in $badge {
|
||||
#{$name}: #{$value};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rz-badge-pill {
|
||||
border-radius: $badge-pill-border-radius;
|
||||
}
|
||||
@@ -113,7 +113,7 @@ $dialog-border-radius: $border-radius !default;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 1000;
|
||||
z-index: 1001;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
|
||||
@@ -612,7 +612,7 @@ $grid-button-line-height: $grid-button-height !default;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: $grid-loading-indicator-background-color;
|
||||
z-index: 1;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.rz-datatable-loading-content {
|
||||
@@ -712,7 +712,6 @@ $grid-button-line-height: $grid-button-height !default;
|
||||
}
|
||||
|
||||
.rz-data-grid {
|
||||
border: 1px solid #ccc;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
@@ -776,6 +775,43 @@ $grid-button-line-height: $grid-button-height !default;
|
||||
}
|
||||
}
|
||||
|
||||
.rz-grid-table tbody > ::deep div {
|
||||
.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;
|
||||
}
|
||||
|
||||
.rz-group-header {
|
||||
background-color: $grid-header-background-color;
|
||||
padding: 15px;
|
||||
border-bottom: $grid-cell-border;
|
||||
}
|
||||
|
||||
.rz-group-header-item {
|
||||
border: $grid-cell-border;
|
||||
padding: 10px;
|
||||
margin:5px;
|
||||
width: fit-content;
|
||||
float:left;
|
||||
}
|
||||
|
||||
.rz-group-header-item-title {
|
||||
margin-right: 5px;
|
||||
}
|
||||
@@ -14,6 +14,7 @@ $rating-disabled-color: $cool-grey !default;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
cursor: default;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
@@ -44,8 +45,9 @@ $rating-disabled-color: $cool-grey !default;
|
||||
}
|
||||
}
|
||||
|
||||
.rz-rating:not(.rz-state-disabled) {
|
||||
.rz-rating:not(.rz-state-disabled):not(.rz-state-readonly) {
|
||||
.rzi-star-o {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: $rating-selected-color;
|
||||
|
||||
|
||||
148
Radzen.Blazor/themes/components/blazor/_splitter.scss
Normal file
148
Radzen.Blazor/themes/components/blazor/_splitter.scss
Normal file
@@ -0,0 +1,148 @@
|
||||
$splitter-bar-color: #6A6A6A !default;
|
||||
$splitter-bar-color-active: #fff !default;
|
||||
$splitter-bar-background-color: #E6ECEF !default;
|
||||
$splitter-bar-background-color-active: #479CC8 !default;
|
||||
$splitter-bar-hover-opacity: 1 !default;
|
||||
|
||||
.rz-splitter {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
> .rz-splitter-bar {
|
||||
flex: 0 0 auto;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: $splitter-bar-color;
|
||||
background-color: $splitter-bar-background-color;
|
||||
opacity: 0.4;
|
||||
user-select: none;
|
||||
|
||||
> .rz-collapse {
|
||||
display: table;
|
||||
|
||||
&:before {
|
||||
font-family: 'Material Icons';
|
||||
line-height: normal;
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
> .rz-resize {
|
||||
border: 1px solid $splitter-bar-color;
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
> .rz-expand {
|
||||
display: table;
|
||||
|
||||
&:before {
|
||||
font-family: 'Material Icons';
|
||||
line-height: normal;
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
&-resizable:hover {
|
||||
background-color: $splitter-bar-background-color;
|
||||
opacity: $splitter-bar-hover-opacity;
|
||||
}
|
||||
|
||||
&-resizable:active {
|
||||
background-color: $splitter-bar-background-color-active;
|
||||
opacity: $splitter-bar-hover-opacity;
|
||||
|
||||
> .rz-expand, > .rz-resize, > .rz-collapse {
|
||||
color: $splitter-bar-color-active;
|
||||
}
|
||||
|
||||
> .rz-resize {
|
||||
border: 1px solid $splitter-bar-color-active;
|
||||
}
|
||||
}
|
||||
|
||||
&-resizable:disabled {
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
&-horizontal {
|
||||
flex-direction: row;
|
||||
|
||||
> .rz-splitter-bar {
|
||||
flex-direction: column;
|
||||
width: 8px;
|
||||
|
||||
> .rz-collapse:before {
|
||||
content: 'arrow_left';
|
||||
}
|
||||
|
||||
> .rz-resize {
|
||||
height: 16px;
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
> .rz-expand:before {
|
||||
content: 'arrow_right';
|
||||
}
|
||||
|
||||
&-resizable:hover {
|
||||
cursor: col-resize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-vertical {
|
||||
flex-direction: column;
|
||||
|
||||
> .rz-splitter-bar {
|
||||
flex-direction: row;
|
||||
height: 8px;
|
||||
|
||||
> .rz-collapse:before {
|
||||
content: 'arrow_drop_up'
|
||||
}
|
||||
|
||||
> .rz-resize {
|
||||
width: 16px;
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
> .rz-expand:before {
|
||||
content: 'arrow_drop_down'
|
||||
}
|
||||
|
||||
&-resizable:hover {
|
||||
cursor: row-resize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-pane {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
flex: 0 0 auto;
|
||||
|
||||
&-collapsed {
|
||||
flex: 0 1 0% !important;
|
||||
overflow: hidden !important;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
&-lastresizable {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -258,6 +258,11 @@ $editor-button-background-color: $default-background-color !default;
|
||||
$editor-button-selected-color: $white !default;
|
||||
$editor-separator-background-color: $body-color !default;
|
||||
|
||||
// Splitter
|
||||
$splitter-bar-color: #fff !default;
|
||||
$splitter-bar-background-color: #4A5A63 !default;
|
||||
$splitter-bar-hover-opacity: 0.8 !default;
|
||||
|
||||
@import 'fonts';
|
||||
@import 'typography';
|
||||
@import 'components';
|
||||
|
||||
@@ -258,6 +258,11 @@ $editor-button-background-color: $default-background-color !default;
|
||||
$editor-button-selected-color: $white !default;
|
||||
$editor-separator-background-color: $body-color !default;
|
||||
|
||||
// Splitter
|
||||
$splitter-bar-color: #fff !default;
|
||||
$splitter-bar-background-color: #4A5A63 !default;
|
||||
$splitter-bar-hover-opacity: 0.8 !default;
|
||||
|
||||
@import 'bootstrap';
|
||||
@import 'fonts';
|
||||
@import 'typography';
|
||||
|
||||
@@ -56,6 +56,9 @@ $slider-handle-hover-background-color: $secondary-hover;
|
||||
$dropdown-item-hover-background-color: $secondary-hover;
|
||||
$radio-checked-hover-background-color: $secondary-hover;
|
||||
|
||||
// Splitter
|
||||
$splitter-bar-background-color-active: #3BA5FC !default;
|
||||
|
||||
@import 'fonts';
|
||||
@import 'typography';
|
||||
@import 'components';
|
||||
|
||||
@@ -56,6 +56,9 @@ $slider-handle-hover-background-color: $secondary-hover;
|
||||
$dropdown-item-hover-background-color: $secondary-hover;
|
||||
$radio-checked-hover-background-color: $secondary-hover;
|
||||
|
||||
// Splitter
|
||||
$splitter-bar-background-color-active: #3BA5FC !default;
|
||||
|
||||
@import 'bootstrap';
|
||||
@import 'fonts';
|
||||
@import 'typography';
|
||||
|
||||
@@ -59,6 +59,9 @@ $radio-checked-hover-background-color: $secondary-hover;
|
||||
// SplitButton
|
||||
$splitbutton-menu-button-border: 1px solid #475359;
|
||||
|
||||
// Splitter
|
||||
$splitter-bar-background-color-active: #598087 !default;
|
||||
|
||||
@import 'fonts';
|
||||
@import 'typography';
|
||||
@import 'components';
|
||||
|
||||
@@ -59,6 +59,9 @@ $radio-checked-hover-background-color: $secondary-hover;
|
||||
// SplitButton
|
||||
$splitbutton-menu-button-border: 1px solid #475359;
|
||||
|
||||
// Splitter
|
||||
$splitter-bar-background-color-active: #598087 !default;
|
||||
|
||||
@import 'bootstrap';
|
||||
@import 'fonts';
|
||||
@import 'typography';
|
||||
|
||||
@@ -129,7 +129,9 @@ window.Radzen = {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
el.addEventListener('keydown', preventDefault, false);
|
||||
if (el) {
|
||||
el.addEventListener('keydown', preventDefault, false);
|
||||
}
|
||||
},
|
||||
loadGoogleMaps: function (defaultView, apiKey, resolve, reject) {
|
||||
resolveCallbacks.push(resolve);
|
||||
@@ -590,10 +592,33 @@ window.Radzen = {
|
||||
}
|
||||
return popups;
|
||||
},
|
||||
repositionPopup: function (parent, id) {
|
||||
var popup = document.getElementById(id);
|
||||
if (!popup) return;
|
||||
|
||||
var rect = popup.getBoundingClientRect();
|
||||
var parentRect = parent ? parent.getBoundingClientRect() : { top: 0, bottom: 0, left: 0, right: 0, width: 0, height: 0 };
|
||||
|
||||
if (/Edge/.test(navigator.userAgent)) {
|
||||
var scrollTop = document.body.scrollTop;
|
||||
} else {
|
||||
var scrollTop = document.documentElement.scrollTop;
|
||||
}
|
||||
|
||||
var top = parentRect.bottom + scrollTop;
|
||||
|
||||
if (top + rect.height > window.innerHeight && parentRect.top > rect.height) {
|
||||
top = parentRect.top - rect.height + scrollTop;
|
||||
}
|
||||
|
||||
popup.style.top = top + 'px';
|
||||
},
|
||||
openPopup: function (parent, id, syncWidth, position, x, y, instance, callback) {
|
||||
var popup = document.getElementById(id);
|
||||
if (!popup) return;
|
||||
|
||||
Radzen.activeElement = document.activeElement;
|
||||
|
||||
var parentRect = parent ? parent.getBoundingClientRect() : { top: y || 0, bottom: 0, left: x || 0, right: 0, width: 0, height: 0 };
|
||||
|
||||
if (/Edge/.test(navigator.userAgent)) {
|
||||
@@ -604,8 +629,8 @@ window.Radzen = {
|
||||
var scrollTop = document.documentElement.scrollTop;
|
||||
}
|
||||
|
||||
var top = y ? y + scrollTop: parentRect.bottom + scrollTop;
|
||||
var left = x ? x + scrollLeft: parentRect.left + scrollLeft;
|
||||
var top = y ? y : parentRect.bottom;
|
||||
var left = x ? x : parentRect.left;
|
||||
|
||||
if (syncWidth) {
|
||||
popup.style.width = parentRect.width + 'px';
|
||||
@@ -620,12 +645,8 @@ window.Radzen = {
|
||||
|
||||
var smartPosition = !position || position == 'bottom';
|
||||
|
||||
if (
|
||||
smartPosition &&
|
||||
top + rect.height > window.innerHeight &&
|
||||
parentRect.top > rect.height
|
||||
) {
|
||||
top = parentRect.top - rect.height + scrollTop;
|
||||
if (smartPosition && top + rect.height > window.innerHeight && parentRect.top > rect.height) {
|
||||
top = parentRect.top - rect.height;
|
||||
|
||||
if (position) {
|
||||
top = top - 40;
|
||||
@@ -638,12 +659,8 @@ window.Radzen = {
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
smartPosition &&
|
||||
left + rect.width - scrollLeft > window.innerWidth &&
|
||||
window.innerWidth > rect.width
|
||||
) {
|
||||
left = window.innerWidth - rect.width + scrollLeft;
|
||||
if (smartPosition && left + rect.width > window.innerWidth && window.innerWidth > rect.width) {
|
||||
left = window.innerWidth - rect.width;
|
||||
|
||||
if (position) {
|
||||
var tooltipContent = popup.children[0];
|
||||
@@ -651,8 +668,8 @@ window.Radzen = {
|
||||
if (tooltipContent.classList.contains(tooltipContentClassName)) {
|
||||
tooltipContent.classList.remove(tooltipContentClassName);
|
||||
tooltipContent.classList.add('rz-left-tooltip-content');
|
||||
left = parentRect.left - rect.width - 5 + scrollLeft;
|
||||
top = parentRect.top - parentRect.height + scrollTop;
|
||||
left = parentRect.left - rect.width - 5;
|
||||
top = parentRect.top - parentRect.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -661,30 +678,26 @@ window.Radzen = {
|
||||
if (position) {
|
||||
top = top + 20;
|
||||
}
|
||||
|
||||
popup.style.top = top + 'px';
|
||||
}
|
||||
|
||||
if (smartPosition) {
|
||||
popup.style.left = left + 'px';
|
||||
}
|
||||
|
||||
if (position == 'left') {
|
||||
popup.style.left = parentRect.left - rect.width - 5 + 'px';
|
||||
popup.style.top = parentRect.top + scrollTop + 'px';
|
||||
left = parentRect.left - rect.width - 5;
|
||||
top = parentRect.top;
|
||||
}
|
||||
|
||||
if (position == 'right') {
|
||||
popup.style.left = parentRect.right + 10 + 'px';
|
||||
popup.style.top = parentRect.top + scrollTop + 'px';
|
||||
left = parentRect.right + 10;
|
||||
top = parentRect.top;
|
||||
}
|
||||
|
||||
if (position == 'top') {
|
||||
popup.style.top = parentRect.top + scrollTop - rect.height + 5 + 'px';
|
||||
popup.style.left = parentRect.left + scrollLeft + 'px';
|
||||
top = parentRect.top - rect.height + 5;
|
||||
left = parentRect.left;
|
||||
}
|
||||
|
||||
popup.style.zIndex = 1000;
|
||||
popup.style.zIndex = 2000;
|
||||
popup.style.left = left + scrollLeft + 'px';
|
||||
popup.style.top = top + scrollTop + 'px';
|
||||
|
||||
if (!popup.classList.contains('rz-overlaypanel')) {
|
||||
popup.classList.add('rz-popup');
|
||||
@@ -693,7 +706,7 @@ window.Radzen = {
|
||||
Radzen[id] = function (e) {
|
||||
if (!e.defaultPrevented) {
|
||||
if (parent) {
|
||||
if (!parent.contains(e.target) && !popup.contains(e.target)) {
|
||||
if (e.type == 'click' && !parent.contains(e.target) && !popup.contains(e.target)) {
|
||||
Radzen.closePopup(id, instance, callback);
|
||||
}
|
||||
} else {
|
||||
@@ -704,10 +717,32 @@ window.Radzen = {
|
||||
}
|
||||
};
|
||||
|
||||
if (!Radzen.closePopupsOnScroll) {
|
||||
Radzen.closePopupsOnScroll = function (e) {
|
||||
for (var i = 0; i < Radzen.popups.length; i++) {
|
||||
var p = Radzen.popups[i];
|
||||
Radzen.closePopup(p.id, p.instance, p.callback);
|
||||
}
|
||||
Radzen.popups = [];
|
||||
};
|
||||
Radzen.popups = [];
|
||||
}
|
||||
|
||||
Radzen.popups.push({id, instance, callback});
|
||||
|
||||
document.body.appendChild(popup);
|
||||
document.removeEventListener('click', Radzen[id]);
|
||||
document.addEventListener('click', Radzen[id]);
|
||||
|
||||
var p = parent;
|
||||
while (p && p != document.body) {
|
||||
if (p.scrollWidth > p.clientWidth || p.scrollHeight > p.clientHeight) {
|
||||
p.removeEventListener('scroll', Radzen.closePopupsOnScroll);
|
||||
p.addEventListener('scroll', Radzen.closePopupsOnScroll);
|
||||
}
|
||||
p = p.parentElement;
|
||||
}
|
||||
|
||||
if (!parent) {
|
||||
document.removeEventListener('contextmenu', Radzen[id]);
|
||||
document.addEventListener('contextmenu', Radzen[id]);
|
||||
@@ -715,6 +750,9 @@ window.Radzen = {
|
||||
},
|
||||
closePopup: function (id, instance, callback) {
|
||||
var popup = document.getElementById(id);
|
||||
if (!popup) return;
|
||||
if (popup.style.display == 'none') return;
|
||||
|
||||
if (popup) {
|
||||
popup.style.display = 'none';
|
||||
}
|
||||
@@ -724,6 +762,11 @@ window.Radzen = {
|
||||
if (instance) {
|
||||
instance.invokeMethodAsync(callback);
|
||||
}
|
||||
|
||||
if (Radzen.activeElement && Radzen.activeElement == document.activeElement || Radzen.activeElement && document.activeElement == document.body) {
|
||||
Radzen.activeElement.focus();
|
||||
Radzen.activeElement = null;
|
||||
}
|
||||
},
|
||||
togglePopup: function (parent, id, syncWidth, instance, callback) {
|
||||
var popup = document.getElementById(id);
|
||||
@@ -761,13 +804,29 @@ window.Radzen = {
|
||||
}
|
||||
}
|
||||
},
|
||||
openDialog: function () {
|
||||
openDialog: function (options) {
|
||||
if (
|
||||
document.documentElement.scrollHeight >
|
||||
document.documentElement.clientHeight
|
||||
) {
|
||||
document.body.classList.add('no-scroll');
|
||||
}
|
||||
|
||||
if (options.autoFocusFirstElement) {
|
||||
setTimeout(function () {
|
||||
var dialogs = document.querySelectorAll('.rz-dialog-content');
|
||||
if (dialogs.length == 0) return;
|
||||
var lastDialog = dialogs[dialogs.length - 1];
|
||||
|
||||
if (lastDialog) {
|
||||
var focusable = lastDialog.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
|
||||
var firstFocusable = focusable[0];
|
||||
if (firstFocusable) {
|
||||
firstFocusable.focus();
|
||||
}
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
},
|
||||
closeDialog: function () {
|
||||
document.body.classList.remove('no-scroll');
|
||||
@@ -1115,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;
|
||||
@@ -1165,5 +1261,140 @@ window.Radzen = {
|
||||
document.addEventListener('mouseup', Radzen[el].mouseUpHandler);
|
||||
document.addEventListener('touchmove', Radzen[el].touchMoveHandler, { passive: true })
|
||||
document.addEventListener('touchend', Radzen[el].mouseUpHandler, { passive: true });
|
||||
}
|
||||
},
|
||||
startSplitterResize: function(id,
|
||||
splitter,
|
||||
paneId,
|
||||
paneNextId,
|
||||
orientation,
|
||||
clientPos,
|
||||
minValue,
|
||||
maxValue,
|
||||
minNextValue,
|
||||
maxNextValue) {
|
||||
|
||||
var el = document.getElementById(id);
|
||||
var pane = document.getElementById(paneId);
|
||||
var paneNext = document.getElementById(paneNextId);
|
||||
var paneLength;
|
||||
var paneNextLength;
|
||||
var panePerc;
|
||||
var paneNextPerc;
|
||||
var isHOrientation=orientation == 'Horizontal';
|
||||
|
||||
var totalLength = 0.0;
|
||||
Array.from(el.children).forEach(element => {
|
||||
totalLength += isHOrientation
|
||||
? element.getBoundingClientRect().width
|
||||
: element.getBoundingClientRect().height;
|
||||
});
|
||||
|
||||
if (pane) {
|
||||
paneLength = isHOrientation
|
||||
? pane.getBoundingClientRect().width
|
||||
: pane.getBoundingClientRect().height;
|
||||
|
||||
panePerc = (paneLength / totalLength * 100) + '%';
|
||||
}
|
||||
|
||||
if (paneNext) {
|
||||
paneNextLength = isHOrientation
|
||||
? paneNext.getBoundingClientRect().width
|
||||
: paneNext.getBoundingClientRect().height;
|
||||
|
||||
paneNextPerc = (paneNextLength / totalLength * 100) + '%';
|
||||
}
|
||||
|
||||
function ensurevalue(value) {
|
||||
if (!value)
|
||||
return null;
|
||||
|
||||
value=value.trim().toLowerCase();
|
||||
|
||||
if (value.endsWith("%"))
|
||||
return totalLength*parseFloat(value)/100;
|
||||
|
||||
if (value.endsWith("px"))
|
||||
return parseFloat(value);
|
||||
|
||||
throw 'Invalid value';
|
||||
}
|
||||
|
||||
minValue=ensurevalue(minValue);
|
||||
maxValue=ensurevalue(maxValue);
|
||||
minNextValue=ensurevalue(minNextValue);
|
||||
maxNextValue=ensurevalue(maxNextValue);
|
||||
|
||||
Radzen[el] = {
|
||||
clientPos: clientPos,
|
||||
panePerc: parseFloat(panePerc),
|
||||
paneNextPerc: isFinite(parseFloat(paneNextPerc)) ? parseFloat(paneNextPerc) : 0,
|
||||
paneLength: paneLength,
|
||||
paneNextLength: isFinite(paneNextLength) ? paneNextLength : 0,
|
||||
mouseUpHandler: function(e) {
|
||||
if (Radzen[el]) {
|
||||
splitter.invokeMethodAsync(
|
||||
'RadzenSplitter.OnPaneResized',
|
||||
parseInt(pane.getAttribute('data-index')),
|
||||
parseFloat(pane.style.flexBasis),
|
||||
paneNext ? parseInt(paneNext.getAttribute('data-index')) : null,
|
||||
paneNext ? parseFloat(paneNext.style.flexBasis) : null
|
||||
);
|
||||
document.removeEventListener('mousemove', Radzen[el].mouseMoveHandler);
|
||||
document.removeEventListener('mouseup', Radzen[el].mouseUpHandler);
|
||||
document.removeEventListener('touchmove', Radzen[el].touchMoveHandler);
|
||||
document.removeEventListener('touchend', Radzen[el].mouseUpHandler);
|
||||
Radzen[el] = null;
|
||||
}
|
||||
},
|
||||
mouseMoveHandler: function(e) {
|
||||
if (Radzen[el]) {
|
||||
|
||||
var spacePerc = Radzen[el].panePerc + Radzen[el].paneNextPerc;
|
||||
var spaceLength = Radzen[el].paneLength + Radzen[el].paneNextLength;
|
||||
|
||||
var length = (Radzen[el].paneLength -
|
||||
(Radzen[el].clientPos - (isHOrientation ? e.clientX : e.clientY)));
|
||||
|
||||
if (length > spaceLength)
|
||||
length = spaceLength;
|
||||
|
||||
if (minValue && length < minValue) length = minValue;
|
||||
if (maxValue && length > maxValue) length = maxValue;
|
||||
|
||||
if (paneNext) {
|
||||
var nextSpace=spaceLength-length;
|
||||
if (minNextValue && nextSpace < minNextValue) length = spaceLength-minNextValue;
|
||||
if (maxNextValue && nextSpace > maxNextValue) length = spaceLength+maxNextValue;
|
||||
}
|
||||
|
||||
var perc = length / Radzen[el].paneLength;
|
||||
if (!isFinite(perc)) {
|
||||
perc = 1;
|
||||
Radzen[el].panePerc = 0.1;
|
||||
Radzen[el].paneLength =isHOrientation
|
||||
? pane.getBoundingClientRect().width
|
||||
: pane.getBoundingClientRect().height;
|
||||
}
|
||||
|
||||
var newPerc = Radzen[el].panePerc * perc;
|
||||
if (newPerc < 0) newPerc = 0;
|
||||
if (newPerc > 100) newPerc = 100;
|
||||
|
||||
pane.style.flexBasis = newPerc + '%';
|
||||
if (paneNext)
|
||||
paneNext.style.flexBasis = (spacePerc - newPerc) + '%';
|
||||
}
|
||||
},
|
||||
touchMoveHandler: function(e) {
|
||||
if (e.targetTouches[0]) {
|
||||
Radzen[el].mouseMoveHandler(e.targetTouches[0]);
|
||||
}
|
||||
}
|
||||
};
|
||||
document.addEventListener('mousemove', Radzen[el].mouseMoveHandler);
|
||||
document.addEventListener('mouseup', Radzen[el].mouseUpHandler);
|
||||
document.addEventListener('touchmove', Radzen[el].touchMoveHandler, { passive: true });
|
||||
document.addEventListener('touchend', Radzen[el].mouseUpHandler, { passive: true });
|
||||
}
|
||||
};
|
||||
|
||||
42
RadzenBlazorDemos/Pages/BadgePage.razor
Normal file
42
RadzenBlazorDemos/Pages/BadgePage.razor
Normal file
@@ -0,0 +1,42 @@
|
||||
@page "/badge"
|
||||
|
||||
<RadzenExample Name="Badge" Documentation="false">
|
||||
<h3>Badges</h3>
|
||||
<RadzenBadge BadgeStyle="BadgeStyle.Primary" Text="Primary" />
|
||||
<RadzenBadge BadgeStyle="BadgeStyle.Secondary" Text="Secondary" />
|
||||
<RadzenBadge BadgeStyle="BadgeStyle.Light" Text="Light" />
|
||||
<RadzenBadge BadgeStyle="BadgeStyle.Success" Text="Success" />
|
||||
<RadzenBadge BadgeStyle="BadgeStyle.Danger" Text="Danger" />
|
||||
<RadzenBadge BadgeStyle="BadgeStyle.Warning" Text="Warning" />
|
||||
<RadzenBadge BadgeStyle="BadgeStyle.Info" Text="Info" />
|
||||
|
||||
<h3 style="margin-top:20px">Pills</h3>
|
||||
<RadzenBadge BadgeStyle="BadgeStyle.Primary" IsPill="true" Text="Primary" />
|
||||
<RadzenBadge BadgeStyle="BadgeStyle.Secondary" IsPill="true" Text="Secondary" />
|
||||
<RadzenBadge BadgeStyle="BadgeStyle.Light" IsPill="true" Text="Light" />
|
||||
<RadzenBadge BadgeStyle="BadgeStyle.Success" IsPill="true" Text="Success" />
|
||||
<RadzenBadge BadgeStyle="BadgeStyle.Danger" IsPill="true" Text="Danger" />
|
||||
<RadzenBadge BadgeStyle="BadgeStyle.Warning" IsPill="true" Text="Warning" />
|
||||
<RadzenBadge BadgeStyle="BadgeStyle.Info" IsPill="true" Text="Info" />
|
||||
|
||||
<h3 style="margin-top:20px">In Button</h3>
|
||||
<RadzenButton ButtonStyle="ButtonStyle.Info">
|
||||
Button
|
||||
<RadzenBadge BadgeStyle="BadgeStyle.Primary" Text="15" />
|
||||
</RadzenButton>
|
||||
|
||||
<RadzenButton ButtonStyle="ButtonStyle.Light">
|
||||
Button
|
||||
<RadzenBadge BadgeStyle="BadgeStyle.Primary" IsPill="@true" Text="15" />
|
||||
</RadzenButton>
|
||||
|
||||
<h3 style="margin-top:20px">Child Content</h3>
|
||||
<RadzenBadge BadgeStyle="BadgeStyle.Primary">
|
||||
Childcontent
|
||||
</RadzenBadge>
|
||||
</RadzenExample>
|
||||
|
||||
|
||||
@code {
|
||||
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
<h1>DataGrid <strong>Advanced Filter Mode</strong></h1>
|
||||
|
||||
<RadzenExample Name="DataGridAdvancedFilter" Heading="false">
|
||||
<RadzenExample Name="DataGridAdvancedFilter" Heading="false" Documentation="false">
|
||||
<RadzenDataGrid AllowFiltering="true" AllowColumnResize="true"
|
||||
FilterMode="FilterMode.Advanced" PageSize="5" AllowPaging="true" AllowSorting="true" Data="@employees" TItem="Employee" ColumnWidth="300px"
|
||||
FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
|
||||
@@ -17,7 +17,7 @@
|
||||
<RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Filterable="false" Title="ID" Frozen="true" Width="50px" TextAlign="TextAlign.Center" />
|
||||
<RadzenDataGridColumn TItem="Employee" Title="Photo" Sortable="false" Filterable="false" Width="200px" >
|
||||
<Template Context="data">
|
||||
<RadzenImage Path="@data.Photo" style="width: 32px; height: 32px; border-radius: 50%;" />
|
||||
<RadzenImage Path="@data.Photo" style="width: 40px; height: 40px; border-radius: 8px;" />
|
||||
</Template>
|
||||
</RadzenDataGridColumn>
|
||||
<RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="First Name" />
|
||||
|
||||
58
RadzenBlazorDemos/Pages/DataGridColumnReoderPage.razor
Normal file
58
RadzenBlazorDemos/Pages/DataGridColumnReoderPage.razor
Normal file
@@ -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}");
|
||||
}
|
||||
}
|
||||
@@ -10,13 +10,13 @@
|
||||
|
||||
<p>Enable column resizing by setting the AllowColumnResizing property to true.</p
|
||||
|
||||
<RadzenExample Name="DataGridColumnResizing" Heading="false">
|
||||
<RadzenExample Name="DataGridColumnResizing" Heading="false" Documentation="false">
|
||||
<RadzenDataGrid Data="@employees" TItem="Employee" ColumnWidth="300px" AllowColumnResize="true" ColumnResized=@OnColumnResized>
|
||||
<Columns>
|
||||
<RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Title="ID" Width="50px" TextAlign="TextAlign.Center" />
|
||||
<RadzenDataGridColumn TItem="Employee" Title="Photo" Sortable="false" Width="200px" >
|
||||
<Template Context="data">
|
||||
<RadzenImage Path="@data.Photo" style="width: 32px; height: 32px; border-radius: 50%;" />
|
||||
<RadzenImage Path="@data.Photo" style="width: 40px; height: 40px; border-radius: 8px;" />
|
||||
</Template>
|
||||
</RadzenDataGridColumn>
|
||||
<RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="First Name" />
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<RadzenDataGridColumn Width="200px" TItem="Order" Property="Customer.CompanyName" Title="Customer" />
|
||||
<RadzenDataGridColumn TItem="Order" Property="Employee.LastName" Title="Employee">
|
||||
<Template Context="order">
|
||||
<RadzenImage Path="@order.Employee?.Photo" style="width: 32px; height: 32px; border-radius: 50%" />
|
||||
<RadzenImage Path="@order.Employee?.Photo" style="width: 40px; height: 40px; border-radius: 8px;" />
|
||||
@order.Employee?.FirstName @order.Employee?.LastName
|
||||
</Template>
|
||||
</RadzenDataGridColumn>
|
||||
|
||||
94
RadzenBlazorDemos/Pages/DataGridEmptyPage.razor
Normal file
94
RadzenBlazorDemos/Pages/DataGridEmptyPage.razor
Normal file
@@ -0,0 +1,94 @@
|
||||
@page "/datagrid-empty"
|
||||
@using RadzenBlazorDemos.Models.Northwind
|
||||
|
||||
|
||||
<h1>Empty DataGrid</h1>
|
||||
|
||||
<RadzenExample Name="DataGridEmpty" Heading="false" Documentation="false">
|
||||
<h2>Using Default Empty Text</h2>
|
||||
<RadzenDataGrid TItem="Employee" Data="@data">
|
||||
<Columns>
|
||||
<RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Title="ID" Width="50px" TextAlign="TextAlign.Center" />
|
||||
<RadzenDataGridColumn TItem="Employee" Title="Photo" Sortable="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>
|
||||
|
||||
<h2>Using Custom Empty Text</h2>
|
||||
<RadzenTextBox @bind-Value="emptyText" />
|
||||
<RadzenDataGrid TItem="Employee" Data="@data" EmptyText="@emptyText">
|
||||
<Columns>
|
||||
<RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Title="ID" Width="50px" TextAlign="TextAlign.Center" />
|
||||
<RadzenDataGridColumn TItem="Employee" Title="Photo" Sortable="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>
|
||||
|
||||
<h2>Using Render Fragment as Empty Text</h2>
|
||||
<RadzenDataGrid TItem="Employee" Data="@data">
|
||||
<EmptyTemplate>
|
||||
<p style="color: red">Empty Data Grid!</p>
|
||||
</EmptyTemplate>
|
||||
<Columns>
|
||||
<RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Title="ID" Width="50px" TextAlign="TextAlign.Center" />
|
||||
<RadzenDataGridColumn TItem="Employee" Title="Photo" Sortable="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>
|
||||
|
||||
@code {
|
||||
string emptyText = "No Items to display!";
|
||||
List<Employee> data = new List<Employee>();
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
<p>Set the initial filter of your RadzenDataGrid via the <code>FilterValue</code> and <code>FilterOperator</code> column properties.</p>
|
||||
|
||||
<RadzenExample Name="DataGridFilterApi" Heading="false">
|
||||
<RadzenExample Name="DataGridFilterApi" Heading="false" Documentation="false">
|
||||
<RadzenDataGrid AllowFiltering="true" AllowColumnResize="true"
|
||||
FilterMode="FilterMode.Advanced" PageSize="5" AllowPaging="true" AllowSorting="true" Data="@employees" TItem="Employee" ColumnWidth="300px"
|
||||
FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
|
||||
@@ -19,7 +19,7 @@
|
||||
<RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Filterable="false" Title="ID" Frozen="true" Width="50px" TextAlign="TextAlign.Center" />
|
||||
<RadzenDataGridColumn TItem="Employee" Title="Photo" Sortable="false" Filterable="false" Width="200px" >
|
||||
<Template Context="data">
|
||||
<RadzenImage Path="@data.Photo" style="width: 32px; height: 32px; border-radius: 50%;" />
|
||||
<RadzenImage Path="@data.Photo" style="width: 40px; height: 40px; border-radius: 8px;" />
|
||||
</Template>
|
||||
</RadzenDataGridColumn>
|
||||
<RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="First Name" FilterValue=@("Nan") FilterOperator="FilterOperator.StartsWith" />
|
||||
|
||||
@@ -10,17 +10,29 @@
|
||||
|
||||
<p>Lock columns to prevent them from scrolling out of view via the <code>Frozen</code> property.</p>
|
||||
|
||||
<RadzenExample Name="DataGridFrozenColumns" Heading="false">
|
||||
<RadzenDataGrid AllowFiltering="true" AllowColumnResize="true" FilterMode="FilterMode.Advanced" PageSize="5" AllowPaging="true" AllowSorting="true" Data="@employees" TItem="Employee" ColumnWidth="300px" LogicalFilterOperator="LogicalFilterOperator.Or">
|
||||
<RadzenExample Name="DataGridFrozenColumns" Heading="false" Documentation="false">
|
||||
<RadzenDataGrid AllowFiltering="true" AllowColumnResize="true" FilterMode="FilterMode.Advanced" AllowPaging="true" AllowSorting="true" Data="@employees" TItem="Employee"
|
||||
ColumnWidth="300px" LogicalFilterOperator="LogicalFilterOperator.Or" Style="height:300px">
|
||||
<Columns>
|
||||
<RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Filterable="false" Title="ID" Frozen="true" Width="50px" TextAlign="TextAlign.Center" />
|
||||
<RadzenDataGridColumn TItem="Employee" Title="Photo" Sortable="false" Filterable="false" Width="200px" >
|
||||
<RadzenDataGridColumn TItem="Employee" Title="Photo" Sortable="false" Filterable="false" Width="200px" Frozen="@frozen">
|
||||
<HeaderTemplate>
|
||||
<RadzenCheckBox @bind-Value="frozen" title="Pin/Unpin this column" />
|
||||
</HeaderTemplate>
|
||||
<Template Context="data">
|
||||
<RadzenImage Path="@data.Photo" style="width: 32px; height: 32px; border-radius: 50%;" />
|
||||
<RadzenImage Path="@data.Photo" style="width: 40px; height: 40px; border-radius: 8px;" />
|
||||
</Template>
|
||||
</RadzenDataGridColumn>
|
||||
<RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="First Name" Frozen="true" />
|
||||
<RadzenDataGridColumn TItem="Employee" Property="LastName" Title="Last Name" Width="150px"/>
|
||||
<RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="First Name" Frozen="true">
|
||||
<FooterTemplate>
|
||||
Total employees: <b>@employees.Count()</b>
|
||||
</FooterTemplate>
|
||||
</RadzenDataGridColumn>
|
||||
<RadzenDataGridColumn TItem="Employee" Property="LastName" Title="Last Name" Width="150px">
|
||||
<FooterTemplate>
|
||||
Footer
|
||||
</FooterTemplate>
|
||||
</RadzenDataGridColumn>
|
||||
<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}" />
|
||||
@@ -38,6 +50,7 @@
|
||||
</RadzenExample>
|
||||
@code {
|
||||
IEnumerable<Employee> employees;
|
||||
bool frozen;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
@page "/datagrid-group-header-template"
|
||||
|
||||
@using RadzenBlazorDemos.Data
|
||||
@using RadzenBlazorDemos.Models.Northwind
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
|
||||
@inject NorthwindContext dbContext
|
||||
|
||||
<h1>DataGrid</h1>
|
||||
|
||||
<p>Use GroupHeaderTemplate to customize DataGrid group header rows.</p>
|
||||
|
||||
<RadzenExample Name="DataGrid" Heading="false" Documentation="false">
|
||||
<RadzenDataGrid @ref="ordersGrid" AllowGrouping="true" AllowFiltering="true" AllowPaging="true" AllowSorting="true"
|
||||
Data="@orders" TItem="Order">
|
||||
<GroupHeaderTemplate>
|
||||
@context.GroupDescriptor.GetTitle(): @context.Data.Key, Group items count: @context.Data.Count, Last order date: @(context.Data.Items.Cast<Order>().OrderByDescending(o => o.OrderDate).FirstOrDefault()?.OrderDate)
|
||||
</GroupHeaderTemplate>
|
||||
<Columns>
|
||||
<RadzenDataGridColumn Width="50px" TItem="Order" Title="#" Filterable="false" Sortable="false" TextAlign="TextAlign.Center">
|
||||
<Template>
|
||||
@(orders.IndexOf(context) + 1)
|
||||
</Template>
|
||||
</RadzenDataGridColumn>
|
||||
<RadzenDataGridColumn Width="200px" TItem="Order" Property="OrderID" Title="Order ID">
|
||||
<FooterTemplate>
|
||||
Displayed orders: <b>@ordersGrid.View.Count()</b> of <b>@orders.Count()</b>
|
||||
</FooterTemplate>
|
||||
</RadzenDataGridColumn>
|
||||
<RadzenDataGridColumn Width="200px" TItem="Order" Property="Customer.CompanyName" Title="Customer" />
|
||||
<RadzenDataGridColumn TItem="Order" Property="Employee.LastName" Title="Employee">
|
||||
<Template Context="order">
|
||||
@order.Employee?.FirstName @order.Employee?.LastName
|
||||
</Template>
|
||||
</RadzenDataGridColumn>
|
||||
<RadzenDataGridColumn TItem="Order" Property="OrderDate" Title="Order Date" FormatString="{0:d}">
|
||||
<FooterTemplate>
|
||||
Last order date: <b>@String.Format("{0:d}", orders.OrderByDescending(o => o.OrderDate).Last().OrderDate)</b>
|
||||
</FooterTemplate>
|
||||
</RadzenDataGridColumn>
|
||||
<RadzenDataGridColumn TItem="Order" Property="Freight" Title="Freight">
|
||||
<Template Context="order">
|
||||
@String.Format(new System.Globalization.CultureInfo("en-US"), "{0:C}", order.Freight)
|
||||
</Template>
|
||||
<FooterTemplate>
|
||||
Total amount: <b>@String.Format(new System.Globalization.CultureInfo("en-US"), "{0:C}", orders.Sum(o => o.Freight))</b>
|
||||
</FooterTemplate>
|
||||
</RadzenDataGridColumn>
|
||||
<RadzenDataGridColumn TItem="Order" Property="ShipName" Title="Ship Name" />
|
||||
</Columns>
|
||||
</RadzenDataGrid>
|
||||
</RadzenExample>
|
||||
@code {
|
||||
IList<Order> orders;
|
||||
RadzenDataGrid<Order> ordersGrid;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
orders = dbContext.Orders.Include("Customer").Include("Employee").ToList();
|
||||
}
|
||||
}
|
||||
56
RadzenBlazorDemos/Pages/DataGridGroupingApiPage.razor
Normal file
56
RadzenBlazorDemos/Pages/DataGridGroupingApiPage.razor
Normal file
@@ -0,0 +1,56 @@
|
||||
@page "/datagrid-grouping-api"
|
||||
|
||||
@using RadzenBlazorDemos.Data
|
||||
@using RadzenBlazorDemos.Models.Northwind
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
|
||||
@inject NorthwindContext dbContext
|
||||
|
||||
<h1>DataGrid</h1>
|
||||
|
||||
<p>Set AllowGrouping="true" to enable group by column and GroupPanelText to localize the group panel text. Set Groupable="false" for column to disable grouping by that column.</p>
|
||||
|
||||
<RadzenExample Name="DataGrid" Heading="false" Documentation="false">
|
||||
<RadzenDataGrid AllowGrouping="true" AllowFiltering="true" AllowColumnResize="true" FilterMode="FilterMode.Advanced" PageSize="5" AllowPaging="true" AllowSorting="true"
|
||||
Data="@employees" TItem="Employee" ColumnWidth="300px" LogicalFilterOperator="LogicalFilterOperator.Or" Render="@OnRender">
|
||||
<Columns>
|
||||
<RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Filterable="false" Title="ID" Frozen="true" Width="70px" TextAlign="TextAlign.Center" />
|
||||
<RadzenDataGridColumn TItem="Employee" Title="Photo" Sortable="false" Filterable="false" Groupable="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>
|
||||
@code {
|
||||
IEnumerable<Employee> employees;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
employees = dbContext.Employees;
|
||||
}
|
||||
|
||||
void OnRender(DataGridRenderEventArgs<Employee> args)
|
||||
{
|
||||
if(args.FirstRender)
|
||||
{
|
||||
args.Grid.Groups.Add(new GroupDescriptor(){ Property = "Title" });
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,13 +23,13 @@
|
||||
</RadzenDataGridColumn>
|
||||
<RadzenDataGridColumn TItem="Order" Property="Employee.LastName" Title="Employee" Width="300px">
|
||||
<Template Context="order">
|
||||
<RadzenImage Path="@order.Employee?.Photo" style="width: 32px; height: 32px; border-radius: 50%;" />
|
||||
<RadzenImage Path="@order.Employee?.Photo" style="width: 40px; height: 40px; border-radius: 8px;" />
|
||||
@order.Employee?.FirstName @order.Employee?.LastName
|
||||
</Template>
|
||||
<EditTemplate Context="order">
|
||||
<RadzenDropDown @bind-Value="order.EmployeeID" Data="@employees" ValueProperty="EmployeeID" Style="width:100%">
|
||||
<Template>
|
||||
<RadzenImage Path="@context.Photo" style="width: 32px; height: 32px; border-radius: 50%;" />
|
||||
<RadzenImage Path="@context.Photo" style="width: 40px; height: 40px; border-radius: 8px;" />
|
||||
@context.FirstName @context.LastName
|
||||
</Template>
|
||||
</RadzenDropDown>
|
||||
|
||||
@@ -10,12 +10,13 @@
|
||||
<p>The <code>LoadData</code> event allows you to perform custom paging, sorting and filtering.</p>
|
||||
|
||||
<RadzenExample Name="DataGridLoadData" Heading="false" Documentation="false">
|
||||
<RadzenDataGrid Count="@count" Data="@employees" LoadData="@LoadData" AllowSorting="true" AllowFiltering="true" AllowPaging="true" PageSize="4" TItem="Employee" ColumnWidth="200px">
|
||||
<RadzenButton Text="Reset" Click="@Reset" Style="margin-bottom: 20px;" />
|
||||
<RadzenDataGrid @ref="grid" Count="@count" Data="@employees" LoadData="@LoadData" AllowSorting="true" AllowFiltering="true" AllowPaging="true" PageSize="4" TItem="Employee" ColumnWidth="200px">
|
||||
<Columns>
|
||||
<RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Filterable="false" Title="ID" Frozen="true" Width="50px" TextAlign="TextAlign.Center" />
|
||||
<RadzenDataGridColumn TItem="Employee" Title="Photo" Sortable="false" Filterable="false" Width="200px" >
|
||||
<Template Context="data">
|
||||
<RadzenImage Path="@data.Photo" style="width: 32px; height: 32px; border-radius: 50%;" />
|
||||
<RadzenImage Path="@data.Photo" style="width: 40px; height: 40px; border-radius: 8px;" />
|
||||
</Template>
|
||||
</RadzenDataGridColumn>
|
||||
<RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="First Name" />
|
||||
@@ -61,18 +62,27 @@ void LoadData(LoadDataArgs args)
|
||||
query = query.OrderBy(args.OrderBy);
|
||||
}
|
||||
|
||||
count = query.Count();
|
||||
|
||||
employees = query.Skip(args.Skip.Value).Take(args.Top.Value).ToList();
|
||||
|
||||
count = dbContext.Employees.Count();
|
||||
|
||||
}
|
||||
</code>
|
||||
</pre>
|
||||
</li>
|
||||
</ol>
|
||||
@code {
|
||||
RadzenDataGrid<Employee> grid;
|
||||
int count;
|
||||
IEnumerable<Employee> employees;
|
||||
|
||||
async Task Reset()
|
||||
{
|
||||
grid.Reset(true);
|
||||
await grid.FirstPage(true);
|
||||
}
|
||||
|
||||
void LoadData(LoadDataArgs args)
|
||||
{
|
||||
// This demo is using https://dynamic-linq.net
|
||||
@@ -90,10 +100,10 @@ void LoadData(LoadDataArgs args)
|
||||
query = query.OrderBy(args.OrderBy);
|
||||
}
|
||||
|
||||
// Important!!! Make sure the Count property of RadzenDataGrid is set.
|
||||
count = query.Count();
|
||||
|
||||
// Perform paginv via Skip and Take.
|
||||
employees = query.Skip(args.Skip.Value).Take(args.Top.Value).ToList();
|
||||
|
||||
// Important!!! Make sure the Count property of RadzenDataGrid is set.
|
||||
count = dbContext.Employees.Count();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Title="Employee ID" />
|
||||
<RadzenDataGridColumn TItem="Employee" Property="Photo" Title="Employee" Sortable="false" Filterable="false">
|
||||
<Template Context="data">
|
||||
<RadzenImage Path="@data.Photo" style="width: 32px; height: 32px; border-radius: 50%" />
|
||||
<RadzenImage Path="@data.Photo" style="width: 40px; height: 40px; border-radius: 8px;" />
|
||||
@data.FirstName @data.LastName
|
||||
</Template>
|
||||
</RadzenDataGridColumn>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Filterable="false" Title="ID" Frozen="true" Width="50px" TextAlign="TextAlign.Center" />
|
||||
<RadzenDataGridColumn TItem="Employee" Title="Photo" Sortable="false" Filterable="false" Width="200px" >
|
||||
<Template Context="data">
|
||||
<RadzenImage Path="@data.Photo" style="width: 32px; height: 32px; border-radius: 50%;" />
|
||||
<RadzenImage Path="@data.Photo" style="width: 40px; height: 40px; border-radius: 8px;" />
|
||||
</Template>
|
||||
</RadzenDataGridColumn>
|
||||
<RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="First Name" />
|
||||
|
||||
@@ -11,12 +11,13 @@
|
||||
<p>Display tabular data with ease. Perform paging, sorting and filtering through Entity Framework without extra code.</p>
|
||||
|
||||
<RadzenExample Name="DataGrid" Heading="false">
|
||||
<RadzenDataGrid AllowFiltering="true" AllowColumnResize="true" FilterMode="FilterMode.Advanced" PageSize="5" AllowPaging="true" AllowSorting="true" Data="@employees" TItem="Employee" ColumnWidth="300px" LogicalFilterOperator="LogicalFilterOperator.Or">
|
||||
<RadzenDataGrid 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" />
|
||||
<RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Filterable="false" Title="ID" Frozen="true" Width="70px" TextAlign="TextAlign.Center" />
|
||||
<RadzenDataGridColumn TItem="Employee" Title="Photo" Sortable="false" Filterable="false" Width="200px" >
|
||||
<Template Context="data">
|
||||
<RadzenImage Path="@data.Photo" style="width: 32px; height: 32px; border-radius: 50%;" />
|
||||
<RadzenImage Path="@data.Photo" style="width: 40px; height: 40px; border-radius: 8px;" />
|
||||
</Template>
|
||||
</RadzenDataGridColumn>
|
||||
<RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="First Name" />
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
|
||||
<h1>DataGrid <strong>Pager API</strong></h1>
|
||||
|
||||
<RadzenExample Name="DataGridPagerApi" Heading="false">
|
||||
<RadzenExample Name="DataGridPagerApi" Heading="false" Documentation="false">
|
||||
<div style="margin-bottom: 16px">
|
||||
<RadzenButton Click="@FirstPage" Text="First page" />
|
||||
<RadzenButton Click="@TenthPage" Text="10th page" />
|
||||
<RadzenButton Click="@LastPage" Text="Last page" />
|
||||
</div>
|
||||
<RadzenDataGrid @ref=@dataGrid Data="@orderDetails" TItem="OrderDetail" AllowPaging="true" AllowSorting="true">
|
||||
<RadzenDataGrid @ref=@dataGrid Data="@orderDetails" TItem="OrderDetail" AllowPaging="true" AllowSorting="true" PageSizeOptions="@pageSizeOptions">
|
||||
<Columns>
|
||||
<RadzenDataGridColumn TItem="OrderDetail" Property="OrderID" Title="OrderID" />
|
||||
<RadzenDataGridColumn TItem="OrderDetail" Property="ProductID" Title="ProductID" />
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
@code {
|
||||
RadzenDataGrid<OrderDetail> dataGrid;
|
||||
|
||||
IEnumerable<int> pageSizeOptions = new int[] { 10, 20, 30 };
|
||||
IEnumerable<OrderDetail> orderDetails;
|
||||
|
||||
async Task FirstPage()
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
<h1>DataGrid <strong>Pager Position</strong></h1>
|
||||
|
||||
<RadzenExample Name="DataGridPagerPosition" Heading="false">
|
||||
<RadzenExample Name="DataGridPagerPosition" Heading="false" Documentation="false">
|
||||
<div style="display: flex; align-items: center; margin-bottom: 16px">
|
||||
<div style="white-space:nowrap; margin-right: 16px">Pager Position:</div>
|
||||
<RadzenDropDown @bind-Value="@pagerPosition" TextProperty="Text" ValueProperty="Value"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
<h1>DataGrid <strong>Simple Filter Mode</strong></h1>
|
||||
|
||||
<RadzenExample Name="DataGridSimpleFilter" Heading="false">
|
||||
<RadzenExample Name="DataGridSimpleFilter" Heading="false" Documentation="false">
|
||||
<RadzenDataGrid AllowFiltering="true" AllowColumnResize="true"
|
||||
FilterMode="FilterMode.Simple" PageSize="5" AllowPaging="true" AllowSorting="true" Data="@employees" TItem="Employee" ColumnWidth="300px"
|
||||
FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
|
||||
@@ -17,7 +17,7 @@
|
||||
<RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Filterable="false" Title="ID" Frozen="true" Width="50px" TextAlign="TextAlign.Center" />
|
||||
<RadzenDataGridColumn TItem="Employee" Title="Photo" Sortable="false" Filterable="false" Width="200px" >
|
||||
<Template Context="data">
|
||||
<RadzenImage Path="@data.Photo" style="width: 32px; height: 32px; border-radius: 50%;" />
|
||||
<RadzenImage Path="@data.Photo" style="width: 40px; height: 40px; border-radius: 8px;" />
|
||||
</Template>
|
||||
</RadzenDataGridColumn>
|
||||
<RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="First Name" />
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<RadzenDataGridColumn TItem="Employee" Property="EmployeeID" Title="Employee ID" />
|
||||
<RadzenDataGridColumn TItem="Employee" Property="Photo" Title="Employee" Sortable="false" Filterable="false">
|
||||
<Template Context="data">
|
||||
<RadzenImage Path="@data.Photo" style="width: 32px; height: 32px; border-radius: 50%" />
|
||||
<RadzenImage Path="@data.Photo" style="width: 40px; height: 40px; border-radius: 8px;" />
|
||||
@data.FirstName @data.LastName
|
||||
</Template>
|
||||
</RadzenDataGridColumn>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
<p>Set the initial sort order of your RadzenDataGrid via the <code>SortOrder</code> column property.</p>
|
||||
|
||||
<RadzenExample Name="DataGridSortApi" Heading="false">
|
||||
<RadzenExample Name="DataGridSortApi" Heading="false" Documentation="false">
|
||||
<RadzenDataGrid AllowColumnResize="true" PageSize="5" AllowPaging="true" AllowSorting="true" Data="@employees" TItem="Employee" ColumnWidth="300px">
|
||||
<Columns>
|
||||
<RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="First Name" SortOrder="SortOrder.Descending" />
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
<h1>DataGrid <strong>Sorting</strong></h1>
|
||||
|
||||
<RadzenExample Name="DataGridSort" Heading="false">
|
||||
<RadzenExample Name="DataGridSort" Heading="false" Documentation="false">
|
||||
<RadzenDataGrid PageSize="5" AllowPaging="true" AllowSorting="true" Data="@employees" TItem="Employee" ColumnWidth="300px">
|
||||
<Columns>
|
||||
<RadzenDataGridColumn TItem="Employee" Property="FirstName" Title="First Name" />
|
||||
|
||||
@@ -8,62 +8,100 @@
|
||||
<RadzenExample Name="DropDownDataGrid" DocumentationUrl="https://www.radzen.com/documentation/blazor/dropdown-datagrid/">
|
||||
<div class="row">
|
||||
<div class="col-xl-6">
|
||||
<h3>DropDownDataGrid</h3>
|
||||
<RadzenDropDownDataGrid TValue="string" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" AllowFiltering="true" AllowClear="true"
|
||||
Data=@(customers.Select(c => new { CustomerID = c.CustomerID, CompanyName = c.CompanyName }).Distinct().AsQueryable())
|
||||
TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "DropDownDataGrid")) />
|
||||
<h3 style="margin-top: 2rem">DropDownDataGrid with filtering by all string columns</h3>
|
||||
<RadzenDropDownDataGrid TValue="string" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" AllowFiltering="true" AllowClear="true"
|
||||
Data=@(customers)
|
||||
TextProperty="CompanyName" ValueProperty="CustomerID" AllowFilteringByAllStringColumns="true"
|
||||
Change=@(args => OnChange(args, "DropDownDataGrid with filtering by all string columns"))>
|
||||
<Columns>
|
||||
<RadzenDropDownDataGridColumn Property="CustomerID" Title="CustomerID" Width="100px" />
|
||||
<RadzenDropDownDataGridColumn Property="CompanyName" Title="CompanyName" Width="200px" />
|
||||
<RadzenDropDownDataGridColumn Property="City" Title="City" Width="100px" />
|
||||
<RadzenDropDownDataGridColumn Property="Country" Title="Country" Width="100px" />
|
||||
</Columns>
|
||||
</RadzenDropDownDataGrid>
|
||||
<h3 style="margin-top: 2rem">DropDownDataGrid with custom filter operator</h3>
|
||||
<RadzenDropDownDataGrid TValue="string" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" FilterOperator="StringFilterOperator.StartsWith"
|
||||
AllowFiltering="true" AllowClear="true" Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "DropDownDataGrid with custom filter operator")) />
|
||||
<h3 style="margin-top: 2rem">DropDownDataGrid with custom filtering</h3>
|
||||
<RadzenDropDownDataGrid TValue="string" LoadData="@LoadData" AllowFiltering="true" AllowClear="true"
|
||||
Data=@customCustomersData Count="@count" TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "DropDownDataGrid with custom filtering")) />
|
||||
<h3 style="margin-top: 2rem">DropDownDataGrid with placeholder</h3>
|
||||
<RadzenDropDownDataGrid TValue="string" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" AllowFiltering="true" AllowClear="true" Placeholder="Select..." Data=@customers TextProperty="CompanyName"
|
||||
ValueProperty="CustomerID" Change=@(args => OnChange(args, "DropDownDataGrid with placeholder")) />
|
||||
<h3 style="margin-top: 2rem">DropDownDataGrid with template</h3>
|
||||
<RadzenDropDownDataGrid AllowFiltering="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" AllowClear="true"
|
||||
@bind-Value="value" Placeholder="Select..." Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "DropDownDataGrid with placeholder")) Style="width:400px">
|
||||
<Template>
|
||||
Company: @((context as Customer).CompanyName)
|
||||
</Template>
|
||||
</RadzenDropDownDataGrid>
|
||||
<h3 style="margin-top: 2rem">DropDownDataGrid with multiple selection and multiple columns</h3>
|
||||
<RadzenDropDownDataGrid @ref="grid" AllowFiltering="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" AllowClear="true" @bind-Value=@multipleValues
|
||||
Multiple="true" Placeholder="Select..." Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "DropDownDataGrid with multiple selection")) Style="width:400px">
|
||||
<Columns>
|
||||
<RadzenDropDownDataGridColumn Width="40px" Sortable="false">
|
||||
<HeaderTemplate>
|
||||
<RadzenCheckBox TriState="false" TValue="bool" Value="@(customers.Any(c => multipleValues != null && multipleValues.Contains(c.CustomerID)))"
|
||||
Change="@(args => multipleValues = args ? grid.View.Cast<Customer>().Select(c => c.CustomerID) : multipleValues = Enumerable.Empty<string>())" />
|
||||
</HeaderTemplate>
|
||||
<Template Context="data">
|
||||
<RadzenCheckBox TriState="false" Value="@(multipleValues != null && multipleValues.Contains(((Customer)data).CustomerID))" />
|
||||
<div class="row">
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>Binding to simple collection</h3>
|
||||
<RadzenDropDownDataGrid TValue="string" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" AllowFiltering="true" AllowClear="true"
|
||||
Data=@(customers.Select(c => c.CompanyName).Distinct().AsQueryable())
|
||||
Change=@(args => OnChange(args, "DropDownDataGrid")) Style="width:100%" />
|
||||
</div>
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>Filtering by all string columns</h3>
|
||||
<RadzenDropDownDataGrid TValue="string" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" AllowFiltering="true" AllowClear="true"
|
||||
Data=@(customers) Style="width:100%"
|
||||
TextProperty="CompanyName" ValueProperty="CustomerID" AllowFilteringByAllStringColumns="true"
|
||||
Change=@(args => OnChange(args, "DropDownDataGrid with filtering by all string columns"))>
|
||||
<Columns>
|
||||
<RadzenDropDownDataGridColumn Property="CustomerID" Title="CustomerID" Width="100px" />
|
||||
<RadzenDropDownDataGridColumn Property="CompanyName" Title="CompanyName" Width="200px" />
|
||||
<RadzenDropDownDataGridColumn Property="City" Title="City" Width="100px" />
|
||||
<RadzenDropDownDataGridColumn Property="Country" Title="Country" Width="100px" />
|
||||
</Columns>
|
||||
</RadzenDropDownDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>Filter operator</h3>
|
||||
<RadzenDropDownDataGrid TValue="string" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" FilterOperator="StringFilterOperator.StartsWith"
|
||||
AllowFiltering="true" AllowClear="true" Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "DropDownDataGrid with custom filter operator")) Style="width:100%" />
|
||||
|
||||
</div>
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>Custom filtering</h3>
|
||||
<RadzenDropDownDataGrid TValue="string" LoadData="@LoadData" AllowFiltering="true" AllowClear="true"
|
||||
Data=@customCustomersData Count="@count" TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "DropDownDataGrid with custom filtering")) Style="width:100%" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>Multiple selection</h3>
|
||||
<RadzenDropDownDataGrid @ref="grid" AllowFiltering="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" AllowClear="true" @bind-Value=@multipleValues
|
||||
Multiple="true" Placeholder="Select..." Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "DropDownDataGrid with multiple selection")) Style="width:100%">
|
||||
<Columns>
|
||||
<RadzenDropDownDataGridColumn Width="40px" Sortable="false">
|
||||
<HeaderTemplate>
|
||||
<RadzenCheckBox TriState="false" TValue="bool" Value="@(customers.Any(c => multipleValues != null && multipleValues.Contains(c.CustomerID)))"
|
||||
Change="@(args => multipleValues = args ? grid.View.Cast<Customer>().Select(c => c.CustomerID) : multipleValues = Enumerable.Empty<string>())" />
|
||||
</HeaderTemplate>
|
||||
<Template Context="data">
|
||||
<RadzenCheckBox TriState="false" Value="@(multipleValues != null && multipleValues.Contains(((Customer)data).CustomerID))" />
|
||||
</Template>
|
||||
</RadzenDropDownDataGridColumn>
|
||||
<RadzenDropDownDataGridColumn Property="CustomerID" Title="CustomerID" Width="100px" />
|
||||
<RadzenDropDownDataGridColumn Property="CompanyName" Title="CompanyName" Width="200px" />
|
||||
<RadzenDropDownDataGridColumn Property="City" Title="City" Width="100px" />
|
||||
<RadzenDropDownDataGridColumn Property="Country" Title="Country" Width="100px" />
|
||||
</Columns>
|
||||
</RadzenDropDownDataGrid>
|
||||
</div>
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>Custom template</h3>
|
||||
<RadzenDropDownDataGrid AllowFiltering="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" AllowClear="true"
|
||||
@bind-Value="value" Placeholder="Select..." Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "DropDownDataGrid with placeholder")) Style="width:100%">
|
||||
<Template>
|
||||
Company: @((context as Customer).CompanyName)
|
||||
</Template>
|
||||
</RadzenDropDownDataGridColumn>
|
||||
<RadzenDropDownDataGridColumn Property="CustomerID" Title="CustomerID" Width="100px" />
|
||||
<RadzenDropDownDataGridColumn Property="CompanyName" Title="CompanyName" Width="200px" />
|
||||
<RadzenDropDownDataGridColumn Property="City" Title="City" Width="100px" />
|
||||
<RadzenDropDownDataGridColumn Property="Country" Title="Country" Width="100px" />
|
||||
</Columns>
|
||||
</RadzenDropDownDataGrid>
|
||||
</RadzenDropDownDataGrid>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>Virtualization using IQueryable</h3>
|
||||
<RadzenDropDownDataGrid TValue="string" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" FilterOperator="StringFilterOperator.StartsWith" AllowVirtualization="true"
|
||||
AllowFiltering="true" AllowClear="true" Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "DropDownDataGrid with virtualization using IQueryable")) Style="width:100%">
|
||||
<Columns>
|
||||
<RadzenDropDownDataGridColumn Property="CustomerID" Title="Customer ID" />
|
||||
<RadzenDropDownDataGridColumn Property="CompanyName" Title="Company Name" />
|
||||
</Columns>
|
||||
</RadzenDropDownDataGrid>
|
||||
|
||||
</div>
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>Virtualization using LoadData event</h3>
|
||||
<RadzenDropDownDataGrid TValue="string" LoadData="@LoadDataVirtualization" AllowFiltering="true" AllowClear="true" AllowVirtualization="true"
|
||||
Data=@customCustomersDataVirtualization Count="@customCustomersDataVirtualizationCount" TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "DropDownDataGrid with virtualization using LoadData event")) Style="width:100%" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-6">
|
||||
<EventConsole @ref=@console />
|
||||
@@ -125,4 +163,30 @@
|
||||
|
||||
InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
int customCustomersDataVirtualizationCount;
|
||||
IEnumerable<Customer> customCustomersDataVirtualization;
|
||||
|
||||
void LoadDataVirtualization(LoadDataArgs args)
|
||||
{
|
||||
var query = dbContext.Customers.AsQueryable();
|
||||
|
||||
if (!string.IsNullOrEmpty(args.Filter))
|
||||
{
|
||||
query = query.Where(c => c.CustomerID.ToLower().Contains(args.Filter.ToLower()) || c.ContactName.ToLower().Contains(args.Filter.ToLower()));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(args.OrderBy))
|
||||
{
|
||||
query = query.OrderBy(args.OrderBy);
|
||||
}
|
||||
|
||||
console.Log($"LoadData with virtualization: Skip:{args.Skip}, Top:{args.Top}, OrderBy:{args.OrderBy}, Filter:{args.Filter}");
|
||||
|
||||
customCustomersDataVirtualizationCount = query.Count();
|
||||
|
||||
customCustomersDataVirtualization = query.Skip(args.Skip.Value).Take(args.Top.Value).ToList();
|
||||
|
||||
InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,43 +10,85 @@
|
||||
<RadzenExample Name="DropDown">
|
||||
<div class="row">
|
||||
<div class="col-xl-6">
|
||||
<h3>DropDown</h3>
|
||||
<RadzenDropDown AllowClear="true" TValue="string"
|
||||
Data=@(customers.Select(c => new { CustomerID = c.CustomerID, CompanyName = c.CompanyName }).Distinct())
|
||||
TextProperty="CompanyName" ValueProperty="CustomerID" Change=@(args => OnChange(args, "DropDown")) />
|
||||
<h3 style="margin-top: 2rem">Disabled DropDown</h3>
|
||||
<div style="display: flex; align-items: center">
|
||||
<RadzenDropDown Disabled=@disabled AllowClear="true" TValue="string"
|
||||
Data=@(customers.Select(c => new { CustomerID = c.CustomerID, CompanyName = c.CompanyName }).Distinct())
|
||||
TextProperty="CompanyName" ValueProperty="CustomerID" Change=@(args => OnChange(args, "DropDown")) />
|
||||
<RadzenSwitch style="margin-left: 1rem" @bind-Value=@disabled />
|
||||
<div class="row">
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>Binding to simple collection</h3>
|
||||
<RadzenDropDown AllowClear="true" TValue="string" Style="width:300px"
|
||||
Data=@(customers.Select(c => c.CompanyName).Distinct())
|
||||
Change=@(args => OnChange(args, "DropDown")) />
|
||||
</div>
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>Disabled DropDown</h3>
|
||||
<div style="display: flex; align-items: center">
|
||||
<RadzenDropDown Disabled=@disabled AllowClear="true" TValue="string" Style="width:300px"
|
||||
Data=@(customers.Select(c => new { CustomerID = c.CustomerID, CompanyName = c.CompanyName }).Distinct())
|
||||
TextProperty="CompanyName" ValueProperty="CustomerID" Change=@(args => OnChange(args, "DropDown")) />
|
||||
<RadzenSwitch style="margin-left: 1rem" @bind-Value=@disabled />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>DropDown with virtualization using IQueryable</h3>
|
||||
<RadzenDropDown AllowClear="true" TValue="string" AllowVirtualization="true" Style="width:300px"
|
||||
AllowFiltering="true" Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "DropDown with virtualization")) />
|
||||
</div>
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>DropDown with virtualization using LoadData event</h3>
|
||||
<RadzenDropDown AllowClear="true" TValue="string" AllowVirtualization="true" Style="width:300px"
|
||||
LoadData=@LoadDataVirtualization AllowFiltering="true" Count="@count"
|
||||
Data=@customCustomersDataVirtualization TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "DropDown with virtualization")) />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>DropDown with custom filter operator</h3>
|
||||
<RadzenDropDown AllowClear="true" TValue="string" Style="width:300px"
|
||||
FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" FilterOperator="StringFilterOperator.StartsWith" AllowFiltering="true"
|
||||
Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" Change=@(args => OnChange(args, "DropDown with custom filter operator")) />
|
||||
</div>
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>DropDown with custom filtering</h3>
|
||||
<RadzenDropDown AllowClear="true" TValue="string" Style="width:300px"
|
||||
LoadData=@LoadData AllowFiltering="true"
|
||||
Data=@customCustomersData TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "DropDown with custom filtering")) />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>DropDown with placeholder</h3>
|
||||
<RadzenDropDown AllowClear="true" TValue="string" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" AllowFiltering="true" Style="width:300px"
|
||||
Placeholder="Select..." Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" Change=@(args => OnChange(args, "DropDown with placeholder")) />
|
||||
|
||||
</div>
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>DropDown with template</h3>
|
||||
<RadzenDropDown AllowClear="true" AllowFiltering="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" @bind-Value=@value Placeholder="Select..."
|
||||
Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" Change=@(args => OnChange(args, "DropDown with placeholder")) Style="width:300px" >
|
||||
<Template>
|
||||
Company: @((context as Customer).CompanyName)
|
||||
</Template>
|
||||
</RadzenDropDown>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>DropDown with multiple selection</h3>
|
||||
<RadzenDropDown AllowClear="true" AllowFiltering="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
|
||||
@bind-Value=@multipleValues Multiple="true" Placeholder="Select..." Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "DropDown with multiple selection")) Style="width:300px" />
|
||||
</div>
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>Bind DropDown Value to model property</h3>
|
||||
<RadzenDropDown AllowClear="true" AllowFiltering="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" Data=@products @bind-Value=@myModel.MyValue
|
||||
TextProperty="ProductName" ValueProperty="ProductID" Change=@(args => ChangeBound(args, "DropDown with bound Value")) Style="width:300px" />
|
||||
</div>
|
||||
</div>
|
||||
<h3 style="margin-top: 2rem">DropDown with custom filter operator</h3>
|
||||
<RadzenDropDown AllowClear="true" TValue="string"
|
||||
FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" FilterOperator="StringFilterOperator.StartsWith" AllowFiltering="true"
|
||||
Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" Change=@(args => OnChange(args, "DropDown with custom filter operator")) />
|
||||
<h3 style="margin-top: 2rem">DropDown with custom filtering</h3>
|
||||
<RadzenDropDown AllowClear="true" TValue="string"
|
||||
LoadData=@LoadData AllowFiltering="true"
|
||||
Data=@customCustomersData TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "DropDown with custom filtering")) />
|
||||
<h3 style="margin-top: 2rem">DropDown with placeholder</h3>
|
||||
<RadzenDropDown AllowClear="true" TValue="string" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" AllowFiltering="true"
|
||||
Placeholder="Select..." Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" Change=@(args => OnChange(args, "DropDown with placeholder")) />
|
||||
<h3 style="margin-top: 2rem">DropDown with template</h3>
|
||||
<RadzenDropDown AllowClear="true" AllowFiltering="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" @bind-Value=@value Placeholder="Select..."
|
||||
Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" Change=@(args => OnChange(args, "DropDown with placeholder")) Style="width:400px">
|
||||
<Template>
|
||||
Company: @((context as Customer).CompanyName)
|
||||
</Template>
|
||||
</RadzenDropDown>
|
||||
<h3 style="margin-top: 2rem">DropDown with multiple selection</h3>
|
||||
<RadzenDropDown AllowClear="true" AllowFiltering="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
|
||||
@bind-Value=@multipleValues Multiple="true" Placeholder="Select..." Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "DropDown with multiple selection")) Style="width:400px" />
|
||||
<h3 style="margin-top: 2rem">Bind DropDown Value to model property</h3>
|
||||
<RadzenDropDown AllowClear="true" AllowFiltering="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" Data=@products @bind-Value=@myModel.MyValue
|
||||
TextProperty="ProductName" ValueProperty="ProductID" Style="width:400px" Change=@(args => ChangeBound(args, "DropDown with bound Value")) />
|
||||
</div>
|
||||
<div class="col-xl-6">
|
||||
<EventConsole @ref=@console />
|
||||
@@ -61,17 +103,20 @@
|
||||
IEnumerable<Product> products;
|
||||
MyObject myModel = new MyObject();
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
customers = dbContext.Customers.ToList();
|
||||
products = dbContext.Products.ToList();
|
||||
}
|
||||
int count;
|
||||
IEnumerable<Customer> customCustomersDataVirtualization;
|
||||
|
||||
IEnumerable<string> multipleValues = new string[] { "ALFKI", "ANATR" };
|
||||
string value = "ALFKI";
|
||||
|
||||
EventConsole console;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
customers = dbContext.Customers.ToList();
|
||||
products = dbContext.Products.ToList();
|
||||
}
|
||||
|
||||
void OnChange(object value, string name)
|
||||
{
|
||||
var str = value is IEnumerable<object> ? string.Join(", ", (IEnumerable<object>)value) : value;
|
||||
@@ -104,4 +149,22 @@
|
||||
|
||||
InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
void LoadDataVirtualization(LoadDataArgs args)
|
||||
{
|
||||
var query = dbContext.Customers.AsQueryable();
|
||||
|
||||
if (!string.IsNullOrEmpty(args.Filter))
|
||||
{
|
||||
query = query.Where(c => c.CustomerID.ToLower().Contains(args.Filter.ToLower()) || c.ContactName.ToLower().Contains(args.Filter.ToLower()));
|
||||
}
|
||||
|
||||
console.Log($"LoadData with virtualization: Skip:{args.Skip}, Top:{args.Top}, Filter:{args.Filter}");
|
||||
|
||||
count = query.Count();
|
||||
|
||||
customCustomersDataVirtualization = query.Skip(args.Skip.Value).Take(args.Top.Value).ToList();
|
||||
|
||||
InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,11 @@
|
||||
</Template>
|
||||
</RadzenDataList>
|
||||
</ChildContent>
|
||||
<SummaryTemplate>
|
||||
<span>
|
||||
@orders.Count() Orders
|
||||
</span>
|
||||
</SummaryTemplate>
|
||||
</RadzenFieldset>
|
||||
</div>
|
||||
<div class="col-xl-6">
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>ListBox with template</h3>
|
||||
<RadzenListBox @bind-Value=@value Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "ListBox with template")) Style="height:200px">
|
||||
Change=@(args => OnChange(args, "ListBox with template")) Style="height:200px">
|
||||
<Template>
|
||||
Company: @((context as Customer).CompanyName)
|
||||
</Template>
|
||||
@@ -27,25 +27,37 @@
|
||||
<div class="row">
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>ListBox with multiple selection</h3>
|
||||
<RadzenListBox AllowFiltering="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" @bind-Value=@multipleValues Multiple="true" Data=@customers
|
||||
TextProperty="CompanyName" ValueProperty="CustomerID" Change=@(args => OnChange(args, "ListBox with multiple selection")) Style="height:200px" />
|
||||
<RadzenListBox AllowFiltering="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" @bind-Value=@multipleValues Multiple="true" Data=@customers
|
||||
TextProperty="CompanyName" ValueProperty="CustomerID" Change=@(args => OnChange(args, "ListBox with multiple selection")) Style="height:200px" />
|
||||
</div>
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>ListBox with filtering</h3>
|
||||
<RadzenListBox AllowFiltering="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" @bind-Value=@value Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "ListBox with filtering")) Style="height:200px" />
|
||||
Change=@(args => OnChange(args, "ListBox with filtering")) Style="height:200px" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>ListBox with custom filter operator</h3>
|
||||
<RadzenListBox AllowFiltering="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" FilterOperator="StringFilterOperator.StartsWith" @bind-Value=@value
|
||||
Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" Change=@(args => OnChange(args, "ListBox with custom filter operator")) Style="height:200px" />
|
||||
Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" Change=@(args => OnChange(args, "ListBox with custom filter operator")) Style="height:200px" />
|
||||
</div>
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>ListBox with custom filtering</h3>
|
||||
<RadzenListBox AllowFiltering="true" LoadData=@OnLoadData @bind-Value=@value Data=@customCustomersData TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "ListBox with custom filtering")) Style="height:200px" />
|
||||
<RadzenListBox AllowFiltering="true" LoadData=@OnLoadData @bind-Value=@value Data=@customCustomersData TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "ListBox with custom filtering")) Style="height:200px" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>ListBox with virtualization using IQueryable</h3>
|
||||
<RadzenListBox AllowFiltering="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" FilterOperator="StringFilterOperator.StartsWith" @bind-Value=@value
|
||||
Data=@customers TextProperty="CompanyName" ValueProperty="CustomerID" Change=@(args => OnChange(args, "ListBox with custom filter operator")) Style="height:200px" />
|
||||
</div>
|
||||
<div class="col-xl-6 mb-5">
|
||||
<h3>ListBox with virtualization using LoadData event</h3>
|
||||
<RadzenListBox AllowVirtualization="true" AllowFiltering="true" Count="@count" LoadData=@LoadDataVirtualization @bind-Value=@value Data=@customCustomersDataVirtualization TextProperty="CompanyName" ValueProperty="CustomerID"
|
||||
Change=@(args => OnChange(args, "ListBox with custom filtering")) Style="height:200px" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -91,4 +103,24 @@
|
||||
|
||||
InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
IEnumerable<Customer> customCustomersDataVirtualization;
|
||||
int count;
|
||||
void LoadDataVirtualization(LoadDataArgs args)
|
||||
{
|
||||
var query = dbContext.Customers.AsQueryable();
|
||||
|
||||
if (!string.IsNullOrEmpty(args.Filter))
|
||||
{
|
||||
query = query.Where(c => c.CustomerID.ToLower().Contains(args.Filter.ToLower()) || c.ContactName.ToLower().Contains(args.Filter.ToLower()));
|
||||
}
|
||||
|
||||
console.Log($"LoadData with virtualization: Skip:{args.Skip}, Top:{args.Top}, Filter:{args.Filter}");
|
||||
|
||||
count = query.Count();
|
||||
|
||||
customCustomersDataVirtualization = query.Skip(args.Skip.Value).Take(args.Top.Value).ToList();
|
||||
|
||||
InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@
|
||||
<RadzenDataGridColumn Width="200px" TItem="Order" Property="Customer.CompanyName" Title="Customer" />
|
||||
<RadzenDataGridColumn Width="150px" TItem="Order" Property="Employee.LastName" Title="Employee">
|
||||
<Template Context="order">
|
||||
<RadzenImage Path="@order.Employee?.Photo" style="width: 32px; height: 32px; border-radius: 50%" />
|
||||
<RadzenImage Path="@order.Employee?.Photo" style="width: 40px; height: 40px; border-radius: 8px;" />
|
||||
@order.Employee?.FirstName @order.Employee?.LastName
|
||||
</Template>
|
||||
</RadzenDataGridColumn>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user