Compare commits

...

13 Commits

Author SHA1 Message Date
Vladimir Enchev
21a8ea11a3 Radzen.Blazor updated 2021-04-26 11:01:59 +03:00
Vladimir Enchev
52af7c44f1 Version updated 2021-04-26 10:55:33 +03:00
Atanas Korchev
18b9bd8e4b AutoComplete not editable in a FilterTemplate. 2021-04-26 10:03:12 +03:00
Atanas Korchev
5cdf7573ee Setting the class attribute in the CellRender event does not work. 2021-04-23 12:02:22 +03:00
Vladimir Enchev
3c415591db DataGrid cannot collapse expanded item in DataGridExpandMode.Single 2021-04-22 08:45:37 +03:00
Vladimir Enchev
667fdc0163 Avoid try/catch block during validation. Components that do not have @bind-Value are valid by default. (#103)
Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2021-04-21 16:44:40 +03:00
Vladimir Enchev
10569b1426 Radzen.Blazor updated 2021-04-21 09:21:05 +03:00
Vladimir Enchev
2f4ddeab9f Version updated 2021-04-21 09:15:28 +03:00
Vladimir Enchev
235ce4873f DropDownDataGrid View exposed 2021-04-20 09:50:16 +03:00
Atanas Korchev
b26e1e12d6 Update version 2021-04-19 20:10:30 +03:00
Atanas Korchev
ef1a2fe75e Submit the form when Action is set even if EditContext is unavailable. 2021-04-19 20:08:49 +03:00
Atanas Korchev
c7766c05d2 Setting a custom CSS class replaces the built-in one in gauge, chart, colorpicker, html editor and scheduler. 2021-04-19 17:09:55 +03:00
Atanas Korchev
85c8b636a8 Improve Scheduler monthly view event rendering to take advantage of remaining space. 2021-04-19 13:43:04 +03:00
18 changed files with 175 additions and 92 deletions

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
namespace Radzen.Blazor
{
@@ -8,5 +9,19 @@ namespace Radzen.Blazor
public DateTime End { get; set; }
public string Text { get; set; }
public object Data { get; set; }
public override bool Equals(object obj)
{
return obj is AppointmentData data &&
Start == data.Start &&
End == data.End &&
Text == data.Text &&
EqualityComparer<object>.Default.Equals(Data, data.Data);
}
public override int GetHashCode()
{
return HashCode.Combine(Start, End, Text, Data);
}
}
}

View File

@@ -8,7 +8,7 @@
<IsPackable>true</IsPackable>
<PackageId>Radzen.Blazor</PackageId>
<Product>Radzen.Blazor</Product>
<Version>3.2.4</Version>
<Version>3.2.7</Version>
<Copyright>Radzen Ltd.</Copyright>
<Authors>Radzen Ltd.</Authors>
<Description>Native Blazor UI components by Radzen Ltd.</Description>

View File

@@ -3,7 +3,7 @@
@if (Visible)
{
<div @ref="Element" class=@GetCssClass() @attributes=@Attributes style=@Style id="@GetId()">
<div @ref="Element" style=@Style @attributes=@Attributes class=@GetCssClass() id="@GetId()">
@if (Width.HasValue && Height.HasValue)
{
<svg style="width: 100%; height: 100%">

View File

@@ -8,7 +8,7 @@
<CascadingValue Value="@this">
@ChildContent
</CascadingValue>
<div @ref="Element" class="@GetCssClass()" @attributes="@Attributes" style="@Style" id="@GetId()">
<div @ref="Element" @attributes="@Attributes" class="@GetCssClass()" style="@Style" id="@GetId()">
@if (Width.HasValue && Height.HasValue)
{
<CascadingValue Value="@this">

View File

@@ -5,7 +5,7 @@
@if (Visible)
{
<div class=@GetCssClass() @ref=@Element @onclick=@Toggle @attributes=@Attributes style=@Style id=@GetId()>
<div @ref=@Element style=@Style @onclick=@Toggle @attributes=@Attributes class=@GetCssClass() id=@GetId()>
@if(Icon != null)
{
<i class="rzi">@Icon</i>

View File

@@ -1,4 +1,6 @@
@using Radzen
@using System.Collections
@using System.Collections.Generic
@using System.Linq.Dynamic.Core
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.JSInterop
@@ -39,7 +41,7 @@
else
{
foreach (var item in selectedItems)
{
{
@Template(item)@(",")
}
}
@@ -78,19 +80,19 @@
@if (AllowFiltering)
{
<div class="rz-lookup-search">
<input id="@SearchID" @ref="@search" tabindex="-1" placeholder="@SearchText"
<input id="@SearchID" @ref="@search" tabindex="-1" placeholder="@SearchText"
@onchange="@((args) => OnFilter(args))" @onkeydown="@((args) => OnFilterKeyPress(args))" value="@searchText" style="@(ShowSearch ? "" : "margin-right:0px;")" />
@if (ShowSearch)
{
<button class="rz-button rz-button-md btn-primary rz-button-icon-only" type="button" title="">
<i class="rz-button-icon-left rzi">search</i>
</button>
<button class="rz-button rz-button-md btn-primary rz-button-icon-only" type="button" title="">
<i class="rz-button-icon-left rzi">search</i>
</button>
}
</div>
}
@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"
<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">
<Columns>
<RadzenGridColumn TItem="object" Property="@TextProperty" Title="@TextProperty" Type="string">
@@ -103,7 +105,7 @@
}
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"
<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)
@@ -112,8 +114,8 @@
}
else
{
<RadzenGridColumn TItem="object" Property="@TextProperty" Title="@TextProperty" Type="string">
</RadzenGridColumn>
<RadzenGridColumn TItem="object" Property="@TextProperty" Title="@TextProperty" Type="string">
</RadzenGridColumn>
}
</Columns>
</RadzenGrid>
@@ -241,6 +243,8 @@
query = query.OrderBy(args.OrderBy);
}
_internalView = query;
count = query.Count();
pagedData = QueryableExtension.ToList(query.Skip(args.Skip.HasValue ? args.Skip.Value : 0).Take(PageSize)).Cast<object>();
@@ -251,6 +255,15 @@
}
}
IEnumerable _internalView = Enumerable.Empty<object>();
public new IEnumerable View
{
get
{
return _internalView;
}
}
protected override IEnumerable<object> Items
{
get
@@ -336,7 +349,8 @@
{
try
{
if (key == "ArrowDown" && selectedIndex < items.Count - 1) {
if (key == "ArrowDown" && selectedIndex < items.Count - 1)
{
selectedIndex++;
}

View File

@@ -179,7 +179,7 @@
}
else
{
<label style="height:35px">
<label class="rz-cell-filter-label" style="height:35px">
@if (column.Type == "string" && column.Format == "date-time")
{
<i onclick="@($"Radzen.togglePopup(this.parentNode, '{PopupID}{column.GetFilterProperty()}')")"
@@ -189,7 +189,7 @@
<span class="rz-current-filter">@column.FilterValue</span>
<i @onclick="@((args) => ClearFilter(column))" class="rzi rz-cell-filter-clear">close</i>
}
<div id="@($"{PopupID}{column.GetFilterProperty()}")" class="rz-overlaypanel "
<div id="@($"{PopupID}{column.GetFilterProperty()}")" class="rz-overlaypanel"
style="display:none;width:550px;" tabindex="0">
<div class="rz-overlaypanel-content">
@@ -946,6 +946,12 @@
{
expandedItems.Remove(itemToCollapse);
await RowCollapse.InvokeAsync(itemToCollapse);
if(object.Equals(item,itemToCollapse))
{
return;
}
}
}

View File

@@ -1,5 +1,5 @@
@typeparam TItem
<td style="@Style" class="@CssClass" @attributes="@Attributes" @onclick="@OnClick" @ondblclick="@OnDblClick" >
<td style="@Style" @attributes="@Attributes" class="@GetCssClass()" @onclick="@OnClick" @ondblclick="@OnDblClick" >
<CascadingValue Value=this>
@ChildContent
</CascadingValue>
@@ -38,4 +38,14 @@
await Grid.OnRowDblClick(Item);
}
}
string GetCssClass()
{
if (Attributes != null && Attributes.TryGetValue("class", out var @class) && !string.IsNullOrEmpty(Convert.ToString(@class)))
{
return $"{CssClass} {@class}".Trim();
}
return CssClass;
}
}

View File

@@ -6,7 +6,7 @@
@if(Visible)
{
<div @ref=Element class=@GetCssClass() @attributes=@Attributes style=@Style id=@GetId()>
<div @ref=Element style=@Style @attributes=@Attributes class=@GetCssClass() id=@GetId()>
<div class="rz-html-editor-toolbar">
<CascadingValue Value=@this>
@if (ChildContent != null)

View File

@@ -2,7 +2,7 @@
@if (Visible)
{
<i @ref="@Element" style="@Style" class="@GetCssClass()" @attributes="Attributes" id="@GetId()">@((MarkupString)Icon)</i>
<i @ref="@Element" style="@Style" @attributes="Attributes" class="@GetCssClass()" id="@GetId()">@((MarkupString)Icon)</i>
}
@code {
[Parameter]

View File

@@ -3,7 +3,7 @@
@inherits GaugeBase
@if (Visible)
{
<div @ref="Element" class=@GetCssClass() @attributes=@Attributes style=@Style id="@GetId()">
<div @ref="Element" style=@Style @attributes=@Attributes class=@GetCssClass() id=@GetId()>
@if (Width.HasValue && Height.HasValue)
{
<svg style="width: 100%; height: 100%">

View File

@@ -11,7 +11,7 @@
<CascadingValue Value="@this">
@ChildContent
</CascadingValue>
<div @ref=Element class=@GetCssClass() style=@Style @attributes=@Attributes id="@GetId()">
<div @ref=Element style=@Style @attributes=@Attributes class=@GetCssClass() id=@GetId()>
<div class="rz-scheduler-nav">
<div class="rz-scheduler-nav-prev-next">
<button class="rz-button rz-prev" @onclick=@OnPrev><RadzenIcon Icon="chevron_left" /></button>

View File

@@ -68,16 +68,7 @@ namespace Radzen.Blazor
{
if (EditContext != null)
{
bool valid = false;
try
{
valid = EditContext.Validate();
}
catch
{
}
bool valid = EditContext.Validate();
if (valid)
{
@@ -92,7 +83,13 @@ namespace Radzen.Blazor
{
await InvalidSubmit.InvokeAsync(new FormInvalidSubmitEventArgs() { Errors = EditContext.GetValidationMessages() });
}
}
else
{
if (Action != null)
{
await JSRuntime.InvokeVoidAsync($"Radzen.submit", Element);
}
}
}

View File

@@ -14,6 +14,7 @@
</div>
@{
var days = 0;
var points = new Dictionary<AppointmentData, double>();
}
<div class="rz-view-content">
@for (var date = StartDate; date < EndDate; date = date.AddDays(7))
@@ -23,9 +24,9 @@
@for (var start = date; start < date.AddDays(7); start = start.AddDays(1))
{
var end = start.AddDays(1);
var appointments = AppointmentsInSlot(start, end);
var excessCount = appointments.Count() - MaxAppointmentsInSlot;
var existingTops = ExistingTops(points, appointments.Take(MaxAppointmentsInSlot));
@foreach(var item in appointments.Take(MaxAppointmentsInSlot))
{
@@ -34,7 +35,12 @@
var left = slotIndex * slotWidth;
var length = Math.Max(1, Math.Ceiling(item.End.Subtract(date).TotalDays) - slotIndex);
var width = item.End <= date.AddDays(7) ? (length) * slotWidth : (7 - slotIndex) * slotWidth;
var top = 1.5 + 1.5 * Array.IndexOf(appointments, item);
if (!points.TryGetValue(item, out var top))
{
top = DetermineTop(existingTops);
points.Add(item, top);
existingTops.Add(top);
}
var height = 1.5;
var data = item;
@@ -103,6 +109,33 @@
await Scheduler.SelectSlot(date, date.AddDays(1));
}
double DetermineTop(HashSet<double> existingTops)
{
var top = 1.5;
while (existingTops.Contains(top))
{
top += 1.5;
}
return top;
}
HashSet<double> ExistingTops(IDictionary<AppointmentData, double> tops, IEnumerable<AppointmentData> appointments)
{
var existingTops = new HashSet<double>();
foreach (var appointment in appointments)
{
if (tops.TryGetValue(appointment, out var existingTop))
{
existingTops.Add(existingTop);
}
}
return existingTops;
}
async Task OnAppointmentClick(AppointmentData data)
{
await Scheduler.SelectAppointment(data);

View File

@@ -86,16 +86,19 @@ namespace Radzen.Blazor
throw new InvalidOperationException($"Cannot find component with Name {Component}");
}
IsValid = Validate(component);
messages.Clear(component.FieldIdentifier);
if (!IsValid)
if (component.FieldIdentifier.FieldName != null)
{
messages.Add(component.FieldIdentifier, Text);
}
IsValid = Validate(component);
EditContext?.NotifyValidationStateChanged();
messages.Clear(component.FieldIdentifier);
if (!IsValid)
{
messages.Add(component.FieldIdentifier, Text);
}
EditContext?.NotifyValidationStateChanged();
}
FieldIdentifier = component.FieldIdentifier;
}

View File

@@ -426,61 +426,65 @@ $grid-button-line-height: $grid-button-height !default;
font-size: $grid-filter-font-size;
font-weight: normal;
label {
display: flex;
flex: auto;
align-items: center;
.rz-cell-filter-label {
display: flex;
flex: auto;
align-items: center;
> .rzi {
width: $grid-filter-icon-width;
height: $grid-filter-icon-height;
font-size: $grid-filter-font-size;
margin: $grid-filter-icon-margin;
color: $grid-filter-color;
> .rzi {
width: $grid-filter-icon-width;
height: $grid-filter-icon-height;
font-size: $grid-filter-font-size;
margin: $grid-filter-icon-margin;
color: $grid-filter-color;
&.rz-cell-filter-clear {
margin-left: auto;
&.rz-cell-filter-clear {
margin-left: auto;
}
}
.rz-spinner {
border: none;
padding: 0;
height: auto;
background-color: transparent;
box-shadow: none;
line-height: 1;
flex: auto;
input {
line-height: 1;
&:focus {
outline: none;
color: $grid-filter-focus-color;
}
}
button {
display: none;
}
}
}
.rz-chkbox-box {
.rz-spinner {
border: none;
padding: 0;
height: auto;
background-color: transparent;
box-shadow: none;
line-height: 1;
flex: auto;
&.rz-state-active {
background-color: $input-background-color;
}
}
input {
> input {
width: 0;
flex: auto;
border: none;
box-shadow: none;
padding: 0;
background-color: transparent;
color: $grid-filter-color;
line-height: 1;
}
button {
display: none;
}
}
.rz-chkbox-box {
&.rz-state-active {
background-color: $input-background-color;
}
}
input {
width: 0;
flex: auto;
border: none;
box-shadow: none;
padding: 0;
background-color: transparent;
color: $grid-filter-color;
line-height: 1;
&:focus {
outline: none;
color: $grid-filter-focus-color;
&:focus {
outline: none;
color: $grid-filter-focus-color;
}
}
}
}

View File

@@ -45,14 +45,14 @@
</Template>
</RadzenDropDownDataGrid>
<h3 style="margin-top: 2rem">DropDownDataGrid with multiple selection and multiple columns</h3>
<RadzenDropDownDataGrid AllowFiltering="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" AllowClear="true" @bind-Value=@multipleValues
<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 ? customers.Select(c => c.CustomerID) : multipleValues = Enumerable.Empty<string>())" />
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))" />
@@ -72,6 +72,7 @@
</RadzenExample>
@code {
RadzenDropDownDataGrid<IEnumerable<string>> grid;
IEnumerable<Customer> customers;
IEnumerable<string> multipleValues;

View File

@@ -5,7 +5,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Radzen.Blazor" Version="3.2.4" />
<PackageReference Include="Radzen.Blazor" Version="3.2.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.0" />
<PackageReference Include="DocumentFormat.OpenXml" Version="2.11.3" />