Compare commits

...

1810 Commits

Author SHA1 Message Date
Vladimir Enchev
045ac03837 Version updated 2023-11-09 16:19:32 +02:00
Vladimir Enchev
6439845d32 bootstrap CSS added 2023-11-08 13:59:25 +02:00
Vladimir Enchev
0b0721b9d3 bootstrap CSS added 2023-11-08 11:41:56 +02:00
Vladimir Enchev
f1ba65affa More DataGrid cell render optimizations 2023-11-07 16:33:37 +02:00
GeorgeKarlinzer
e60bdbf80c Make RadzenDataGrid.ItemEquals protected (#1239)
Co-authored-by: Heorhi Kupryianau <h.kupryianau@sente.pl>
2023-11-07 09:51:40 +02:00
Vladimir Enchev
2269b500f3 Fixed RadzenDropDownDataGrid not calling LoadData when virtualized and empty initially 2023-11-06 16:34:40 +02:00
Vladimir Enchev
089f2e964c Version updated 2023-11-06 11:26:42 +02:00
Vladimir Enchev
1e477f71ef Demo service changed to our OData service which support In operator 2023-11-06 11:25:03 +02:00
Vladimir Enchev
430e8efd42 DataGrid In/NotIn filter operators should be available only for IEnumerable
Opt
2023-11-06 11:17:00 +02:00
kSacred
bddd7e5417 Fix columns visibility when DataGrid Reset, columns visibility returns to its default state (#1233) 2023-11-06 10:21:55 +02:00
Paul Ruston
10deb4c51a Add property to SplitterPane to be able to hide Splitter Bar (#1238) 2023-11-06 10:21:02 +02:00
Victor Ureta
530c3a5576 Gets the currently selected RadzenTabsItem based on the selectedIndex (#1235) 2023-11-06 10:20:44 +02:00
Vladimir Enchev
4e5cb34051 cell render improved (#1234) 2023-11-03 18:36:39 +02:00
Vladimir Enchev
e7c5eb6bee DropDown and DropDownDataGrid InputAttributes added
Close #1016 #1232
2023-11-03 09:46:39 +02:00
Vladimir Enchev
f2cb6ed1a6 DropDownDataGrid keyboard row navigation added 2023-11-02 17:29:12 +02:00
yordanov
ce745204f7 Update product descriptions 2023-11-02 15:36:12 +02:00
yordanov
8b3c9f2f72 Update example reference 2023-11-02 10:52:50 +02:00
Vladimir Enchev
2aa1c85972 missing title added 2023-11-02 10:36:36 +02:00
Vladimir Enchev
766e5db363 Version updated 2023-11-02 10:16:12 +02:00
Vladimir Enchev
c1504e104d ToggleButton component added (#1231)
* Added ToggleButton component

* IconColor support added to ToggleButton

* ToggleButtonStyle and ToggleShade added

* toggleStyle fixed

* ToggleIcon added

* code improved

* Update ToggleButton demos

* use ToggleIcon only if specified

* ToggleShade imroved

* ToggleShade set to Shade.Default

* Shade.Darker for ToggleShade

* rz-shade-default removed when toggled

* buttonStyle replaced

* classes reworked

* base classes reworked

* Update ToggleButton demos

---------

Co-authored-by: yordanov <vasil@yordanov.info>
2023-11-02 10:12:56 +02:00
DanRogers99
3705b740c9 Close Nested Modals (#1227) 2023-10-31 09:34:12 +02:00
Vladimir Enchev
85889ee338 Added ContextMenu Support on RadzenMenuItem
Fix #1224
2023-10-30 16:13:10 +02:00
Atanas Korchev
32254fbed8 Display error if the example cannot be loaded. 2023-10-30 10:35:30 +02:00
Vladimir Enchev
62fbac2d19 Version updated 2023-10-30 09:41:19 +02:00
Vladimir Enchev
6b02bb973f DialogOptions.CloseDialogOnEsc behavior fixed
Fix #1221
2023-10-30 09:40:51 +02:00
Vladimir Enchev
1ad15035de Fixed RequiredValidator validation of DropDown with multiple selection. 2023-10-27 13:27:30 +03:00
Vladimir Enchev
dd7a21010a Fixed DataGrid LoadData filter when binding to OData with virtualization
Fix #1220
2023-10-26 16:58:31 +03:00
Atanas Korchev
f69ab641f7 Add mask to the full height overlay. 2023-10-25 13:21:52 +03:00
yordanov
27308b59ea Update tags in Layout demos 2023-10-25 13:03:22 +03:00
yordanov
f1aa9fe906 Style collapse button in sidebar 2023-10-25 12:43:31 +03:00
Atanas Korchev
112b28342a Layout demo improvements. 2023-10-25 12:05:23 +03:00
Vladimir Enchev
2f9fe92b6c multiple CaptureUnmatchedValues removed 2023-10-24 11:39:17 +03:00
Vladimir Enchev
4a45c78512 InputAttributes added to various form components
Fix #1212
2023-10-24 09:17:20 +03:00
Vladimir Enchev
0c78f66c21 Row keeps highlighted state after clearing DropDownDataGrid
Fix #1215
2023-10-24 08:58:24 +03:00
Dave Bagler
be6f934e7b Added expand/collapse title and aria-label attributes to panels. (#1217) 2023-10-24 08:36:19 +03:00
Vladimir Enchev
79fa11f2c9 demo improved 2023-10-23 14:32:11 +03:00
yordanov
349966a7c3 Update premium themes 2023-10-23 10:30:33 +03:00
Vladimir Enchev
4867825367 Version updated 2023-10-23 09:33:00 +03:00
kSacred
36686afe04 New parameter UniqueFilters in DataFilter. (#1199)
* New parameter Unique filters in DataFilter. If set to true, then only unique filters can be used, that is, one property can only be used once in a filter.
The IsSelected parameter has been added to DataFilterProperty. Indicates whether the property has already been selected in the DataFilter.

* merge master
2023-10-23 09:31:21 +03:00
Vladimir Enchev
9547896074 Second DataGrid frozen columns demo removed 2023-10-23 09:21:00 +03:00
Péter Vida
4ecb737ea7 Right side frozen columns for RadzenDataGrid (#1213)
* FrozenPosition added#

* Some improvements.

* Some improvements.

* Column demo improved.

* Styling fixes.

* _grid.scss update

* Cleanup.

* Cleanup.

* Demo exapmle message.

* ident fix.

---------

Co-authored-by: Péter Vida <vida.peter@vigapeta.com>
2023-10-23 09:20:19 +03:00
Guillermo Orue Marighetti
0147f398ec Catch JSRuntime invoke exceptions (#1210) 2023-10-23 08:55:06 +03:00
Guillermo Orue Marighetti
3fd0420b52 Add EmptyTemplate to RadzenDropdown (#1211)
* Add an empty template to RadzenDropdown

* Adapt validation from RadzenDatagrid structure

* Simplified validations
2023-10-23 08:54:07 +03:00
Atanas Korchev
decba39373 Trying to upload files in RadzenHtmlEditor sometimes throws JS exceptions "target.matches is not a function". 2023-10-20 21:50:10 +03:00
Atanas Korchev
15972a9203 Prevent memory leaks related to validation. 2023-10-20 13:41:14 +03:00
Dave Bagler
94c0a52824 Expand/Collapse aria-label and title attributes. (#1204)
* Adding aria-label and title attribute parameters to field sets and accordion items.

* Changing the Label parameters to AriaLabel
2023-10-20 08:56:18 +02:00
Dave Bagler
d583f52d7e Adding aria-label and title attributes to pager buttons. (#1205)
* Adding aria-label and title attributes to pager buttons.

* Changing the Label parameters to AriaLabel.
2023-10-20 08:55:25 +02:00
Dave Bagler
9b243f90ee Adding title and aria-label attributes to step buttons. (#1208) 2023-10-20 08:54:09 +02:00
GAUSS-LVS Dev
18168e4577 More Image properties (#1207)
* Added an Image property to RadzenLink

* Replaced Version with VersionPrefix in order to specify a VersionSuffix with dotnet pack

* Revert "Replaced Version with VersionPrefix in order to specify a VersionSuffix with dotnet pack"

This reverts commit 457a7b24b8.

* More Image properties
- Added in ContextMenuItem
- Used in RadzenContextMenu
- Added and used in RadzenProfileMenuItem

* Removed Parameter attribute

---------

Co-authored-by: pb <p.baumann@gauss-lvs.de>
2023-10-19 16:20:01 +03:00
GAUSS-LVS Dev
a18e5454ce Added an Image property for RadzenLink (#1203)
* Added an Image property to RadzenLink

* Replaced Version with VersionPrefix in order to specify a VersionSuffix with dotnet pack

* Revert "Replaced Version with VersionPrefix in order to specify a VersionSuffix with dotnet pack"

This reverts commit 457a7b24b8.

---------

Co-authored-by: pb <p.baumann@gauss-lvs.de>
2023-10-19 10:59:58 +03:00
kSacred
7bf16f2891 Added property Sorts to the Query, to obtain sorting in different services, for example during export. (#1206) 2023-10-19 10:59:27 +03:00
kSacred
8491387a15 Fixed loading datagrid filter settings with quotes. When loading the filter value from json, get the string value of the element. (#1202) 2023-10-18 16:03:36 +03:00
Vladimir Enchev
123ae18a64 Version updated 2023-10-18 11:19:58 +03:00
kSacred
f3a19597fc Set the filter operator specified in the code when adding a filter in DataFilter (#1198) 2023-10-18 11:16:29 +03:00
Vladimir Enchev
6c6ccbf07c Fixed exception when removing groups from virtualized DataGrid 2023-10-18 11:12:27 +03:00
Guillermo Orue Marighetti
09af9a2576 Add placeholder to dropdown filter (#1196)
* Add placeholder to dropdown filter

* Fix summary
2023-10-16 14:15:09 +03:00
kSacred
cf813d7eb4 Added the missing classes to the DataFilter elements, by analogy with the already existing rz-datafilter-* element classes. (#1197) 2023-10-16 14:14:37 +03:00
Vladimir Enchev
f0ca523dfb Version updated 2023-10-16 09:53:19 +03:00
Atanas Korchev
6a08443853 Override Dispose in the Monaco component. 2023-10-16 09:45:43 +03:00
DanielSugdenPhoenix
030b9b0c82 Added the ability to display smaller segmented pie charts (#1191)
* Added functionality to allow the changing of the starting angle of, and the number of degrees the pie and donut charts span

* Removed nullable on StartAngle and TotalAngle, added default values and removed unneeded checks

* Updated comment about default value of the StartAngle in RadzenPieSeries

* Refactor the implementation of StartAngle and TotalAngle.

* Fix for rendering segments greater than180 degrees

* Restore the demo.

* Revert "Restore the demo."

This reverts commit 3d44fa71b0.

---------

Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2023-10-16 09:43:21 +03:00
yordanov
8a0b511649 Fix PanelMenu expand arrow position in item template 2023-10-16 09:40:01 +03:00
Marek
7853b830ae RadzenStepsItem can have own NextText and PreviousText (#1195)
Co-authored-by: Marek Mička <xmicka13@vutbr.cz>
2023-10-16 09:18:59 +03:00
Vladimir Enchev
77eb7f7821 SelectBarItem not updated on Disabled change 2023-10-13 11:49:06 +03:00
Atanas Korchev
65e71ac56f More styling fixes in the installation article. 2023-10-13 10:07:21 +03:00
Atanas Korchev
a2a1bcb77b Styling fixes in the installation article. 2023-10-13 09:55:55 +03:00
Atanas Korchev
e8fadc638c Upload documentation fixes. 2023-10-13 09:48:20 +03:00
Atanas Korchev
507a8330b7 .NET 8 documentation updates. 2023-10-13 09:48:13 +03:00
Vladimir Enchev
1dc1c99c33 Slider cannot reach the maximum when initial value is equal to Max 2023-10-12 15:53:59 +03:00
Vladimir Enchev
0cd89585e2 PageSizeOptions added to demo 2023-10-12 10:12:17 +03:00
Guillermo Orue Marighetti
c54148c291 Add placeholder to datagrid filter (#1192) 2023-10-12 08:54:34 +03:00
Vladimir Enchev
f7d7fa5031 Version updated 2023-10-10 15:19:04 +03:00
Vladimir Enchev
d959bd6c34 Tabs item Visible=false not working with TabRenderMode.Client
Fixed
2023-10-10 12:06:06 +03:00
Vladimir Enchev
92240d3e8b Check if grid is not null
Fix #1188
2023-10-10 09:28:42 +03:00
kSacred
0c634a4fa6 Added FilterOperator.Custom check to GetColumnFilter. (#1187)
With FilterOperator.Custom there is no need to generate a filterString, otherwise it throws an error.
2023-10-10 08:36:52 +03:00
Vladimir Enchev
c8e2414a70 RadzenComponents used in the demos 2023-10-09 14:50:42 +03:00
Vladimir Enchev
a6956b34db Version updated 2023-10-09 14:41:30 +03:00
Vladimir Enchev
055c2ec202 Ensure Google API is loaded when calling updateMap() 2023-10-09 14:41:20 +03:00
kSacred
1c0e03eadc Added a check for FilterOperator.Custom in ClearFilters so that the FilterOperator does not change and remains FilterOperator.Custom (#1186) 2023-10-09 14:17:16 +03:00
Vladimir Enchev
f8c44cf2d3 IconColor added to all components with Icon. Predefined theme colors added in Colors class. (#1185) 2023-10-06 11:18:29 +03:00
Vladimir Enchev
d99eeb1e1e RadzenComponents added to simplify adding of special components to layout 2023-10-05 11:16:35 +03:00
Vladimir Enchev
c42a4d9d1c Version updated 2023-10-04 10:07:40 +03:00
Nathan Stuller
2b8eb11bc3 Changing method modifiers so they can be overridden (#1178)
* Changing method modifiers so they can be overridden

* Removing the event handler for onkeydown is what really speeds it up

* Revert OnKeyDown change

---------

Co-authored-by: Nathan Stuller <stullern@hotmail.com>
2023-10-04 07:08:13 +03:00
kSacred
f4f62c6edf Fixed exception when set/load a filter with Nullable enum type in DataGrid (#1179) 2023-10-03 14:48:07 +03:00
kSacred
142f75e662 Added Filters to Query to be able to get filter data via grid.Query.Filters (#1177)
* Added Filters to Query to be able to get filter data via grid.Query.Filters

* Return FilterParameters
removed change for RadzenGrid.razor

* removed change for RadzenGrid.razor
2023-10-03 11:54:55 +03:00
Vladimir Enchev
1bc19921ff Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-09-29 09:24:51 +03:00
Vladimir Enchev
d901b795f7 Version updated 2023-09-29 09:24:48 +03:00
johnmiller86
de19e3abec Added a RadzenGoogleMap boolean parameter to zoom the map to fit marker bounds on update - JDM (#1176)
Co-authored-by: John Miller <JMiller@geo-blue.com>
2023-09-29 09:23:42 +03:00
kSacred
ee1ab72d0a Fix DataGrid not loading with settings if equal to default. (#1175) 2023-09-29 09:22:56 +03:00
Vladimir Enchev
c699dd71af Avoid Radzen is not defined error 2023-09-28 09:15:05 +03:00
Vladimir Enchev
3452bafd4b demo updated 2023-09-28 09:04:32 +03:00
kSacred
0aabac338d Added "Custom" to FilterOperator, for manually building a custom filter (#1169) 2023-09-28 08:56:21 +03:00
kSacred
a9a25a9197 Fixed pagination when set a filter via SetFilterValueAsync in FilterTemplate. (#1173) 2023-09-28 08:51:29 +03:00
Stuart Turner
aa295e9688 Add support for EditTemplate (#1171) 2023-09-27 16:41:01 +03:00
Vladimir Enchev
9cf21b1192 DataGrid multiple selection demo updated 2023-09-27 10:54:22 +03:00
Atanas Korchev
7efb6fc125 Update the scheduler demo to pass a copy of the appointment so cancelling works. 2023-09-24 11:50:38 +03:00
Atanas Korchev
a050af7985 Stacked charts sometimes render gaps. 2023-09-22 17:51:16 +03:00
Vladimir Enchev
25e3fd90c5 Version updated 2023-09-22 15:44:43 +03:00
Vladimir Enchev
e79384a3c4 DropDownBase multiple selection fixed
Fix #1163
2023-09-22 15:44:32 +03:00
Vladimir Enchev
c784af67da Version updated 2023-09-21 09:09:14 +03:00
Vladimir Enchev
74d4681f33 DropDown selected items should be cleared when retrieving from Value 2023-09-21 09:07:20 +03:00
yordanov
eaa939eda3 Update premium themes 2023-09-20 14:10:50 +03:00
Vasil Yordanov
a3b21debb0 Switch from LibSass to Dart Sass (#1161)
Replacing LibSass with Dart Sass. Resolves #1077
2023-09-20 13:59:19 +03:00
Vladimir Enchev
db9168e179 DropDownDataGrid inner DataGrid exposed as property 2023-09-20 09:10:47 +03:00
Vladimir Enchev
d68a5106a5 DataGrid RenderAsync event added
Fix #1160
2023-09-19 16:47:57 +03:00
TimChen
5244d7af1e add IsShowArrow (#1158)
* add IsShowArrow

* layout demo add IsShowArrow

* Modify ShowArrow name
2023-09-18 16:01:32 +03:00
Vladimir Enchev
0ee095617e DataGrid and DataList LoadingTemplate added 2023-09-18 15:58:09 +03:00
Vladimir Enchev
8d7d022576 FocusAsync() method added to all form components 2023-09-18 12:15:40 +03:00
Vladimir Enchev
098cf78753 AutoComplete FocusAsync() method added 2023-09-18 11:52:14 +03:00
Vladimir Enchev
4131811e32 Version updated 2023-09-18 11:21:30 +03:00
Vladimir Enchev
260cd62329 DataGrid RefreshDataAsync() method improved 2023-09-18 10:21:03 +03:00
Vladimir Enchev
b6b8ce55c6 Fixed DataFilter OData filter when selecting all elements of IEnumerable
Fix #1156
2023-09-18 09:11:46 +03:00
Vladimir Enchev
1d3e5a60e2 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-09-18 08:59:01 +03:00
Vladimir Enchev
b2397cfd54 Virtualized DataGrid sorting and cache improved 2023-09-18 08:58:51 +03:00
johanpolak
15ef3bdadb Allow Template in RadioButtonListItem (#1155)
Co-authored-by: Johan Polak | Camas IT bv <JohanPolak@camasit.nl>
2023-09-18 08:47:40 +03:00
Vladimir Enchev
c353e713cc Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-09-18 08:45:54 +03:00
Atanas Korchev
1eaaad320f Allow specific generic definitions. 2023-09-14 18:48:50 +03:00
Atanas Korchev
e0c0071d8b Enable RadzenComponentActivator only for .NET 5 or greater. 2023-09-14 18:35:56 +03:00
Atanas Korchev
0a7c274f33 Add component activator that allows replacing component intsances with custom ones. 2023-09-14 18:32:34 +03:00
yordanov
d4621f8b8a Update premium themes 2023-09-14 11:37:57 +03:00
yordanov
5b0c1fd16e Fix alignment in DataGrid column draggable hint 2023-09-14 11:31:58 +03:00
yordanov
6b5847f149 Update premium themes 2023-09-14 09:33:31 +03:00
yordanov
b227d89a01 Fix DataGrid group header spacing in compact mode 2023-09-14 09:24:48 +03:00
Vladimir Enchev
a4191556ea DataGrid RefreshDataAsync() method added 2023-09-14 05:24:12 +03:00
yordanov
a7d90c0b39 Fix Wrap option in RadzenStack demo 2023-09-13 19:37:22 +03:00
yordanov
6edef4ec97 Update premium themes 2023-09-13 19:00:10 +03:00
yordanov
17f7ae7daa Add today styles to DatePicker 2023-09-13 18:46:24 +03:00
Vladimir Enchev
03d33f2074 Version updated 2023-09-13 16:02:11 +03:00
Vladimir Enchev
8787d8ad43 DataGrid LoadSettings event added 2023-09-13 16:01:52 +03:00
Vladimir Enchev
69f98aa756 demo fixed 2023-09-13 15:20:24 +03:00
Vladimir Enchev
9620faafe1 version updated 2023-09-13 11:48:33 +03:00
Vladimir Enchev
2ba0b164fc DataGrid internal clear of the LoadData args cache imlemented 2023-09-13 11:48:11 +03:00
Vladimir Enchev
77b9b2e8ce DataGrid Reload() overload simplified 2023-09-13 10:50:42 +03:00
Vladimir Enchev
58be436aaa DataGrid LoadData args cache simplified 2023-09-13 10:21:32 +03:00
Vladimir Enchev
5995eb8b8e DataGrid should not call LoadData twice on first render when virtualized 2023-09-13 10:13:36 +03:00
Vladimir Enchev
0e4f942b15 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-09-12 17:16:56 +03:00
Vladimir Enchev
c14f773ed4 DataGrid Reload() method overload added with ability to clear the cache 2023-09-12 17:16:46 +03:00
TimChen
3ef08a53d1 add icon sidebar demo (#1153) 2023-09-12 17:06:09 +03:00
Vladimir Enchev
67d32c5a96 Version updated 2023-09-12 10:20:48 +03:00
Vladimir Enchev
e351793043 DataGrid LoadData event calls optimized when virtualization is on 2023-09-12 10:14:50 +03:00
Vladimir Enchev
f0a987e7a2 Fixed UTC dates to work with fi-FI and dk-DK cultures 2023-09-12 08:42:47 +03:00
AlittaSakraf
c0354961f7 Update RadzenNumeric.razor.cs (#1149)
There is a bug: Uncaught ReferenceError: False is not defined
at HTMLInputElement.onblur
2023-09-11 19:24:32 +03:00
TimChen
4c8c8dcdab panel menu item add display style (#1147)
* panel menu item add display style

* Remove unnecessary DisplayStyle attributes
2023-09-11 19:23:43 +03:00
Vladimir Enchev
cae80096e1 DatePicker day render refactored 2023-09-08 09:55:12 +03:00
Vladimir Enchev
45d4fcc0bf DataFilter will clear FilterValue and disable input if operator is set to empty/null 2023-09-08 09:30:10 +03:00
Marek
da5380a472 Added columnPickerTitle (#1144)
Co-authored-by: Marek Mička <xmicka13@vutbr.cz>
2023-09-07 17:53:17 +03:00
Vladimir Enchev
b27544663e Version updated 2023-09-07 11:06:19 +03:00
Vladimir Enchev
75c35aa9e5 Popup should not be destroyed on dispose 2023-09-07 11:05:37 +03:00
Vladimir Enchev
ad0fd8d5c8 Fixed DropDown ClearSearchAfterSelection behavior
Fix #1143
2023-09-07 09:07:48 +03:00
Vladimir Enchev
c60cd1fabb DataGrid settings save/load of arrays fixed
Fixed #1139
2023-09-06 16:36:40 +03:00
kSacred
7cfb6258d5 Fix calling DataGrid Reload when loading settings with filter and page greater than 1. (#1141) 2023-09-06 10:18:43 +03:00
Vladimir Enchev
ff1bc2577f Version updated 2023-09-04 16:20:00 +03:00
Vladimir Enchev
07ab3621b3 Popup toggle logic fixed 2023-09-04 16:17:54 +03:00
Vladimir Enchev
0af3f3fcce Fixed DatePicker closed immediately after selecting a month or year from the drop-down lists when using PopupRenderMode.OnDemand
Fix #1138
2023-09-04 13:33:11 +03:00
Vladimir Enchev
cb8a70744d Cannot toggle visibility of Steps item 2023-09-04 11:51:16 +03:00
Vladimir Enchev
c6a8d3e251 ExpandMode removed from DataGrid self-referenced hierarchy demo 2023-09-04 10:11:17 +03:00
TimChen
d871292d39 Add TabsModify Demo (#1133)
* Add TabsModify

* Fix the tabs modify example
2023-09-04 09:32:20 +03:00
Vladimir Enchev
255febcd70 Selected item not retrieved properly when bound using LoadData with custom filtering 2023-09-01 14:46:16 +03:00
Vladimir Enchev
c7d8f77fb4 Version updated 2023-09-01 10:16:21 +03:00
Vladimir Enchev
248de4ef0f AddRadzenComponents() method used across demos 2023-09-01 10:16:13 +03:00
Vladimir Enchev
56ae5d2c33 Tooltip close logic fixed to not show tooltips with delay if Close() is invoked 2023-09-01 10:11:06 +03:00
Vladimir Enchev
2cc575d74b Avoid acessing DataGrid PageSize directly when loading settings 2023-08-29 17:00:28 +03:00
yordanov
b0b68d16a4 Update premium themes 2023-08-29 16:29:48 +03:00
Vladimir Enchev
45fd510e15 AddRadzenComponents() extension method added 2023-08-29 11:16:34 +03:00
Vladimir Enchev
0376a58374 Version updated 2023-08-29 09:45:16 +03:00
Vladimir Enchev
b1d1d2c7f8 DataGrid will not call LoadData in simple filter with virtualization enabled 2023-08-29 09:45:00 +03:00
Vladimir Enchev
6de14c91e4 Clear selected rows button added 2023-08-28 16:23:40 +03:00
Vladimir Enchev
a04cbeba78 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-08-28 10:54:11 +03:00
Vladimir Enchev
82610e281d ContextMenu doesn't work for RadzenPanelMenuItem
Fix #1130
2023-08-28 10:54:02 +03:00
stlufred
e9b3213d8b Make icon used by data grid filter customizable (#1129) 2023-08-28 10:32:13 +03:00
mvoxland-MoorheadSchools
313ee50bf2 Indication for isNull/isNotNull in simple datagrid filter (#1127)
Added an Indication for when a datagrid (in simple mode)'s filter operator is set to either "is null" or "is not null". Before there was no way to see that any filters were applied until the popup was opened.
2023-08-28 10:26:22 +03:00
Vladimir Enchev
fca72e3fad Version updated 2023-08-24 10:12:54 +03:00
yordanov
97657da95d Update premium themes 2023-08-23 18:06:23 +03:00
Atanas Korchev
f32240ba65 RadzenHtmlEditor fires its Change event before updating the argument specified with @bind-Value. 2023-08-23 16:28:01 +03:00
yordanov
1d8d20a7d7 Keep base, light, and dark styles in a single base-styles-map for consistency across themes 2023-08-22 11:05:51 +03:00
Cosmatevs
5fba2685b1 Timeline: add missing light and dark styles (#1122) 2023-08-22 10:44:26 +03:00
AlittaSakraf
2c39551560 Update RadzenDataGridFilterMenu.razor (#1123)
If you use "FilterMode.SimpleWithMenu" and Grid Settings together, then the "Clear" button in the fitler menu, do not work, because there was a SaveSetting() calling in the ClearFilter function. (Always loaded the "last" settings, after the Clear button has pushed.
2023-08-22 09:31:58 +03:00
Vladimir Enchev
265ca8b433 themes updated 2023-08-21 15:36:25 +03:00
Vladimir Enchev
8c4b33ec17 Version updated 2023-08-21 15:28:40 +03:00
yordanov
937bf6f57a ShowValue should display ProgressBar label in Material and Fluent themes. Resolves #1119 2023-08-21 14:46:51 +03:00
Vladimir Enchev
e2f142ed28 DropDownDataGrid pager will not wrap if not needed 2023-08-21 13:44:08 +03:00
yordanov
9a835690aa Update Material Dark theme 2023-08-21 11:12:38 +03:00
Atanas Korchev
5f4ec1c446 Add the Appointment model in the demo. 2023-08-21 11:05:19 +03:00
Atanas Korchev
7b11516520 Update the MoreSelect documentation. 2023-08-21 11:05:19 +03:00
Atanas Korchev
4a6543b0c6 Add related files to the export demo. 2023-08-21 11:05:19 +03:00
Atanas Korchev
fa197c1b7f Dispose the editor and support csharp language syntax highlighting. 2023-08-21 11:05:19 +03:00
Cosmatevs
ab4ab7e63b Fix wobbly tab selection in Material theme – resolves #1116
To do: update Material Dark theme
2023-08-21 10:39:07 +03:00
Vladimir Enchev
b88a8e605a Test deleted since the DatePicker will treat now default(DateTime) as null 2023-08-21 10:08:53 +03:00
Vladimir Enchev
519d8fc64a DatePicker will treat default(DateTime) as null 2023-08-18 10:44:59 +03:00
Vladimir Enchev
8032fde262 demo updated 2023-08-18 09:06:23 +03:00
Vladimir Enchev
02b4b0b9b6 Version updated 2023-08-18 08:47:06 +03:00
Vladimir Enchev
933c820f20 RadzenNumeric defaults to min value on tab 2023-08-18 08:46:31 +03:00
Thorsten Liborius
8476fdb77f OpenAsync method signature changed to virtual to support unit testing (#1117)
Co-authored-by: Thorsten Liborius <thorsten.liborius@shkb.ch>
2023-08-18 08:05:31 +03:00
Vladimir Enchev
ae1f280062 DropDown, DropDownDataGrid and ListBox SearchText two-way binding support added 2023-08-17 16:38:48 +03:00
Vladimir Enchev
d58dd28051 AdditionalSourceCodePages set 2023-08-17 11:41:40 +03:00
Vladimir Enchev
a212382da6 DataGridFooterTotals demo improved 2023-08-17 11:33:34 +03:00
Vladimir Enchev
b1819ff755 Enabled warnings to be treated as errors
[BREAKING] DropDownDataGrid SearchText renamed to SearchTextPlaceholder
2023-08-16 12:20:55 +03:00
Cosmatevs
2317305f0e Switch: make clicking a label change a value of the corresponding switch (by Name property; as in the case of ordinary checkboxes) (#1115) 2023-08-15 16:28:26 +03:00
Vladimir Enchev
da5f7e27c4 Allow DataGrid settings to be loaded in OnInitialized() 2023-08-15 11:19:19 +03:00
Vladimir Enchev
4c4dd71195 Version updated 2023-08-11 08:48:22 +03:00
Vladimir Enchev
61c3d3c34a Virtualized DropDownDataGrid refresh after filter will not work properly in some cases 2023-08-11 08:45:10 +03:00
Vladimir Enchev
59d4e30469 Version updated 2023-08-11 07:59:19 +03:00
Cosmatevs
e0dd34df2b DataGrid: prevent sorting from being triggerred while resizing a reorderable column (#1109)
* DataGrid: give unique IDs to column resizers and column reorderers to avoid using wrong elements in js functions

* Typo fix
2023-08-11 07:58:47 +03:00
Cosmatevs
41366d9376 DataGrid: make headers and footers of frozen columns frozen just like cells are (fix to commit 2795413) (#1108) 2023-08-11 07:56:41 +03:00
Vladimir Enchev
1779b8d67e Version updated 2023-08-10 16:35:49 +03:00
Vladimir Enchev
b673cbe411 Load settings by Property/UniqueID improved 2023-08-10 16:35:41 +03:00
Vladimir Enchev
1a595c5043 DataGrid will no longer auto-generate column UniqueID and will save settings for columns only if Property or UniqueID is set 2023-08-10 16:30:52 +03:00
Vladimir Enchev
bce5ae88ee Version updated 2023-08-10 14:57:05 +03:00
Vladimir Enchev
b81d15cdef DataGrid will use column index instead GUID for UniqueID 2023-08-10 14:56:27 +03:00
Vladimir Enchev
ec6747ac09 Too early close of filter popup can cause improper filter 2023-08-10 13:51:45 +03:00
Vladimir Enchev
5cd35bbfb5 DatePicker should not allow dates outside of Min/Max on Ok button
Fix #1107
2023-08-10 11:10:27 +03:00
Vladimir Enchev
1b07509e18 Theme page simplified 2023-08-10 10:54:43 +03:00
Vladimir Enchev
35211b94db DataGrid CloseFilter() logic fixed with OnDemand FilterPopupRenderMode 2023-08-10 10:32:10 +03:00
yordanov
0e9338a0e4 Add Themes demo page 2023-08-10 09:07:40 +03:00
Vladimir Enchev
95b099d62c Added DataGrid self-reference hierarchy expanded class for indent
Fix #1104
2023-08-09 08:05:47 +03:00
yordanov
b295963d8d Update demos descriptions 2023-08-08 12:11:50 +03:00
Vladimir Enchev
884ca797d8 Version updated 2023-08-08 10:43:52 +03:00
Vasil Yordanov
3664b4acec Timeline component (#1103)
* Add RadzenTimeline component, styles and demos

---------

Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2023-08-08 10:37:39 +03:00
Vladimir Enchev
95f33310bf Fixed RadzenTabs - selected tab styling incorrect with hidden tabs
Fix #1003
2023-08-07 11:41:17 +03:00
Vladimir Enchev
a1500051b9 Cascading data loaded on-demand 2023-08-07 11:24:51 +03:00
Vladimir Enchev
be1a6cc985 Added Save/Load settings support for DataGrid columns without Property
Fix #1058
2023-08-07 11:17:53 +03:00
Vladimir Enchev
32525a0204 RadzenNumeric inconsistently resets Value when out of Max/Min
Fixed #1098
2023-08-07 10:58:39 +03:00
Vladimir Enchev
8b64c8afd3 Fixed popup close logic
Fix #1086
2023-08-07 10:44:50 +03:00
stlufred
2795413fc1 Fix customizing style of in HeaderCellRender and FooterCellRender (#1102) 2023-08-07 10:11:48 +03:00
Vladimir Enchev
8db9fc3f17 other filtering demos improved to respect auto-filter setting in template filters 2023-08-01 11:08:49 +03:00
Vladimir Enchev
d7c2fb8a02 OrderID will respect auto-filter setting 2023-08-01 11:03:14 +03:00
Vladimir Enchev
6c9d09f6c3 Date only filtering demo added 2023-08-01 09:17:57 +03:00
Vladimir Enchev
1482fe3e1b RadzenNumeric added to DataGrid column filter template demo 2023-08-01 08:51:07 +03:00
Vladimir Enchev
c2f0422a68 Fixed DataGrid inner filter popups not closed properly 2023-07-31 17:17:04 +03:00
Vladimir Enchev
4b3a7af308 Version updated 2023-07-31 08:04:58 +03:00
Vladimir Enchev
7b2cd6e4b0 DataList Reload() fixed
Fix #1095
2023-07-31 08:04:28 +03:00
Vladimir Enchev
60dbe28dca Popup demo improved 2023-07-28 10:14:41 +03:00
Vladimir Enchev
3dde8c5905 Fixed DropDown, DropDownDataGrid and ListBox filtering input logic 2023-07-28 09:48:09 +03:00
Vladimir Enchev
9207ef357f Version updated 2023-07-27 10:58:49 +03:00
Vladimir Enchev
ce7ea27255 DataList Reload() fixed in case of virtualization 2023-07-27 10:54:36 +03:00
Vladimir Enchev
c3eb701c56 Search added to custom popup demo 2023-07-27 10:54:19 +03:00
Vladimir Enchev
180c1fe185 Popup component example added 2023-07-27 09:46:40 +03:00
Rogier Reedijk
9b3138102d Add ParseInput to DatePicker (#1090)
* Add ParseInput to DatePicker

* Add demo for DatePicker.ParseInput

---------

Co-authored-by: Rogier Reedijk <reedijkr@wigo4it.nl>
2023-07-26 18:02:51 +03:00
Thomas Knudsen
e43412c02f Use key directive for notifications (#1092)
Co-authored-by: Thomas H. Knudsen <thk@yco.dk>
2023-07-26 18:01:45 +03:00
Cosmatevs
a223fad28c RadzenDataGridColumn: handle non-px widths of frozen columns (#1076)
* DataGridColumn: handle non-px widths of frozen columns, simplify css style conditions

* DataGridColumn: simplify calculation of frozen column style
2023-07-25 20:32:30 +03:00
Vladimir Enchev
9ade31a813 Version updated 2023-07-25 10:08:37 +03:00
Vladimir Enchev
fd91024b8d DataFilter PropertiesCollection added similar to DataGrid ColumnsCollection 2023-07-25 09:30:36 +03:00
Vladimir Enchev
0d9526ed72 LoadStateAsync called multiple times in the demo
Fix #1083
2023-07-25 09:06:07 +03:00
Vladimir Enchev
d4e51a1b51 OData filtering of DateTime fixes for various cultures 2023-07-25 08:49:42 +03:00
nitrouscookies
ded26df5d0 DataFilter - Added AllowColumnFiltering (#1079)
Co-authored-by: dstillwell <dstillwell@moorheadschools.org>
2023-07-25 08:43:28 +03:00
kSacred
a3ba44771f Added "Show button" parameter to radzendatapicker. (#1075)
Allows to hide the button in the field and open popup datepicker when you click on the field with "input is allowed"

Co-authored-by: Sacred <s>
2023-07-25 08:43:07 +03:00
Cosmatevs
83f4ac980e DataGridColumnHeaderCell: make the resizing element fill the whole cell while resizing to prevent an accidental click on the cell and therefore an unexpected resort (#1082) 2023-07-25 08:40:49 +03:00
Ben Croughs
5da102c058 close event on x (#1085)
Co-authored-by: BC3 <bc3@telenet.be>
2023-07-25 08:39:20 +03:00
kSacred
27608327af Added SetFilterValueAsync method set column filter value and reload grid. Allows you to use the FilterTemplate without initializing an additional property. (#1087)
Co-authored-by: Sacred <s>
2023-07-25 08:38:56 +03:00
Vladimir Enchev
fcbbd53dd8 Version updated 2023-07-19 10:54:53 +03:00
Vladimir Enchev
76aaab319c Revert "switching from libsass to dartsass (#1068)"
This reverts commit f77ebe3af7.
2023-07-19 10:54:10 +03:00
yordanov
6ea6a46c15 Update premium themes 2023-07-19 09:47:34 +03:00
Victor Ureta
c0f3e62a10 Add MarkupString in RadzenFormField (#1071) 2023-07-18 19:56:41 +03:00
Vladimir Enchev
5f71660c7a version updated 2023-07-18 10:14:26 +03:00
Vladimir Enchev
e6b15de5a4 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-07-18 10:11:09 +03:00
Vladimir Enchev
bf74569906 themes updated 2023-07-18 10:11:06 +03:00
Atanas Korchev
b70f1f84be Change the implementation of NoTools and rename it to ShowToolbar. 2023-07-18 10:08:24 +03:00
Dave Bagler
a2209e73fc Htmledit on input (#1070)
* adding a paramter for allow for no-tool HTMLEditors.

* Adding input event to the HTMLEditor
2023-07-18 09:38:08 +03:00
Dave Bagler
f77ebe3af7 switching from libsass to dartsass (#1068) 2023-07-18 09:37:31 +03:00
Cosmatevs
8c4370780d Progress bar circular component + progress bar extension (#1044)
Add RadzenProgressBarCircular component
2023-07-17 19:29:58 +03:00
Cosmatevs
e4b352f1ce DataGridColumn: Add ShowUpDownForNumericFilter function; rename the class file for hierarchy (#1065)
Demos/GataGridFilterApi: Use override of ShowUpDownForNumericFilter
2023-07-17 19:13:03 +03:00
Jimmy Ho
a679e33d54 fix AddButton not enable (#1066)
click AddButton, then click Edit/Delete button on the other row, how ever save/cancel, the AddButton still disable
2023-07-17 19:11:15 +03:00
Vladimir Enchev
e477ce3d9a Version updated 2023-07-14 12:17:17 +03:00
kSacred
f15d7ac445 Fix: enum dropdown beyond the edge of the column (#1061) 2023-07-14 09:42:47 +03:00
kSacred
d36af364bf Added custom text for null enum value in filter. Default value "No value" instead of "<null>". (#1062)
Co-authored-by: Sacred <s>
2023-07-14 09:41:41 +03:00
Vladimir Enchev
b0ebcf86e6 DropDownBase filtering enum by description support added 2023-07-14 09:40:49 +03:00
Atanas Korchev
247ec75c9e Scheduler does not display certain events in day and week view. 2023-07-13 20:08:11 +03:00
Atanas Korchev
3b43bf3579 Cannot edit demos that use other pages. 2023-07-13 14:10:10 +03:00
atafra92
2be6d5cdef add isLoading property to dropdown datagrid component (#1054)
* add isLoading property to dropdown datagrid component

* Revert "add isLoading property to dropdown datagrid component"

This reverts commit 7299939f7c.

* added isLoading property to dropdown datagrid component
2023-07-13 09:47:35 +03:00
kSacred
fef7526af4 Fix search with quotes in RadzenDataGrid filter (#1051) 2023-07-12 14:57:46 +03:00
yordanov
88ee26ecf8 Fix typo. Resolves #1053 2023-07-12 09:47:57 +03:00
Atanas Korchev
947c602cb0 A visual glitch appears when using StrokeWidth in RadzenPieSeries. 2023-07-07 09:35:51 +03:00
Ben Croughs
fd0cf4e4e3 do not hide 2 notification when clicking close (#1047)
Co-authored-by: BC3 <bc3@telenet.be>
2023-07-06 21:08:14 +03:00
foerdi
0d11bffa82 fixed PropertyAccess.GetProperty for complex property expressions (#1048)
RadzenDataGrid could not be filtered or sorted by colums with advanced
proprty expressions like function calls

Co-authored-by: Ferdinand Lange <lange@iftc.uni-hannover.de>
2023-07-06 08:45:05 +03:00
Vladimir Enchev
c9a9c48de3 Version updated 2023-07-03 19:47:06 +03:00
Vladimir Enchev
fbbcb58e3f DataGrid INotifyCollectionChanged support added 2023-06-30 11:40:06 +03:00
yordanov
ed9dbea34a Add Quickstart image 2023-06-28 11:21:37 +03:00
yordanov
9ccca42011 Add a Quickstart video to Get started page 2023-06-28 11:19:47 +03:00
dependabot[bot]
d7bc92e465 Bump System.Linq.Dynamic.Core from 1.2.22 to 1.3.0 in /Radzen.Blazor (#1041)
Bumps [System.Linq.Dynamic.Core](https://github.com/zzzprojects/System.Linq.Dynamic.Core) from 1.2.22 to 1.3.0.
- [Release notes](https://github.com/zzzprojects/System.Linq.Dynamic.Core/releases)
- [Changelog](https://github.com/zzzprojects/System.Linq.Dynamic.Core/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zzzprojects/System.Linq.Dynamic.Core/compare/v1.2.22...v1.3.0)

---
updated-dependencies:
- dependency-name: System.Linq.Dynamic.Core
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-28 10:48:38 +03:00
yordanov
5d29ebfde2 Update see in action link 2023-06-28 10:16:12 +03:00
Vladimir Enchev
efa14f2dcd DatePicker FormattedValue do not respect specified Culture 2023-06-26 14:47:07 +03:00
Vladimir Enchev
2e07802a05 Version updated 2023-06-26 11:13:05 +03:00
Vladimir Enchev
34a83a46d9 DataGrid column picker not closed properly when FilterPopupRenderMode=OnDemand
Fix #1039
2023-06-26 10:11:48 +03:00
Atanas Korchev
9db5c68a64 Fix wrong tag name in HelpPrerequirements.razor. 2023-06-26 09:18:58 +03:00
Atanas Korchev
5dac84c511 Add FocusAsync method to RadzenHtmlEditor. 2023-06-26 09:18:58 +03:00
yordanov
ce834c9b18 Update DataGrid footer totals and template demos 2023-06-23 18:20:07 +03:00
Atanas Korchev
0af5f626bc Make the anchors in RadzenText scroll the page. 2023-06-22 12:47:13 +03:00
Atanas Korchev
0d68186dfe The remember me text is missing when FormFieldVariant is set of RadzenLogin. 2023-06-22 10:15:29 +03:00
Vladimir Enchev
65e226d02d Version updated 2023-06-20 14:37:16 +03:00
Vladimir Enchev
15d0654cd7 FocusTrap not working on Dialog when last focusable component is RadzenDatePicker
Fix #1024
2023-06-20 14:36:43 +03:00
Vladimir Enchev
f7c36efab8 Not possible to close multiple nested dialogs using the Escape key
Fix #1026
2023-06-20 10:58:28 +03:00
Vladimir Enchev
09e372f37b dialogResizer disposed 2023-06-20 10:37:23 +03:00
Vladimir Enchev
a020e06c3d Dialog height/width should not be changed on drag but only on resize
Close #1032
2023-06-20 10:33:31 +03:00
Atanas Korchev
650f2caf42 Improve RadzenScheduler rendering algorithm to handle more cases. 2023-06-19 17:32:32 +03:00
Vladimir Enchev
bfaa5a9878 Fixed DataGrid doesn't show empty message with empty Data
Fix #1034
2023-06-19 09:55:49 +03:00
Vladimir Enchev
7d22fc727b PagedDataBoundComponent should not raise PageSizeChanged on firs render
Fix #1030
2023-06-19 09:50:27 +03:00
ChristianA1992
e78db0d549 Method to replace only the first occurence of a string (#1028)
There is a bug, if you column is called something like Car.ApiCar.Brand.
When the GetPropertyType method is run, it replaces all occurences of Car. which makes it so the column can't be filtered.
2023-06-16 15:13:45 +03:00
Vladimir Enchev
4a610d9868 Example fixed 2023-06-15 18:03:17 +03:00
yordanov
2c08ab1e52 Update premium themes 2023-06-15 17:24:38 +03:00
Vladimir Enchev
70c26493c4 text fixed 2023-06-15 17:18:45 +03:00
Vladimir Enchev
e5f45550d4 Version updated 2023-06-15 17:07:15 +03:00
Vladimir Enchev
80c196d863 DataFilter LoadData demo added 2023-06-15 17:06:29 +03:00
Vladimir Enchev
516ee4b762 DatePicker doesn't render correctly with PopupRenderMode.OnDemand
Fix #1025
2023-06-15 11:32:02 +03:00
Vladimir Enchev
7371e15ebb Numeric FormattedValue demo fixed
Fix #1022
2023-06-14 16:01:28 +03:00
Vladimir Enchev
b6f6f79c00 DateFilter in DataGrid can not be cleared by using backspace/delete
Fix #1023
2023-06-14 15:50:26 +03:00
Vladimir Enchev
d8dd38dcdd DataGrid column picker filtering made case-insensitive 2023-06-14 11:44:38 +03:00
yordanov
1384c2b477 Update new and updated demo badges 2023-06-14 10:43:35 +03:00
Vladimir Enchev
2006a44fdd DataGrid LoadData executed twice on filter
Fix #1020
2023-06-14 09:53:49 +03:00
yordanov
f7c04c9f7e Card Variant property added 2023-06-14 08:57:45 +03:00
yordanov
1dbb36bd77 Fix accordion border radius. Resolves #1018 2023-06-14 08:45:03 +03:00
yordanov
54cabebbfa Fix FormField label line-height. Resolves #995 2023-06-13 15:26:54 +03:00
Vladimir Enchev
f31c2296dd Version updated 2023-06-13 11:35:11 +03:00
Vladimir Enchev
6f66fd9597 DataGrid column FilterValueTemplate and SecondFilterValueTemplate properties added
Easily customize default DataGrid advanced filter with custom components for FilterValue/SecondFIlterValue. More generic than #1015. Close #1015.
2023-06-13 11:32:54 +03:00
Vladimir Enchev
8c33bd828a example fixed 2023-06-13 10:06:46 +03:00
Vladimir Enchev
068352de91 Numeric should not default to min when value type is nullable 2023-06-13 09:15:49 +03:00
Vladimir Enchev
f5c166906b Fixed DataGrid filtering with In/NotIn in combination with other filter 2023-06-13 08:38:36 +03:00
Atanas Korchev
514772f5c2 Fix typo. 2023-06-12 12:39:53 +03:00
Vladimir Enchev
2e0c2aa8bc DataGrid multiple sorting order saved/restored in proper order from Settings
Fix #1010
2023-06-09 12:05:43 +03:00
Vladimir Enchev
bfd641f1b1 DataGrid ColumnsPickerAllowFiltering property added 2023-06-08 08:00:29 +03:00
Vladimir Enchev
1c45af855d Version updated 2023-06-07 11:27:17 +03:00
Vasil Yordanov
5d7cf75bed New Material 3, Material 3 Dark and Fluent UI Dark premium themes (#1009)
* Update Stack, Row, and Column demos
* Reorder themes in theme picker
* Update premium themes
---------
Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2023-06-07 11:26:29 +03:00
Vladimir Enchev
04ee23b7b5 DataGrid EmptyTemplate not shown with virtualization using LoadData
Fix #1008
2023-06-06 11:14:27 +03:00
yordanov
99c3c71be8 RadzenBody should have padding 2023-06-06 10:24:12 +03:00
yordanov
0c2fb54d14 Fix css selectors 2023-06-06 09:31:33 +03:00
yordanov
eaf875dfd5 Fix RadzenFormField label position with RadzenRadioButtonList or RadzenCheckBoxList inside 2023-06-06 09:14:02 +03:00
Victor Ureta
29e61087ac Add "Create" Button Functionality to RadzenDropDownDataGrid Component (#1007)
* Add

* Add

* Add

---------

Co-authored-by: Bikotoru Ryzen <you@example.com>
2023-06-06 09:02:44 +03:00
Vladimir Enchev
ef989e7909 Version updated 2023-06-05 16:21:59 +03:00
Vladimir Enchev
ab1fd464cf Fixed DataFilter remove filter 2023-06-05 16:21:13 +03:00
Vladimir Enchev
4a042b73b8 In/NotIn operators removed from DataFilter 2023-06-05 16:03:39 +03:00
Vladimir Enchev
b416a7de09 Use CultureInfo.InvariantCulture when parsing DateTime for OData 2023-06-05 15:29:52 +03:00
Vladimir Enchev
ebec631cde DataGrid Sorts collection exposed 2023-06-05 10:35:03 +03:00
Vladimir Enchev
cd6a751a68 DataGrid ColumnsPickerMaxSelectedLabels property added
Close #https://github.com/radzenhq/radzen-blazor/pull/1001
2023-06-02 09:40:37 +03:00
myfayyad
f90692b526 fix nested columns with grouping in datagrid (#998)
* Update RadzenDataGrid.razor to only show the collapse cell for first row not for nested columns rows header

* Update RadzenDataGridGroupRow.razor to have group record with colspan of visible columns and last leaf columns if nested

* Update RadzenDataGrid.razor remove unnecessary testing classes

* Update RadzenDataGridRow.razor fix nested columns grouping with allow composite cell

* Update RadzenDataGridHeaderCell.razor to allow grouping to composite cells

* fix count columns for colspan calcualtion if we have visible coulmns plus template columns

* modification to allow grouping "AllowCompositeDataCells, HideGroupedColumn" with composite columns when hidegroupedcolumn equal true and allowcompositecolumn equal true

* return example as it to not hide columns grouped by
2023-06-02 09:28:40 +03:00
Vladimir Enchev
b4ff72d424 demo fixed
Fix #999
2023-06-01 15:01:23 +03:00
yordanov
61de002e0e Update premium themes 2023-05-31 19:03:33 +03:00
yordanov
6c063c856c Update badge styles on demos homepage 2023-05-31 11:08:57 +03:00
yordanov
a075a0b29b Update text colors in Colors demo page 2023-05-31 11:04:35 +03:00
yordanov
0e85e70470 Fix rz-body padding 2023-05-31 10:45:57 +03:00
Vladimir Enchev
0e84d1dad1 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-05-30 15:01:04 +03:00
Vladimir Enchev
092b3bf9c2 Version updated 2023-05-30 15:00:49 +03:00
OndrejUzovic
87cf688e27 ColorPicker opens and immediately closes #990 (#992) 2023-05-30 14:58:47 +03:00
yordanov
892cab3adf Add --rz-text-selection CSS variables 2023-05-30 10:13:26 +03:00
stlufred
c547f50dc8 Fixed Chart Click method (#991)
* Fixed chart Click method

- Was not using x and y parameters
- Use the same maximum distance as the tooltip (so that click and tooltip returns the same thing)
- Fixed xDelta and yDelta that were not considering MarginLeft and MarginTop

* Add ClickTolerance and TooltipTolerance.

---------

Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2023-05-30 09:51:49 +03:00
yordanov
952bcecb12 Add text color to AutoComplete input 2023-05-29 17:13:11 +03:00
yordanov
1da97c3cd6 Add variable for text color in RadzenSidebar --rz-sidebar-color 2023-05-29 16:55:29 +03:00
blake-fm
b9abc13364 Loop parameters once during SetParametersAsync (#989)
Down from 6.
2023-05-29 12:18:01 +03:00
Vladimir Enchev
fcd2ffa630 Added support for collection filter in DataGrid column Property/FilterProperty and In/Not operators
Close https://github.com/radzenhq/radzen-blazor/pull/987
2023-05-29 09:44:50 +03:00
Atanas Korchev
1f769bc7b5 RadzenHtmlEditor does not show its value if it is initially hidden. 2023-05-26 17:29:30 +03:00
yordanov
e84a5ad62a RadzenBody should have transparent background if only child in RadzenLayout 2023-05-26 10:57:50 +03:00
yordanov
5a481aeb5e Fix text color in outlined and text RadzenButton variants 2023-05-26 10:54:37 +03:00
yordanov
24cea1d8d2 Update Close button styles in RadzenAlert 2023-05-26 10:31:04 +03:00
Vladimir Enchev
134f368953 Numeric FormattedValue should use specified Culture 2023-05-26 08:53:35 +03:00
yordanov
8a6749e38b Add --rz-panel-menu-padding custom CSS property 2023-05-25 16:05:53 +03:00
yordanov
0722639001 Update CSS classes and variables in layout components 2023-05-25 16:05:53 +03:00
Vladimir Enchev
e372dd8ddf index column removed 2023-05-25 14:30:52 +03:00
Vladimir Enchev
c66022eaa8 code fixed 2023-05-25 14:29:50 +03:00
Vladimir Enchev
3b873fc06c Demos data variables update to IQueryable 2023-05-25 14:28:57 +03:00
Vladimir Enchev
f2ac7cca28 Fixed deleting all text in Numeric leads to no data shown
Fix #974
2023-05-25 10:09:27 +03:00
Vladimir Enchev
d21d909de6 DropDown/DropDownDataGrid trailing separator removed 2023-05-25 08:36:17 +03:00
Dave Bagler
7c476ec104 Dialog wrapper class option. (#985)
* Adding WrapperCSSClass parameter to the dialog service.

* Updating container rendering and adding demo.
2023-05-25 08:11:47 +03:00
Atanas Korchev
3716772a06 Tooltip is always visible in Pie and Donut series. 2023-05-24 19:01:03 +03:00
Vladimir Enchev
c1100a5c62 demo reworked 2023-05-23 16:44:23 +03:00
Vladimir Enchev
0ae1332480 Template fixed 2023-05-23 16:30:20 +03:00
Vladimir Enchev
222debc335 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-05-23 16:14:09 +03:00
Vladimir Enchev
7702ac5475 Version updated 2023-05-23 16:13:56 +03:00
stlufred
b4f4b10332 Improved chart tooltips (#976)
* Improved chart tooltips

- Show closest tooltip in line chart (instead of the first close enough)
- Improved speed
- Show it over or under to greatly reduce chances of tooltip being offscreen

* Moved caching into the Category method

* Reset categoryPropertyCache in SetParametersAsync.

* Revert tooltips to always show above

* Update _chart.scss

---------

Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2023-05-23 16:05:54 +03:00
Vladimir Enchev
fb795a22c8 DataGrid support for In/NotIn filter operators added for OData 2023-05-23 14:33:57 +03:00
Vladimir Enchev
e5a4af88cc DataGrid support for In/NoIn filter operators added for IQueryable (#983)
* In and NotIt filter operators added

* FilterOperator fixed

* demo updated
2023-05-22 16:57:04 +03:00
yordanov
f68508a9ef Update colors in Card demo 2023-05-22 09:24:27 +03:00
yordanov
1e4adf115c Update EventConsole colors 2023-05-22 09:24:27 +03:00
yordanov
dbc8a2b7b2 Update Colors page layout 2023-05-22 09:24:27 +03:00
yordanov
f339bfe45d Add theming variable for chart marker stroke color 2023-05-22 09:24:27 +03:00
yordanov
a78b88c2a4 Update theme variables in RadzenPanelMenu 2023-05-22 09:24:27 +03:00
yordanov
4a338ad94e Update theme variables in RadzenNotification 2023-05-22 09:24:27 +03:00
yordanov
03d0e38f15 Update theme variables in RadzenUpload 2023-05-22 09:24:27 +03:00
yordanov
7da16b469c Update theme variables in RadzenAlert 2023-05-22 09:24:27 +03:00
Dave Bagler
c80fcc5494 Change DatePicker icon based on TimeOnly parameter. (#979)
* changing the icon to schedule when time only.

* added tests for the two icons
2023-05-19 16:44:44 +03:00
Vladimir Enchev
0286396175 missing host file added 2023-05-19 15:07:46 +03:00
Atanas Korchev
edf381c914 Address issues introduced by .NET 7.0.302. 2023-05-19 11:55:03 +03:00
Vladimir Enchev
58d85518f0 Version updated 2023-05-16 13:31:28 +03:00
Vladimir Enchev
32e8ebf4f8 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-05-16 13:30:55 +03:00
Vladimir Enchev
c8cba6ba91 Fixed DropDownDataGrid exception with multiple selection and filtering 2023-05-16 13:30:44 +03:00
AndrzejKl
fba5487231 Added CustomValidator component (source and Demo) (#968)
* Added CustomValidator component (source and Demo)

* ValidateNewEmail property as a Task

* Revert "ValidateNewEmail property as a Task"

This reverts commit 25640e45e5.

* Renaming property name from 'CheckIsValid' to 'IsValid'

* fixed typo on demo page

* Mark as new.

* Change the API to use Func<bool>

---------

Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2023-05-16 13:30:08 +03:00
Vladimir Enchev
9d81fbcbcb Update radiobuttonlist.md 2023-05-16 09:42:23 +03:00
Vladimir Enchev
40c55b3515 DataGrid will go to previews page on reload if needed 2023-05-16 08:08:13 +03:00
Vladimir Enchev
e5aaaff32e Version updated 2023-05-15 11:39:49 +03:00
Vladimir Enchev
6071b138f0 Added support for HTML in RadzenDataGrid.PagingSummaryFormat 2023-05-15 11:06:00 +03:00
Atanas Korchev
71174f5d40 Improve the side dialog demo. 2023-05-15 09:28:41 +03:00
Cosmatevs
bb4ca4ff9e Dialog: fix width and height css style of side dialogs (missing semicolons) (#975) 2023-05-12 09:19:00 +03:00
Atanas Korchev
93f42e9a67 Stacked series throw exception when the data is empty. 2023-05-11 19:10:48 +03:00
yordanov
2b6c1ec771 Add --rz-on-[color] css variables for text colors 2023-05-10 16:45:05 +03:00
Cosmatevs
958546fd0c DatePicker: simplify 'ToggleAmPm' function, handle AM/PM formatted hour input consistently, fix possible out-of-range values of hour/minutes/seconds on input (#971) 2023-05-10 08:54:54 +03:00
sobaka06243
d263494229 methods ClearFilter and ApplyFilter changed from internal to public (#970)
* method GetFilterOperatorText() changed from internal to public

* methods ClearFilter and ApplyFilter changed from internal to public

---------

Co-authored-by: Ivan Kiselev <ivan.kiselev1999@outlook.com>
2023-05-09 10:15:58 +03:00
Vladimir Enchev
12d51318a8 copyrights added to themes 2023-05-09 10:15:08 +03:00
Vladimir Enchev
aa8861643f themes updated 2023-05-09 10:11:27 +03:00
Vladimir Enchev
0f0e4e35ce Version updated 2023-05-09 08:57:18 +03:00
Atanas Korchev
79f63a794d Document RadzenHtmlEditorSource. Closes #936. 2023-05-09 08:10:43 +03:00
Atanas Korchev
47e01dadb7 Implement UploadError event callback. Closes #775. 2023-05-09 08:10:43 +03:00
johanpolak
3bfa2bd9e4 Use method to get classes for RadzenStepsItem (#966)
* Use method to get classes for RadzenStepsItem

* Revert remove method

---------

Co-authored-by: Johan Polak | Camas IT bv <johanpolak@camasit.nl>
2023-05-09 07:15:08 +03:00
pigwing
b1aac49824 fix pageSize change datagrid not reload work (#962)
* fix ProgressBar template display error

* @see f5b7ddcf0e
PageSize changed should invoke Reload() only when needed
here if pageSize = value;
base.OnPageSizeChanged(value); await InvokeAsync(Reload);  will always false

* modify the method call order
2023-05-09 07:14:01 +03:00
sobaka06243
16fdfa3cb1 method GetFilterOperatorText() changed from internal to public (#969)
Co-authored-by: Ivan Kiselev <ivan.kiselev1999@outlook.com>
2023-05-09 07:13:19 +03:00
Atanas Korchev
9c43badbfc Remove warnings from FormComponent and RadzenAlert. 2023-05-08 15:24:05 +03:00
Atanas Korchev
96689b8e67 Remove some warnings by adding documentation or disabling them in the project settings. 2023-05-08 15:10:17 +03:00
Atanas Korchev
95b2a56f80 Add missing </code> 2023-05-08 12:54:53 +03:00
Atanas Korchev
6c33f6ff08 Add notest about nesting dialog, context menu, notification and tooltip. 2023-05-08 12:54:10 +03:00
Atanas Korchev
ab515920de OverflowException in RadzenNumericRangeValidator. 2023-05-08 12:28:44 +03:00
Vasil Yordanov
46fd65f98a Merge pull request #964 from Cosmatevs/radio-button-disabled-fix
Radio Button & Check Box: fix appearance of disabled state
2023-05-08 07:24:37 +03:00
Cosmatevs
e9986c9667 CheckBox: fix appearance of disabled state 2023-05-06 08:23:01 +02:00
Cosmatevs
fec40dd91c RadioButtonListItem: fix appearance of disabled state (to make it look like before the form field update) 2023-05-05 21:45:44 +02:00
Vladimir Enchev
e8bffd8dc6 Using InvariantCulture for filter strings 2023-05-05 15:54:10 +03:00
yordanov
59e6271373 Update logos 2023-05-05 11:06:16 +03:00
Cosmatevs
0dbb0b6e12 Autocomplete, Numeric: display focus state (#960) 2023-05-05 09:01:45 +03:00
Cosmatevs
5d1c166606 Color Picker: reset the color to the initial state when a popup with an 'ok' button was closed by clicking outside (#956) 2023-05-05 08:58:28 +03:00
Vladimir Enchev
366463ac4e Fixed DataGrid with saved settings raises an exception when filtering a column where TValue is float
Fix #961
2023-05-05 08:53:00 +03:00
AlittaSakraf
ed5d4f5fcd Update RadzenDataGridColumn.cs (#955)
Change the SetTitle() method to public.
Why? It's easier for developers because there are fewer properties in the source code, and if you have a common localization process for example:
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            foreach (var col in grd.ColumnsCollection.Where(x => x.Property != null && string.IsNullOrEmpty(x.Title)).ToList())
            {
                col.SetTitle(LocalizationHelper.Localizer( col.Property));        // out localization process
            }
        }
    }
...then all properties can be managed together in the system ("Name" = "Név" ,etc)
(ps:Unfortonatelly the "Title" property is not good, bevaous of "Component parameter should not be set outside of its component")
2023-05-05 08:42:43 +03:00
CoderJason123
787bc2243f add await on async call to OnFilter (#959)
When a filter is applied along with other properties, the lack of await might be causing something to fire out of order, losing the settings of the filter.
2023-05-05 08:41:52 +03:00
Vladimir Enchev
8b5fccdd0d Version updated 2023-05-04 15:51:41 +03:00
Vladimir Enchev
fa79467c19 Login component ShowLoginButton property added 2023-05-04 15:51:34 +03:00
trueMeon
5a4577b7ec [RadzenDatePicker] Renamed AbbreviatedDayNames to ShiftedAbbreviatedDayNames and fixed to react on the Culture property changes (#953) 2023-05-04 15:07:53 +03:00
AlittaSakraf
0c82c60c03 Update RadzenDataGridColumn.cs (#952)
This method has only one reference, in the RadzenDataGrid.razor.cs. 
It has to change the ordering of the column based on the parameter.
So, checking the SortOrder value by GetSortOrder() isn't good, because it is the "past". The "order" value is the right SortOrder value.
See: https://forum.radzen.com/t/radzendatagrid-and-default-sortorder-and-datagridsettings-bug/13938
2023-05-04 15:03:47 +03:00
Vladimir Enchev
84e33ec18a RadzenDataGridColumn ColumnsCollection property added 2023-05-04 14:59:20 +03:00
AndrzejKl
779be53910 Exposed SearchText property and added Action SearchTextChanged (#951)
* Exposed SearchText property and added Action SearchTextChanged

* Added StateHasChanged to refresh component

* Visual cosmetics on Demo page
2023-05-04 08:44:48 +03:00
GodzSky
cda6e3c204 Make DataGridColumn GetOrderIndex method from internal to public. (#949)
So can access 'orderIndex' variable, in case of discrepancy compared to OrderIndex

Co-authored-by: Elyes Ghoul <elyes.ghoul@bluenext.it>
2023-05-03 08:40:47 +03:00
Vladimir Enchev
c73aee1633 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-05-02 11:24:55 +03:00
Vladimir Enchev
d486b8b4cf Date filter in advanced mode doesn't use "ShowTimeForDateTimeFilter()"
Fix #948
2023-05-02 11:24:46 +03:00
yordanov
31909ba17b Fix typos 2023-05-02 11:19:03 +03:00
Vladimir Enchev
27dc30ca57 Version updated 2023-05-02 10:01:23 +03:00
Vladimir Enchev
f5b7ddcf0e PageSize changed should invoke Reload() only when needed 2023-05-02 09:53:18 +03:00
Vladimir Enchev
f1aac3e9e2 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-05-02 09:49:11 +03:00
Vladimir Enchev
0f626dada2 Clear filters on collapse 2023-05-02 09:49:00 +03:00
yordanov
74f4c74f47 Revert "Update banner"
This reverts commit 167030c15c.
2023-05-02 09:29:20 +03:00
GodzSky
3e93ab0fac fix (#942)
Co-authored-by: Elyes Ghoul <elyes.ghoul@bluenext.it>
2023-05-02 09:27:07 +03:00
Cosmatevs
4ac4ec58a8 Color Picker: HSV picker base color fix + alpha resetting fix (#946)
* Color Picker: Fix HSV saturation picker base color

* Color Picker: Make initial RGB and HSV consistent

* Color Picker: Get rid of inconsistent HSV property and always use handlers instead; fix alpha resetting or wrong shown value when changing HEX or choosing a predefined color

---------

Co-authored-by: Nopke <anopke@gmail.com>
2023-05-01 15:24:21 +03:00
Vladimir Enchev
af552414ac ContextMenu will not work properly when custom id attribute is set 2023-04-28 13:31:14 +03:00
yordanov
728d7c5d24 Improve design of CheckBox checked state in Standard theme. Resolves #940 2023-04-28 08:40:24 +03:00
yordanov
ee17b54872 Fix padding class name in Spacing demo 2023-04-28 08:06:26 +03:00
Vladimir Enchev
373a557ad2 DataGrid IsRowExpanded() method added 2023-04-27 15:36:33 +03:00
Vladimir Enchev
062eeb8ac0 Version updated 2023-04-27 10:37:05 +03:00
Vladimir Enchev
473a7fc647 RadzenDataGridColumn.GetStyle() made virtual
Fix #937
2023-04-27 10:36:22 +03:00
Vladimir Enchev
4ddd9dd874 DropDownBase FilterAsYouType property added 2023-04-25 14:51:56 +03:00
Vladimir Enchev
05dd048410 Fixed escape dialog close doesn't work with sequential dialogs
Fix #932
2023-04-25 09:42:19 +03:00
Vladimir Enchev
c2c4afa094 Update _paginator.scss 2023-04-21 11:50:48 +03:00
Jason Finch
be2567f478 docs: Add note about pre-requirements when using certain controls (#933) 2023-04-21 11:20:06 +03:00
Vladimir Enchev
e9e9c9f702 EscapeTabIndex renamed to CloseTabIndex 2023-04-21 11:14:53 +03:00
DanRogers99
1e3d653d1c Add support for setting tab index for escape button in dialogs (#915) 2023-04-21 11:13:09 +03:00
Vladimir Enchev
63f3f3899e Fixed MouseEnter event doesn't work on RadzenText
Fix #934
2023-04-21 11:08:54 +03:00
Vladimir Enchev
08362d1bb6 Version updated 2023-04-20 16:15:20 +03:00
Vladimir Enchev
f1d3d78f89 code fixed 2023-04-20 16:14:49 +03:00
Philip Jacobs
5f084b9d7c Fix JSDisconnectedException in RadzenContextMenu.razor.cs (#931)
On page refresh, the SignalR connection is already disrupted resulting in a JSDisconnectedExcepion. This will suppress the error in the console.
2023-04-20 16:11:37 +03:00
Vladimir Enchev
224d694ffa Login FormFieldVariant property added (#930)
* Added form fields for Login component

* Login buttons added to FormField part

* validators added

* RadzenSwitch should not be used inside FormField

* Login form field demo added
2023-04-20 12:05:40 +03:00
yordanov
1be4b06d33 Add optional .rz-scrollbars css class 2023-04-20 10:39:56 +03:00
Vladimir Enchev
155c3a4b50 RadzenCheckBoxList ReadOnlyProperty and DisabledProperty example added 2023-04-20 09:22:06 +03:00
Vladimir Enchev
371f912c1d CheckBoxListReadOnlyItem example added 2023-04-20 09:17:41 +03:00
johanpolak
41c47fbc58 Add ReadOnly property to CheckBoxList and CheckBoxListItem (#928)
* Add ReadOnly property to CheckBoxList and CheckBoxListItem

* Set tabindex for CheckBox to -1 if ReadOnly

* Add disabled and read-only property for checkboxlist populated from data

---------

Co-authored-by: Johan Polak | Camas IT bv <JohanPolak@camasit.nl>
2023-04-20 09:12:53 +03:00
yordanov
167030c15c Update banner 2023-04-19 08:52:27 +03:00
Vladimir Enchev
7403a07614 themes updated 2023-04-18 15:13:00 +03:00
Vladimir Enchev
fd0bad9a91 Version updated 2023-04-18 12:08:03 +03:00
yordanov
c2381ac3f5 Rename RadzenFormField class file 2023-04-18 11:45:57 +03:00
yordanov
ee18fbac19 Fix typo 2023-04-18 11:36:45 +03:00
yordanov
b83ec99e4f Update FormField rendering and styles 2023-04-18 11:16:38 +03:00
Vladimir Enchev
72bd03d368 code improved 2023-04-18 09:45:34 +03:00
Vladimir Enchev
a6ee68efe8 Dialog focus trap added
Fix #923
2023-04-18 09:38:14 +03:00
Vladimir Enchev
795ca64ac0 CheckBox ReadOnly property added
Based on https://github.com/radzenhq/radzen-blazor/pull/924. Close #https://github.com/radzenhq/radzen-blazor/pull/924/
2023-04-18 09:09:33 +03:00
Daniel Chalmers
ee26df3b68 Update README.md (#922) 2023-04-18 07:13:24 +03:00
Atanas Korchev
bc0cf84297 Show the correct stack bar source 2023-04-17 17:31:45 +03:00
sobaka06243
049f846980 Close all context menus on dispose (#920)
Co-authored-by: Ivan Kiselev <ivan.kiselev1999@outlook.com>
2023-04-17 09:31:07 +03:00
Jason Finch
67308b8e3a docs: Describe what Frozen=true does. (#919)
Co-authored-by: Jason Finch <jason.finch@epw.qld.gov.au>
2023-04-17 08:25:59 +03:00
Atanas Korchev
8c9cdb28d0 Pager dropdown items are numbers. 2023-04-14 10:03:13 +03:00
yordanov
dd30b30b34 Fix wrong source code for FormField helper text example 2023-04-13 22:09:03 +03:00
yordanov
6446097840 Fix border radius of ColorPicker value 2023-04-13 15:39:18 +03:00
Atanas Korchev
589cf2afd8 Bump up the version. 2023-04-12 15:46:18 +03:00
Atanas Korchev
fb1928d5ec Update premium themes. 2023-04-12 15:37:08 +03:00
Atanas Korchev
552b41f855 Update version. 2023-04-12 15:20:18 +03:00
Vasil Yordanov
e2a036192a Form field component (#913)
* RadzenFormField WIP.

* Add empty state class.

* Add more input components. Set placeholder so it can be used from CSS.

* Add blank input styles

* Update initial form field styles

* Update form field label position

* Add ellipsis to form field label

* Position form field label in different themes

* Fix form field hover and focus shadows

* Remove redundant blank input styles

* Fix form field start/end padding in material theme

* Update form field css variables

* Add helper placeholder under form field

* Fix vertical align

* Password uses CurrentPlaceholder.

* Support disabled state.

* Add Variant property to FormField

* Update FormField demo

* Fix hover in filled text field and bg colors in dark themes

* Use --rz-border-width instead of hardcoded pixel values

* Fix textarea top margin in filled and flat form fields

* Fix states of datepicker and textarea in a form field

* Style disabled form fields

* Fix focused disabled state

* Style should be applied to form field wrapper

* Update form field demos

* Fix helper padding in text form field

* Add more form field examples

* Update FormField demo

* Add for mfield validation example

* Update disabled form field example

* Toggle password visibility.

* Update form field examples

* Update form field helper example

* Add XML API reference.

* Update content in form field examples

---------

Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2023-04-12 15:09:14 +03:00
Atanas Korchev
b6c5f670b3 Set the target to _top to prevent the Blazor router from navigating. 2023-04-12 13:53:02 +03:00
Atanas Korchev
ecac1c5b78 Use the Anchor property in the demos. 2023-04-12 13:29:51 +03:00
Atanas Korchev
1d3f124845 RadzenText can create anchors. 2023-04-12 13:06:12 +03:00
Evan Dixon
d0b39df3e2 Add ability to customize OData string by column (#908)
Co-authored-by: Dixon, Evan <edixon@mimeo.com>
2023-04-11 08:50:19 +03:00
Atanas Korchev
beb52670fa Add UploadUrl to the editor demo. 2023-04-07 14:13:49 +03:00
Vladimir Enchev
c924407569 ContextMenu separator example added 2023-04-05 10:39:34 +03:00
Vladimir Enchev
bb72002452 Version updated 2023-04-04 09:48:43 +03:00
Vladimir Enchev
78f045ddf2 DataList IsLoading added
Close https://github.com/radzenhq/radzen-blazor/pull/895
2023-04-04 09:48:12 +03:00
yordanov
ba49220e43 Update Switch demo 2023-04-03 19:04:55 +03:00
yordanov
857bceba76 Update layout in TemplateForm example 2023-04-03 18:00:24 +03:00
Vladimir Enchev
859280c2d7 Tree item label click should check the CheckBox 2023-04-03 16:56:04 +03:00
SGeorgeFramatome
e8ac5dbe8d Panel menu item click (#897)
* Add files via upload

Add Click event, as per RadzenMenu implementation

* Add files via upload

Alter example to show Click event on child
2023-04-03 16:31:46 +03:00
msdevcode
86ec75b05e RadzenAutoComplete - Close Popup if value is smaller than MinLength (#896) 2023-04-03 16:27:07 +03:00
yordanov
6b00fdb19e Update content in Dialog examples 2023-04-03 13:53:05 +03:00
msdevcode
b9707ea486 RadzenContextMenu Icon property added (#893) 2023-03-31 10:43:46 +03:00
sobaka06243
f9dd71c05a Close all tooltips on dispose (#894)
Co-authored-by: Ivan Kiselev <ivan.kiselev1999@outlook.com>
2023-03-31 10:43:08 +03:00
Paul Ruston
0720a9b8f0 Scheduler changes - Better handling of Yearview clicks and overridable MoreText event (#874)
* React to clicks in YearView better and create SelectMore Event to override default code.

* Remove unused method

* Revert "Remove unused method"

This reverts commit 646542c7bf.

* Revert "React to clicks in YearView better and create SelectMore Event to override default code."

This reverts commit 0f7bab5300.

* Scheduler DaySelect event. Also cleaned up some code (removed nested if...else...)

* Revert "Scheduler DaySelect event. Also cleaned up some code (removed nested if...else...)"

This reverts commit 1d15a8fa06.

* Extend SlotSelect to pass Appointments. Bit of code condense in YearView

* Added original SelectSlot method signature to IScheduler and RadzenScheduler

* Ignore this push

* Revert tabs in MonthView

* Revert "Revert tabs in MonthView"

This reverts commit d65a6ec490.

* Revert "Ignore this push"

This reverts commit 0c5fae70ed.

* Revert "Added original SelectSlot method signature to IScheduler and RadzenScheduler"

This reverts commit 320b353af6.

* Revert "Extend SlotSelect to pass Appointments. Bit of code condense in YearView"

This reverts commit e7cbebedc8.

* Extend SelectSlot to include list of appointments in slot

* Revert "Extend SelectSlot to include list of appointments in slot"

This reverts commit c901ec3b48.

* Implement ability to prevent default action on YearView ListClick. Add MoreSelect and offer same default prevention for Month, Planner and Timeline views. Extend SlotArgs to include list of appointments and current view.

* Do not allow add and edit in Year view.

---------

Co-authored-by: Paul Ruston <paul.ruston@live.co.uk>
Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2023-03-31 09:11:05 +03:00
Vladimir Enchev
0289733f7f themes updated 2023-03-30 16:55:47 +03:00
Vladimir Enchev
50ed8ad1e5 Version updated 2023-03-30 16:53:19 +03:00
yordanov
a10fabd927 Removed styles that override the appearance of small button in a DataGrid cell 2023-03-30 14:26:35 +03:00
Vladimir Enchev
0dd9fdf7e6 comment added 2023-03-30 12:03:26 +03:00
Vladimir Enchev
ade5f386b6 Numeric custom value convert support added (#889)
* Numeric custom convert value support added

* code reworked
2023-03-30 11:59:56 +03:00
msdevcode
315b135a3b RadzenDataList/RadzenGrid - Add Pager-Density Property (#883)
* DataList/Grid - Add Pager-Density Property

* DataGrid/DataList/Pager - Add Pager-Density tests
2023-03-29 16:32:19 +03:00
James723
bc3d1daf11 Add milliseconds to column filter string for DateTime. (#881)
Co-authored-by: James Turner <james.turner@mlp.com>
2023-03-29 13:46:09 +03:00
yordanov
50d738c7b6 Update sidebar toggle icon CSS classes 2023-03-29 11:06:00 +03:00
serkanaslan34
0a23ac1401 TooltipService Open with Four Position (#880) 2023-03-29 10:22:25 +03:00
Atanas Korchev
9cbfb4ccbe Split the scheduler demo to fix issues with sharing the reference. 2023-03-28 09:31:06 +03:00
Vladimir Enchev
7c1a76d38e Version updated 2023-03-27 16:36:53 +03:00
Johannes Henrich
b501b86656 Removed unnecessary curly brace in Link component (#876) 2023-03-27 16:32:00 +03:00
Vladimir Enchev
f118cff5c0 Version updated 2023-03-27 14:02:38 +03:00
Atanas Korchev
66d7a9e520 RadzenMenuItem, RadzenPanelMenuItem and RadzenProfileMenuItem can have empty string as Path. 2023-03-27 11:52:32 +03:00
msdevcode
a3424ce020 Link/MenuItem/PanelMenuItem/ProfileMenuItem - Add NavLink-Match Property (#873)
* Link/MenuItem/PanelMenuItem/ProfileMenuItem - Add NavLink-Match Property

* RadzenLink - keep the existing formatting
2023-03-27 09:08:46 +03:00
Vladimir Enchev
7cb72b25be Export should use only columns with defined Property 2023-03-24 15:14:26 +02:00
Vladimir Enchev
f3584b02ac Version updated 2023-03-24 09:40:44 +02:00
Vladimir Enchev
f2aaf9cc26 Microsoft.CSharp should be referenced for netstandard2.1 only 2023-03-24 09:29:31 +02:00
Vladimir Enchev
ea0bab5bd6 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-03-23 09:23:09 +02:00
Vladimir Enchev
78be6f9839 Version updated 2023-03-23 09:22:52 +02:00
Jason
a7df5c7fac Add datagrid parameter for enabling/disabling column title tooltip. (#869)
Co-authored-by: Jason Vos <jason.p.vos@nasa.gov>
2023-03-23 09:04:17 +02:00
Vladimir Enchev
516a6be98e DataGrid crashes when filter is applied to Decimal? field and loaded from Settings
Fix #871
2023-03-23 09:00:26 +02:00
yordanov
7077e30d94 Fix text align in Menu demo 2023-03-22 11:40:16 +02:00
yordanov
21b4053b8b Change ripple's pseudo-element 2023-03-22 11:30:23 +02:00
Vladimir Enchev
85c634480d Added MarkupString support for RadzenRadioButtonListItem Text and RadzenCheckBoxListItem Text
Fix #866
2023-03-22 10:04:15 +02:00
Atanas Korchev
54eefe2295 The code editor is missing certain changes. 2023-03-22 09:42:55 +02:00
yordanov
b32dbc3ac5 Update ContextMenu demo 2023-03-21 19:14:01 +02:00
yordanov
4a5d089e5d Update Accordion demo 2023-03-21 18:42:34 +02:00
yordanov
22cad5a2ab Update ListBox width in ListBox demos 2023-03-21 18:09:15 +02:00
yordanov
acbebd7102 Update DropDown width in DropDown demos 2023-03-21 18:09:15 +02:00
yordanov
301ae12169 Remove third-level icons 2023-03-21 18:09:15 +02:00
yordanov
f04bdcee69 Update HtmlEditor demos 2023-03-21 18:09:15 +02:00
Vladimir Enchev
d4b78fbf87 demo fixed 2023-03-21 16:39:21 +02:00
Vladimir Enchev
500fbc9190 ColumnWidth set to avoid squashed columns on edit 2023-03-21 10:00:37 +02:00
Vladimir Enchev
420f7e9b4e demo updated 2023-03-20 13:22:57 +02:00
Vladimir Enchev
b273c6083f DataGrid settings not loaded in there is a filtering that leads to empty collection 2023-03-20 13:16:05 +02:00
Vladimir Enchev
8877c705c5 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-03-20 10:03:14 +02:00
Vladimir Enchev
1e30f794fe Version updated 2023-03-20 10:03:03 +02:00
HieronymusBlaze
29ad82db7c coderub: DataGridInLineEditor (#863) 2023-03-20 10:02:03 +02:00
Matias Gonzalo Mena
a9046be00c Added NavLinkMatch property to RadzenMenuItem (#862) 2023-03-20 10:01:39 +02:00
Vladimir Enchev
a70efc95c6 Changing PageSize in DataGrid with bound Settings causes an infinite loop 2023-03-20 09:54:00 +02:00
Atanas Korchev
b4b8774110 RadzenLoging does not post the value of the "Remember me" switch. 2023-03-20 09:07:52 +02:00
Vladimir Enchev
d87e03b0cf DropDownBase support for ICollection<> added 2023-03-17 19:29:22 +02:00
Vladimir Enchev
af07ccb87e demo updated 2023-03-17 18:40:52 +02:00
yordanov
dc43918a77 Update CompareValidator demo 2023-03-17 18:17:12 +02:00
Eric
a04b131394 Updated confirm/alert methods to virtual in the dialog service to allow for mocking in unit tests (#860)
Co-authored-by: Eric Barke <ebarke@silvergate.com>
2023-03-17 10:34:04 +02:00
Atanas Korchev
874f18fa6a Setting the font size or font does not work in HtmlEditor. 2023-03-17 09:20:50 +02:00
Vladimir Enchev
fdc93e5130 Version updated 2023-03-16 10:00:17 +02:00
Atanas Korchev
6109e18fe6 The HtmlEditor view source button submits the parent form. Fixes #859. 2023-03-15 16:07:36 +02:00
Scott
27aca28523 Change RadzenComponent.Element setter to protected internal (#858)
* Change RadzenComponent.Element setter to protected

Changing this setter allows custom components inheriting the RadzenComponent class to reference the html element in @ref tags.

* Changing to protected internal to resolve compile issues.
2023-03-15 09:42:36 +02:00
yordanov
2ac4aacee5 Remove duplicated common styles 2023-03-14 13:46:10 +02:00
yordanov
824a741634 rz-helper-hidden-accessible should not use overflow hidden 2023-03-14 13:45:37 +02:00
Vladimir Enchev
819722e7da Version updated 2023-03-14 09:39:44 +02:00
Vladimir Enchev
959d442690 Check for enum before other types 2023-03-14 09:33:47 +02:00
mderoo
b20868328f Update RadzenDataGridColumn.cs (#856)
Setting the grid settings to null causes the selected column count to display a wrong number.
https://forum.radzen.com/t/radzen-datagrid-settings/13408
2023-03-14 09:31:13 +02:00
Vladimir Enchev
679c729985 Nullable enum check added 2023-03-13 17:24:25 +02:00
Vladimir Enchev
bc2ca273a5 Version updated 2023-03-13 10:57:08 +02:00
Vladimir Enchev
8a2612878d Fixed OData enum filter value should use single quotes 2023-03-13 10:51:57 +02:00
Vladimir Enchev
dd76d149ee Fixed DataGrid Query.OrderBy not populated with initial column sorting 2023-03-13 10:43:59 +02:00
Vladimir Enchev
2770d0fbec Dialog cannot be moved horizontally with CultureInfo "de-DE"
Fix #854
2023-03-13 10:18:30 +02:00
Vladimir Enchev
55b2c1e186 Fixed DataGrid column title not updated when changed runtime 2023-03-13 10:16:12 +02:00
Vladimir Enchev
c4c291056b DataGrid state will be updated after frozen column resize. 2023-03-13 10:02:59 +02:00
Vladimir Enchev
b80b81ada6 DataGrid will save in Settings only columns with defined Property 2023-03-13 08:59:45 +02:00
Vladimir Enchev
a0f3d44832 Fixed Tree parent item should not be part of CheckedValues if at least one child is unchecked
Fix #780
2023-03-09 17:00:29 +02:00
Vladimir Enchev
d9e4c00ccf themes updated 2023-03-09 11:07:02 +02:00
Vladimir Enchev
c34a186eaf version updated 2023-03-09 11:01:18 +02:00
Atanas Korchev
be27c930d3 Update legend title. 2023-03-08 18:49:27 +02:00
Atanas Korchev
66818872c2 Add required validator with dropdown example. 2023-03-08 18:47:06 +02:00
Khaled Sliman
cc1ac368b3 Created RadzenDataGridCustomHeader (#849)
* Created RadzenDataGridCustomHeader
Created DataGridCustomHeaderPage.razor
Created DataGridCustomHaderWithColumnPickerPageSamples
Update RadzenDataGrid.razor to display the render fragment for RadzenDataGridCustomHeader if it is not empty
Updated the ExampleService to have the menu options for RadzenDataGridCustomHeader

* Removed RadzenDataGridCustomHeader.razor as it was not needed per code review
Updated RadzenDataGrid to have HeaderTemplate property
Updated Demo pages for the grid to use the new property

---------

Co-authored-by: Khaled A Sliman <Khaled.Ah.Sliman>
2023-03-08 16:26:25 +02:00
cvanstone
03e22098ca Update OrderIndex for all Columns (#851)
Co-authored-by: Chris Vanstone <chris.vanstone@blugem.com>
2023-03-08 15:33:21 +02:00
Vladimir Enchev
724b5eb1e0 demo code fixed 2023-03-07 15:00:57 +02:00
Vladimir Enchev
45a1ce4b55 Version updated 2023-03-07 11:22:21 +02:00
Atanas Korchev
3e5cb2e30b Persist changes in the code editor. 2023-03-07 10:55:11 +02:00
yordanov
d0a4c6aaf1 Improve Button focus state 2023-03-07 10:44:19 +02:00
John Gold Inc
be4bcb7390 Add Density Parameter to DropDownDataGrid (#848)
Co-authored-by: John Gold <john.gold@haulerhub.com>
2023-03-07 08:54:07 +02:00
Vladimir Enchev
a63c3aa4c2 Fixed ContextMenu click event 2023-03-07 08:50:43 +02:00
yordanov
e8e43d97f2 Update ColorPicker demo 2023-03-06 16:49:28 +02:00
yordanov
9939ff4452 Fix ColorPicker disabled state. Resolves #803 2023-03-06 15:32:02 +02:00
Vladimir Enchev
b69bbc899e ColumnWidth and resizing enabled 2023-03-06 15:29:05 +02:00
Vladimir Enchev
f0cba24cc7 demo fixed 2023-03-06 15:07:53 +02:00
Vladimir Enchev
fd5fa0e798 attempt to fix online demo 2023-03-06 14:41:47 +02:00
yordanov
1ba1d53884 Remove LoginConfig page 2023-03-06 12:29:15 +02:00
yordanov
00a118b901 Update Login demo 2023-03-06 12:27:57 +02:00
Vladimir Enchev
ba2ea55884 demo fixed 2023-03-06 10:34:28 +02:00
Vladimir Enchev
70b4c3dd0f Version updated 2023-03-06 10:30:26 +02:00
Vladimir Enchev
412e19252c Demo updated with row index 2023-03-06 10:29:10 +02:00
Paul Ruston
73e1974583 Addition of a Source View for Html Editor (#838)
* Creation of a Source View for Html Editor

* Updated changes #1 as per conversations

* Make the view source tool last. Use the private mode field to track the state as parameters should not do that. View Source should blur the editor in order to update its state when switching modes. Simplify the CSS.

* Change GetMode() access to Public

* Add comment for GetMode() method

---------

Co-authored-by: Paul Ruston <paul.ruston@live.co.uk>
Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2023-03-06 09:07:30 +02:00
Vladimir Enchev
25c57d645b .rz-navigation-item-link added to checks 2023-03-03 11:46:00 +02:00
Vladimir Enchev
a6c6021923 version updated 2023-03-03 11:32:27 +02:00
Vladimir Enchev
2886ac9d7c DataGrid should not reset settings on Reset() if using LoadData 2023-03-03 11:32:02 +02:00
Vladimir Enchev
c121414767 Numeric demo source code fixed 2023-03-03 09:58:58 +02:00
Conduci
35f02ef7a9 Added SelectView(ISchedulerView) to RadzenScheduler which allows consumers to programatically change the selected view (#842) 2023-03-02 18:36:10 +02:00
Vladimir Enchev
ffeb972a82 demo improved 2023-03-02 17:15:08 +02:00
Vladimir Enchev
f20a74674f demo code improved 2023-03-02 16:50:51 +02:00
Vladimir Enchev
03396fbbe2 Fixed error with Tooltip and navigating to a page with a different layout 2023-03-02 16:36:24 +02:00
Vladimir Enchev
54a5c0805e demo fixed 2023-03-02 11:39:54 +02:00
Vladimir Enchev
486cb66b6c SplitButton demo updated 2023-03-02 10:28:31 +02:00
Vladimir Enchev
e5d7a344c7 Fixed SplitButton disabled state when Busy 2023-03-02 10:00:00 +02:00
Vladimir Enchev
60fe0ed25f SplitButton demos updated 2023-03-02 09:56:22 +02:00
Vladimir Enchev
04741c702a Version updated 2023-03-02 09:35:51 +02:00
Vladimir Enchev
6e190fe903 SplitButton demo updated 2023-03-02 09:33:54 +02:00
yordanov
5bb3e65eb9 Add Density property to RadzenPager 2023-03-02 08:23:20 +02:00
yordanov
c3b29ffcd1 Fix text align in ListBox 2023-03-01 17:33:14 +02:00
yordanov
a889c3e97b Document text wrap css classes 2023-03-01 17:17:59 +02:00
Vladimir Enchev
bd578ca7cd SplitButton IsBusy property added
Fix #802
2023-03-01 15:33:36 +02:00
Atanas Korchev
2a9a115c31 Stacked bar and column charts (#837)
* Initial stack column series.

* Better maximum. Rounded corners only on the last series.

* Tooltips.

* Fix the offset of the first series.

* Actually make it correct.

* Optimizations.

* Update the demo.

* Add stacked bar files.

* Stacked bar tooltip.

* Data labels.

* Update the headings.
2023-03-01 13:54:33 +02:00
Vladimir Enchev
4d1848a5e1 demo code fixed
Fix #836
2023-03-01 11:54:04 +02:00
Vladimir Enchev
4bd8f777e0 Dialog demo updated 2023-03-01 10:21:18 +02:00
yordanov
4654a9011b Fix text align of DropDown value 2023-02-28 18:12:01 +02:00
yordanov
22a5dc148a Fix white-space after RadzenLink 2023-02-28 17:25:48 +02:00
yordanov
88dc4c0607 Radzen link text should inherit vertical alignment from parent 2023-02-28 17:25:11 +02:00
yordanov
0a7c47fa70 Remove obsolete chart styles 2023-02-28 16:41:19 +02:00
yordanov
e6f311ebba Update code tag styles 2023-02-28 11:58:30 +02:00
yordanov
88d09f0fef Add Chart demos for Series, Axis, Legend, and Tooltip 2023-02-28 11:58:30 +02:00
Zak Kohler
7467d87e36 Allow for zero width stroke (#834) 2023-02-28 08:37:16 +02:00
yordanov
b50e793a9c Fix wrapping of badges 2023-02-27 11:12:09 +02:00
yordanov
1147390576 Add social badges to demos homepage and footer 2023-02-27 11:07:12 +02:00
Vladimir Enchev
539785f079 isLoading check added 2023-02-27 11:03:11 +02:00
Vladimir Enchev
b99b516346 demo fixed 2023-02-27 10:41:35 +02:00
Vladimir Enchev
c0dc4f4236 delay removed 2023-02-27 10:29:11 +02:00
Vladimir Enchev
5b8f664530 Version updated 2023-02-27 10:12:39 +02:00
Vladimir Enchev
cc490692ad Revert "Show arrow icon when ChildContent exists (#832)"
This reverts commit 582a9bae31.
2023-02-27 10:12:11 +02:00
Vladimir Enchev
5ef415c87d Revert "DataGrid SaveSettings made awaitable"
This reverts commit 95f51ed935.
2023-02-27 10:12:04 +02:00
Vladimir Enchev
ff3c67409d Version updated 2023-02-27 09:49:18 +02:00
Ben Ghaner
582a9bae31 Show arrow icon when ChildContent exists (#832) 2023-02-27 09:14:32 +02:00
Vladimir Enchev
95f51ed935 DataGrid SaveSettings made awaitable
Fix #831
2023-02-27 09:13:37 +02:00
yordanov
0dca22c219 Fix DataGrid frozen-cell hover and selection background colors 2023-02-24 16:25:59 +02:00
yordanov
eaf67e197b Update Area chart demo 2023-02-24 15:50:18 +02:00
Vladimir Enchev
b8db918348 DataGrid save/load settings with LoadData demo fixed
Fix #824
2023-02-24 15:29:35 +02:00
Vladimir Enchev
c865073605 DataGrid KeyProperty added 2023-02-24 14:31:51 +02:00
yordanov
192ccbec25 Update pager demo 2023-02-24 12:35:35 +02:00
yordanov
b8b3b29d01 Update DataFilter demos 2023-02-24 12:06:20 +02:00
yordanov
00ea9a4393 Update DataList demo 2023-02-24 12:06:20 +02:00
Vladimir Enchev
267392d0b7 Fixed Splitter cannot be expanded runtime if Collapsed set to true 2023-02-24 09:37:33 +02:00
Atanas Korchev
e5f041208f SeriesClick event is sometimes not fired when clicking a marker. 2023-02-23 17:58:39 +02:00
Atanas Korchev
82010353c6 Missing ; after clip-path in bar charts. 2023-02-23 17:58:39 +02:00
yordanov
7daf4d1f58 Add Chart to popular components list 2023-02-23 17:25:00 +02:00
Vladimir Enchev
ebb940ee0e DataGrid inline edit demo updated 2023-02-23 16:35:12 +02:00
Dave Bagler
1ce8c98837 Adding an autocomplete type parameter. (#827)
* Adding an autocomplete type parameter.

* Converting the static class to an enum with an extension method.

* undoing some file changes that shouldn't have been included in the last commit
2023-02-23 13:27:29 +02:00
mderoo
257948cbe1 RadzenRequiredValidator firing on duplicate property names (#829)
* Update ValidatorBase.cs

fix for:
https://forum.radzen.com/t/required-validator-issue/13224/3
https://github.com/radzenhq/radzen-blazor/issues/395

* Invert the if.

---------

Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2023-02-23 11:33:08 +02:00
Vladimir Enchev
8971e0aa1a Fixed DataGrid column visibility out of sync with column picker when Visible changed runtime 2023-02-23 09:46:36 +02:00
Vladimir Enchev
2209b050b0 Version updated 2023-02-23 08:59:44 +02:00
yordanov
b5a876a93e Improve responsiveness of demos homepage layout 2023-02-22 18:58:13 +02:00
Vladimir Enchev
4c64ee24d5 Added RadzenTreeItem support for arbitrary attributes 2023-02-22 18:36:09 +02:00
Vladimir Enchev
1a3376374f Fixed DataFilter error with DateTimeOffset 2023-02-22 15:53:11 +02:00
Vladimir Enchev
ee88560090 Fixed DataGrid is skipping to last page when PageSize option selected greater than data present.
Fix #828
2023-02-22 11:39:10 +02:00
Vladimir Enchev
aae7eba068 MarkupString support added for DialogService Confirm and Alert 2023-02-22 11:21:57 +02:00
Vladimir Enchev
6715bc34d8 SpeechToTextButton demo updated 2023-02-22 10:21:41 +02:00
Vladimir Enchev
55d0ea5e22 obsolete file deleted 2023-02-21 16:22:25 +02:00
Vladimir Enchev
11c692b146 Slider demo updated 2023-02-21 16:21:54 +02:00
Vladimir Enchev
ab47bd2e7b obsolete files deleted 2023-02-21 16:10:20 +02:00
Vladimir Enchev
6dd9933d55 SelectBar demo updated 2023-02-21 16:08:20 +02:00
Vladimir Enchev
d08d398b47 Rating demo updated 2023-02-21 15:26:27 +02:00
Vladimir Enchev
aa3903d8f0 Fixed DataGrid column SecondFilterValue not set correctly when using FilterTemplate
Fix #826
2023-02-21 15:16:05 +02:00
Vladimir Enchev
26f9030cef Fixed RadzenCheckBoxList AllowSelectAll doesn't work when using Data Property
Fix #823
2023-02-21 15:12:49 +02:00
tecxx
0500a10671 add ClearSelection method to RadzenTree (#822)
Co-authored-by: Robert Rostek <robert@rostech.at>
2023-02-21 15:02:31 +02:00
WoodyJ007
c3ae2d3eda Added option to stop auto focus on filter input on DropDownDatagrid. This improves user experience on mobile devices. (#825)
Co-authored-by: John Wood <john.wood@woodstarsoftware.co.uk>
2023-02-21 15:01:27 +02:00
Artur Madjidov
e502c51886 Add parameters for the example texts in RadzenHtmlEditorFormatBlock. (#821) 2023-02-21 12:15:40 +02:00
Vladimir Enchev
063c1aa6c0 Password updated 2023-02-21 11:25:51 +02:00
Vladimir Enchev
5e5db9193e Numeric demo updated 2023-02-21 10:40:46 +02:00
Vladimir Enchev
26a38fc56c RadioButtonList demo updated 2023-02-21 10:10:58 +02:00
Vladimir Enchev
aad0558a9c ListBox demo updated 2023-02-21 09:41:09 +02:00
yordanov
a911f975da Update Column demo 2023-02-20 20:12:04 +02:00
yordanov
a99c8fbc88 Update Image demo 2023-02-20 17:05:07 +02:00
yordanov
79525227a9 Update Gravatar demo 2023-02-20 17:05:07 +02:00
Vladimir Enchev
66b8eb72bf DropDownDataGrid demo updated 2023-02-20 16:39:00 +02:00
yordanov
1eff269b80 Update Tabs demo 2023-02-20 14:27:09 +02:00
Vladimir Enchev
2dc01b528c DropDownCustomObjects updated 2023-02-20 12:56:13 +02:00
Vladimir Enchev
30e200896d DropDownGrouping updated 2023-02-20 12:47:24 +02:00
Vladimir Enchev
7d2e827e6f DropDownFiltering demo updated 2023-02-20 12:38:35 +02:00
Vladimir Enchev
94e6b3086b DropDownVirtualization demo updated 2023-02-20 12:31:33 +02:00
Vladimir Enchev
0849e90574 DropDown multiple selection demo reworked 2023-02-20 11:10:48 +02:00
Vladimir Enchev
d3eef33371 DropDown single selection demo updated 2023-02-20 10:53:57 +02:00
yordanov
1cee0d10e5 Update Steps demo 2023-02-20 10:43:34 +02:00
Vladimir Enchev
3f044b407a DatePicker demo updated 2023-02-20 10:16:05 +02:00
Vladimir Enchev
b25ce3760b Obsolete demo removed 2023-02-20 09:44:54 +02:00
Vladimir Enchev
6e810761f8 CheckBoxList demo updated 2023-02-20 09:34:13 +02:00
yordanov
6dea80e13e Update PanelMenu demo 2023-02-17 15:36:59 +02:00
yordanov
a715616a6a Update ProfileMenu demo 2023-02-17 15:17:09 +02:00
yordanov
e87db432d5 Update Menu demo 2023-02-17 15:15:12 +02:00
yordanov
0b4b89dcbd Update Link description 2023-02-17 14:48:14 +02:00
yordanov
0e980051e3 Update Link demo 2023-02-17 14:46:35 +02:00
yordanov
4bd489a530 Update breadcrumb template description and remove config page 2023-02-17 14:18:03 +02:00
yordanov
ed02c0dbc1 Update BreadCrumb demo 2023-02-17 14:08:53 +02:00
yordanov
81e2432426 Update texts in Tooltip demo 2023-02-17 14:08:53 +02:00
Vladimir Enchev
3a14099831 Card removed from CheckBox demos 2023-02-17 12:55:51 +02:00
Vladimir Enchev
84712967b0 AutoCompleteConfig removed 2023-02-17 12:54:51 +02:00
yordanov
1fc70b7591 Update AutoComplete demos 2023-02-17 11:39:50 +02:00
Vladimir Enchev
b9f8345964 CheckBox demo reworked 2023-02-17 11:18:21 +02:00
yordanov
fcd9e674d5 Update Tooltip demo 2023-02-17 11:02:40 +02:00
Vladimir Enchev
2cf2dfaea5 AutoComplete reworked 2023-02-17 10:36:39 +02:00
yordanov
797be4e57c Update console log 2023-02-17 09:48:03 +02:00
yordanov
2478f1478f Update ProgressBar demo 2023-02-16 17:11:13 +02:00
Vladimir Enchev
58cd508be4 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-02-16 16:39:31 +02:00
Vladimir Enchev
9ca094f4f8 demo updated 2023-02-16 16:39:21 +02:00
yordanov
9ed9878193 Update Alert demos 2023-02-16 16:39:18 +02:00
Vladimir Enchev
c878a47f92 Save/Load settings demo category added 2023-02-16 16:21:15 +02:00
Vladimir Enchev
42d7a8860a DataGrid Save/Load settings with LoadData demo added 2023-02-16 15:41:20 +02:00
yordanov
718824f359 Revert body translateZ. Animations require a new stacking context under WebKit. 2023-02-16 12:16:12 +02:00
yordanov
3b5b649530 Remove will-change property from rz-body 2023-02-16 11:38:03 +02:00
Vladimir Enchev
8702af0c42 IsBusy added on run 2023-02-16 11:22:28 +02:00
yordanov
b038157f2f Remove rz-body translateZ transform to prevent new stacking context 2023-02-16 10:55:22 +02:00
Vladimir Enchev
0033bdd570 Heading and Documentation removed from all examples 2023-02-16 10:48:45 +02:00
Vladimir Enchev
99b40cac43 Version updated 2023-02-16 09:32:05 +02:00
Vladimir Enchev
7fa91f98c6 Extended Blazor server buffer size 2023-02-16 09:29:41 +02:00
yordanov
a6e3f48044 Update spacing in MainLayout sidebar 2023-02-15 19:00:06 +02:00
Vladimir Enchev
d25921f6c8 Look for inner filter expressions recursive 2023-02-15 18:16:35 +02:00
yordanov
e1986dc8eb Fix spacing in MainLayout 2023-02-15 17:03:30 +02:00
yordanov
ebba5b860f Introduce Radzden Blazor Studio 2023-02-15 16:58:36 +02:00
yordanov
4beff8932e Update Layout demo 2023-02-15 11:55:19 +02:00
yordanov
e26bd9adfb Update panel demo IDs 2023-02-15 11:55:19 +02:00
Vladimir Enchev
2eadc7b5ea code fixed 2023-02-15 10:58:18 +02:00
Vladimir Enchev
a15aeade6a RequiredValidator demo updated 2023-02-15 10:53:29 +02:00
Vladimir Enchev
1990b7fad5 NumericRangeValidator demo updated 2023-02-15 10:52:05 +02:00
Vladimir Enchev
d81d5a37f8 LengthValidator demo updated 2023-02-15 10:51:02 +02:00
Vladimir Enchev
1c1da0b080 EmailValidator demo updated 2023-02-15 10:49:45 +02:00
Vladimir Enchev
4063bce178 CompareValidator demo updated 2023-02-15 10:48:35 +02:00
Vladimir Enchev
b4d33c6472 Tooltip demo updated 2023-02-15 10:46:55 +02:00
Vladimir Enchev
44005c607d AlertStylingConfig demo updated 2023-02-15 10:45:33 +02:00
Vladimir Enchev
c17852a583 Alert demo updated 2023-02-15 10:44:26 +02:00
Vladimir Enchev
f94b22666b Notification demo updated 2023-02-15 10:43:09 +02:00
Vladimir Enchev
3c8c690a79 StylingGaugeConfig updated 2023-02-15 10:40:54 +02:00
Vladimir Enchev
6f416ffe79 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-02-15 10:39:22 +02:00
Vladimir Enchev
e4f8fe9ea2 ArcGauge demo updated 2023-02-15 10:39:14 +02:00
yordanov
003738149e Update Panel info 2023-02-15 10:38:18 +02:00
Vladimir Enchev
6f39223787 StylingChartConfig updated 2023-02-15 10:37:28 +02:00
Vladimir Enchev
06649c2207 ChartInterpolationConfig demo updated 2023-02-15 10:36:02 +02:00
Vladimir Enchev
18f51becd8 ChartTrendsConfig updated 2023-02-15 10:33:11 +02:00
Vladimir Enchev
916792abea PieChartConfig updated 2023-02-15 10:31:26 +02:00
Vladimir Enchev
c8f8e019f6 LineChartConfig updated 2023-02-15 10:30:09 +02:00
Vladimir Enchev
7b6c6bb930 DonutChartConfig updated 2023-02-15 10:28:52 +02:00
Vladimir Enchev
b826993a0d ColumnChartConfig updated 2023-02-15 10:27:36 +02:00
Vladimir Enchev
00385c8e15 BarChart demo updated 2023-02-15 10:26:11 +02:00
Vladimir Enchev
5b982766fb AreaChart demo updated 2023-02-15 10:24:34 +02:00
Vladimir Enchev
be27dfd918 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-02-15 10:22:10 +02:00
Vladimir Enchev
a82089aff3 HtmlEditorCustomTools updated 2023-02-15 10:22:00 +02:00
yordanov
215ba8bfbf Update Panel demo 2023-02-15 10:20:52 +02:00
Vladimir Enchev
7b1e9185f7 HtmlEditor demo updated 2023-02-15 10:20:20 +02:00
Vladimir Enchev
8c756e99c1 Upload demo updated 2023-02-15 10:18:13 +02:00
Vladimir Enchev
d2384e74cd TextBox demo updated 2023-02-15 10:17:03 +02:00
Vladimir Enchev
b2ff2852bd TextArea updated 2023-02-15 10:16:16 +02:00
Vladimir Enchev
3b4505af27 TemplateForm demo fixed 2023-02-15 10:11:42 +02:00
Vladimir Enchev
87eee126e5 Switch demo updated 2023-02-15 10:09:29 +02:00
Vladimir Enchev
6234f04457 SplitButton updated 2023-02-15 10:08:22 +02:00
Vladimir Enchev
c8e808082f SpeechToTextButton demo updated 2023-02-15 10:06:56 +02:00
Vladimir Enchev
b2f2642c82 Slider demo updated 2023-02-15 10:05:52 +02:00
Vladimir Enchev
0f77730011 SelectBar demo updated 2023-02-15 10:04:52 +02:00
Vladimir Enchev
b062d56928 Rating demo updated 2023-02-15 10:03:30 +02:00
Vladimir Enchev
a3f8552b80 RadioButtonList demo updated 2023-02-15 10:02:16 +02:00
Vladimir Enchev
8faf5a81ca Numeric demo updated 2023-02-15 10:01:03 +02:00
Vladimir Enchev
7d7c0ae320 Mask demo updated 2023-02-15 09:59:57 +02:00
Vladimir Enchev
2bd8b71927 ListBox demo updated 2023-02-15 09:58:54 +02:00
Vladimir Enchev
19a323ec77 DropDownDataGrid demo updated 2023-02-15 09:57:19 +02:00
Vladimir Enchev
29ee95165e DatePicker demo updated 2023-02-15 09:55:23 +02:00
Vladimir Enchev
c618a31e44 ColorPicker demo updated 2023-02-15 09:53:07 +02:00
Vladimir Enchev
f972de507f CheckBoxList demo updated 2023-02-15 09:51:45 +02:00
Vladimir Enchev
51a0be31d5 CheckBox demo updated 2023-02-15 09:50:18 +02:00
Vladimir Enchev
d986c12564 AutoComplete demo updated 2023-02-15 09:47:52 +02:00
Vladimir Enchev
1ae17b121e Steps demo updated 2023-02-15 09:41:41 +02:00
Vladimir Enchev
afb294f170 Login demo updated 2023-02-15 09:40:08 +02:00
Vladimir Enchev
2b63fa343a ContextMenu demo updated 2023-02-15 09:38:45 +02:00
Vladimir Enchev
35121f1141 BreadCrumb demo updated 2023-02-15 09:37:37 +02:00
Vladimir Enchev
9d0f26fede Accordion demo updated 2023-02-15 09:36:07 +02:00
Vladimir Enchev
f0289b73b8 Dialog demo updated 2023-02-15 09:34:38 +02:00
Vladimir Enchev
1009619ecd Column demo updated 2023-02-15 09:31:55 +02:00
Vladimir Enchev
f30b1b1e08 Row demo updated 2023-02-15 09:30:09 +02:00
Vladimir Enchev
d151f39a22 Stack demo updated 2023-02-15 09:28:30 +02:00
Vladimir Enchev
be6d4accff Layout demo updated 2023-02-15 09:26:19 +02:00
yordanov
69e71202ee Update Card demo 2023-02-15 09:09:31 +02:00
yordanov
fece284aee Update badge usage demo 2023-02-15 09:09:08 +02:00
yordanov
4bcb44bcb2 Update Badge demo 2023-02-14 20:04:15 +02:00
Paul Ruston
0891dbf5a8 Pie and Donut render errors (#813)
* Pie and Donut render errors

* Take into account negative values. Added property ItemsGreaterZero

* Moved ItemsGreaterZero to RadzenPieSeries

* Rename the property and set it once to avoid multiple allocations.

---------

Co-authored-by: Paul Ruston <paul.ruston@live.co.uk>
Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2023-02-14 18:08:32 +02:00
Vladimir Enchev
b5b5a86025 Splitter demo updated 2023-02-14 16:43:05 +02:00
Vladimir Enchev
3fcbe831d7 Image demo updated 2023-02-14 16:39:52 +02:00
Vladimir Enchev
d253151296 Scheduler demo updated 2023-02-14 16:36:03 +02:00
Vladimir Enchev
4e9beb86b0 DropDown demo updated 2023-02-14 16:31:21 +02:00
Vladimir Enchev
7f85b49f3f DropDownVirtualization updated 2023-02-14 16:29:10 +02:00
Vladimir Enchev
1ea8c56631 DropDownMultiple updated 2023-02-14 16:27:48 +02:00
Vladimir Enchev
5d76cbee26 DropDownGrouping updated 2023-02-14 16:26:38 +02:00
Vladimir Enchev
682e4af619 DropDownFiltering updated 2023-02-14 16:25:32 +02:00
Vladimir Enchev
c446476fbc DropDownCustomObjects updated 2023-02-14 16:23:48 +02:00
Vladimir Enchev
e18a05001e RegexValidator updated 2023-02-14 16:19:51 +02:00
Vladimir Enchev
0685f8b9c0 TreeCheckBoxes updated 2023-02-14 16:16:45 +02:00
Vladimir Enchev
bdd1d4e8c1 TreeDataBinding updated 2023-02-14 16:15:50 +02:00
Vladimir Enchev
bf6923f909 TreeFileSystem demo reworked 2023-02-14 16:14:43 +02:00
Vladimir Enchev
faa37c3322 TreeSelection updated 2023-02-14 15:46:02 +02:00
Vladimir Enchev
1fe5b07f86 Tree demo updated 2023-02-14 15:44:44 +02:00
Vladimir Enchev
7a9ad3933b TemplateForm demo updated 2023-02-14 15:42:07 +02:00
Vladimir Enchev
df2e447362 Tabs demo updated 2023-02-14 15:39:25 +02:00
Vladimir Enchev
b2033f3dcd RadialGauge demo updated 2023-02-14 15:37:00 +02:00
Vladimir Enchev
186bce852d ProgressBar demo updated 2023-02-14 15:34:56 +02:00
Vladimir Enchev
e1494441b0 ProfileMenu demo updated 2023-02-14 15:33:28 +02:00
Vladimir Enchev
1b67c130c7 Password demo updated 2023-02-14 15:31:52 +02:00
yordanov
628b980655 Update Dashboard demo 2023-02-14 12:00:32 +02:00
Vladimir Enchev
0e04a17380 Panel demo updated 2023-02-14 11:53:16 +02:00
Vladimir Enchev
cee1a14ebd PanelMenu demo updated 2023-02-14 11:51:14 +02:00
Vladimir Enchev
3862205053 Pager demo updated 2023-02-14 11:49:35 +02:00
Vladimir Enchev
9696f044a0 Menu demo reworked 2023-02-14 11:46:53 +02:00
Vladimir Enchev
b61a0f2c94 Link demo updated 2023-02-14 11:44:23 +02:00
Vladimir Enchev
afb2e3a8a2 Card demo updated 2023-02-14 11:39:38 +02:00
Vladimir Enchev
65cc0a0ed5 ChartAnnotations updated 2023-02-14 11:37:47 +02:00
Vladimir Enchev
dba6f2ec6a GravatarConfig updated 2023-02-14 11:35:52 +02:00
Vladimir Enchev
b39ea03ba6 FileInputConfig reworked 2023-02-14 11:33:56 +02:00
Vladimir Enchev
528483b905 GoogleMapConfig reworked 2023-02-14 11:32:04 +02:00
Vladimir Enchev
fb7434f1b4 Fieldset demo updated 2023-02-14 11:26:58 +02:00
Vladimir Enchev
a239e6405b FieldsetConfig reworked 2023-02-14 11:25:37 +02:00
Vladimir Enchev
d5c00b81d7 ExportToExcelCsv reworked 2023-02-14 11:23:28 +02:00
Vladimir Enchev
590f6c8c8b CascadingDropDowns reworked 2023-02-14 11:22:05 +02:00
Vladimir Enchev
edf2495a9f DataGridMasterDetail reworked 2023-02-14 11:20:04 +02:00
Vladimir Enchev
ed0a034414 DataGridMasterDetailHierarchy reworked 2023-02-14 11:17:49 +02:00
Vladimir Enchev
3e33e0d0e1 DataGridMasterDetailHierarchyOnDemand reworked 2023-02-14 11:14:53 +02:00
Vladimir Enchev
c9e1c2711e code fixed 2023-02-14 11:11:39 +02:00
Vladimir Enchev
1f0420dc1f DataList page reworked 2023-02-14 10:52:48 +02:00
Vladimir Enchev
f0320c6ff9 DataGridVirtualization reworked 2023-02-14 10:49:29 +02:00
Vladimir Enchev
904eb1364c DataGridVirtualizationLoadData reworked 2023-02-14 10:48:31 +02:00
Vladimir Enchev
e5ef184515 DataGridSort reworked 2023-02-14 10:47:30 +02:00
Vladimir Enchev
2a4111643c DataGridSortApi reworked 2023-02-14 10:46:34 +02:00
Vladimir Enchev
53ffe057b2 DataGridSingleSelection reworked 2023-02-14 10:45:42 +02:00
Vladimir Enchev
b2632e1727 DataGridSimpleFilterWithMenu reworked 2023-02-14 10:44:51 +02:00
Vladimir Enchev
84554d6dea DataGridSimpleFilter reworked 2023-02-14 10:43:57 +02:00
Vladimir Enchev
6fd8f8380b DataGridSelfReferenceHierarchy reworked 2023-02-14 10:43:00 +02:00
Vladimir Enchev
5330929efd DataGridSaveSettings reworked 2023-02-14 10:41:30 +02:00
Vladimir Enchev
c67bc9938c DataGridPerformance reworked 2023-02-14 10:40:40 +02:00
Vladimir Enchev
f41f0e94be DataGridPagerPosition reworked 2023-02-14 10:39:45 +02:00
Vladimir Enchev
74b1c6f4ed DataGridPagerHorizontalAlign reworked 2023-02-14 10:38:51 +02:00
Vladimir Enchev
54d7e20baa DataGridPagerApi reworked 2023-02-14 10:38:02 +02:00
Vladimir Enchev
221d88c52c DataGridOData reworked 2023-02-14 10:37:00 +02:00
Vladimir Enchev
eb3c8050fe DataGridMultipleSort reworked 2023-02-14 10:36:01 +02:00
Vladimir Enchev
fdab854799 DataGridMultipleSelection reworked 2023-02-14 10:34:59 +02:00
Vladimir Enchev
ba32761a0c DataGridLoadData reworked 2023-02-14 10:33:53 +02:00
Vladimir Enchev
6d002838a5 DataGridInLineEdit reworked 2023-02-14 10:32:38 +02:00
Vladimir Enchev
d8f53db387 DataGridGroupingApi reworked 2023-02-14 10:31:15 +02:00
Vladimir Enchev
f15db1637e DataGridGroupHeaderTemplate reworked 2023-02-14 10:29:11 +02:00
Vladimir Enchev
5f98e2fdc5 DataGridGroupFooterTemplate reworked 2023-02-14 10:28:13 +02:00
Vladimir Enchev
603dc9f9c6 DataGridGridLines reworked 2023-02-14 10:27:11 +02:00
Vladimir Enchev
0692079384 DataGridFrozenColumns reworked 2023-02-14 10:24:51 +02:00
Vladimir Enchev
e046cdce45 DataGridFooterTotals reworked 2023-02-14 10:23:48 +02:00
Vladimir Enchev
595419df77 DataGridFilterApi reworked 2023-02-14 10:22:52 +02:00
Vladimir Enchev
1a641afaa8 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-02-14 10:21:37 +02:00
Vladimir Enchev
29c73ae90f DataGridEmpty reworked 2023-02-14 10:21:27 +02:00
yordanov
e055f99f63 Update spacing in UI fundamentals demos 2023-02-14 10:20:52 +02:00
Vladimir Enchev
888d4797d0 DataGridDynamicData reworked 2023-02-14 10:20:04 +02:00
Vladimir Enchev
b95d63e974 DataGridDensity reworked 2023-02-14 10:19:08 +02:00
Vladimir Enchev
195abb59ff DataGridConditionalTemplate reworked 2023-02-14 10:18:07 +02:00
Vladimir Enchev
306ceba474 DataGridCompositeColumns reworked 2023-02-14 10:17:04 +02:00
Vladimir Enchev
2be1476130 DataGridColumnTemplate reworked 2023-02-14 10:16:05 +02:00
Vladimir Enchev
ca80356c27 DataGridColumnResizing reworked 2023-02-14 10:15:03 +02:00
Vladimir Enchev
eed34d9b7d DataGridColumnReoder reworked 2023-02-14 10:14:00 +02:00
Vladimir Enchev
1144ab32b7 DataGridColumnPicking reworked 2023-02-14 10:12:55 +02:00
Vladimir Enchev
0061e609d4 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-02-14 10:11:32 +02:00
Vladimir Enchev
680b64c98f DataGridColumnFilterTemplate reworked 2023-02-14 10:11:21 +02:00
yordanov
325048efcb Update RadzenText demo 2023-02-14 10:09:59 +02:00
Vladimir Enchev
aedb293d50 DataGridColumnEnumFilter example reworked 2023-02-14 10:09:45 +02:00
Vladimir Enchev
6cdc1943fb DataGrid cell select page reworked 2023-02-14 10:07:25 +02:00
Vladimir Enchev
9ff40875c2 DataGrid cell context menu demo reworked 2023-02-14 10:02:31 +02:00
Vladimir Enchev
3a851d59fe DataGrid advanced filter mode demo reworked 2023-02-14 09:46:50 +02:00
Vladimir Enchev
64de7abada DataFilter page updated 2023-02-14 09:42:31 +02:00
yordanov
6d9feebedd Update ripple demo 2023-02-14 09:15:12 +02:00
yordanov
441658eb7a Update shadows demo 2023-02-14 09:01:36 +02:00
yordanov
01a441a99c Update borders demo 2023-02-14 08:41:40 +02:00
yordanov
1d10141c1d Update icons demo 2023-02-13 19:51:05 +02:00
Vladimir Enchev
952313acee demo updated 2023-02-13 17:04:07 +02:00
Vladimir Enchev
d537b742dc Export demo update to handle sub properties as alias 2023-02-13 16:55:12 +02:00
Vladimir Enchev
f3b706bcc2 themes updated 2023-02-13 14:37:36 +02:00
Vladimir Enchev
2a57af944f Version updated 2023-02-13 14:30:38 +02:00
Sergiu Ciudin
3f42b93300 Fixed DatePicker Kind getting lost when type is DateTime (#807)
* Update RadzenDatePicker.razor.cs

Fixed DatePicker Kind getting lost when type is DateTime

* Fixed DatePicker Kind getting lost when type is DateTime

* Update RadzenDatePicker.razor.cs

The right version

* Probably i should check type also
2023-02-13 14:27:50 +02:00
Vladimir Enchev
59a58eb886 DataGrid AllowFilterDateInput property added
Fix #811
2023-02-13 14:04:18 +02:00
yordanov
d91d5bcd9b Add new views to Scheduler demo 2023-02-13 12:01:49 +02:00
yordanov
c6a08c79e1 Fix scheduler planner view overflow 2023-02-13 12:00:52 +02:00
yordanov
d550b65bc7 Update other month and weekend slot styles 2023-02-13 10:34:12 +02:00
yordanov
42418ef393 Update year view styles in material theme 2023-02-13 10:34:12 +02:00
yordanov
12f4156ae0 Refactor year view styles 2023-02-13 10:34:12 +02:00
yordanov
ff58873fcb Refactor timeline view styles 2023-02-13 10:34:12 +02:00
yordanov
925c72f6aa Refactor planner view styles 2023-02-13 10:34:12 +02:00
Paul Ruston
345d853e2d Creation of new views for scheduler 2023-02-13 10:34:12 +02:00
Vladimir Enchev
10b064dc40 Added title to DataFilter with OData 2023-02-10 11:51:42 +02:00
Vladimir Enchev
75a7187a87 DataFilter OData page reworked for source edit 2023-02-10 10:15:18 +02:00
Vladimir Enchev
6182e00c31 code fixed 2023-02-10 10:13:40 +02:00
Vladimir Enchev
e3ba93a6b8 VirtualizationOverscanCount added to DropDown, DropDownDataGrid and ListBox 2023-02-10 09:28:49 +02:00
Vladimir Enchev
109d8cacbc code viewer fixed 2023-02-09 17:40:35 +02:00
Vladimir Enchev
3bcc18f035 DataGrid binding to IQueryable reworked 2023-02-09 17:22:11 +02:00
Vladimir Enchev
92baa1affb Version updated 2023-02-09 15:56:30 +02:00
Vladimir Enchev
32a9457de3 Fixed DataGrid filter popup will not open after column Visible change
`
2023-02-09 15:56:10 +02:00
Vladimir Enchev
32c147fa16 Title, subtitle and class attribute improved for all demos 2023-02-09 15:23:54 +02:00
Vladimir Enchev
d61d75f8bb PublishTrimmed set to false 2023-02-09 09:50:22 +02:00
Vladimir Enchev
eae6cd5396 themes updated 2023-02-09 09:26:04 +02:00
Vladimir Enchev
6f16f230d1 Version updated 2023-02-09 09:04:20 +02:00
Emil Nachev
f458a057e8 Last order date: From OrderByDescending take First (#801)
Last order date: 
From OrderByDescending take First item
or 
from OrderBy take Last item
2023-02-09 08:57:52 +02:00
yordanov
d013300fa3 Update example source tab text and title 2023-02-08 16:01:55 +02:00
yordanov
d6b8394044 Update Support page 2023-02-08 16:01:55 +02:00
yordanov
c1fa630602 Update Get Started page 2023-02-08 16:01:55 +02:00
Emil Nachev
28a03dadaf Update DataGridVirtualizationLoadDataPage.razor (#799) 2023-02-08 14:54:15 +02:00
Vladimir Enchev
29cfc2ea6b Fixed closing dialogs logic
Fix #791
2023-02-08 10:10:31 +02:00
Vladimir Enchev
f4c776f10e Fixed DataGrid filter popup no working correctly after column Visible change runtime 2023-02-07 14:57:15 +02:00
tecxx
04be6bc38b workaround for HTMLEditor innerHTML exception (#728) (#795)
Co-authored-by: Robert Rostek <robert@rostech.at>
2023-02-07 11:36:45 +02:00
Vladimir Enchev
4f0bbeeab0 Fixed DataGridColumn and DataFilterProperty FormatString logic 2023-02-07 11:18:53 +02:00
Vladimir Enchev
5a356a8d75 DataGrid ExpandRows() and CollapseRows() methods added 2023-02-07 09:31:20 +02:00
yordanov
7f35f46eaa Remove invalid --rz-paginator-button-size css variable. Resolves #794 2023-02-06 17:33:17 +02:00
yordanov
ea7be67d83 Update Support page 2023-02-06 16:48:05 +02:00
yordanov
8f0d65766d Update Colors page layout 2023-02-06 16:48:05 +02:00
yordanov
a140f318a2 Update MainLayout padding and remove TOC 2023-02-06 16:48:05 +02:00
yordanov
d0a2d1644f Add ComponentName parameter to RadzenExample 2023-02-06 16:48:05 +02:00
yordanov
e69b153e1c Add initial TOC styles 2023-02-06 16:48:05 +02:00
yordanov
d19d383738 Update Spacing page 2023-02-06 16:48:05 +02:00
yordanov
253f288323 Update Breakpoints page 2023-02-06 16:48:05 +02:00
yordanov
d6ce0536ca Update Button demo page 2023-02-06 16:48:05 +02:00
yordanov
0168c01915 Style RadzenExample tabs and source code editor 2023-02-06 16:48:05 +02:00
Atanas Korchev
7329fec67a Add copy button and error handling. 2023-02-06 16:48:05 +02:00
Atanas Korchev
5fea22294e Update branch name. 2023-02-06 16:48:05 +02:00
Atanas Korchev
669124a6b3 Runnable snippets. 2023-02-06 16:48:05 +02:00
Atanas Korchev
c44d141c07 Add monaco editor. 2023-02-06 16:48:05 +02:00
Atanas Korchev
0b30e00b8c Compile examples. 2023-02-06 16:48:05 +02:00
Vladimir Enchev
1e7bd1bf48 AsODataEnumerable() removed from the demo 2023-02-06 13:02:49 +02:00
Vladimir Enchev
c2c4d6aa02 Version updated 2023-02-06 11:27:07 +02:00
Vladimir Enchev
7e0c64191c DataGrid advanced filter mode reworked with form to handle submit on enter key 2023-02-06 11:24:26 +02:00
Vladimir Enchev
323e4e971a DataGrid advanced filter mode will apply filter on enter key
Fix #786
2023-02-06 10:07:50 +02:00
Vladimir Enchev
99b4f8f8fc Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-02-06 09:53:10 +02:00
Vladimir Enchev
7c1cf76c5c Fixed DialogOptions.CloseDialogOnEsc behavior
Fix #791
2023-02-06 09:52:53 +02:00
Atanas Korchev
305e1b7af6 Paste images as data URI if the UploadUrl property of RadzenHtmlEditor is not set. 2023-02-06 09:46:51 +02:00
Vladimir Enchev
6880a70227 Tabs component select with RenderMode Client should not set display:block
Fix #792
2023-02-06 09:41:39 +02:00
yordanov
0482969755 Add text transform utility css classes 2023-02-02 14:27:46 +02:00
Atanas Korchev
4c9b429dae Update performance demo. 2023-02-02 10:09:16 +02:00
Vladimir Enchev
60b8400e29 DataFilter OData demo should not inherit from DbContextPage 2023-02-01 15:36:01 +02:00
Vladimir Enchev
7260be98d6 Version updated 2023-02-01 15:25:07 +02:00
Vladimir Enchev
be94094de7 DataFilter OData support added 2023-02-01 14:23:06 +02:00
Vladimir Enchev
645077f39b DataGrid VirtualizationOverscanCount property added 2023-01-31 13:55:10 +02:00
Vladimir Enchev
b42940441d Version updated 2023-01-30 12:30:40 +02:00
yordanov
fc7071c04e Update main demos layouts 2023-01-27 19:01:27 +02:00
yordanov
de887a4e3f Generate display utility classes with responsive breakpoints 2023-01-27 15:59:25 +02:00
yordanov
7f629309c7 Add mixin for utility classes with responsive breakpoints 2023-01-27 15:59:25 +02:00
yordanov
fa45e209d5 Add text-align with responsive breakpoints and classes for white-space 2023-01-27 15:59:25 +02:00
Vladimir Enchev
40aec6cd0d Set FilterPopupRenderMode="PopupRenderMode.OnDemand" for various DataGrid examples 2023-01-27 13:58:35 +02:00
Vladimir Enchev
969ae7aeca DataGrid FilterPopupRenderMode Initial improved 2023-01-27 13:50:17 +02:00
Vladimir Enchev
a64bbd34f3 DataGrid advanced filtering demo updated 2023-01-27 13:42:02 +02:00
Vladimir Enchev
79acf83d6f Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-01-27 13:39:54 +02:00
Vladimir Enchev
786e8d0be1 FilterPopupRenderMode default value changed to Initial 2023-01-27 13:39:45 +02:00
Foitn
2757850f28 #748 Added methods to edit a range of rows and cancel a range of rows (#784)
Co-authored-by: DEMCON\MFE <marijn.feijten@demcon.com>
2023-01-27 13:36:48 +02:00
Vladimir Enchev
7c6f39f3b5 DataGrid FilterPopupRenderMode property added with OnDemand as default value 2023-01-27 12:04:00 +02:00
Vladimir Enchev
70723d0437 Fixed RadzenDataFilterProperty FilterTemplate context to be the underling Filter 2023-01-26 15:56:47 +02:00
Vladimir Enchev
bd9b0f798b Version updated 2023-01-26 10:52:35 +02:00
Bruno Silva
0c406b2ad8 Update DataGridInLineEditPage.razor (#783)
After inserting a new object the insert button was disabled.
2023-01-26 09:26:02 +02:00
Vladimir Enchev
822891541c check if event is present 2023-01-25 10:05:47 +02:00
Vladimir Enchev
bf064fd4e3 Added MarkupString support for Accordion item Text property 2023-01-24 15:55:22 +02:00
Vladimir Enchev
6c9e055d42 Added Template support for DropDown and DropDownDataGrid chips 2023-01-24 15:50:14 +02:00
Vladimir Enchev
7455d1bfb2 Fixed popups will steal focus in some cases
Fix #774
2023-01-24 10:29:09 +02:00
yordanov
7b923b6625 Add new series colors to chart's pastel color scheme 2023-01-23 09:59:34 +02:00
Vladimir Enchev
bcd18e9395 Version updated 2023-01-23 09:49:32 +02:00
yordanov
082d577834 Add more series colors 2023-01-23 09:43:33 +02:00
Vladimir Enchev
68bf4f9df3 DataGrid rz-data-row rz-state-disabled updated 2023-01-23 09:43:05 +02:00
Vladimir Enchev
9348698aac DataGrid rz-state-disabled added to rz-data-row 2023-01-23 09:40:14 +02:00
Vladimir Enchev
979025f7d9 Fixed DataGrid columns order not reset when Settings set to null 2023-01-23 09:27:20 +02:00
Vladimir Enchev
9aa09050da Fixed Autocomplete steals focus
#774
2023-01-20 16:29:00 +02:00
Vladimir Enchev
f331de4185 Fixed DataGrid AllowColumnReorder ignored when AllowGrouping is true 2023-01-20 13:38:18 +02:00
Vladimir Enchev
1ce067c854 DropDownDataGrid will render rz-state-disabled class for disabled items 2023-01-20 13:30:50 +02:00
Vladimir Enchev
e6d537f0f8 Set Gap and RowGap as px if specified just as number 2023-01-20 11:31:53 +02:00
Vladimir Enchev
6a69a8d21a Selection and more columns added to DataGrid dynamic data demo 2023-01-20 10:49:41 +02:00
Vladimir Enchev
415cc09a06 Fixed DataGrid will not populate pickable columns if AllowColumnPicking is initially false 2023-01-20 09:26:47 +02:00
Vladimir Enchev
fb482e133e DropDownBase select all should exclude disabled items 2023-01-20 09:13:05 +02:00
Vladimir Enchev
c8134ce2ec Disable select all CheckBox if AllowSelectAll is false 2023-01-20 08:59:37 +02:00
Vladimir Enchev
a59c062dda Version updated 2023-01-20 08:45:16 +02:00
Vladimir Enchev
fe604d3439 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-01-20 08:44:51 +02:00
Vladimir Enchev
53ad8466ad Fixed popups positioning in old and new Edge browsers 2023-01-20 08:44:39 +02:00
yordanov
9e3c844231 Change rz-col selector specificity. Resolves #779 2023-01-19 22:35:34 +02:00
Vladimir Enchev
85a10e7c72 DataList AllowVirtualization property added 2023-01-19 17:09:59 +02:00
Vladimir Enchev
902dc5bdd1 themes updated 2023-01-19 10:27:11 +02:00
yordanov
666cbc9e47 Add --rz-chart-legend-font-size 2023-01-19 10:18:19 +02:00
yordanov
745fae3f76 Update Column and Stack demos 2023-01-19 10:00:36 +02:00
Vladimir Enchev
bb2c4d4c3f Version updated 2023-01-19 09:46:34 +02:00
Vladimir Enchev
f8c8d6725c themes updated 2023-01-19 09:46:27 +02:00
yordanov
54747dc800 Enable wrapping in Stack/Row demo configs 2023-01-18 18:43:04 +02:00
Vladimir Enchev
63b6c0cab4 code fixed 2023-01-18 18:41:27 +02:00
Vladimir Enchev
92c85a0791 demo fixed 2023-01-18 18:37:15 +02:00
Vladimir Enchev
83f47bfe6e Stack demo updated 2023-01-18 18:33:32 +02:00
Vladimir Enchev
2f034e98c0 Stack Wrap property added 2023-01-18 18:29:26 +02:00
Vladimir Enchev
cb416c3583 RadzenRow, RadzenColumn and RadzenStack components added (#777)
* Stack and RadzenRow/RadzenCol components added

* Add responsive breakpoints scss map to utilities

* Add initial layout styles for RadzenRow and RadzenCol

* Update RadzenCol breakpoints and default css class

* Rename rz-col-gap to rz-gap

* RadzenCol Size property added

* RadzenRow Gap and RowGap properties added

* Add spacing utility css classes

* Add RadzenCol offset and order styles

* Update RadzenCol css class names

* Order properties updated to string

* Remove negative margin css classes

* Add zero offset option

* RadzenCol renamed to RadzenColumn

* Fix offset map name

* Add Row and Column demos

* Rename RadzenCol to RadzenColumn

* column order fixed

* RadzenColumn reworked

* Stack Spacing changed to Gap

* stack demo updated

* Add display: none utility class

* Add Breakpoints and Spacing demos and update Layout demos

* Add rz-stack css class and set default gap for stack to --rz-gap

* Update demos

Co-authored-by: yordanov <vasil@yordanov.info>
2023-01-18 18:11:17 +02:00
Vladimir Enchev
584353a240 DataGrid simple filter with menu will not update settings on column filter operator change 2023-01-17 13:10:29 +02:00
Vladimir Enchev
729456c2a0 DataGrid simple filter demo improved 2023-01-17 09:31:43 +02:00
Vladimir Enchev
a02a2e5332 Version updated 2023-01-16 15:58:44 +02:00
Vladimir Enchev
78f0204d86 DropDown/DropDownDataGrid Chips remove button should not be triggered by Form submit on enter 2023-01-16 15:43:32 +02:00
Vladimir Enchev
b76ef5ca80 Second argument added to DataGrid SelectRow() method specifying if RowSelect event should be raised
Fix #769
2023-01-16 09:31:04 +02:00
Vladimir Enchev
788fc01cfb DataGrid expand/collapse should not select the row 2023-01-13 13:19:07 +02:00
Vladimir Enchev
4dc9360b34 DropDownDataGrid Separator property fixed 2023-01-12 18:23:07 +02:00
Vladimir Enchev
6c0e1b7f01 RadzenPanelMenu Multiple property added 2023-01-12 15:55:14 +02:00
Vladimir Enchev
27b91642f2 version updated 2023-01-12 15:08:59 +02:00
Vladimir Enchev
0c7be4b2c7 DropDownDataGrid AllowFilteringByAllStringColumns fixed 2023-01-12 15:08:42 +02:00
Vladimir Enchev
e41ba71828 version updated 2023-01-12 09:27:55 +02:00
paulo-rico
2b2b6b98f1 RadzenDropDownDataGrid - Option to search by individual keywords seperated by a space as per forum entry https://forum.radzen.com/t/dropdowndatagrid-with-multiple-columns/3076 (#768)
Co-authored-by: Paul Ruston <paul.ruston@live.co.uk>
2023-01-11 16:42:16 +02:00
Atanas Korchev
8f6b20abd1 Add Text property to RadzenAlert. 2023-01-10 19:27:45 +02:00
Dave Bagler
21a69c4a61 Add child content example to label API docs. (#766)
This change adds an additional example to show the new child content property for the label component.
2023-01-10 16:06:35 +02:00
Vladimir Enchev
e7b671283a Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2023-01-10 10:54:17 +02:00
Vladimir Enchev
d46a7a50b5 Label tests fixed 2023-01-10 10:54:09 +02:00
Atanas Korchev
dfae4e0848 The category axis of a bar chart is not visible when the Visible property of the value axis is set to false. 2023-01-10 10:44:21 +02:00
Vladimir Enchev
a0f7e924e5 More Edge checks updated 2023-01-09 11:08:42 +02:00
Vladimir Enchev
fd2f3c7dbe Version updated 2023-01-09 10:42:32 +02:00
Vladimir Enchev
da442dc02b Label ChildContent property added 2023-01-09 09:42:01 +02:00
Magnus Warvik
eaea900100 Fix side dialog width + title (#759)
* Set max-width of left/right side dialogs to 100%

* Use MarkupString for side dialog title (same as normal dialog)
2023-01-09 09:31:06 +02:00
Vladimir Enchev
449662f858 Check for Edge updated 2023-01-09 07:25:10 +02:00
Vladimir Enchev
def2219f41 DataGrid ShowCellDataAsTooltip property added 2023-01-06 11:03:04 +02:00
Vladimir Enchev
4670fc477d DataGrid AllGroupsExpanded property added 2023-01-06 09:19:40 +02:00
Vladimir Enchev
cea4572843 Version updated 2023-01-05 10:51:17 +02:00
Vladimir Enchev
b769d4644a Performance demo update with loading indicator 2023-01-05 09:54:08 +02:00
Vladimir Enchev
3d9b117a74 themes updated 2023-01-05 09:00:34 +02:00
Vladimir Enchev
3b1a5f227e Fixed DropDownBase exception if ValueProperty is named after system type 2023-01-04 15:40:33 +02:00
Vladimir Enchev
a66a2d936e Drag visual not destroyed on group 2023-01-04 15:12:45 +02:00
yordanov
8b5c334d47 Update copyright year 2023-01-04 12:52:00 +02:00
Vladimir Enchev
5597cf6753 performance demo restored to IQueryable 2023-01-04 12:31:53 +02:00
Vladimir Enchev
9d2d83d8d1 demo updated with LoadData 2023-01-04 12:24:55 +02:00
Vladimir Enchev
bc695479fa less records selected for the performance demo 2023-01-04 12:11:29 +02:00
Vladimir Enchev
c0f7f2accd less records selected for the performance demo 2023-01-04 12:04:55 +02:00
Vladimir Enchev
08309d6162 demo code improved 2023-01-04 11:55:09 +02:00
Vladimir Enchev
b217036ad0 DataGrid performance demo added 2023-01-04 11:46:43 +02:00
Vladimir Enchev
a276652cbc added page render time 2023-01-04 11:08:03 +02:00
Vladimir Enchev
39f643330a alignment fixed 2023-01-04 10:47:40 +02:00
Vladimir Enchev
2967cc917c code simplified 2023-01-04 10:47:16 +02:00
Vladimir Enchev
78d22b3165 obsolete code removed 2023-01-04 10:19:20 +02:00
yordanov
989036bdf2 Fix font-size in Scheduler slots 2023-01-03 17:31:30 +02:00
Vladimir Enchev
926e9ff92c Version updated 2023-01-03 11:50:56 +02:00
Vladimir Enchev
4696567514 DataGrid EmptyTemplate not shown when AllowVirtualization is true 2023-01-03 10:57:13 +02:00
Vladimir Enchev
e153a30186 Fixed incorrect culture handling in RadzenDataGridColumn
Fix #755
2023-01-03 10:35:39 +02:00
Vladimir Enchev
e8bbd3dace Fixed Numeric will throw exception on value change with empty string as Format 2023-01-03 10:13:00 +02:00
Vladimir Enchev
d2d1344858 Single expand PanelMenu example added 2023-01-03 09:55:00 +02:00
Vladimir Enchev
6be828079d DataGrid will save Settings on Reset() 2022-12-30 04:59:15 +02:00
Atanas Korchev
7a07a5c646 Prevent text selection during column resizing and grouping. 2022-12-28 14:21:42 +02:00
yordanov
ee649ebeb9 Add MaterialSymbols icon font to demos and update icons demo 2022-12-21 16:41:07 +02:00
yordanov
67fe2a5a67 Add support for different icon fonts via --rz-icon-font-family 2022-12-21 16:38:07 +02:00
yordanov
6ac193c139 Update Material Icons font 2022-12-21 13:34:24 +02:00
Vladimir Enchev
b7492a6dfa Version updated 2022-12-19 16:06:46 +02:00
Atanas Korchev
224e86f673 Change the Min and Max property types of RadzenNumericRangeValidator. 2022-12-19 12:20:30 +02:00
Marco Papst
f014e155d6 Bugfix/side dialog positioning (#754)
* fix side dialog does not use full height when main content is scrollable

* allow scrolling the content of the side dialog in vertical direction
2022-12-19 09:00:03 +02:00
Vladimir Enchev
7aa37cd6cb DataGrid initial column sorting ignores column SortProperty 2022-12-16 16:55:10 +02:00
Vladimir Enchev
b1cc09fcb6 DateTime column added to DataGrid dynamic data demo 2022-12-16 08:58:18 +02:00
Vladimir Enchev
4717293666 Fixed DataGrid Template and EmptyTemplate rendering with composite columns 2022-12-14 18:22:22 +02:00
Vladimir Enchev
a80cd0720f Version updated 2022-12-13 15:27:31 +02:00
Vladimir Enchev
e238676efc Image demo updated 2022-12-13 15:24:44 +02:00
Marco Papst
e1df231137 Feature: Open a Dialog on the side (#739)
* implement side dialog based on DialogService

* extend Dialog sample

* add optional Mask and RIght/Left position for side dialog

* add OpenSideAsync to dialog documentation

* mark Dialog as updated in demos

* add top and bottom position for side dialog

* extend side dialog docs with details to only one open dialog

* reduce default height of top/bottom side dialog

* fix failing test in RadzenNumeric due to NullreferenceException

Co-authored-by: Marco Papst <papst@sma.de>
2022-12-13 13:48:23 +02:00
Vladimir Enchev
f40d10b35c Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2022-12-13 12:37:43 +02:00
Vladimir Enchev
ea20e5445e Check for format in Numeric before replacing digit placeholder 2022-12-13 12:37:35 +02:00
Atanas Korchev
4a6f2dbdc3 Default theme does not load. 2022-12-13 12:30:16 +02:00
Vladimir Enchev
11ff01bc61 Added support for custom numeric formats in Numeric 2022-12-13 11:20:34 +02:00
Atanas Korchev
2a292e6a82 Avoid duplicate CSS loading. 2022-12-13 11:03:02 +02:00
Maxim Becker
dc11242b77 Optimize rendering of chart tooltip (#745)
* Optimize rendering of chart tooltip

* Add performance test
2022-12-12 17:22:48 +02:00
Vladimir Enchev
4ec8f5fc28 Version updated 2022-12-12 15:22:59 +02:00
Vladimir Enchev
690f3ed87c Fixed self-reference hierarchy does not work in LoadData
Fix #740
2022-12-12 15:20:23 +02:00
Vladimir Enchev
04e8f6f2e3 DataGrid column LogicalFilterOperator not saved in Settings
Fix #746
2022-12-12 15:07:55 +02:00
Vladimir Enchev
e96ab86198 DataGrid column HeaderCssClass not applied to header cell 2022-12-12 11:35:26 +02:00
Igor Telheiro
eae010a23b Update RadzenScheduler.razor.cs
Currently there's no easy way to get the current selectedView. This is because the selectedView that gets updated is the field, and not the public property.
The Scheduler.IsSelected is not an easy way to get it, as you need to test every view to get the current one.
Please consider updating the SelectedIndex property or making that SelectedView getter public.
2022-12-12 09:00:25 +02:00
Atanas Korchev
d9d829e37d Change a bit theme registration so RBS can pick it up. 2022-12-09 10:47:50 +02:00
Vladimir Enchev
53680fc774 Version updated 2022-12-08 10:41:21 +02:00
Vladimir Enchev
46b8378297 Fixed virtualized DataGrid sort null ref. exception with bound Settings and LoadData
Fix #733
2022-12-08 10:40:55 +02:00
Vladimir Enchev
a26b4f779e Check for null elements to focus 2022-12-08 09:32:07 +02:00
Vladimir Enchev
c2e8c87f3b Fixed DropdownBase.SelectItem Invalid Cast Exception when using Value Property
Fix #734
2022-12-08 09:28:56 +02:00
yordanov
c99e82bd8e Fix DropDown alignment in Chromium 108 2022-12-07 22:21:15 +02:00
Atanas Korchev
1398e54896 FormSubmit sometimes does not trigger when the model is a record type. 2022-12-07 19:46:10 +02:00
yordanov
2d93e5bb1c Card css variables should be exposed at :root level 2022-12-07 18:46:10 +02:00
Vladimir Enchev
6b901d42f7 Fixed disabled DatePicker can be cleared
Fix #735
2022-12-07 16:57:12 +02:00
Vladimir Enchev
0cc8a968ed Fixed exception with example source code tab 2022-12-07 16:05:03 +02:00
Vladimir Enchev
3f2914c6fa DropDown multi select item inline style removed 2022-12-07 09:41:56 +02:00
Vladimir Enchev
9e01786278 Fixed Dialog el.computedStyleMap is not a function
Fix #732
2022-12-06 14:10:54 +02:00
Vladimir Enchev
78ec625cd5 Version updated 2022-12-05 19:58:42 +02:00
Vladimir Enchev
02855e3ac4 Fixed DataGrid will not display data if EmptyText is set 2022-12-05 19:58:22 +02:00
Vladimir Enchev
2fc65f135d Version updated 2022-12-05 11:36:42 +02:00
Atanas Korchev
88085ca5a6 Change the test to be more accurate. 2022-12-05 11:05:17 +02:00
Vladimir Enchev
fe26a82d66 Fixed RadzenDataGrid EmptyText causes ParameterView instance exception in MAUI
Fixed #https://github.com/radzenhq/radzen-blazor/issues/729
2022-12-05 10:31:19 +02:00
Joseph
e98678b1f7 Allow set language for speech recognition (#730) 2022-12-05 10:17:09 +02:00
Atanas Korchev
ef2b4d785a Support members that differ only in casing. 2022-12-03 19:55:33 +02:00
yordanov
b721f3e3ce Fix nested DataGrid footer background color 2022-12-01 18:02:28 +02:00
Vladimir Enchev
13cc0fc08c Fixed DropDown item can be selected using ENTER key even if disabled
Fix #727
2022-12-01 10:46:38 +02:00
Vladimir Enchev
65fe95d464 version updated 2022-11-30 20:56:17 +02:00
Vladimir Enchev
80a887b0d0 Fixed Radzen.closeAllPopups() 'Cannot read properties of undefined' error 2022-11-30 20:56:09 +02:00
yordanov
bed1915da4 Input should not change font-size under 768px max-width 2022-11-30 18:11:54 +02:00
yordanov
65cde0af99 Move responsive styles for body, header and footer under RadzenLayout component styles. Resolves #724 2022-11-30 18:10:37 +02:00
yordanov
a0a2b8b265 Remove root-font-size variable from scheduler styles 2022-11-30 16:45:56 +02:00
EkaterinaTikhomirova
ed01254c84 Reset DropDown list after selection (#726)
Co-authored-by: ekaterina.tikhomirova <ekaterina.tikhomirova@dsr-corporation.com>
2022-11-30 14:56:39 +02:00
Vladimir Enchev
e03864ac03 Version updated 2022-11-30 12:25:51 +02:00
Vladimir Enchev
83796c5aa4 Fixed DataGrid with 'AllowColumnPicking' and 'AllowColumnReorder' always allows groupings
Fix #725
2022-11-30 12:25:32 +02:00
Atanas Korchev
0e329def1a ColorPicker throws NullReferenceException if it cannot parse its value as a valid color. 2022-11-29 19:36:15 +02:00
Maxim Becker
27859cf183 Add interpolation in RadzenLineSeries to make rendering more generic (#722)
* Add interpolation in RadzenLineSeries to make rendering of them more generic

* Added new lines at end of new files

* Add interpolation in RadzenAreaSeries too

* Revert the Are and Line chart demos. Add a new one.

Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2022-11-29 16:15:51 +02:00
Vladimir Enchev
5560e7ee3d DataGrid GridLines property added (#723)
* DataGridGridLines added

* Add initial styles for GridLines

* Use child combinator to style first-level gridlines only

* Add style selectors for gridlines with composite cells

Co-authored-by: yordanov <vasil@yordanov.info>
2022-11-29 15:56:05 +02:00
Vladimir Enchev
72bab915b1 Fixed DataGrid filter popup closes on scrolling of DataGrid placed in column FIlterTemplate 2022-11-29 15:54:29 +02:00
Greg Horvath
f5fefcdd55 Implemented stand alone speech to text component (#703)
* Implemented stand alone speech to text component radzenhq#699 radzenhq#700

* Addressed radzenhq#703 PR review comments.

* radzenhq#703 Changed position of default title and aria-label attributes so caller can override them.

* radzradzenhq#703 Added unit test for verify default title and aria-label can be overridden.

* radzradzenhq#703 Added speech recognication error handling.  Minor refactor to toggleDictation js function.

* Refactor the implementation of toggleDictation. Change the class name. Use the Reference inherited from RadzenComponent. Other smaller changes.

* Check what component started the speech recording.

* Update speech to text button styles

* Remove important rule

* Update demo and add it to main menu

* Add StopIcon, Title and StopTitle properties. Remove console logging.

Co-authored-by: Atanas Korchev <akorchev@gmail.com>
Co-authored-by: yordanov <vasil@yordanov.info>
2022-11-29 15:06:37 +02:00
Atanas Korchev
160634ea38 Fix the installation article. 2022-11-29 13:59:12 +02:00
Vladimir Enchev
50fb5a96d8 DropDown enum example fixed to work in WASM 2022-11-29 13:10:54 +02:00
Vladimir Enchev
79c7ea16d8 DropDownBase will use Display attribute of Enum 2022-11-29 12:49:11 +02:00
Atanas Korchev
a166db0ea1 Revert "Add black friday banners"
This reverts commit 0c4e92ebec.
2022-11-29 08:24:58 +02:00
Vladimir Enchev
2b905615d1 test fixed 2022-11-28 20:30:06 +02:00
Vladimir Enchev
a18c1b5e0c version updated 2022-11-28 20:21:09 +02:00
Vladimir Enchev
c066043ceb Fixed Chart ValueProperty does not accept decimal
DynamicExpressionParser will be used for indexer only
2022-11-28 20:21:01 +02:00
Vladimir Enchev
41d64f1b7c Version updated 2022-11-28 13:03:44 +02:00
Vladimir Enchev
36023fdc35 Fixed DropDownBase exception with property names named after system types 2022-11-28 13:03:24 +02:00
Atanas Korchev
8437cf279d Update instructions for .NET 7. 2022-11-28 10:54:26 +02:00
Vladimir Enchev
d2e19cf3c7 DataFilter initial FilterOperator of filters added runtime fixed 2022-11-28 09:31:58 +02:00
Atanas Korchev
9a90be6e79 Create ci.yml 2022-11-26 09:02:52 +02:00
Atanas Korchev
903a4c78e2 Cannot select listbox item if ValueProperty is a string property. 2022-11-26 08:52:17 +02:00
Atanas Korchev
19049bfea8 Fix failing tests. 2022-11-26 08:51:50 +02:00
yordanov
0c4e92ebec Add black friday banners 2022-11-25 11:41:49 +02:00
Vladimir Enchev
aefe937adc DataGrid nested filter popups close fixed 2022-11-25 09:38:20 +02:00
Vladimir Enchev
63eda04815 DataGrid will display localized enum values in cells from Display attribute if present 2022-11-25 08:46:21 +02:00
Atanas Korchev
18c7783942 Reset the state during paging, sorting and filtering. 2022-11-25 06:57:28 +02:00
Vladimir Enchev
6c17e1e9c5 more broken links fixes 2022-11-24 21:51:47 +02:00
Vladimir Enchev
955355460e various broken links fixed 2022-11-24 21:43:06 +02:00
Vladimir Enchev
51a110b9a3 Fixed filtering of DataFilter with IEnumerable property 2022-11-24 15:26:14 +02:00
Atanas Korchev
43da6c3656 Compatibility with RBS. 2022-11-24 11:54:51 +02:00
Vladimir Enchev
411c916a26 RadzenLink ChildContent reworked 2022-11-24 11:31:25 +02:00
Vladimir Enchev
c0cc14ec99 Image url fixed 2022-11-24 11:23:21 +02:00
Vladimir Enchev
4f8dd8844c Link ChildContent support added 2022-11-24 11:23:10 +02:00
Vladimir Enchev
36f8f43aad Version updated 2022-11-24 10:00:24 +02:00
Zak Kohler
534d7f570e Fix typos in documentation (#718) 2022-11-23 07:26:59 +02:00
Vladimir Enchev
599e514afc DialogService.OpenAsync will not execute Radzen.openDialog() when options.ChildContent is set
Fix #717
2022-11-22 16:31:05 +02:00
Vladimir Enchev
42054827a2 seed reworked 2022-11-22 15:27:09 +02:00
Vladimir Enchev
bfe517ef75 docs links fixed 2022-11-22 10:07:02 +02:00
Vladimir Enchev
c585f3455d Component source links fixed 2022-11-22 09:56:27 +02:00
Vladimir Enchev
fe1d3dd82b Only RadzenExample Name property should be used to display source of the example page.
Source property should be used to link source code of the component.
2022-11-22 09:41:20 +02:00
yordanov
92d503335b Add scrollbar size. Resolves #675 2022-11-21 19:14:58 +02:00
Atanas Korchev
782f93169d Fix links to Dialog and Layout source. 2022-11-21 19:08:38 +02:00
Vladimir Enchev
0c12177091 Fixed focus lost with DropDown/DropDownDataGrid with AllowFiltering 2022-11-21 17:40:48 +02:00
Vladimir Enchev
cc90ff97e3 code fixed 2022-11-21 16:51:05 +02:00
Vladimir Enchev
525230cf2d RadioButtonList from HorizontalAlign enum demo added 2022-11-21 12:15:21 +02:00
Vladimir Enchev
2df9ef3fca Version updated 2022-11-21 11:55:57 +02:00
Vladimir Enchev
9de1b6d9d2 HtmlEditor not focused in dialog with AutoFocusFirstElement
Fix #714
2022-11-21 11:45:12 +02:00
yordanov
94b096259a Update docs templates and demos homepage 2022-11-18 15:22:02 +02:00
yordanov
4e7011f12b Update READMEs 2022-11-18 15:21:10 +02:00
yordanov
ff123ddcb4 Introducing Radzen Blazor Studio 2022-11-18 14:41:09 +02:00
aalex675
9d98fefdef Fix: PropertyAccess.Getter method doesn't allow access of array members. Change to use DynamicExpressionParser.ParseLambda from Linq. (#713)
Co-authored-by: Alden Alexander <aalexander@bachelorcontrols.com>
2022-11-18 10:54:40 +02:00
Atanas Korchev
573bddb1ae Cannot set the style of RadzenAccordion. 2022-11-18 08:58:07 +02:00
Vladimir Enchev
8386848e0e Fixed e.target.closest is not a function
Fix #712
2022-11-17 13:50:06 +02:00
Vladimir Enchev
5ba0220a74 Added CSS class "rz-group-row" to DataGrid group rows 2022-11-16 18:29:22 +02:00
Vladimir Enchev
d24cadcf00 Menu child items cannot be opened with click once closed when ClickToOpen=false 2022-11-16 14:18:24 +02:00
Vladimir Enchev
fbe53df424 Menu clickToOpen option removed from the demo 2022-11-16 13:28:42 +02:00
Vladimir Enchev
eb0347073e Version updated 2022-11-16 13:17:37 +02:00
for7raid
45907bdcca Split button improvements (#709) 2022-11-16 11:49:04 +02:00
Vladimir Enchev
b5b8aaf731 Menu ClickToOpen behavior fixed 2022-11-16 11:06:35 +02:00
Vladimir Enchev
d4eb749729 Version updated 2022-11-15 13:46:14 +02:00
Vladimir Enchev
3e09882b0c RadzenMenu ClickToOpen property added (#706) 2022-11-15 13:44:49 +02:00
Vladimir Enchev
a443b57ead Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2022-11-15 13:11:13 +02:00
Vladimir Enchev
3a430b3586 DataGrid load settings fixed with filter and paging 2022-11-15 13:11:05 +02:00
EkaterinaTikhomirova
f09f8ba4eb Add parameter in RadzenDropDown to clear search input after selection. (#705)
Co-authored-by: ekaterina.tikhomirova <ekaterina.tikhomirova@dsr-corporation.com>
2022-11-15 12:44:44 +02:00
Vladimir Enchev
c6a1560a0f DropDown item select in multi select changed from SPACE to ENTER key to allow entering space during filter 2022-11-15 12:42:55 +02:00
Vladimir Enchev
805f596f1f Fixed DataGrid second filter in advanced mode 2022-11-15 09:14:48 +02:00
Vladimir Enchev
bcee601d4c Exception fixed 2022-11-15 08:57:51 +02:00
Vladimir Enchev
ea009e802b Version updated 2022-11-14 17:36:58 +02:00
Vladimir Enchev
e421eaaf1a DataGrid group row expression fixed 2022-11-14 17:36:41 +02:00
Vladimir Enchev
997cd88db8 Employees images fixed 2022-11-14 16:48:13 +02:00
Vladimir Enchev
ccc8fbde05 Radzen.Blazor version updated 2022-11-14 13:19:42 +02:00
Vladimir Enchev
0fdf7721a7 readme updated 2022-11-14 13:19:09 +02:00
Vladimir Enchev
96f1863711 WebAssembly version of demos added (#704)
* Demos as WASM

* Copy the default wasm loading CSS.

* InMemory database instead SQLite

* DbContext filled with data

* Host project added

* Server renamed to Host

* Remove location.reload.

* Remove startup.

* Stop github caching to file. Use larger page size to improve load time.

* Display enum values.

* DbContext with static data

* Host DbContex added

* Examples and Sitemap added

* docker updated

* Theme changing.

* Update Dockerfile

* Set WORKDIR.

* Do not throw errors for duplicate assets.

* Do not inherit Index from DbContextPage

* Documentation works again.

* Sqlite removed from host

* DataGrid Save/Load settings fixed

* Demo source fixed

* Add loading.

* Add loading image

* Hide the loading with JS interop.

* Add the loading globally.

* Add server demos.

* Delete data files.

* Remove the db copy code from Dockerfile.

* DbContext seed fixed

* missing await added

* Separate solutions for all project, Blazor server and Blazor WebAssembly added

* tree demos data access fixed

* Avoid using Last() and First()

* Orders and OrderDetails data made smaller

* Update loading animation

* Move the loading to MainLayout.

* Update loading animation speed

* Seed() improved

* Revert "Move the loading to MainLayout."

This reverts commit f43ce050396b9483e8809af35493eb35531f254c.

* Fix homepage bg color with dark theme

* Revert "Revert "Move the loading to MainLayout.""

This reverts commit faee40d4ad92f474577434c61f31d847e6777a53.

Co-authored-by: Atanas Korchev <akorchev@gmail.com>
Co-authored-by: yordanov <vasil@yordanov.info>
2022-11-14 13:14:47 +02:00
Vladimir Enchev
ea9c7543d9 Fixed class attribute should not override default Css class for Accordion, CheckBoxList and RadioButtonList items
Fix #698
2022-11-14 10:56:21 +02:00
Vladimir Enchev
b69a02c878 Fixed showing tooltip on RadionButtonListItem and CheckBoxListItem 2022-11-14 08:52:39 +02:00
msdevcode
4d9c792a25 LayoutPage - Tab "Source" fix (#693) 2022-11-11 17:43:08 +02:00
yordanov
7a6992845a Update Layout demo 2022-11-11 14:05:51 +02:00
Vladimir Enchev
f2deb8f402 Dynamic and version updated 2022-11-10 15:11:11 +02:00
Vladimir Enchev
c067b162b9 Fixed possible exception with SelectBar in .NET 7 2022-11-10 15:10:59 +02:00
Vladimir Enchev
f1415d7583 Fixed DropDown error on KeyPress "Delete"
Fix #691
2022-11-10 14:59:39 +02:00
Atanas Korchev
14f23e79f1 Demonstrate RadzenLayout 2022-11-10 11:51:42 +02:00
Atanas Korchev
a5a55e207c The argument of the ResetPassword event is empty. 2022-11-09 18:05:44 +02:00
Vladimir Enchev
990337e4f4 Version updated 2022-11-09 10:05:20 +02:00
Vladimir Enchev
c35cce7b34 Fixed onmouseenter incompatibility with .NET 7.0
Fix #689
2022-11-09 09:02:48 +02:00
Vladimir Enchev
cb36e60af7 sdk path changed 2022-11-08 19:19:24 +02:00
Vladimir Enchev
65baef92b1 .NET 7 support added 2022-11-08 19:16:34 +02:00
Vladimir Enchev
c624db6833 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2022-11-08 17:14:24 +02:00
Vladimir Enchev
8aed964f47 DatePicker current day "rz-datepicker-currentday" CSS class added
Fix #688
2022-11-08 17:13:44 +02:00
Daniel Nutu
3874cb93e1 fix quotation marks for alert component (#686)
Co-authored-by: DanielNutu <daniel.nutu@kyndryl.com>
2022-11-08 16:57:02 +02:00
Vladimir Enchev
f966d7ab99 Fixed DataGrid ignores sort order when data takes long to load
Fix #687
2022-11-08 16:56:20 +02:00
Vladimir Enchev
2079705626 DatePicker AM/PM buttons style fixed 2022-11-08 09:51:55 +02:00
Atanas Korchev
e0a56d350b Improve support for cases when all RadzenChart series values are negative. Fixes #685. 2022-11-08 09:24:35 +02:00
David Tosi
181aa4f43b Added click event support to the popup Notification Message. (#682)
Co-authored-by: David Tosi <davidtosi@inphonite.com>
2022-11-08 09:24:25 +02:00
Vladimir Enchev
302ba9be44 version updated 2022-11-07 09:56:33 +02:00
Vladimir Enchev
77422c8dda DropDown examples separated 2022-11-04 16:20:31 +02:00
Vladimir Enchev
eead43e0d9 Use getter instead reflection in DropDownBase 2022-11-04 15:09:13 +02:00
Vladimir Enchev
87927d04aa DataGrid settings not saved properly on simple DateTime filter 2022-11-04 14:44:59 +02:00
Vladimir Enchev
aa1b4b2785 Fixed SelectBar items will not show tooltip 2022-11-04 14:31:39 +02:00
Vladimir Enchev
a7f1d7181d DropDownBase will keep selected items by value if ValueProperty is set 2022-11-04 14:11:55 +02:00
Vladimir Enchev
c4a50efa43 version updated 2022-11-03 17:32:35 +02:00
Vladimir Enchev
b30f7d95e2 Dialog Draggable=true fixed 2022-11-03 17:32:13 +02:00
mafei1982
845b8aac1b Fix issue #680 (#681)
* fix issue #673 When trying to filter on a property from parent interface (Current Titem type is also an interface), the FilterPropertyType is null

* rename the private method

* Fix the refactor issue

* Fix issue #680
2022-11-03 13:52:19 +02:00
Vladimir Enchev
d449469a99 DialogService Alert dialog added 2022-11-03 11:28:56 +02:00
Vladimir Enchev
776ae01c7b Close all popups on dialog open 2022-11-03 09:38:58 +02:00
Vladimir Enchev
a9951fc624 DataGrid Save/Load settings with enum filtering fixed
Fix #677
2022-11-02 17:16:26 +02:00
Vladimir Enchev
d8dfcd9cf7 version updated 2022-11-02 09:01:09 +02:00
mafei1982
fac6744ead Fix the missing call to get the type of the property for the interface (#676)
* fix issue #673 When trying to filter on a property from parent interface (Current Titem type is also an interface), the FilterPropertyType is null

* rename the private method

* Fix the refactor issue
2022-11-02 08:39:26 +02:00
Vladimir Enchev
0a539d1328 DataGrid self-ref hierarchy filtering fixed 2022-11-01 20:03:25 +02:00
Vladimir Enchev
3e137d1c0e Tree item expanded state cannot be changed when bound to model
https://forum.radzen.com/t/ontreenodecollapse-backfires-to-ontreenodeexpand-immediately/12122
2022-11-01 16:19:40 +02:00
Vladimir Enchev
8391556f8f code refactored 2022-11-01 11:18:39 +02:00
mafei1982
365374e73e fix issue #673 When trying to filter on a property from parent interf… (#674)
* fix issue #673 When trying to filter on a property from parent interface (Current Titem type is also an interface), the FilterPropertyType is null

* rename the private method
2022-11-01 11:09:56 +02:00
Vladimir Enchev
19a118c096 themes updated 2022-10-31 16:32:15 +02:00
Vladimir Enchev
62a5505c9d disclaimer restored 2022-10-31 16:22:54 +02:00
Vladimir Enchev
60dcb66805 MaterialDark and Fluent themes updated 2022-10-31 16:20:23 +02:00
Vladimir Enchev
51e6306c19 Version updated 2022-10-31 12:01:23 +02:00
yordanov
683453f63a Update alert close button shades 2022-10-31 11:56:26 +02:00
yordanov
366e042c60 Add base-styles-map to dark theme 2022-10-31 11:56:26 +02:00
yordanov
e599d96b7f Update Alert message margins in different sizes 2022-10-31 11:56:26 +02:00
Vladimir Enchev
6f3fde82ef Close button size improved 2022-10-31 11:56:26 +02:00
yordanov
8ba561b55b Add --rz-alert-icon-size 2022-10-31 11:56:26 +02:00
Vladimir Enchev
79ac8e8cd8 Alert ShowIcon property added 2022-10-31 11:56:26 +02:00
yordanov
cb809156f2 Update Alert icons 2022-10-31 11:56:26 +02:00
Vladimir Enchev
d8aa4dde98 getIcon() fixed 2022-10-31 11:56:26 +02:00
yordanov
938fd759c1 Update Alert icons and close button colors 2022-10-31 11:56:26 +02:00
yordanov
2740f54331 Add base, light and dark styles to Alert 2022-10-31 11:56:26 +02:00
Vladimir Enchev
6f929e48b8 example name fixed and docs link removed 2022-10-31 11:56:26 +02:00
yordanov
308db7888a Add Alert Styling demo 2022-10-31 11:56:26 +02:00
yordanov
657a5c5416 Add AlertSize and update scss 2022-10-31 11:56:26 +02:00
Vladimir Enchev
d12f3921f9 code fixed 2022-10-31 11:56:26 +02:00
Vladimir Enchev
601957ba2a Alert Icon property added. Different Icon and close button depending on AlertStyle 2022-10-31 11:56:26 +02:00
yordanov
e12ffb1a75 Add more examples to Alert demo 2022-10-31 11:56:26 +02:00
yordanov
25543b363b Add initial Alert styling 2022-10-31 11:56:26 +02:00
yordanov
3e8ab559b2 Update Alert links in demos navigation 2022-10-31 11:56:26 +02:00
Vladimir Enchev
9059f3f60b Alert component added 2022-10-31 11:56:26 +02:00
Atanas Korchev
aa4ce25bda RadzenLogin does not fire the Login event. Fixes #670. 2022-10-28 20:59:13 +03:00
Atanas Korchev
5ecd9e0782 Setting Stroke of RadzenGridLines has no visual effect. Fixes #669. 2022-10-28 10:20:32 +03:00
Vladimir Enchev
ba84cc7ea6 DropDown/AutoComplete PopupStyle property added instead PopupHeight 2022-10-28 09:20:04 +03:00
Vladimir Enchev
7edae77736 DropDown/AutoComplete PopupHeight property added 2022-10-27 18:22:42 +03:00
Vladimir Enchev
b5f414623e version updated 2022-10-27 09:41:52 +03:00
yordanov
58c92c94f6 Fix 'remember me' margin in Login 2022-10-27 09:37:01 +03:00
yordanov
3f0509b0b9 Remove absolute position of rz-messages-error and width of components in rz-form 2022-10-27 09:23:14 +03:00
yordanov
33858d2679 Fix chart axis font-size 2022-10-26 16:01:40 +03:00
Vladimir Enchev
5d3b4fab0b re-subscribe to FilterValueChange on property change 2022-10-26 15:46:17 +03:00
Vladimir Enchev
6f998cffe9 Member access of interface properties fixed
Fix #665
2022-10-26 15:33:19 +03:00
yordanov
1f520b904f Add margin to remember me switch 2022-10-26 13:18:19 +03:00
yordanov
94c49deaf7 Fix Switch hover outline in material theme 2022-10-26 12:20:49 +03:00
yordanov
4360896634 Add vertical-align: middle to RadzenLabel 2022-10-26 12:16:58 +03:00
yordanov
8513edc118 Add vertical-align: middle to Switch 2022-10-26 12:16:27 +03:00
Atanas Korchev
6dc08ede91 Implement AllowRememberMe functionality in RadzenLogin. 2022-10-26 10:47:28 +03:00
Vladimir Enchev
8f05520c2f Fixed DropDownBase SelectItem() will not work properly in case of IEnummerable with nullable element type 2022-10-25 18:42:30 +03:00
yordanov
0c3878a8fc Improve dialog responsiveness and refactor styles 2022-10-25 09:58:08 +03:00
Vladimir Enchev
e0d9fa6e95 Fixed DataGrid Groups not loaded properly from settings
Fix #664
2022-10-25 09:00:48 +03:00
yordanov
ef5f613b0b Update material dialog content padding and title 2022-10-24 17:41:36 +03:00
Vladimir Enchev
8617557084 Version updated 2022-10-24 17:38:32 +03:00
Vladimir Enchev
55c0fe05cc Fixed virtualized DataGrid exception with LoadData 2022-10-24 17:38:14 +03:00
yordanov
bdaaa9643e Remove duplicate styles of rz-helper-hidden-accessible 2022-10-24 14:09:29 +03:00
yordanov
883ab83c91 Fix box-sizing and trimmed dropdown label with bootstrap 4.6. Resolves #662 2022-10-24 13:18:44 +03:00
Vladimir Enchev
6df9a499ef Version updated 2022-10-24 11:07:10 +03:00
yordanov
2bbb6919b6 Fix initial width of dropdown. Related to #662 2022-10-24 10:44:18 +03:00
Vladimir Enchev
44e0102073 Get first element type only for in-memory data 2022-10-24 09:55:00 +03:00
Vladimir Enchev
a772a2dd51 Fixed DropDownBase support for non generic IEnumerable
Fix #657
2022-10-24 09:26:11 +03:00
Vladimir Enchev
8cd812cf33 DataGrid PageSizeChanged event added 2022-10-24 09:14:10 +03:00
msdevcode
dbf30f4869 Tabindex depending on Disabled-property (#656) 2022-10-24 07:37:04 +03:00
Atanas Korchev
3b5ec52a06 Add ability to customize the scheduler week view header text. 2022-10-23 19:00:24 +03:00
Vladimir Enchev
740e39fb46 Social OnAfterRender changed to OnAfterRenderAsync 2022-10-21 16:34:10 +03:00
Vladimir Enchev
44fff4fc0a Version updated 2022-10-21 16:18:11 +03:00
Vladimir Enchev
acc3a0c9d4 DataFilter FilterProperty FilterOperator change fixed 2022-10-21 16:17:35 +03:00
yordanov
e9f7f9d027 Update width of pickers in datafilter 2022-10-21 15:38:14 +03:00
Vladimir Enchev
3ff9bcf853 Version updated 2022-10-21 10:18:46 +03:00
Vladimir Enchev
18dd011a84 Fixed DataGrid numeric filter will not save settings
Fix #654
2022-10-21 10:10:28 +03:00
Vladimir Enchev
5ccfd4e838 Fixed DataGrid raising twice RowClick/CellClick/RowSelect on double click 2022-10-21 10:00:13 +03:00
Vladimir Enchev
b0baad56e7 DropDown binding and rendering optimized 2022-10-20 19:10:39 +03:00
Vladimir Enchev
0732938d1d Version updated 2022-10-20 10:02:12 +03:00
yordanov
1df2d8da9b Use correct label padding scss variable in dropdown 2022-10-20 09:57:11 +03:00
Vladimir Enchev
dfdc7567f5 DropDownDataGrid chips rendering improved 2022-10-20 09:54:30 +03:00
Vladimir Enchev
3453b7f84c DataFilter FilterTemplate fixed 2022-10-19 13:47:04 +03:00
yordanov
59137196c6 Change dropdown display to inline-flex 2022-10-19 10:49:57 +03:00
Vladimir Enchev
8d686da3fb DataGrid in-line demo improved
Fix #652
2022-10-19 09:31:03 +03:00
Vladimir Enchev
10aa459ebd Fixed Tree will not hide expand/collapse icon when HasChildren changed runtime 2022-10-18 19:34:27 +03:00
msdevcode
a3737624fe Radzen.Blazor.Tests-Project fix (#649) 2022-10-17 21:31:57 +03:00
Vladimir Enchev
70dd7d8744 DataFilter documentation link removed 2022-10-17 15:44:21 +03:00
Vladimir Enchev
8d52a98504 Version updated 2022-10-17 14:47:48 +03:00
yordanov
994166c88f Fix gutter width in dark theme 2022-10-17 13:11:44 +03:00
yordanov
2a9252b53b Add borders to composite cells 2022-10-17 13:04:57 +03:00
Vladimir Enchev
e8ff2a36be Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2022-10-17 11:50:24 +03:00
Vladimir Enchev
9ac700b758 rz-grid-table-composite added in case of composite columns 2022-10-17 11:42:06 +03:00
yordanov
1bf994384d Fix spacing between css classes 2022-10-17 11:36:17 +03:00
yordanov
0258389b61 Update number of components 2022-10-17 11:06:11 +03:00
yordanov
8491807987 Update package tags 2022-10-17 10:54:03 +03:00
Vladimir Enchev
e95d07fee1 Fixed virtualized DataGrid bound with LoadData not scrolled to top on sort 2022-10-17 09:49:01 +03:00
Vladimir Enchev
7b0d07e116 DataGrid second filter value not saved properly in Settings 2022-10-17 09:18:19 +03:00
msdevcode
5228ed8543 RadzenSelectBar - RadzenSelectBarItem add disabled-property (#647) 2022-10-17 09:15:06 +03:00
Vladimir Enchev
8f5550576f Fixed DataGrid save settings in case of column FIlterTemplate 2022-10-14 10:09:19 +03:00
Vladimir Enchev
c51e4b5411 Fixed DataGrid paging with Settings when bound with LoadData and
Fix #644
2022-10-14 09:55:42 +03:00
yordanov
ef3918f50c Fix PanelMenu expand/collapse with ripple 2022-10-13 16:57:29 +03:00
Vladimir Enchev
2b29e5371d Version updated 2022-10-13 08:49:58 +03:00
Vladimir Enchev
249815607e Fixed DataGrid groups not saved properly in Settings
Fix #642
2022-10-13 08:48:58 +03:00
Vladimir Enchev
b9f9138ae4 DropDown with groups demo filtering fixed
Fix #641
2022-10-12 08:57:41 +03:00
Vladimir Enchev
00296bacf2 DataGrid grouping API demo improved 2022-10-11 12:05:13 +03:00
Vladimir Enchev
18e6771fcc Delay added to TooltipOptions 2022-10-11 10:21:59 +03:00
yordanov
0c8131ebb3 Fix icon alignment in fieldset legend 2022-10-10 15:27:39 +03:00
Vladimir Enchev
831f0209ae Map demo update with InfoWindow 2022-10-10 15:18:36 +03:00
Vladimir Enchev
488fc2719f Fixed collection was modified exception in DropDownDataGrid
Fix #639
2022-10-06 16:35:49 +03:00
yordanov
ba98d6dfef Show up down arrows in Numeric with text-align 2022-10-06 09:45:10 +03:00
Vladimir Enchev
45d9b69191 version updated 2022-10-06 09:41:19 +03:00
yordanov
5205c94c73 Update Dialog demos 2022-10-06 09:35:25 +03:00
Vladimir Enchev
953bc6370a Tree Collapse event added 2022-10-06 09:14:41 +03:00
Ernesto Roque
7ffd7b10f5 adding Chips support to DropDownDataGrid (#637) 2022-10-06 08:50:59 +03:00
Vladimir Enchev
2a054bce6e Numeric CSS classes fixed 2022-10-05 18:32:42 +03:00
yordanov
de1ed66aaa Fix numeric input right padding 2022-10-05 17:44:51 +03:00
yordanov
caeeee9109 Update validation styles in Login component 2022-10-05 17:31:24 +03:00
Vladimir Enchev
3c9368b05f DataGrid save/load Settings for PageSize change fixed
Fix #633
2022-10-04 09:58:39 +03:00
yordanov
e31567727a Update project icon 2022-10-04 09:39:46 +03:00
nanocortex
7b761c50d7 Add Separator parameter to Dropdown (#631) 2022-10-03 20:19:00 +03:00
Vladimir Enchev
11306a3ce5 Version updated 2022-10-03 17:18:18 +03:00
yordanov
9d23d4df1f Update DataGrid inline editing demo 2022-10-03 16:34:28 +03:00
yordanov
45c35d1d37 DataGrid Density styles and demo 2022-10-03 15:48:29 +03:00
Vladimir Enchev
7b1c7cbcb2 DataGrid Density property added 2022-10-03 15:05:28 +03:00
Vladimir Enchev
01b4431627 DataGrid simple filter row frozen cells class fixed 2022-10-03 14:39:41 +03:00
yordanov
70b478a4b7 Add ExtraSmall button size 2022-10-03 12:10:07 +03:00
Christian Gräfe
6e7d227504 Added Text-Align to RadzenNumeric (#627) 2022-10-03 10:33:35 +03:00
Charles-André Beaudry
962afaf613 [Docs] Fix miscellaneous annoyances in the docs (#622)
* Adjust indentation

* Remove html leftovers?
2022-10-03 10:32:37 +03:00
Vladimir Enchev
ad0ba5d3bf CheckBoxList AllowSelectAll and SelectAllText properties added
Fix #628
2022-10-03 10:31:35 +03:00
Vladimir Enchev
6c729deb77 Tooltip will execute TooltipService.Close when closing on outside click or duration 2022-09-30 11:15:59 +03:00
Vladimir Enchev
0e887d8b28 ContextMenu will execute ContextMenuService.Close event when clicking outside 2022-09-30 11:08:41 +03:00
Vladimir Enchev
8fdaf68707 Fixed DataGrid filtering by bool column will not save settings 2022-09-30 10:13:10 +03:00
Atanas Korchev
0bbbf70e81 Update premium themes. 2022-09-29 17:55:29 +03:00
yordanov
1342c306a3 Add updated tag to Menu demos 2022-09-29 17:38:26 +03:00
yordanov
8890ae4520 Fix tabs padding in material theme 2022-09-29 17:26:56 +03:00
yordanov
72d6fa5454 Set bootstrap grid-gutter-width value to 2rem 2022-09-29 16:07:35 +03:00
Vladimir Enchev
1f700a80bc Version updated 2022-09-29 15:05:17 +03:00
yordanov
d9a25c88e7 Make dropdown label right padding as smaller as possible 2022-09-29 13:51:55 +03:00
yordanov
e060b80b67 Update css selectors for DataGrid selection 2022-09-29 13:26:00 +03:00
yordanov
45687e665d Scope grid alternating rows to tbody only. Fixes #625 2022-09-29 13:10:38 +03:00
yordanov
5a3dffbc98 Update Menu demo page 2022-09-29 12:07:11 +03:00
yordanov
9e932f025f Reduce top item x-padding in material menu 2022-09-29 12:06:47 +03:00
yordanov
5ea729d0d0 Update Menu styling. Fixes #623 2022-09-29 11:12:43 +03:00
yordanov
67b6c52031 Fix sidebar z-index 2022-09-29 11:12:43 +03:00
yordanov
8b9c26c12b Fix grid data row class in table-reflow 2022-09-29 11:12:43 +03:00
Vladimir Enchev
bede7d3fc9 DataGrid settings saved on clear column filter 2022-09-29 11:06:46 +03:00
Vladimir Enchev
cf2d4b890a preventPopupDefault removed 2022-09-29 09:14:37 +03:00
Vladimir Enchev
3aa05efe9c Fixed cannot edit DatePicker time parts 2022-09-28 22:40:08 +03:00
Vladimir Enchev
ac00b513a8 DataGrid columns reset on Settings clear 2022-09-28 21:19:18 +03:00
Vladimir Enchev
7fb4f6de65 DataGrid column filter saved in settings cleared on filter 2022-09-28 21:07:48 +03:00
yordanov
26251a2158 Grid alternating rows inverted 2022-09-28 16:51:22 +03:00
Vladimir Enchev
4a0b1f8f10 DataGrid exception fixed on select/deselect all columns from column picker 2022-09-28 16:40:55 +03:00
Vladimir Enchev
d6cce4a11b Fixed Tree AllowCheckParents behavior
Fix #593
2022-09-28 16:32:05 +03:00
Vladimir Enchev
2ad79ea3d1 DataGrid self-ref items indent with multiple parent items on same level fixed
Fix #617
2022-09-28 12:30:47 +03:00
Vladimir Enchev
82ce761b88 DataGrid AllowPickAllColumns property added 2022-09-28 09:18:37 +03:00
Vladimir Enchev
d1241a6997 DropDown/ListBox AllowSelectAll property added 2022-09-28 09:07:32 +03:00
Vladimir Enchev
eb28720cd2 code fixed 2022-09-27 18:42:53 +03:00
Vladimir Enchev
436a36a704 Version updated 2022-09-27 18:30:54 +03:00
yordanov
c2298b2ae0 Fix selectable grid row hover styles 2022-09-27 17:30:01 +03:00
Vladimir Enchev
9bc1431291 rz-data-row class added to DataGrid data rows 2022-09-27 17:13:18 +03:00
yordanov
695a57153a Update standard base theme pager buttons and shadows 2022-09-27 16:00:35 +03:00
yordanov
b19ce01e2e Fix Pager selected button padding 2022-09-27 16:00:35 +03:00
Vladimir Enchev
d0c74b73dc DataGrid simple filter mode with nullable enums improved
Fix #620
2022-09-27 15:47:07 +03:00
yordanov
673fce5054 Fix background of menu top items with material theme 2022-09-27 15:26:22 +03:00
yordanov
9195f7ed31 Fix alignment of menu top items and reorder scss variables 2022-09-27 15:25:23 +03:00
yordanov
baf97b205f Fix steps widget content overflow 2022-09-27 13:23:34 +03:00
Vladimir Enchev
13da03396f Fixed touch keyboard closes popup in Windows 2022-09-27 09:05:00 +03:00
Vladimir Enchev
52846e3bf2 avoid null ref. exception on string filter 2022-09-26 21:47:24 +03:00
Vladimir Enchev
164c43e2e5 DataFilterProperty GetFilterOperators() made virtual and example added 2022-09-26 21:42:31 +03:00
Vladimir Enchev
3af93df990 Version updated 2022-09-26 16:40:44 +03:00
Vladimir Enchev
6026d27b18 LoadSettings code improved 2022-09-26 16:20:05 +03:00
Vladimir Enchev
ba8786c4fe DataGrid load settings fixed 2022-09-26 16:18:19 +03:00
Atanas Korchev
5650349868 Premium themes (#619)
* Show premium themes in the online demo.

* Set the id of the theme dropdown.

* Update colors in theme picker

* Style theme picker with Pro badges

* Update pro themes.

Co-authored-by: yordanov <vasil@yordanov.info>
2022-09-26 14:15:10 +03:00
yordanov
8bd3c32a65 Update logos 2022-09-26 12:05:56 +03:00
Vladimir Enchev
07623acf41 Save/load settings demo reworked to use ProtectedLocalStorage 2022-09-26 11:22:57 +03:00
Vladimir Enchev
446629b9f8 DataGridSettingsService deleted 2022-09-26 11:09:35 +03:00
Vladimir Enchev
21dca42e33 Save/Load settings demo reworked 2022-09-26 11:01:15 +03:00
Vladimir Enchev
7c5c9fc8be demo text updated 2022-09-26 09:59:48 +03:00
Vladimir Enchev
b2262ad4b8 Version updated 2022-09-26 09:54:22 +03:00
Vladimir Enchev
4f7aba1e4b PageSize added to DataGridSettings 2022-09-26 09:48:01 +03:00
Vladimir Enchev
2bfbc68df8 Save/Load DataGrid runtime settings added (#618) 2022-09-26 09:44:43 +03:00
yordanov
682ae2ed59 Update logos on demos homepage 2022-09-26 09:40:59 +03:00
yordanov
a13705c1fe Fix link text decoration in Panel, SplitButton and Steps with -base themes 2022-09-23 17:25:00 +03:00
yordanov
e4f4ba46f5 Add rz- prefix to all login CSS classes 2022-09-23 16:40:08 +03:00
yordanov
1f4b343a2e Update Login component CSS classes and styles 2022-09-23 16:36:10 +03:00
yordanov
f4e01f42c5 Add pointer cursor to rz-link 2022-09-23 16:36:10 +03:00
Vladimir Enchev
7416ea1a54 DropDownBase HasValue will check if value has items in case of multiple selection 2022-09-23 14:02:49 +03:00
yordanov
b9593b7b4c Add font-smoothing to demos 2022-09-23 10:12:28 +03:00
yordanov
43d7725522 Fix cards position 2022-09-23 10:12:28 +03:00
aaayd
d8d3a392b2 Implement Navigation on Filtered Sidebar (#612)
Implements navigation on the sidebar when filtered with navigation items which do not include children.
This will also implement the Icon for the navigation item.
2022-09-23 09:26:54 +03:00
starkuss
5a36e72616 enable possibility to add custom css class to dialog (#616) 2022-09-23 09:25:37 +03:00
Atanas Korchev
e9bfe72914 Update docs to use base themes instead of full. 2022-09-22 18:58:07 +03:00
Vladimir Enchev
db23f28388 Version updated 2022-09-22 17:09:32 +03:00
yordanov
46bd9a5324 Update demos to use Bootstrap 5 layout css classes 2022-09-22 16:48:22 +03:00
yordanov
d225b6d454 Scope base themes to style radzen components only 2022-09-22 16:48:22 +03:00
yordanov
17fb991744 Add theme's font-family to RadzenText component 2022-09-22 16:48:22 +03:00
yordanov
1035d413de Add --rz-text-font-family and --rz-body-background-color css variables 2022-09-22 16:48:22 +03:00
yordanov
9bbccb72e4 Fix fieldset legend float in Bootstrap 5 2022-09-22 16:48:22 +03:00
yordanov
4b525256fb Fix link text-decoration in components 2022-09-22 16:48:22 +03:00
Vladimir Enchev
960059e307 DataFilter should filter on operator change 2022-09-22 10:58:52 +03:00
Atanas Korchev
0941627527 Use full bootstrap and -base.css for the themes. 2022-09-22 10:18:13 +03:00
Vladimir Enchev
efea8c451b DataGrid self-reference filtering improved 2022-09-22 09:43:36 +03:00
Vladimir Enchev
d9811f4ff1 datafilter link fixed 2022-09-21 18:32:45 +03:00
Vladimir Enchev
11e6713f20 README.md path fixed 2022-09-21 17:43:48 +03:00
Vladimir Enchev
0d37538778 Version updated 2022-09-21 17:40:42 +03:00
yordanov
c88f8bb277 Update grid hieararchy demo tags 2022-09-21 17:29:40 +03:00
yordanov
cd8a8ba310 Update styles for alternating rows 2022-09-21 17:16:30 +03:00
yordanov
9cb81c5fb8 Update new/updated demo tags 2022-09-21 16:31:24 +03:00
Vladimir Enchev
e2d3dc1258 DataGrid AllowAlternatingRows property added 2022-09-21 16:26:51 +03:00
Vladimir Enchev
3c51397be8 SplitButton will close popup on default action 2022-09-21 16:09:21 +03:00
Vladimir Enchev
84d51bf653 RenderMode renamed to PopupRenderMode 2022-09-21 15:35:33 +03:00
Vladimir Enchev
70c541b06f DataGrid self-reference hierarchy support added (#613)
* DataGrid self-reference hierarchy added

* Self ref demo inherited from DbContextPage

* Update grid self reference demo

* rz-cell-toggle added

* rzi-grid-sort removed from expand icon

* Style rz-cell-toggle in DataGrid

Co-authored-by: yordanov <vasil@yordanov.info>
2022-09-21 15:27:56 +03:00
yordanov
79a7095739 Rename Text page 2022-09-21 12:28:40 +03:00
yordanov
cf7fbf0b83 Update Tabs demo 2022-09-21 12:28:35 +03:00
yordanov
f1bf807b67 Update Card demo 2022-09-21 12:26:12 +03:00
Vladimir Enchev
f02581d20a DatePicker PopupRenderMode property added (#611)
* Experiment with on demand popup rendering.

* Delay the open until the popup content has rendered.

* DatePicker PopupRenderMode property added

* DatePicker RenderMode.Initial improved

* ColorPicker PopupRenderMode added

Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2022-09-21 11:14:51 +03:00
Vladimir Enchev
03450fc4f7 Fixed DropDown SelectAll InvalidCastException when bind-Value is IList
Fix #610
2022-09-21 08:44:52 +03:00
Atanas Korchev
5e0eaa529f Update theme instructions. 2022-09-20 19:35:23 +03:00
Vladimir Enchev
56184370a7 DataFilter nested filters fixed 2022-09-20 18:23:15 +03:00
yordanov
6fdc672dc4 Fix height of slots and events in Scheduler 2022-09-20 16:41:00 +03:00
yordanov
ec82a24910 Style labels in bootstrap forms 2022-09-20 16:27:16 +03:00
Atanas Korchev
06157a9e5c Add rz-form class to RadzenTemplateForm. 2022-09-20 16:18:02 +03:00
Vladimir Enchev
a53022bac0 DataFilter component added (#608)
* RadzenDataFilter added

* Add SplitButton Variants, ButtonStyles and Shades

* Add Flat variant to Button and Button gap

* Add SelectBar Size

* Add initial DataFilter styles

* rz-datafilter-group-item class added

* reset filter on property change

* missing rz-datafilter-group-item added

* rz-datafilter-group-item fixed

* inner filter add fixed

* code reworked

* Make datagrid's filter buttons flat

* Update filter node paths

Co-authored-by: yordanov <vasil@yordanov.info>
2022-09-20 14:59:15 +03:00
Vladimir Enchev
896c775fef DataGridCellSelect improved 2022-09-20 13:45:57 +03:00
Vladimir Enchev
f907d689e5 DataGridCellSelect demo improved 2022-09-20 13:28:44 +03:00
Vladimir Enchev
90a9850034 Cell selection color changed to rz-secondary-lighter 2022-09-20 12:19:13 +03:00
Vladimir Enchev
4418d348c5 DataGrid CellClick/CellDoubleClick events and example for cell selection added. 2022-09-20 11:36:36 +03:00
Vladimir Enchev
7ce93da521 DbContext demos reworked with DbContextFactory 2022-09-19 17:21:28 +03:00
Vladimir Enchev
aeb08616b5 DataGrid groups change event disposed 2022-09-19 11:07:04 +03:00
Vladimir Enchev
a10df3a133 reference disposed 2022-09-19 11:00:02 +03:00
Vladimir Enchev
c4039f5663 Force GC on example dispose 2022-09-19 10:50:51 +03:00
Vladimir Enchev
30df4a257a DataGrid column picker not updated when setting column Visible property with code 2022-09-16 19:00:29 +03:00
yordanov
6f0df065ad Update badge size in sidebar 2022-09-16 18:24:01 +03:00
yordanov
8cfc5567d1 Fix Badge bootstrap overrides 2022-09-16 18:24:01 +03:00
Vladimir Enchev
32defc6833 GoogleMap component should not reset zoom and center on marker update. Options property added. 2022-09-16 17:45:43 +03:00
yordanov
4485cf33df Fix border-radius of outlined buttons 2022-09-16 17:39:55 +03:00
Vladimir Enchev
d7638ea764 DataGrid multi sort column index indicator now is Badge 2022-09-16 15:36:15 +03:00
yordanov
d334a472ce Update grid header cell layout based on text-align 2022-09-16 15:15:38 +03:00
Vladimir Enchev
19672dba39 DataGrid column text-align fixed
Fix #606
2022-09-16 10:00:32 +03:00
Vladimir Enchev
24358eeb51 Readme added 2022-09-16 09:27:05 +03:00
Vladimir Enchev
c1a823cd42 Description updated 2022-09-16 09:18:52 +03:00
Vladimir Enchev
849c4982a8 Version updated 2022-09-15 16:07:40 +03:00
yordanov
032d6a1ae1 Update new and updated demo badges 2022-09-14 15:19:03 +03:00
yordanov
b012c48e62 Hide link to docs 2022-09-14 15:19:03 +03:00
yordanov
76aa0f70aa Use css color variables in conditional template 2022-09-14 15:19:03 +03:00
yordanov
1c3c525d2b Make rz-cell-data overflow visible if content is button or checkbox 2022-09-14 15:19:03 +03:00
yordanov
9042b16df4 Add fill color to rz-donut-title 2022-09-14 15:19:03 +03:00
yordanov
1f9198964b Fix z-index of fetching data panel in dashboard demo 2022-09-14 15:19:03 +03:00
yordanov
698513ea84 Update Badge child content demo 2022-09-14 15:19:03 +03:00
yordanov
0cb68d9b5d Fix rz-grid-filter padding 2022-09-14 15:19:03 +03:00
yordanov
221a0942ab Fix standard theme secondary color 2022-09-14 15:19:03 +03:00
yordanov
c83fcc4602 Add Dark styles, Shade styles, Outline and Text variants to Button and Badge 2022-09-14 15:19:03 +03:00
yordanov
b51abc68a8 Update DataList demo styles 2022-09-14 15:19:03 +03:00
yordanov
9040c32f52 Add Pager responsive styles 2022-09-14 15:19:03 +03:00
yordanov
dc81c7244a Update demos layouts and headings 2022-09-14 15:19:03 +03:00
yordanov
62debd3df4 Add functional text css variables 2022-09-14 15:19:03 +03:00
yordanov
a048cf0f23 Update support page 2022-09-14 15:19:03 +03:00
yordanov
50ed79c0b3 Fix content scroll in Steps and add padding to Steps prev next buttons 2022-09-14 15:19:03 +03:00
yordanov
b6963c7cab Remove text uppercase in lg button 2022-09-14 15:19:03 +03:00
yordanov
9f5af15987 Fix demo layouts 2022-09-14 15:19:03 +03:00
yordanov
5119048f33 Update heading styles 2022-09-14 15:19:03 +03:00
yordanov
090f45092c Remove checkbox and radio margin 2022-09-14 15:19:03 +03:00
yordanov
925e36e33b Fix demo layouts and typography 2022-09-14 15:19:03 +03:00
yordanov
720b64ff90 Update layout in dropdown demo 2022-09-14 15:19:03 +03:00
yordanov
4cd9f11f0b Fix padding of dropdown with chips 2022-09-14 15:19:03 +03:00
yordanov
1b54504165 Update console message styles 2022-09-14 15:19:03 +03:00
yordanov
080e514527 Remove unused css classes 2022-09-14 15:19:03 +03:00
yordanov
392ed8b517 Style Chips in DropDown 2022-09-14 15:19:03 +03:00
yordanov
546701894d CLose RadzenText in Upload demo 2022-09-14 15:19:03 +03:00
yordanov
b90139aee4 Fix title text overflow in demos header 2022-09-14 15:19:03 +03:00
yordanov
5d39b554e0 Fix background in ripple demo 2022-09-14 15:19:03 +03:00
yordanov
51b9ab3661 Update headings in steps demo 2022-09-14 15:19:03 +03:00
yordanov
b58672b8ec Update images in get started article 2022-09-14 15:19:03 +03:00
yordanov
4148b57819 Fix steps disabled state 2022-09-14 15:19:03 +03:00
yordanov
8a9f0ddd24 Add Material theme 2022-09-14 15:19:03 +03:00
yordanov
4ccc377f1c Update demos layouts and headings 2022-09-14 15:19:03 +03:00
yordanov
dc56d18595 Remove button-sizes from standard theme 2022-09-14 15:19:03 +03:00
yordanov
ff78f68443 Add button min-width in standard theme 2022-09-14 15:19:03 +03:00
yordanov
5b52b070d9 Fix h6 font-size 2022-09-14 15:19:03 +03:00
yordanov
8f28becd6c Fix validator callout and paddings 2022-09-14 15:19:03 +03:00
yordanov
14212a744a Fix calendar input padding-right 2022-09-14 15:19:03 +03:00
yordanov
cb0af54ab4 Update card box-shadow 2022-09-14 15:19:03 +03:00
yordanov
b6b737a0cd Add UI Fundamentals demos 2022-09-14 15:19:03 +03:00
yordanov
092ec1a8f0 Fix usege of --border-radius-* 2022-09-14 15:19:03 +03:00
yordanov
9476d8bbcd Add scss mixins and fill-in missing utility maps 2022-09-14 15:19:03 +03:00
yordanov
72e4a6ccc7 Fix naming and generation of border css variables 2022-09-14 15:19:03 +03:00
yordanov
73d2c83d8e Refactor generation of css variables and utility classes 2022-09-14 15:19:03 +03:00
yordanov
540b315213 Fix background colors in dark theme 2022-09-14 15:19:03 +03:00
yordanov
9594014358 Add link text-decoration variables and update border css classes 2022-09-14 15:19:03 +03:00
yordanov
d3e781607d Update font-weights of default headings 2022-09-14 15:19:03 +03:00
yordanov
e9d6874ff5 Add text-decoration, hover and focus styles to rz-link 2022-09-14 15:19:03 +03:00
yordanov
729b43cd54 Fix grid filter and date filter dropdown layouts 2022-09-14 15:19:03 +03:00
yordanov
5278060aaa Add background-color to rz-calendar-inline 2022-09-14 15:19:03 +03:00
yordanov
d25a1e8463 Add fill to rz-series-data-label and update chart tooltip padding 2022-09-14 15:19:03 +03:00
yordanov
24e260dc0d Update texts in Dashbboard example 2022-09-14 15:19:03 +03:00
yordanov
ea6a010c5e Fix variable font-sizes in typography headings 2022-09-14 15:19:03 +03:00
yordanov
07715fd541 Add CSS vars to RadzenText 2022-09-14 15:19:03 +03:00
yordanov
6b9e0e60c5 Add CSS classes for colors 2022-09-14 15:19:03 +03:00
yordanov
1040b041a4 Update scss variables in themes 2022-09-14 15:19:03 +03:00
yordanov
914dcced2b Close strong tag in title 2022-09-14 15:19:03 +03:00
yordanov
520d2bf0a8 Replace demo headings and paragraphs with RadzenText component 2022-09-14 15:19:03 +03:00
yordanov
886a09553f Update SCSS variables - names and values 2022-09-14 15:19:03 +03:00
yordanov
9436fa50b8 Set background color to files upload clear button in dark theme 2022-09-14 15:19:03 +03:00
yordanov
feae293d17 Add fieldset legend margin scss variable 2022-09-14 15:19:03 +03:00
yordanov
8eba025e02 Add rating ban icon color variable 2022-09-14 15:19:03 +03:00
yordanov
060f5dfd6c Add overflow hidden to listbox wrapper 2022-09-14 15:19:03 +03:00
yordanov
e3e3bb2731 Fix dropdown item border radius 2022-09-14 15:19:03 +03:00
yordanov
1082dd5aa4 Fix grid filter row background and padding 2022-09-14 15:19:03 +03:00
yordanov
aaba37325b Update dropdown min-width 2022-09-14 15:19:03 +03:00
yordanov
fe225efde5 Remove btn- css classes 2022-09-14 15:19:03 +03:00
yordanov
1726a45738 Fix colors of remove upload files button 2022-09-14 15:19:03 +03:00
yordanov
09f3ebec80 Remove sort icon color from standard theme 2022-09-14 15:19:03 +03:00
yordanov
f8a4534496 Add initial shadow values 2022-09-14 15:19:03 +03:00
yordanov
299833b974 Add button min-width 2022-09-14 15:19:03 +03:00
yordanov
317a1cd8ca Fix navigation link cursor 2022-09-14 15:19:03 +03:00
yordanov
81d7ecde04 Fix numeric button border radius 2022-09-14 15:19:03 +03:00
yordanov
1377769eff Fix LogicalFilterOperator dropdown width 2022-09-14 15:19:03 +03:00
yordanov
1cbde75953 Fix resize, sort, reorder and composite-cell behavior of grid header cells 2022-09-14 15:19:03 +03:00
yordanov
72d16e22be Add background and color to remove file button 2022-09-14 15:19:03 +03:00
yordanov
8fa6721a26 Add color variables for notification icons 2022-09-14 15:19:03 +03:00
yordanov
aeb2355d75 Remove cursor when hue and alpha pickers are active 2022-09-14 15:19:03 +03:00
yordanov
81a3adb483 Add background color to color picker button 2022-09-14 15:19:03 +03:00
yordanov
8298a22023 Fix content alignment in breadcrumb links 2022-09-14 15:19:03 +03:00
yordanov
c3612ec9a6 Update dropdown scss variables - new trigger-icon and item-border-radius 2022-09-14 15:19:03 +03:00
yordanov
c05f158663 Add box-shadow to slider handle and reorder variables 2022-09-14 15:19:03 +03:00
yordanov
671851f345 Reorder switch scss variables 2022-09-14 15:19:03 +03:00
yordanov
1611429d83 Fix transitions and border width between states of radio button 2022-09-14 15:19:03 +03:00
yordanov
a8593078ad Use vertical-offest instead of margin for second level menus 2022-09-14 15:19:03 +03:00
yordanov
6165c25976 Add CSS variables to set margin and border-radius to second level items in panel menu 2022-09-14 15:19:03 +03:00
yordanov
47598a9d7a Add line-height CSS variable to steps number 2022-09-14 15:19:03 +03:00
yordanov
09c727e91a Add color variables for icon in menu item 2022-09-14 15:19:03 +03:00
yordanov
0619557f05 Add border-radius to menu top item 2022-09-14 15:19:03 +03:00
yordanov
aa5a9c6c2d Fix navigation item active indicator margin 2022-09-14 15:19:03 +03:00
yordanov
e3ad81926e Add menu-item-border-radius var 2022-09-14 15:19:03 +03:00
yordanov
37abd6d5b8 Rename sidebar-toggle CSS class to rz-sidebar-toggle 2022-09-14 15:19:03 +03:00
yordanov
5a7499c80e Reorder sidebar-toggle scss variables 2022-09-14 15:19:03 +03:00
yordanov
ce3bb23b8c Add accordion header margin and border-top 2022-09-14 15:19:03 +03:00
yordanov
845d5b2351 Update demos layout 2022-09-14 15:19:03 +03:00
yordanov
08ee361c9c Add special color classes to utilities 2022-09-14 15:19:03 +03:00
yordanov
c6e6a4bd7d Fix FileInput delete button onclick 2022-09-14 15:19:03 +03:00
yordanov
85b571594c Refactor Button, Card and PanelMenu styles 2022-09-14 15:19:03 +03:00
Atanas Korchev
5088c94db5 Some documentation and default property values. 2022-09-14 15:19:03 +03:00
Atanas Korchev
2dc9e9e04c Allow tag name overriding. 2022-09-14 15:19:03 +03:00
Atanas Korchev
2752c641ed Add RadzenText. 2022-09-14 15:19:03 +03:00
yordanov
4c0b6bff9d Update grid columns' width 2022-09-14 15:19:03 +03:00
yordanov
5acebc3e44 Update title in dashboard example 2022-09-14 15:19:03 +03:00
yordanov
1e8c065fdb Update Typography page 2022-09-14 15:19:03 +03:00
yordanov
b35775b3e0 Update demos layout 2022-09-14 15:19:03 +03:00
yordanov
0693853c0a Fix button height 2022-09-14 15:19:03 +03:00
yordanov
6994d12eb6 Update demos layout to fixed width 2022-09-14 15:19:03 +03:00
yordanov
dc0dda35fc Fix event list button top position unit 2022-09-14 15:19:03 +03:00
yordanov
085fc2a764 Style scheduler event list button 2022-09-14 15:19:03 +03:00
yordanov
7ecae9e3a2 Style grid group header item 2022-09-14 15:19:03 +03:00
yordanov
61d687882f Add Large button size 2022-09-14 15:19:03 +03:00
yordanov
354eed23b9 Update humanistic theme vars 2022-09-14 15:19:03 +03:00
yordanov
99996613bc Update main color variables in dark theme 2022-09-14 15:19:03 +03:00
yordanov
c6e7b1d68a Fix shadow variable 2022-09-14 15:19:03 +03:00
yordanov
69e9823640 Add Typography demo 2022-09-14 15:19:03 +03:00
yordanov
6e74d02e95 Fix colorpicker hover state in editor 2022-09-14 15:19:03 +03:00
yordanov
397d3073c6 Add default typography styles 2022-09-14 15:19:03 +03:00
yordanov
ecba921352 Update github icon color 2022-09-14 15:19:03 +03:00
yordanov
bea36fdcb5 Update main theme color scss variables 2022-09-14 15:19:03 +03:00
yordanov
0379e0ee6d Fix slot header and slot title font-sizes 2022-09-14 15:19:03 +03:00
yordanov
787a48a795 Update chart color schemes with css vars 2022-09-14 15:19:03 +03:00
yordanov
ce257fcc95 Add scss variables for colors in notification 2022-09-14 15:19:03 +03:00
yordanov
becc50d2b8 Remove inline styles in time picker OK button 2022-09-14 15:19:03 +03:00
yordanov
673be6056c Fix toggle icon order in accordion 2022-09-14 15:19:03 +03:00
yordanov
5c7b19527d Update progressbar style scss vars 2022-09-14 15:19:03 +03:00
yordanov
4304099d3a Add more shadow variables 2022-09-14 15:19:03 +03:00
yordanov
5911968469 Fix numeric button alignment and spacing in pager 2022-09-14 15:19:03 +03:00
yordanov
6afde15a1d Reorder css rules 2022-09-14 15:19:03 +03:00
yordanov
ab578f499c Refactor pager scss variables 2022-09-14 15:19:03 +03:00
yordanov
e78c3bc6aa Refactor grid scss variables 2022-09-14 15:19:03 +03:00
yordanov
6394a8ee76 Refactor datalist scss variables 2022-09-14 15:19:03 +03:00
yordanov
5f4e62824f Add button size examples 2022-09-14 15:19:03 +03:00
yordanov
f1966f42de Refactor tree scss variables 2022-09-14 15:19:03 +03:00
yordanov
704039afc2 Remove inline styles of checkbox in tree 2022-09-14 15:19:03 +03:00
yordanov
b1c9b27f17 Refactor scheduler variables 2022-09-14 15:19:03 +03:00
yordanov
3a1c0a707a Use RadzenButton in nav-views 2022-09-14 15:19:03 +03:00
yordanov
781c28044a Remove icon css classes 2022-09-14 15:19:03 +03:00
yordanov
76346a435a Add rz-button-box container 2022-09-14 15:19:03 +03:00
yordanov
a4ebe3532b Update tabs variables 2022-09-14 15:19:03 +03:00
yordanov
189c8c5a2a Update switch background colors and sizing 2022-09-14 15:19:03 +03:00
yordanov
c1c50fcdb0 Add slider handle transitions 2022-09-14 15:19:03 +03:00
yordanov
aad91c32d1 Add radio border-width 2022-09-14 15:19:03 +03:00
yordanov
b80a84822e Update panel icon size 2022-09-14 15:19:03 +03:00
yordanov
3e4f86d5fe Update panel-menu styles 2022-09-14 15:19:03 +03:00
yordanov
3cb9fa6926 Add pager border-radius and button hover styles 2022-09-14 15:19:03 +03:00
yordanov
900fe003d4 FIx numeric input padding 2022-09-14 15:19:03 +03:00
yordanov
3c923f7a20 Fix input focus styles 2022-09-14 15:19:03 +03:00
yordanov
6d95c85719 Use proper icon size variable 2022-09-14 15:19:03 +03:00
yordanov
5a0bdb6358 Add checkbox border-width and fix background 2022-09-14 15:19:03 +03:00
yordanov
49f8d7ac56 Fix autocomplete background, transition and transform styles 2022-09-14 15:19:03 +03:00
yordanov
fd99d88510 Add Accordion toggle icon variables 2022-09-14 15:19:03 +03:00
yordanov
29f37bbe43 Add line-height to button 2022-09-14 15:19:03 +03:00
yordanov
1567dd6163 Remove inline style 2022-09-14 15:19:03 +03:00
yordanov
297d0b7466 Update DropDown styles 2022-09-14 15:19:03 +03:00
yordanov
7db378a8c8 Update filtering dropdown width 2022-09-14 15:19:03 +03:00
yordanov
3f5c73ca26 Remove inline margin 2022-09-14 15:19:03 +03:00
yordanov
53f7ddcb82 Add initial typography styles 2022-09-14 15:19:03 +03:00
yordanov
1f54a40147 Update font size 2022-09-14 15:19:03 +03:00
yordanov
4c3cdaf593 Update Roboto font 2022-09-14 15:19:03 +03:00
yordanov
af00eeaf2a Fix border-radius variable 2022-09-14 15:19:03 +03:00
yordanov
ed5629f7cf Add context menu padding 2022-09-14 15:19:03 +03:00
yordanov
88d1854b0d Update theme constants 2022-09-14 15:19:03 +03:00
yordanov
328cb3a4dc Add toggle icon font-size 2022-09-14 15:19:03 +03:00
yordanov
a1c83ebb10 Add font-size and icon-size variables 2022-09-14 15:19:03 +03:00
yordanov
d440a78c7b Update themes 2022-09-14 15:19:03 +03:00
yordanov
6e643d7cda Fix scss vars 2022-09-14 15:19:03 +03:00
yordanov
0f705bd755 Update dark theme 2022-09-14 15:19:03 +03:00
yordanov
f436e44233 Update base palette 2022-09-14 15:19:03 +03:00
yordanov
29f6c5907c Update color variables 2022-09-14 15:19:03 +03:00
yordanov
a4d5015875 Add font smoothing 2022-09-14 15:19:03 +03:00
yordanov
e8aa282a3a Update theme colors 2022-09-14 15:19:03 +03:00
yordanov
44dc55822d Update transitions 2022-09-14 15:19:03 +03:00
yordanov
473bc16384 Add transitions 2022-09-14 15:19:03 +03:00
yordanov
8984a1baf6 Add utilities and typography under components 2022-09-14 15:19:03 +03:00
yordanov
8fda96eabf Organize default global variables 2022-09-14 15:19:03 +03:00
yordanov
5110c5d248 Add css vars and update colors 2022-09-14 15:19:03 +03:00
yordanov
d23bdee6ed Add css vars and update colors 2022-09-14 15:19:03 +03:00
yordanov
2f2ecbbeb0 Add css vars and update colors 2022-09-14 15:19:03 +03:00
yordanov
867fe28c5f Add CSS vars and update colors 2022-09-14 15:19:03 +03:00
yordanov
958cdc627a Add css vars to input and badge 2022-09-14 15:19:03 +03:00
yordanov
473aa9c429 Add css vars to standard and default theme 2022-09-14 15:19:03 +03:00
yordanov
846dd24dde Add global css vars 2022-09-14 15:19:03 +03:00
yordanov
c01823024d Add selection and default body font-size 2022-09-14 15:19:03 +03:00
yordanov
1cba327f24 Remove sizing from standard theme 2022-09-14 15:19:03 +03:00
yordanov
c973edee05 Update typography 2022-09-14 15:19:03 +03:00
yordanov
6744926708 Update sizing 2022-09-14 15:19:03 +03:00
yordanov
a5f040d69d Update sizing 2022-09-14 15:19:03 +03:00
Vladimir Enchev
0507f25e86 DataGrid column ShowTimeForDateTimeFilter() virtual method added
Fix #601
2022-09-13 09:43:25 +03:00
Vladimir Enchev
f782f18f04 RadzenDataGridColumn GetFilterOperators() made virtual
Fix #601
2022-09-12 16:44:30 +03:00
Vladimir Enchev
ddb58f148d Fixed DateTime operators order in DataGrid simple filter mode
Fix #602
2022-09-12 16:14:57 +03:00
Vladimir Enchev
75904cf88c Version updated 2022-09-12 09:58:21 +03:00
Vladimir Enchev
522deec88b DropDownDataGrid AllowRowSelectOnRowClick behavior fixed 2022-09-12 09:57:17 +03:00
Vladimir Enchev
4c07d608c5 Pager GetPage() code fixed 2022-09-10 08:59:37 +03:00
Vladimir Enchev
c3490ac819 SSRSViewer Load event added 2022-09-08 16:35:00 +03:00
Vladimir Enchev
0ada1f2e46 DataGrid pager not recalculated properly when using Page event
Fix #598
2022-09-08 14:40:18 +03:00
Vladimir Enchev
6d7493c6e5 Version updated 2022-09-08 09:34:55 +03:00
Vladimir Enchev
3306d8a276 DropDown/AutoComplete scroll to selected item improved 2022-09-07 10:23:39 +03:00
Vladimir Enchev
d5b607eb72 DropDown item selection check improved 2022-09-07 10:11:41 +03:00
Vladimir Enchev
af22c74602 DropDown and DropDownDataGrid popup cannot be opened when nested in label
Fix #597
2022-09-07 09:30:10 +03:00
Vladimir Enchev
1822850835 DataGridColumn FilterPropertyType made public 2022-09-06 12:37:16 +03:00
Vladimir Enchev
f185b9c30d Numeric AutoComplete set to false by default 2022-09-06 11:06:17 +03:00
Vladimir Enchev
d6c39e05f9 RadzenSelectBarItem Template property added
Fix #595
2022-09-05 15:29:09 +03:00
GioeEng
d7abef33a6 RadzenAutoComplete with IEnumerable of strings (#596)
* feat: Dropdown with badges view

* Rename BadgesView to ChipsView and update styling

* Rename ChipsView to Chips. Do not set Multiple to true - require the developer to set it instead. Some cosmetic changes.

* Tag dropdown demo as updated.

* Reposition popup when chip is removed.

* fix: RadzenAutoComplete support IEnumerable of strings

Co-authored-by: yordanov <vasil@yordanov.info>
Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2022-09-05 14:16:22 +03:00
Vladimir Enchev
a0f6712c57 Version updated 2022-09-05 09:25:18 +03:00
Vladimir Enchev
e81acee86b AutoComplete Multiline property added 2022-09-02 16:05:47 +03:00
Vladimir Enchev
bbc9080cfa Upload ParameterName property added 2022-09-02 15:22:25 +03:00
Vladimir Enchev
2095280783 AutoComplete Template property added 2022-09-02 09:27:35 +03:00
Vladimir Enchev
d2b2e9a0d9 Version updated 2022-09-01 19:29:45 +03:00
Vladimir Enchev
e62adf9131 SelectBar item Icon and Image properties added 2022-09-01 19:29:24 +03:00
Vladimir Enchev
4f22a869b8 DropDown with groups example added 2022-09-01 15:22:12 +03:00
Vladimir Enchev
8cf5868a30 code fixed 2022-09-01 14:17:55 +03:00
Vladimir Enchev
f8d2b47006 Fixed virtualized DropDownBase not refreshed on data change
Fix #592
2022-09-01 14:15:48 +03:00
Vladimir Enchev
71f0f53cae DataGrid should be reset to first page on data change
Fix #591
2022-08-31 16:07:14 +03:00
Vladimir Enchev
5b1fe105ba Version updated 2022-08-30 07:44:14 +03:00
Vladimir Enchev
7f447ac21f Fixed ProgressBar Template 2022-08-30 06:52:23 +03:00
Atanas Korchev
425c7cd390 Fix the search textbox in the navigation. 2022-08-29 09:50:55 +03:00
Vladimir Enchev
7f72143ee7 Version updated 2022-08-29 07:58:49 +03:00
Vladimir Enchev
e743500d6c ProgressBar Template property added 2022-08-28 15:32:52 +03:00
Vladimir Enchev
77e3952849 DialogService Close() method made virtual
Fix #588
2022-08-26 15:02:58 +03:00
Vladimir Enchev
21dab1bf50 DropDownDataGrid clear button should not open popup 2022-08-26 12:08:45 +03:00
Vladimir Enchev
4e9aa726c6 Fixed big number exception in Numeric with nullables
Fix #586
2022-08-26 09:38:18 +03:00
Vladimir Enchev
004babb572 Version updated 2022-08-25 08:43:34 +03:00
Vladimir Enchev
256c048598 Added CloseTooltipOnDocumentClick to TooltipOptions
Fix #582
2022-08-25 08:43:00 +03:00
Vladimir Enchev
59b884f4e4 AutoComplete popup will not open on Android 2022-08-24 12:09:36 +03:00
Jimmy Ho
45ff535d31 Fix Grid width is wrong in responsive mode (#584)
* style: fix grid width is wrong in responsive mode

* style: adjust tbody layer under table
2022-08-24 07:59:44 +03:00
Atanas Korchev
4cd8c53645 Loading indicator appears below the headers of an empty RadzenDataGrid. 2022-08-22 17:33:11 +03:00
Vladimir Enchev
b856ef4ea6 Version updated 2022-08-22 16:15:33 +03:00
Vladimir Enchev
ea3d83962f Fixed exception when filtering virtualized DropDownDataGrid bound with LoadData 2022-08-22 16:13:34 +03:00
Atanas Korchev
1d79076e65 Allow custom bar and column series sizes. 2022-08-22 10:58:06 +03:00
Vladimir Enchev
1e6bae6801 Fixed DataGrid SimpleWithMenu mode IsNotEmpty
Fix #583
2022-08-22 10:38:55 +03:00
Vladimir Enchev
6cda51ebbe Demos navigation expanded state fixed 2022-08-22 09:23:01 +03:00
Vladimir Enchev
e4c4c1b964 Fixed too big number in Numeric will raise exception
Fix #580
2022-08-22 07:53:29 +03:00
Vladimir Enchev
939c8c6d0e PanelMenuItem ExpandedChange argument fixed
#581
2022-08-20 07:49:03 +03:00
GioeEng
33c3963f66 feat: Dropdown with badges view (#568)
* feat: Dropdown with badges view

* Rename BadgesView to ChipsView and update styling

* Rename ChipsView to Chips. Do not set Multiple to true - require the developer to set it instead. Some cosmetic changes.

* Tag dropdown demo as updated.

* Reposition popup when chip is removed.

Co-authored-by: yordanov <vasil@yordanov.info>
Co-authored-by: Atanas Korchev <akorchev@gmail.com>
2022-08-18 19:42:46 +03:00
Vladimir Enchev
88bfaa532d Version updated 2022-08-17 17:14:51 +03:00
Vladimir Enchev
66e321ebea Added optional forceReload argument to PagedDataBoundComponent GoToPage() method 2022-08-17 10:41:02 +03:00
Vladimir Enchev
8d2838e928 Fixed Tooltip cannot be opened on first button click 2022-08-17 09:32:02 +03:00
Vladimir Enchev
98d896eb81 Fixed DataGrid pager not recalculated properly after Count change
#579
2022-08-17 08:57:01 +03:00
Vladimir Enchev
62bd56e70d DataGrid IsEmpty/IsNotEmpty filter expression should use double quotes 2022-08-17 08:25:15 +03:00
Vladimir Enchev
bbc7e0f648 Added support for IList value binding in DropDownBase 2022-08-16 17:08:50 +03:00
Vladimir Enchev
534c8e0bc3 Clear filter button added to DataGrid string columns in simple filter mode 2022-08-16 10:04:05 +03:00
Vladimir Enchev
1f9897e551 Fixed DataGrid frozen columns not properly stacked
Fix #577
2022-08-15 16:43:25 +03:00
Vladimir Enchev
eba54c8da3 Fixed missing attributes in RadzenSplitterPane 2022-08-15 07:51:24 +03:00
Vladimir Enchev
e47ac5b02d version updated 2022-08-11 08:20:48 +03:00
Nick Williams
9d134f8171 RadzenUpload proposed cancel functionality (#573)
* Change to DatePicker to optionally pad the time picker hour, minute or seconds components with leading zeros. Corresponding new boolean parameters are PadHours, PadMinutes and PadSeconds.

* Fixed issue with RadzenDialog where closing a nested dialog removed the 'no-scroll' class from the page body, allowing the background to scroll. The javascript 'closeDialog' function is now only invoked when the last dialog is closed.
Added a  potential impovement to RadzenDialog, whereby the dialog mask is only shown for the top most dialog, rather than the accumulative effect of multiple masks. This might be personal perference, but makes more sense to me.

* Added boolean Cancel property to UploadProgressArgs, allowing the underlying XMLHttpRequest to be aborted if required. Thereby cancelling the upload. Added boolean Cancelled property to UploadCompleteEventArgs, to determine if the request completed due to being canelled.
2022-08-11 05:54:54 +02:00
Vladimir Enchev
1ec477b5bc Catch possible exception with tooltip on dispose
Fix #572
2022-08-10 11:54:28 +02:00
Vladimir Enchev
022f203a2e Fixed DataGrid advanced filter popup when Property is not set
Fix #567
2022-08-10 09:41:58 +03:00
Vladimir Enchev
191f21bf50 DropDown aria-label fixed
Fix #566
2022-08-10 09:28:15 +03:00
Vladimir Enchev
98c4b37664 AutoComplete should open popup only on keypress not on focus 2022-08-10 09:23:46 +03:00
Atanas Korchev
2f2b40ca53 Pass the formatted text to the chart axis tick template. 2022-08-08 18:19:14 +03:00
Vladimir Enchev
8a8be30657 Version updated 2022-08-05 10:24:26 +03:00
GioeEng
0c0aafb956 fix: RadzenDropDownItem behavior on older versions of the blazor.js framework (#563) 2022-08-05 10:23:25 +03:00
Vladimir Enchev
c0bca5b923 Fixed FileInput reference not updated on Visible change 2022-08-05 10:17:02 +03:00
Vladimir Enchev
55ea356efd version updated 2022-08-04 18:16:44 +03:00
Vladimir Enchev
fbcd357b69 DropDownDataGrid string SelectedValue should not treated like IEnumerable 2022-08-04 18:16:20 +03:00
Vladimir Enchev
41db619e28 Fixed FileInput value cannot be cleared 2022-08-04 18:10:39 +03:00
Vladimir Enchev
1de8b11d75 version updated 2022-08-04 09:23:16 +03:00
Vladimir Enchev
b85f082d03 DropDownDataGrid multiple selection with LoadData improved
Fix #481
2022-08-04 09:22:37 +03:00
Vladimir Enchev
c2f08b47aa Fixed RadzenNumeric does not allow certain numbers to be entered when min and max are set 2022-08-04 08:39:51 +03:00
Vladimir Enchev
329784c9a7 DataGrid PickedColumnsChanged event added
Fix #557
2022-08-02 08:45:54 +03:00
Atanas Korchev
1d357aab0a Tooltip is not displayed for area and line series with a single value. 2022-08-01 21:51:12 +03:00
Vladimir Enchev
fe6deb559b DropDown ReadOnly property added
Fix #460
2022-08-01 15:32:21 +03:00
Vladimir Enchev
591ef4d1f9 net6.0 added to TargetFrameworks. NET5 preprocessor changed to NET5_0_OR_GREATER. 2022-08-01 14:12:45 +03:00
Vladimir Enchev
6a8a991f42 DataGrid OData demo with custom filter fixed to go to first page 2022-08-01 12:25:05 +03:00
Vladimir Enchev
87161cb97a DataGrid LoadData demo with custom filter fixed to go to first page 2022-08-01 12:21:53 +03:00
Vladimir Enchev
a28b667b38 Version updated 2022-08-01 09:48:06 +03:00
Vladimir Enchev
62c8b4b9e9 Fixed keyboard navigation for virtualized DropDownBase
Fix #556
2022-08-01 09:46:56 +03:00
GioeEng
bc0d5e2e7e feat: Dropdown disabled Items (#551)
fix: Dropdown keyboard selecting after filtering
2022-08-01 08:34:20 +03:00
Greg Horvath
a66ea60ae7 Implemented more consistent handling of DateTimeOffSet. See https://github.com/radzenhq/radzen-blazor/issues/554 (#555) 2022-08-01 08:31:08 +03:00
Nick Williams
80f908353f RadzenDialog Improvements (#550)
* Change to DatePicker to optionally pad the time picker hour, minute or seconds components with leading zeros. Corresponding new boolean parameters are PadHours, PadMinutes and PadSeconds.

* Fixed issue with RadzenDialog where closing a nested dialog removed the 'no-scroll' class from the page body, allowing the background to scroll. The javascript 'closeDialog' function is now only invoked when the last dialog is closed.
Added a  potential impovement to RadzenDialog, whereby the dialog mask is only shown for the top most dialog, rather than the accumulative effect of multiple masks. This might be personal perference, but makes more sense to me.
2022-08-01 08:30:27 +03:00
Atanas Korchev
a3a8ad87d3 Trend lines do not render in some cultures. 2022-07-28 19:10:04 +03:00
Vladimir Enchev
ea52a7a9ec Version updated 2022-07-28 08:30:37 +03:00
Vladimir Enchev
972042645c PagedDataBoundComponent FirstPage() method logic with forceReload fixed 2022-07-28 08:29:37 +03:00
Nick Williams
e01c8d4e13 Change to DatePicker to optionally pad the time picker hour, minute or seconds components with leading zeros. Corresponding new boolean parameters are PadHours, PadMinutes and PadSeconds. (#544) 2022-07-27 08:37:11 +03:00
Vladimir Enchev
351373aea5 Fixed Mask component will not apply mask initially 2022-07-26 19:55:05 +03:00
Vladimir Enchev
287680df87 Fixed DataGrid virtualization not working properly in Firefox 2022-07-26 15:13:21 +03:00
Vladimir Enchev
aa96a98722 Fixed validators not working in DataGrid in-line edit with grouping 2022-07-26 09:00:46 +03:00
Vladimir Enchev
58aa231cd2 Version updated 2022-07-25 08:58:02 +03:00
Vladimir Enchev
d0a59e9d6f DataGrid LoadData called twice on FirstPage() with top and bottom pagers 2022-07-25 08:46:00 +03:00
Vladimir Enchev
972c278356 Fixed DataGrid enum filtering
Fix #542
2022-07-25 08:28:25 +03:00
Vladimir Enchev
d3b236107b Version updated 2022-07-23 09:21:20 +03:00
Vladimir Enchev
ddd359afe0 Fixed DropDown multiple selection
Fix #540
2022-07-23 09:20:59 +03:00
Vladimir Enchev
0278777ff4 Version updated 2022-07-21 18:21:07 +03:00
Vladimir Enchev
c8b703778b page restored 2022-07-21 18:19:45 +03:00
Vladimir Enchev
a0d49f8c29 Fixed DropDown does not throw errors within an async Task set to the Change event
Fix #537
2022-07-21 18:19:28 +03:00
Marco Papst
93f9a318b0 allow override of Template with ChildContent in BreadCrumbItem (#536)
Co-authored-by: Marco Papst <papst@sma.de>
2022-07-21 08:54:02 +03:00
pigwing
bc6679505d add ShowEmptyMessage attribute (#535)
* add DisableEmptyText attribute fix when AllowPaging = true && LoadData.HasDelegate && Count == 0 DataGrid InLine Editing not working

* adopt a suggestion
2022-07-21 08:53:15 +03:00
Vladimir Enchev
5698e1a4fb Fixed Accrodion exception when set Visible property of the item 2022-07-21 08:51:26 +03:00
Vladimir Enchev
61c39a8919 Fixed numeric input with zero min/max
Fix #533
2022-07-19 17:09:57 +03:00
Vladimir Enchev
ae2e8b6abd Version updated 2022-07-19 09:23:53 +03:00
Vladimir Enchev
e1bce30ee3 DataGrid simple mode filtering by date will not show value if filter is not applied 2022-07-19 09:23:33 +03:00
Vladimir Enchev
44da884057 Fixed Numeric input and paste logic when min/max is set
Fix #532
2022-07-19 08:58:14 +03:00
Vladimir Enchev
7f9f05ae0e Version updated 2022-07-18 15:40:49 +03:00
Vladimir Enchev
4638d173b6 Order of FileInput events during file remove fixed 2022-07-18 14:46:47 +03:00
Vladimir Enchev
43bc3cee06 Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2022-07-18 09:00:05 +03:00
Vladimir Enchev
2db68559d5 FileInput FileName and FileSize parameters added 2022-07-18 08:59:46 +03:00
glutio
122b07b757 Do not show trend tooltip if the line is not visible and fix line names (#531)
* Do not show trend tooltip if the line is not visible and fix line names
Revert accidental removal of commit 6b9d2c19a7 (FilterCleared event)

* Fixed trend lines length and contains() method
2022-07-15 14:32:01 +03:00
Atanas Korchev
d6760ca4b9 Having async code in Expand handler sometimes prevents RadzenTreeItem from rendering. 2022-07-15 14:26:02 +03:00
Vladimir Enchev
fe036e75a3 Version updated 2022-07-14 09:51:03 +03:00
Vladimir Enchev
a574e77f0a Numeric oninput and onpaste attributes fixed
Fix #524
2022-07-14 09:50:08 +03:00
Vladimir Enchev
b4c885067d Fixed FileInput will not select the same file if already removed 2022-07-14 09:10:03 +03:00
glutio
200fb9d9ee Chart overlays - data labels, trends and annotations. 2022-07-13 17:31:48 +03:00
Vladimir Enchev
ec06fdcda6 DropDownBase clear selection using delete key will respect AllowClear property 2022-07-13 14:01:06 +03:00
Atanas Korchev
fb31cc7268 Add missing comma 2022-07-12 16:53:38 +03:00
Atanas Korchev
afdbf2ac0b Set example titles. 2022-07-12 16:43:21 +03:00
Vladimir Enchev
4197230ffd Version updated 2022-07-12 07:24:01 +03:00
Vladimir Enchev
952e22367e Fix DropDownDataGrid selected value not displayed properly in some cases 2022-07-12 07:21:18 +03:00
Atanas Korchev
a497660c64 Prevent exceptions if the value entered in the numeric filter is invalid. Closes #523 and #522. 2022-07-11 16:17:17 +03:00
Vladimir Enchev
bd3f4e08b2 DropDownBase SelectedItems reverted 2022-07-08 18:43:11 +03:00
Vladimir Enchev
c2e5aba0e4 SelectedItems/SelectedItemsChanged added to DropDownBase 2022-07-08 17:45:43 +03:00
Vladimir Enchev
729cf2c033 Fixed DataGrid filtering with virtualization enabled not refreshing UI 2022-07-08 16:17:46 +03:00
Vladimir Enchev
2633bd46c3 Improved Numeric min/max validation 2022-07-08 09:06:11 +03:00
Vladimir Enchev
f6430d421e Fixed DatePicker AM/PM should be clicked multiple times in some cases 2022-07-08 08:14:02 +03:00
Vladimir Enchev
1045290320 Fixed DataGrid group header cell colspan not correct in case of Template defined 2022-07-08 08:00:28 +03:00
Vladimir Enchev
0416bb20b3 DataGrid advanced filtering more fixed with IsEmpty/IsNotEmpty 2022-07-07 16:03:47 +03:00
130nk3r5
cb7223dee1 RadzenDataGrid: Added Is Empty and Is not empty Filter operators (#514)
* Updated the RadzenDataGrid's filter operators too have a 'Is Empty' and 'Is not empty' Options

* IsNull/IsNotNull should work with null while IsEmpty/IsNotEmpty with empty string

Co-authored-by: Hugo Human <hugo@tangentsolutions.co.za>
Co-authored-by: Vladimir Enchev <vladimir.enchev@gmail.com>
2022-07-07 15:14:30 +03:00
Vladimir Enchev
59b535b0d8 Version updated 2022-07-07 10:27:11 +03:00
glutio
6b9d2c19a7 Add FilterCleared event to DataGrid to fire when filter is clered to allow custom logic to tell the difference between operator/value change and filter clear event. In my case it allows me to keep the operator even though it's reset to default in ClearFilter(). (#506)
Co-authored-by: Eugene Pistrak <evpistra@microsoft.com>
2022-07-07 10:25:26 +03:00
Vladimir Enchev
3d7fbefa24 Fixed DatePicker months and years drop downs not update on Min/Max change 2022-07-07 09:46:28 +03:00
Vladimir Enchev
24311c2e71 Fixed FileInput not showing file name and size if not image 2022-07-07 08:32:21 +03:00
Vladimir Enchev
93db8cc163 Fixed DataGrid column Type property not initialized correctly in some cases 2022-07-06 14:09:26 +03:00
Vladimir Enchev
bdd833e05b DataGrid dynamic data demo simplified 2022-07-05 11:13:52 +03:00
Vladimir Enchev
64bcb9b4c3 DataGrid demo with dynamic data reworked 2022-07-05 11:01:54 +03:00
Vladimir Enchev
6f2cf36ba6 Fixed Numeric value change with percent format 2022-07-04 09:52:13 +03:00
Vladimir Enchev
4828af7130 DataGrid Reset() method should respect FilterOperator for string and IEnumerable columns 2022-07-01 16:39:44 +03:00
Vladimir Enchev
0d0aa7c9a0 Do not attempt to filter collections with non valid comparison 2022-06-30 19:27:02 +03:00
Atanas Korchev
f0c962fde0 Toggling the Visible property of a form component breaks validation. 2022-06-30 18:25:13 +03:00
yordanov
a04197f145 Fix grid cell border-bottom in nested grids 2022-06-30 10:41:10 +03:00
Vladimir Enchev
530e9b05ef ListBox/DropDown select all CheckBox checked logic improved 2022-06-30 09:53:34 +03:00
Vladimir Enchev
5276b5f9f7 Version updated 2022-06-30 09:36:18 +03:00
Vladimir Enchev
9a8f5f7186 DataGrid column methods for get/set filter values and operators made public 2022-06-30 08:56:29 +03:00
Vladimir Enchev
7de2b3567d DropDown ValueTemplate property added 2022-06-29 17:14:00 +03:00
Vladimir Enchev
2a53fd6f13 DataGrid Filter event will be raised on clear filter from column filter menu 2022-06-28 08:40:47 +03:00
Vladimir Enchev
1092fd4198 Version updated 2022-06-23 12:16:20 +03:00
Vladimir Enchev
dd5619c1f9 Fixed DropDownDataGrid delegate to an instance method cannot have null 'this' 2022-06-23 12:16:05 +03:00
Vladimir Enchev
06cffc101f Version updated 2022-06-23 10:18:29 +03:00
Vladimir Enchev
5f17dae777 Fixed DropDownBase selected item cannot be removed 2022-06-23 10:04:55 +03:00
Vladimir Enchev
001a8a276f ListBox multiple selection fixed with virtualization enabled 2022-06-22 15:44:16 +03:00
Vladimir Enchev
16986f0f56 DataGrid clear filter added to the filtering menu 2022-06-22 11:09:30 +03:00
Vladimir Enchev
36ff2808bd Merge branch 'master' of https://github.com/radzenhq/radzen-blazor 2022-06-22 10:36:08 +03:00
Vladimir Enchev
b566e10847 Should execute DataGrid Reload() on LogicalFilterOperator and FilterCaseSensitivity change 2022-06-22 10:36:01 +03:00
TheNoNinja
1b4fbf17a8 Get total item count after loading the data into the datagrid (#500)
Co-authored-by: ChristiaanBrant <Christiaan.Brant@Notilyze.com>
2022-06-22 10:30:38 +03:00
Vladimir Enchev
1475b1a299 Fixed DataGrid will not clear all filters on Reset() 2022-06-22 10:22:59 +03:00
Vladimir Enchev
147c5455ff Fixed DropDownDataGrid will not clear selection when set @bind-Value to null 2022-06-22 10:18:36 +03:00
Vladimir Enchev
73bfd9b66c Fixed collection was modified exception with async data binding 2022-06-22 09:15:40 +03:00
Atanas Korchev
f5fa061392 Improve Chart tooltip positioning. Reduce the number of roundrips required to display a tooltip. 2022-06-21 14:57:26 +03:00
Atanas Korchev
71b50171de Delete unnecesary Category() call. Allow toggling the visibility of series in LegendClick. 2022-06-21 11:54:18 +03:00
Paul Ruston
a172caba24 LegendClick after fork recreate 202206181900 2022-06-21 11:54:18 +03:00
Vladimir Enchev
ab39c3bbdb ContextMenu removed from tree demo 2022-06-20 11:36:27 +03:00
Vladimir Enchev
29733cc474 ContextMenu example added to Tree demo 2022-06-20 11:35:29 +03:00
Vladimir Enchev
00a358cfb6 Radzen.Blazor PackageReference Version set to * 2022-06-20 10:39:50 +03:00
Vladimir Enchev
000475884d DropDownDataGrid CellRender and RowRender events added
Fix #496
2022-06-20 10:10:05 +03:00
Vladimir Enchev
49b2cda0c2 Fixed Chromium browsers will crash on popup open from frozen cell 2022-06-20 09:57:44 +03:00
Domen
fdf229400a Removed duplicated code from SCSS, Changed positionCSS 2022-06-17 10:12:22 +03:00
Domen
c79d485d69 Added TopRight and BottomRight position to TabPositon 2022-06-17 10:12:22 +03:00
Vladimir Enchev
3f9aa621d1 Version updated 2022-06-16 10:06:17 +03:00
Atanas Korchev
c94c00d933 Expose the EditContext property of RadzenTemplateForm as a parameter. 2022-06-15 13:36:47 +03:00
Max Reble
e540855bf9 fixes #471
if endtime is > 24h appointments now will be shown
2022-06-15 13:32:11 +03:00
Johan
e3d55f4e3d Possible to set placeholder for HtmlEditorFormatBlock 2022-06-14 16:03:07 +03:00
Johan
988fc92456 Possible to set placeholder for HtmlEditorFontSize 2022-06-14 16:03:07 +03:00
Johan
c02b153ef1 Possible to set placeholder for HtmlEditorFontName 2022-06-14 16:03:07 +03:00
Atanas Korchev
70ca4893ba Make the title inline. 2022-06-14 15:58:34 +03:00
Carsten Heinrich
4e15d3779c Change span to div to enable a valid <h..> inside 2022-06-14 15:58:34 +03:00
Atanas Korchev
f924a18d07 Temporarily use strings for categories. 2022-06-14 08:27:07 +03:00
Vladimir Enchev
bce1ec1c66 Version updated 2022-06-13 15:28:28 +03:00
Vladimir Enchev
7c4347ad9b Fixed error when navigating to route
Fix #485
2022-06-13 15:27:35 +03:00
Vladimir Enchev
820c594c1e Fixed low level example categories not expanded on filter 2022-06-13 10:45:25 +03:00
thedomingo
5c2d319b3a Add ProgressBarStyle to RadzenProgressBar (#482)
* Added ProgressBarStyle to ProgressBar

* Added test and demo

* Improved css, updated test, updated demo page
2022-06-13 09:21:17 +03:00
Instant.SC
ff62cc55c2 Fix right edge cropping of the filter button (#484) 2022-06-13 09:19:33 +03:00
Atanas Korchev
dee872fec2 Expose TickDistance to allow developers to set it. 2022-06-09 10:17:11 +03:00
Vladimir Enchev
87b670ca4e version updated 2022-06-09 09:15:54 +03:00
Vladimir Enchev
60c4c2f526 Fixed DataGrid infinite loop with LoadData and virtualization 2022-06-03 15:41:29 +03:00
yordanov
6fd03f826c Fix links alignment in breadcrumb 2022-06-03 14:30:09 +03:00
Vladimir Enchev
365cdb9fef Version updated 2022-06-02 09:15:39 +03:00
Vladimir Enchev
4342602202 Changing Tabs item visibility will reset selected tab to first in TabRenderMode.Client 2022-06-02 09:14:49 +03:00
Atanas Korchev
a168c10938 RadzenHtmlEditor sometimes does not allow specifying the text when the insert link tool is used. 2022-05-31 10:22:33 +03:00
Vladimir Enchev
09da6f870a Fixed DropDownDataGrid selection when AllowRowSelectOnRowClick is set to false 2022-05-30 11:32:14 +03:00
Vladimir Enchev
8a4b334d20 ContextMenu should not be closed when expanding child items 2022-05-27 15:40:11 +03:00
Atanas Korchev
4f6916a2df RadzenUpload can have an Icon. 2022-05-27 13:19:24 +03:00
Vladimir Enchev
14a9c94944 Export demo and controller updated 2022-05-26 11:41:56 +03:00
Atanas Korchev
6ad0fda364 Update documentation about .NET 6 and use Blazor Server and Blazor WebAssembly. 2022-05-26 10:20:27 +03:00
Atanas Korchev
491c124ac1 The HeadOutlet was not rendered correctly. 2022-05-26 10:20:27 +03:00
Vladimir Enchev
81cb7b4f84 Radzen.Blazor version updated 2022-05-26 10:07:53 +03:00
Vladimir Enchev
90c91c2b16 DataGrid group cannot be expanded when collapsed on first render in GroupRowRender
Fix #472
2022-05-26 09:57:17 +03:00
Vladimir Enchev
161d2810a3 Fixed DropDownDataGrid @bind-Value will not select item when bound using LoadData 2022-05-26 09:46:33 +03:00
Vladimir Enchev
9c0dae8d9a DataGrid boolean column filtering toggle fixed 2022-05-25 11:57:14 +03:00
Vladimir Enchev
6375be4d2c Virtualize panel will need double refresh when using LoadData :( 2022-05-25 11:37:00 +03:00
Atanas Korchev
64234815cc Do not check parent checkbox if AllowCheckParents is false. 2022-05-25 11:17:33 +03:00
Vladimir Enchev
b56d4d1ca3 Fixed virtualized DropDownDataGrid not reloaded properly on clear filter when bound using LoadData 2022-05-23 16:02:50 +03:00
Vladimir Enchev
8d31b287f2 Version updated 2022-05-23 09:31:16 +03:00
Vladimir Enchev
8e59d905ba Demos filtering fixed
#470
2022-05-23 09:30:16 +03:00
Vladimir Enchev
028661f9f8 Fixed DataGrid sorting when grouped 2022-05-20 10:26:05 +03:00
Vladimir Enchev
f6189c6d8a Version updated 2022-05-19 09:31:03 +03:00
Vladimir Enchev
ee677ced24 Fixed DropDownDataGrid selected item lost on paging when using LoadData binding 2022-05-18 09:40:16 +03:00
Vladimir Enchev
5f5c142d03 Fixed DropDownDataGrid will not select item on initial value set using @bind-Value 2022-05-18 09:18:54 +03:00
Benjamin Vertonghen
2a7fe455ad FIX GetDescription instead of Description for localization Enum Filter (#463) 2022-05-17 08:59:46 +03:00
Vladimir Enchev
047469de5b Version updated 2022-05-16 09:48:55 +03:00
Benjamin Vertonghen
7a61a68f00 Add Display Attribute and localization for Enum Filter (#455)
* Add Display Attribute and localization

* Fix simple mode and use actual value not string.
2022-05-12 16:01:23 +03:00
SUBRAHMANYA ORUGANTI
50f71390f8 Made RadzenDataGridColumn.GetValue as virtual 2022-05-09 14:25:13 +03:00
Vladimir Enchev
fba7bb68fe Version updated 2022-05-09 09:49:59 +03:00
Vladimir Enchev
2f6749bf5e DatePicker TimeOnly parse fixed 2022-05-04 08:52:08 +03:00
Vladimir Enchev
9253c6dd7b DataGrid enum filter enabled for Simple and SimpleWithMenu filtering modes. EnumFilterSelectText property added. 2022-05-03 13:31:14 +03:00
Vladimir Enchev
e23ad8239b Version updated 2022-05-02 12:38:25 +03:00
Vladimir Enchev
2f9e624c31 Drag demo deleted 2022-04-29 16:01:11 +03:00
Vladimir Enchev
a336b50e0f Drag Documentation and Heading turned off 2022-04-29 15:23:27 +03:00
Vladimir Enchev
5bc4a96e77 empty comit 2022-04-29 15:17:06 +03:00
Vladimir Enchev
113ba8223c Drag example added 2022-04-29 15:00:57 +03:00
Vladimir Enchev
a760150d75 Null ref. exception fixed 2022-04-29 09:27:28 +03:00
Vladimir Enchev
42a52dc606 DataGrid group by column will use ascending sort order if column is not sorted 2022-04-28 15:02:30 +03:00
Vladimir Enchev
b0c45c115e Fixed AutoComplete e.target.closest is not a function error 2022-04-28 14:55:09 +03:00
Vladimir Enchev
6a427a04ff DataGrid Groups.Clear() will not restore column visibility if HideGroupedColumn=true 2022-04-28 10:48:55 +03:00
1047 changed files with 61183 additions and 20961 deletions

26
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,26 @@
# This workflow will build a .NET project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net
name: .NET
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.0.x
- name: Build
run: dotnet build Radzen.Blazor/Radzen.Blazor.csproj
- name: Test
run: dotnet test Radzen.Blazor.Tests/Radzen.Blazor.Tests.csproj

View File

@@ -19,7 +19,7 @@ You can ask your question here. Please use the [Radzen.Blazor Components](https:
### Dedicated technical support
Radzen staff provides technical support with guaranteed response time to Radzen Professional and Enterprise subscribers. The pricing options are available [here](https://www.radzen.com/pricing/).
Radzen staff provides technical support with guaranteed response time to Radzen Professional and Enterprise subscribers. The pricing options are available [here](https://www.radzen.com/blazor-studio/pricing/).
## How Can I Contribute?

View File

@@ -13,18 +13,19 @@ RUN apt-get update && apt-get install unzip wget git -y && wget -q -P /tmp https
COPY Radzen.Blazor /app/Radzen.Blazor
COPY Radzen.DocFX /app/DocFX
COPY RadzenBlazorDemos /app/RadzenBlazorDemos
COPY RadzenBlazorDemos.Host /app/RadzenBlazorDemos.Host
WORKDIR /app
RUN docfx DocFX/docfx.json
FROM mcr.microsoft.com/dotnet/sdk:6.0-focal
FROM mcr.microsoft.com/dotnet/sdk:7.0
COPY --from=0 /app/RadzenBlazorDemos /app
WORKDIR /app
COPY --from=0 /app/RadzenBlazorDemos.Host /app/RadzenBlazorDemos.Host
COPY --from=0 /app/RadzenBlazorDemos /app/RadzenBlazorDemos
WORKDIR /app/RadzenBlazorDemos.Host
RUN dotnet publish -c Release -o out
COPY RadzenBlazorDemos/northwind.db /app/out
COPY RadzenBlazorDemos/northwind.sql /app/out
ENV ASPNETCORE_URLS http://*:5000
WORKDIR /app/out
WORKDIR /app/RadzenBlazorDemos.Host/out
ENTRYPOINT ["dotnet", "RadzenBlazorDemos.dll"]
ENTRYPOINT ["dotnet", "RadzenBlazorDemos.Host.dll"]

View File

@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2018-2022 Radzen Ltd
Copyright (c) 2018-2023 Radzen Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -5,7 +5,7 @@
</h1>
<p align="center">
A set of <strong>60+ free and open source</strong> native Blazor UI controls.
A set of <strong>70+ free and open source</strong> native Blazor UI controls.
</p>
<div align="center">
@@ -21,7 +21,7 @@
<img alt="License - MIT" src="https://img.shields.io/github/license/radzenhq/radzen-blazor?logo=github&style=for-the-badge" />
</a>
<a href="https://www.nuget.org/packages/Radzen.Blazor">
<img alt="Nuget Downloads" src="https://img.shields.io/nuget/dt/Radzen.Blazor?color=%232694F9&label=nuget%20downloads&logo=nuget&style=for-the-badge" />
<img alt="NuGet Downloads" src="https://img.shields.io/nuget/dt/Radzen.Blazor?color=%232694F9&label=nuget%20downloads&logo=nuget&style=for-the-badge" />
</a>
<img alt="Last Commit" src="https://img.shields.io/github/last-commit/radzenhq/radzen-blazor?logo=github&style=for-the-badge" />
<a href="https://github.com/radzenhq/radzen-blazor/graphs/contributors">
@@ -39,15 +39,15 @@
### :sparkles: Free
Radzen Blazor Components are open source and free for commercial use. You can install them from [nuget](https://www.nuget.org/packages/Radzen.Blazor) or build your own copy from source.
Radzen Blazor Components are open source and free for commercial use. You can install them from [NuGet](https://www.nuget.org/packages/Radzen.Blazor) or build your own copy from source.
Paid support is available as part of the [Radzen Professional subscription](https://www.radzen.com/pricing/).
Paid support is available as part of the [Radzen Professional subscription](https://www.radzen.com/blazor-studio/pricing/).
### :computer: Native
The components are implemented in C# and take full advantage of the Blazor framework. They do not depend on or wrap existing JavaScript frameworks or libraries.
Both **server-side** and **client-side** (WASM) Blazor are supported.
Blazor Server and Blazor WebAssembly are fully supported.
### :seedling: Growing
@@ -55,7 +55,7 @@ We add new components and features on a regular basis.
Short development cycle. We release as soon as new stuff is available. No more quarterly releases.
## Support exceeding your expectations
## Support exceeding your expectations
### :speech_balloon: Community Support
Everybody is welcome to visit the [Radzen Community forum](https://forum.radzen.com/). Join the growing community and participate in the discussions!
@@ -64,10 +64,10 @@ Everybody is welcome to visit the [Radzen Community forum](https://forum.radzen.
The Radzen team monitors the forum threads, but does not guarantee a response to every question. For guaranteed responses you may consider the dedicated support option.
Dedicated support for the Radzen Blazor Components is available as part of the [Radzen Professional subscription](https://www.radzen.com/pricing/).
Dedicated support for the Radzen Blazor Components is available as part of the [Radzen Professional subscription](https://www.radzen.com/blazor-studio/pricing/).
Our flagship product [Radzen Studio](https://www.radzen.com/features/) provides tons of productivity features for Blazor developers:
- The first in the industry WYSIWYG Blazor design time canvas
Our flagship product [Radzen Blazor Studio](https://www.radzen.com/blazor-studio/) provides tons of productivity features for Blazor developers:
- An industry-leading WYSIWYG Blazor design time canvas
- Scaffolding a complete CRUD applications from a database
- Built-in security - authentication and authorization
- Visual Studio Code and Professional support
@@ -78,9 +78,9 @@ Our flagship product [Radzen Studio](https://www.radzen.com/features/) provides
### 1. Install
Radzen Blazor Components are distributed as a [Radzen.Blazor nuget package](https://www.nuget.org/packages/Radzen.Blazor). You can add them to your project in one of the following ways
Radzen Blazor Components are distributed as a [Radzen.Blazor NuGet package](https://www.nuget.org/packages/Radzen.Blazor). You can add them to your project in one of the following ways
- Install the package from command line by running `dotnet add package Radzen.Blazor`
- Add the project from the Visual Nuget Package Manager
- Add the project from the Visual NuGet Package Manager
- Manually edit the .csproj file and add a project reference
### 2. Import the namespace
@@ -89,26 +89,30 @@ Open the `_Imports.razor` file of your Blazor application and add this line `@us
### 3. Include a theme
Open the `_Host.cshtml` file (server-side Blazor) or `wwwroot/index.html` (client-side Blazor) and include a theme CSS file by adding this snippet
```html
<link rel="stylesheet" href="_content/Radzen.Blazor/css/default.css">
```
If you either add Bootstrap manually or don't use it at all, include this instead:
```html
<link rel="stylesheet" href="_content/Radzen.Blazor/css/default-base.css">
```
Radzen Blazor components come with five free themes: Material, Standard, Default, Dark, Software and Humanistic.
To use a theme
1. Pick a theme. The [online demos](https://blazor.radzen.com/colors) allow you to preview the available options via the theme dropdown located in the header. The Material theme is currently selected by default.
1. Include the theme CSS file in your Blazor application. Open `Pages\_Layout.cshtml` (Blazor Server .NET 6), `Pages\_Host.cshtml` (Blazor Server .NET 7) or `wwwroot/index.html` (Blazor WebAssembly) and include a theme CSS file by adding this snippet
```html
<link rel="stylesheet" href="_content/Radzen.Blazor/css/material-base.css">
```
To include a different theme (i.e. Standard) just change the name of the CSS file:
```
<link rel="stylesheet" href="_content/Radzen.Blazor/css/standard-base.css">
```
### 4. Include Radzen.Blazor.js
Open the `_Host.cshtml` file (server-side Blazor) or `wwwroot/index.html` (client-side Blazor) and include this snippet:
Open `Pages\_Layout.cshtml` (Blazor Server .NET 6), `Pages\_Host.cshtml` (Blazor Server .NET 7) or `wwwroot/index.html` (Blazor WebAssembly) and include this snippet:
```html
<script src="_content/Radzen.Blazor/Radzen.Blazor.js"></script>
```
### 5. Use a component
Use any Radzen Blazor component by typing its tag name in a Blazor page e.g.
Use any Radzen Blazor component by typing its tag name in a Blazor page e.g.
```html
<RadzenButton Text="Hi"></RadzenButton>
```
@@ -133,3 +137,6 @@ Use any Radzen Blazor component by typing its tag name in a Blazor page e.g.
}
}
```
## Run demos locally
Use Radzen.Server.sln to open and run demos as Blazor server application or Radzen.WebAssembly.sln to open and run demos as Blazor WebAssembly application. Radzen.sln has reference to all projects including tests.

View File

@@ -0,0 +1,74 @@
using Xunit;
namespace Radzen.Blazor.Tests
{
public class AutoCompleteTests
{
[Fact]
public void AutoComplete_Enum_Converts_To_Attr_Value()
{
// Options
Assert.Equal("off", AutoCompleteType.Off.GetAutoCompleteValue());
Assert.Equal("on", AutoCompleteType.On.GetAutoCompleteValue());
Assert.Equal("name", AutoCompleteType.Name.GetAutoCompleteValue());
Assert.Equal("honorific-prefix", AutoCompleteType.HonorificPrefix.GetAutoCompleteValue());
Assert.Equal("given-name", AutoCompleteType.GivenName.GetAutoCompleteValue());
Assert.Equal("additional-name", AutoCompleteType.AdditionalName.GetAutoCompleteValue());
Assert.Equal("family-name", AutoCompleteType.FamilyName.GetAutoCompleteValue());
Assert.Equal("honorific-suffix", AutoCompleteType.HonorificSuffix.GetAutoCompleteValue());
Assert.Equal("nickname", AutoCompleteType.Nickname.GetAutoCompleteValue());
Assert.Equal("email", AutoCompleteType.Email.GetAutoCompleteValue());
Assert.Equal("username", AutoCompleteType.Username.GetAutoCompleteValue());
Assert.Equal("new-password", AutoCompleteType.NewPassword.GetAutoCompleteValue());
Assert.Equal("current-password", AutoCompleteType.CurrentPassword.GetAutoCompleteValue());
Assert.Equal("one-time-code", AutoCompleteType.OneTimeCode.GetAutoCompleteValue());
Assert.Equal("organization-title", AutoCompleteType.OrganizationTitle.GetAutoCompleteValue());
Assert.Equal("organization", AutoCompleteType.Organization.GetAutoCompleteValue());
Assert.Equal("street-address", AutoCompleteType.StreetAddress.GetAutoCompleteValue());
Assert.Equal("address-line1", AutoCompleteType.AddressLine1.GetAutoCompleteValue());
Assert.Equal("address-line2", AutoCompleteType.AddressLine2.GetAutoCompleteValue());
Assert.Equal("address-line3", AutoCompleteType.AddressLine3.GetAutoCompleteValue());
Assert.Equal("address-level1", AutoCompleteType.AddressLevel1.GetAutoCompleteValue());
Assert.Equal("address-level2", AutoCompleteType.AddressLevel2.GetAutoCompleteValue());
Assert.Equal("address-level3", AutoCompleteType.AddressLevel3.GetAutoCompleteValue());
Assert.Equal("address-level4", AutoCompleteType.AddressLevel4.GetAutoCompleteValue());
Assert.Equal("country", AutoCompleteType.Country.GetAutoCompleteValue());
Assert.Equal("country-name", AutoCompleteType.CountryName.GetAutoCompleteValue());
Assert.Equal("postal-code", AutoCompleteType.PostalCode.GetAutoCompleteValue());
Assert.Equal("cc-name", AutoCompleteType.CcName.GetAutoCompleteValue());
Assert.Equal("cc-given-name", AutoCompleteType.CcGivenName.GetAutoCompleteValue());
Assert.Equal("cc-additional-name", AutoCompleteType.CcAdditionalName.GetAutoCompleteValue());
Assert.Equal("cc-family-name", AutoCompleteType.CcFamilyName.GetAutoCompleteValue());
Assert.Equal("cc-number", AutoCompleteType.CcNumber.GetAutoCompleteValue());
Assert.Equal("cc-exp", AutoCompleteType.CcExp.GetAutoCompleteValue());
Assert.Equal("cc-exp-month", AutoCompleteType.CcExpMonth.GetAutoCompleteValue());
Assert.Equal("cc-exp-year", AutoCompleteType.CcExpYear.GetAutoCompleteValue());
Assert.Equal("cc-csc", AutoCompleteType.CcCsc.GetAutoCompleteValue());
Assert.Equal("cc-type", AutoCompleteType.CcType.GetAutoCompleteValue());
Assert.Equal("transaction-currency", AutoCompleteType.TransactionCurrency.GetAutoCompleteValue());
Assert.Equal("transaction-amount", AutoCompleteType.TransactionAmount.GetAutoCompleteValue());
Assert.Equal("language", AutoCompleteType.Language.GetAutoCompleteValue());
Assert.Equal("bday", AutoCompleteType.Bday.GetAutoCompleteValue());
Assert.Equal("bday-day", AutoCompleteType.BdayDay.GetAutoCompleteValue());
Assert.Equal("bday-month", AutoCompleteType.BdayMonth.GetAutoCompleteValue());
Assert.Equal("bday-year", AutoCompleteType.BdayYear.GetAutoCompleteValue());
Assert.Equal("sex", AutoCompleteType.Sex.GetAutoCompleteValue());
Assert.Equal("tel", AutoCompleteType.Tel.GetAutoCompleteValue());
Assert.Equal("tel-country-code", AutoCompleteType.TelCountryCode.GetAutoCompleteValue());
Assert.Equal("tel-national", AutoCompleteType.TelNational.GetAutoCompleteValue());
Assert.Equal("tel-area-code", AutoCompleteType.TelAreaCode.GetAutoCompleteValue());
Assert.Equal("tel-local", AutoCompleteType.TelLocal.GetAutoCompleteValue());
Assert.Equal("tel-extension", AutoCompleteType.TelExtension.GetAutoCompleteValue());
Assert.Equal("impp", AutoCompleteType.Impp.GetAutoCompleteValue());
Assert.Equal("url", AutoCompleteType.Url.GetAutoCompleteValue());
Assert.Equal("photo", AutoCompleteType.Photo.GetAutoCompleteValue());
// Synonyms
Assert.Equal("address-level1", AutoCompleteType.State.GetAutoCompleteValue());
Assert.Equal("address-level1", AutoCompleteType.Province.GetAutoCompleteValue());
Assert.Equal("postal-code", AutoCompleteType.ZipCode.GetAutoCompleteValue());
Assert.Equal("given-name", AutoCompleteType.FirstName.GetAutoCompleteValue());
Assert.Equal("additional-name", AutoCompleteType.MiddleName.GetAutoCompleteValue());
Assert.Equal("family-name", AutoCompleteType.LastName.GetAutoCompleteValue());
}
}
}

View File

@@ -134,11 +134,11 @@ namespace Radzen.Blazor.Tests
component.SetParametersAndRender(parameters => parameters.Add(p => p.ButtonStyle, ButtonStyle.Primary));
Assert.Contains(@$"btn-primary", component.Markup);
Assert.Contains(@$"rz-primary", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add(p => p.ButtonStyle, ButtonStyle.Secondary));
Assert.Contains(@$"btn-secondary", component.Markup);
Assert.Contains(@$"rz-secondary", component.Markup);
}
[Fact]

View File

@@ -0,0 +1,54 @@
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Bunit;
using Radzen.Blazor.Rendering;
using Xunit;
using Xunit.Abstractions;
namespace Radzen.Blazor.Tests;
public class ChartTests
{
private readonly ITestOutputHelper output;
public ChartTests(ITestOutputHelper output)
{
this.output = output;
}
[Fact(Timeout = 30000)]
public async Task Chart_Tooltip_Performance()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
ctx.JSInterop.Setup<Rect>("Radzen.createChart", _ => true).SetResult(new Rect {Left = 0, Top = 0, Width = 200, Height = 200});
var seriesData = Enumerable.Range(0, 5000).Select(i => new Point { X = i, Y = i });
var chart = ctx.RenderComponent<RadzenChart>(chartParameters =>
chartParameters
.AddChildContent<RadzenLineSeries<Point>>(seriesParameters =>
seriesParameters
.Add(p => p.CategoryProperty, nameof(Point.X))
.Add(p => p.ValueProperty, nameof(Point.Y))
.Add(p => p.Data, seriesData))
.AddChildContent<RadzenCategoryAxis>(axisParameters =>
axisParameters
.Add(p => p.Step, 100)
.Add(p => p.Formatter, x =>
{
Thread.Sleep(100);
return $"{x}";
})));
var stopwatch = Stopwatch.StartNew();
foreach (var _ in Enumerable.Range(0, 10))
{
await chart.InvokeAsync(() => chart.Instance.MouseMove(100, 80));
Assert.Contains("<div class=\"rz-chart-tooltip", chart.Markup);
await chart.InvokeAsync(() => chart.Instance.MouseMove(0, 0));
Assert.DoesNotContain("<div class=\"rz-chart-tooltip", chart.Markup);
}
output.WriteLine($"Time took: {stopwatch.Elapsed}");
}
}

View File

@@ -160,5 +160,83 @@ namespace Radzen.Blazor.Tests
Assert.Contains(@$"rz-state-active", component.Markup);
Assert.Contains(@$"rzi-times", component.Markup);
}
[Fact]
public void CheckBox_Renders_ReadonlyParameter()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenCheckBox<bool>>();
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.ReadOnly, true));
Assert.Contains(@$"readonly", component.Markup);
}
[Fact]
public void CheckBox_DoesNotRaise_ChangedEvent_ReadonlyParameter()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenCheckBox<bool>>();
var raised = false;
component.SetParametersAndRender(parameters => parameters
.Add<bool>(p => p.ReadOnly, true)
.Add(p => p.Change, args => { raised = true; })
);
component.Find("div.rz-chkbox-box").Click();
Assert.False(raised);
}
[Fact]
public void CheckBox_DoesNotRaise_ValueChangedEvent_ReadonlyParameter()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenCheckBox<bool>>();
var raised = false;
component.SetParametersAndRender(parameters => parameters
.Add<bool>(p => p.ReadOnly, true)
.Add(p => p.ValueChanged, args => { raised = true; })
);
component.Find("div.rz-chkbox-box").Click();
Assert.False(raised);
}
[Fact]
public void CheckBox_ValueNotChanged_ReadonlyParameter()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenCheckBox<bool>>();
var value = true;
component.SetParametersAndRender(parameters => parameters
.Add<bool>(p => p.ReadOnly, true)
.Add<bool>(p => p.Value, value)
);
component.Find("div.rz-chkbox-box").Click();
Assert.Contains(@$"rz-state-active", component.Markup);
component.SetParametersAndRender(parameters => parameters
.Add<bool>(p => p.ReadOnly, !true)
.Add<bool>(p => p.Value, value)
);
component.Find("div.rz-chkbox-box").Click();
Assert.DoesNotContain(@$"rz-state-active", component.Markup);
}
}
}

View File

@@ -0,0 +1,16 @@
using Bunit;
using Xunit;
namespace Radzen.Blazor.Tests
{
public class ColorPickerTests
{
[Fact]
public void ColorPicker_ShouldAcceptInvalidValues()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenColorPicker>(ComponentParameter.CreateParameter("Value", "invalid"));
}
}
}

View File

@@ -74,11 +74,11 @@ namespace Radzen.Blazor.Tests
});
});
var markup = new Regex(@"\s\s+").Replace(component.Markup, "").Trim();
var data = component.FindAll(".rz-cell-data");
Assert.Contains(@$"<span class=""rz-cell-data"">1</span>", markup);
Assert.Contains(@$"<span class=""rz-cell-data"">2</span>", markup);
Assert.Contains(@$"<span class=""rz-cell-data"">3</span>", markup);
Assert.Equal("1", data[0].TextContent.Trim());
Assert.Equal("2", data[1].TextContent.Trim());
Assert.Equal("3", data[2].TextContent.Trim());
}
[Fact]
@@ -99,9 +99,56 @@ namespace Radzen.Blazor.Tests
});
});
var markup = new Regex(@"\s\s+").Replace(component.Markup, "").Trim();
var title = component.Find(".rz-column-title");
Assert.Equal("MyId", title.TextContent.Trim());
}
Assert.Contains(@$"<span class=""rz-column-title"">MyId</span>", markup);
[Fact]
public void DataGrid_Renders_TitleAttribute()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
var component = ctx.RenderComponent<RadzenDataGrid<dynamic>>(parameterBuilder =>
{
parameterBuilder.Add(p => p.ShowColumnTitleAsTooltip, true);
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(RadzenDataGridColumn<dynamic>));
builder.AddAttribute(1, "Title", "MyId");
builder.CloseComponent();
});
});
var title = component.Find(".rz-column-title");
Assert.Equal("MyId", title.TextContent.Trim());
Assert.Equal("MyId", title.GetAttribute("title"));
}
[Fact]
public void DataGrid_DoesNotRender_TitleAttribute()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
var component = ctx.RenderComponent<RadzenDataGrid<dynamic>>(parameterBuilder =>
{
parameterBuilder.Add(p => p.ShowColumnTitleAsTooltip, false);
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(RadzenDataGridColumn<dynamic>));
builder.AddAttribute(1, "Title", "MyId");
builder.CloseComponent();
});
});
var title = component.Find(".rz-column-title");
Assert.Equal("MyId", title.TextContent.Trim());
Assert.Empty(title.GetAttribute("title"));
}
[Fact]
@@ -380,6 +427,44 @@ namespace Radzen.Blazor.Tests
Assert.Contains(@$"rz-paginator-bottom", component.Markup);
}
[Fact]
public void DataGrid_Renders_PagerDensityDefault()
{
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, Enumerable.Range(0, 100)));
component.SetParametersAndRender(parameters =>
{
parameters.Add<bool>(p => p.AllowPaging, true);
parameters.Add<PagerPosition>(p => p.PagerPosition, PagerPosition.Top);
parameters.Add<Density>(p => p.Density, Density.Default);
});
Assert.DoesNotContain(@$"rz-density-compact", component.Markup);
}
[Fact]
public void DataGrid_Renders_PagerDensityCompact()
{
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, Enumerable.Range(0, 100)));
component.SetParametersAndRender(parameters =>
{
parameters.Add<bool>(p => p.AllowPaging, true);
parameters.Add<PagerPosition>(p => p.PagerPosition, PagerPosition.Top);
parameters.Add<Density>(p => p.Density, Density.Compact);
});
Assert.Contains(@$"rz-density-compact", component.Markup);
}
[Fact]
public void DataGrid_Renders_DefaultEmptyText()
{

View File

@@ -64,6 +64,40 @@ namespace Radzen.Blazor.Tests
Assert.Contains(@$"rz-paginator-bottom", component.Markup);
}
[Fact]
public void DataList_Renders_PagerDensityDefault()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenDataList<int>>(parameterBuilder => parameterBuilder.Add<IEnumerable<int>>(p => p.Data, Enumerable.Range(0, 100)));
component.SetParametersAndRender(parameters =>
{
parameters.Add<bool>(p => p.AllowPaging, true);
parameters.Add<PagerPosition>(p => p.PagerPosition, PagerPosition.Top);
parameters.Add<Density>(p => p.Density, Density.Default);
});
Assert.DoesNotContain(@$"rz-density-compact", component.Markup);
}
[Fact]
public void DataList_Renders_PagerDensityCompact()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenDataList<int>>(parameterBuilder => parameterBuilder.Add<IEnumerable<int>>(p => p.Data, Enumerable.Range(0, 100)));
component.SetParametersAndRender(parameters =>
{
parameters.Add<bool>(p => p.AllowPaging, true);
parameters.Add<PagerPosition>(p => p.PagerPosition, PagerPosition.Top);
parameters.Add<Density>(p => p.Density, Density.Compact);
});
Assert.Contains(@$"rz-density-compact", component.Markup);
}
[Fact]
public void DataList_Renders_WrapItemsParameter()
{

View File

@@ -1,6 +1,7 @@
using Bunit;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Xunit;
@@ -48,7 +49,7 @@ namespace Radzen.Blazor.Tests
var component = ctx.RenderComponent<RadzenDatePicker<DateTime>>();
component.SetParametersAndRender(parameters => {
component.SetParametersAndRender(parameters => {
parameters.Add<bool>(p => p.ShowTime, true);
parameters.Add<bool>(p => p.ShowSeconds, true);
});
@@ -92,7 +93,7 @@ namespace Radzen.Blazor.Tests
component.SetParametersAndRender(parameters => {
parameters.Add(p => p.DateFormat, format);
parameters.Add<object>(p => p.Value, DateTime.Now);
parameters.Add<object>(p => p.Value, DateTime.Now);
});
Assert.Contains(@$"value=""{string.Format("{0:" + format + "}", DateTime.Now)}""", component.Markup);
@@ -145,7 +146,7 @@ namespace Radzen.Blazor.Tests
component.SetParametersAndRender(parameters => {
parameters.Add<object>(p => p.Value, DateTime.Now);
parameters.Add<bool>(p => p.AllowClear, true);
parameters.Add<bool>(p => p.AllowClear, true);
});
Assert.Contains(@$"<i class=""rz-dropdown-clear-icon rzi rzi-times""", component.Markup);
@@ -319,12 +320,12 @@ namespace Radzen.Blazor.Tests
DateTime previousDay = DateTime.Today.AddDays(-1);
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
var component = ctx.RenderComponent<RadzenDatePicker<DateTime>>();
var raised = false;
object newValue = null;
object newValue = null;
component.SetParametersAndRender(parameters => {
parameters.Add(p => p.ValueChanged, args => { raised = true; newValue = args; })
@@ -377,14 +378,79 @@ namespace Radzen.Blazor.Tests
Assert.True(raised);
Assert.Null(newValue);
}
[Fact]
public void DatePicker_Parses_Input_Using_DateFormat()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
var component = ctx.RenderComponent<RadzenDatePicker<DateTime?>>();
var raised = false;
object newValue = null;
component.SetParametersAndRender(parameters =>
{
parameters.Add(p => p.DateFormat, "ddMM");
parameters.Add(p => p.ValueChanged, args => { raised = true; newValue = args; });
});
var inputElement = component.Find(".rz-inputtext");
string input = "3012";
ctx.JSInterop.Setup<string>("Radzen.getInputValue", invocation => true).SetResult(input);
inputElement.Change(input);
Assert.True(raised);
Assert.Equal(new DateTime(DateTime.Now.Year, 12, 30), newValue);
}
[Fact]
public void DatePicker_Parses_Input_Using_ParseInput()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
var component = ctx.RenderComponent<RadzenDatePicker<DateTime?>>();
Func<string, DateTime?> customParseInput = (input) => {
if (DateTime.TryParseExact(input, "ddMM", null, DateTimeStyles.None, out var result))
{
return result;
}
return null;
};
var raised = false;
object newValue = null;
component.SetParametersAndRender(parameters =>
{
parameters.Add(p => p.ParseInput, customParseInput);
parameters.Add(p => p.ValueChanged, args => { raised = true; newValue = args; });
});
var inputElement = component.Find(".rz-inputtext");
string input = "3012";
ctx.JSInterop.Setup<string>("Radzen.getInputValue", invocation => true).SetResult(input);
inputElement.Change(input);
Assert.True(raised);
Assert.Equal(new DateTime(DateTime.Now.Year, 12, 30), newValue);
}
[Fact]
public void DatePicker_Respects_DateTimeMaxValue()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
var component = ctx.RenderComponent<RadzenDatePicker<DateTime>>(parameters =>
{
parameters.Add(p => p.Value, DateTime.MaxValue);
@@ -397,25 +463,6 @@ namespace Radzen.Blazor.Tests
Assert.Null(exception);
}
[Fact]
public void DatePicker_Respects_DateTimeMinValue()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
var component = ctx.RenderComponent<RadzenDatePicker<DateTime>>(parameters =>
{
parameters.Add(p => p.Value, DateTime.MinValue);
});
Assert.Contains(DateTime.MinValue.ToString(component.Instance.DateFormat), component.Markup);
var exception = Record.Exception(() => component.Find(".rz-datepicker-prev-icon")
.Click());
Assert.Null(exception);
}
[Theory]
[InlineData(DateTimeKind.Local)]
[InlineData(DateTimeKind.Unspecified)]
@@ -464,5 +511,72 @@ namespace Radzen.Blazor.Tests
Assert.Contains(actionsTemplate, component.Markup);
}
[Fact]
public void DatePicker_Converts_DateTimeOffSet_FromUtc_ToLocal()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
var valueUtc = DateTimeOffset.UtcNow;
var kind = DateTimeKind.Local;
var component = ctx.RenderComponent<RadzenDatePicker<DateTimeOffset>>(parameters =>
{
parameters.Add(p => p.Kind, kind);
parameters.Add(p => p.Value, valueUtc);
});
Assert.Equal(kind, (component.Instance.Value as DateTime?)?.Kind);
Assert.Equal(valueUtc.LocalDateTime.ToString(CultureInfo.InvariantCulture), (component.Instance.Value as DateTime?)?.ToString(CultureInfo.InvariantCulture));
}
[Fact]
public void DatePicker_Converts_DateTimeOffSet_Local_ToUtc()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
var valueUtc = DateTimeOffset.Now;
var kind = DateTimeKind.Utc;
var component = ctx.RenderComponent<RadzenDatePicker<DateTimeOffset>>(parameters =>
{
parameters.Add(p => p.Kind, kind);
parameters.Add(p => p.Value, valueUtc);
});
Assert.Equal(kind, (component.Instance.Value as DateTime?)?.Kind);
Assert.Equal(valueUtc.UtcDateTime.ToString(CultureInfo.InvariantCulture), (component.Instance.Value as DateTime?)?.ToString(CultureInfo.InvariantCulture));
}
[Fact]
public void DatePicker_Displays_Calender_Icon()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
var component = ctx.RenderComponent<RadzenDatePicker<DateTime>>();
Assert.Contains(@$"rzi-calendar", component.Markup);
}
[Fact]
public void DatePicker_Displays_Schedule_Icon()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
var component = ctx.RenderComponent<RadzenDatePicker<DateTime>>(parameters =>
{
parameters.Add(p => p.TimeOnly, true);
});
Assert.Contains(@$"rzi-time", component.Markup);
}
}
}

View File

@@ -0,0 +1,144 @@
using System;
using System.Threading.Tasks;
using Bunit;
using Xunit;
namespace Radzen.Blazor.Tests
{
public class DropDownTests
{
class DataItem
{
public string Text { get; set; }
public int Id { get; set; }
}
private static IRenderedComponent<RadzenDropDown<T>> DropDown<T>(TestContext ctx, Action<ComponentParameterCollectionBuilder<RadzenDropDown<T>>> configure = null)
{
var data = new [] {
new DataItem { Text = "Item 1", Id = 1 },
new DataItem { Text = "Item 2", Id = 2 },
};
var component = ctx.RenderComponent<RadzenDropDown<T>>();
component.SetParametersAndRender(parameters => {
parameters.Add(p => p.Data, data);
parameters.Add(p => p.TextProperty, nameof(DataItem.Text));
if (configure != null)
{
configure.Invoke(parameters);
}
else
{
parameters.Add(p => p.ValueProperty, nameof(DataItem.Id));
}
});
return component;
}
[Fact]
public async Task Dropdown_SelectItem_Method_Should_Not_Throw()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
var component = DropDown<int>(ctx);
var items = component.FindAll(".rz-dropdown-item");
Assert.Equal(2, items.Count);
//this throws
await component.InvokeAsync(async () => await component.Instance.SelectItem(1));
}
[Fact]
public void DropDown_RendersItems()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
var component = DropDown<int>(ctx);
var items = component.FindAll(".rz-dropdown-item");
Assert.Equal(2, items.Count);
}
[Fact]
public void DropDown_AppliesSelectionStyleForIntValue()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
var component = DropDown<int>(ctx);
var items = component.FindAll(".rz-dropdown-item");
items[0].Click();
component.Render();
items = component.FindAll(".rz-dropdown-item");
Assert.Contains("rz-state-highlight", items[0].ClassList);
}
[Fact]
public void DropDown_AppliesSelectionStyleForStringValue()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
var component = DropDown<string>(ctx, parameters => {
parameters.Add(p => p.ValueProperty, nameof(DataItem.Text));
});
var items = component.FindAll(".rz-dropdown-item");
items[0].Click();
component.Render();
items = component.FindAll(".rz-dropdown-item");
Assert.Contains("rz-state-highlight", items[0].ClassList);
}
[Fact]
public void DropDown_AppliesSelectionStyleWhenMultipleSelectionIsEnabled()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
var component = DropDown<string>(ctx, parameters => {
parameters.Add(p => p.ValueProperty, nameof(DataItem.Text));
parameters.Add(p => p.Multiple, true);
});
var items = component.FindAll(".rz-multiselect-item");
items[0].Click();
component.Render();
items = component.FindAll(".rz-multiselect-item");
items[1].Click();
component.Render();
var selectedItems = component.FindAll(".rz-state-highlight");
Assert.Equal(2, selectedItems.Count);
}
}
}

View File

@@ -17,7 +17,6 @@ namespace Radzen.Blazor.Tests
component.Render();
Assert.Contains(@$"rz-fieldset", component.Markup);
Assert.Contains(@$"rz-fieldset-legend", component.Markup);
Assert.Contains(@$"rz-fieldset-content-wrapper", component.Markup);
Assert.Contains(@$"rz-fieldset-content", component.Markup);
}

View File

@@ -17,7 +17,7 @@ namespace Radzen.Blazor.Tests
component.SetParametersAndRender(parameters => parameters.Add(p => p.Icon, icon));
Assert.Contains(@$">{icon}</i>", component.Markup);
Assert.Contains(@$"<i class=""rzi d-inline-flex justify-content-center align-items-center""", component.Markup);
Assert.Contains(@$"class=""rzi""", component.Markup);
}
[Fact]
@@ -58,6 +58,18 @@ namespace Radzen.Blazor.Tests
Assert.Contains(@$"rzi-primary", component.Markup);
}
[Fact]
public void Icon_Renders_IconColor()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenIcon>();
component.SetParametersAndRender(parameters => parameters.Add(icon => icon.IconColor, Colors.Primary));
Assert.Contains(@$"color:", component.Markup);
}
[Fact]
public void Icon_NotRenders_IconStyleClass_WhenNull()
{
@@ -69,5 +81,17 @@ namespace Radzen.Blazor.Tests
Assert.DoesNotContain(@$"rzi-primary", component.Markup);
}
[Fact]
public void Icon_NotRenders_IconColor_WhenNull()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenIcon>();
component.SetParametersAndRender(parameters => parameters.Add(icon => icon.IconColor, null));
Assert.DoesNotContain(@$"color:", component.Markup);
}
}
}

View File

@@ -30,8 +30,10 @@ namespace Radzen.Blazor.Tests
component.SetParametersAndRender(parameters => parameters.Add(p => p.Text, text));
Assert.Contains(@$">{text}</span>", component.Markup);
Assert.Contains(@$"class=""rz-link-text""", component.Markup);
var textElement = component.Find(".rz-link-text");
Assert.NotNull(textElement);
Assert.Equal(text, textElement.TextContent.Trim());
}
[Fact]

View File

@@ -26,7 +26,12 @@ namespace Radzen.Blazor.Tests
var component = ctx.RenderComponent<RadzenLogin>();
Assert.Contains(@$"<label class=""col-sm-3 col-form-label"" for=""username"">Username</label>", component.Markup);
component.SetParametersAndRender(p => {
p.AddUnmatched("id", "login");
});
var label = component.Find($@"label[for=""login-username""]");
Assert.NotNull(label);
}
[Fact]
@@ -63,7 +68,7 @@ namespace Radzen.Blazor.Tests
component.SetParametersAndRender(parameters => {
parameters.Add(p => p.Username, "user");
parameters.Add(p => p.Password, "pwd");
parameters.Add(p => p.Login, args => { clicked = true; });
parameters.Add(p => p.Login, args => { clicked = true; });
});
component.Find("button").Click();
@@ -114,7 +119,7 @@ namespace Radzen.Blazor.Tests
parameters.Add(p => p.AllowResetPassword, true);
});
Assert.Contains(@$"Forgot password</a>", component.Markup);
Assert.Contains(@$"Forgot password?</a>", component.Markup);
}
[Fact]
@@ -190,7 +195,7 @@ namespace Radzen.Blazor.Tests
parameters.Add(p => p.Register, args => { clicked = true; });
});
component.Find(".register > button").Click();
component.Find(".rz-secondary").Click();
Assert.True(clicked);
}

View File

@@ -128,6 +128,34 @@ namespace Radzen.Blazor.Tests
Assert.Contains(@$"autocomplete=""on""", component.Markup);
}
[Fact]
public void Mask_Renders_TypedAutoCompleteParameter()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenMask>();
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, false));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.On));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.Off));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.AdditionalName));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.AdditionalName.GetAutoCompleteValue()}""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.Email));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.Email.GetAutoCompleteValue()}""", component.Markup);
}
[Fact]
public void Mask_Renders_MaxLengthParameter()
{

View File

@@ -0,0 +1,159 @@
using System;
using System.Threading.Tasks;
using Bunit;
using Microsoft.AspNetCore.Components.Forms;
using Xunit;
namespace Radzen.Blazor.Tests
{
public class NumericRangeValidatorTests
{
class FormComponentTestDouble : IRadzenFormComponent
{
public bool IsBound => false;
public bool HasValue => true;
public string Name { get; set; }
public FieldIdentifier FieldIdentifier => throw new System.NotImplementedException();
public object GetValue()
{
return Value;
}
public ValueTask FocusAsync()
{
throw new NotImplementedException();
}
public object Value { get; set; }
}
class RadzenNumericRangeValidatorTestDouble : RadzenNumericRangeValidator
{
public bool Validate(object value)
{
return base.Validate(new FormComponentTestDouble { Value = value });
}
}
[Fact]
public void Throws_Exception_If_Min_And_Max_Are_Null()
{
var validator = new RadzenNumericRangeValidatorTestDouble();
Assert.Throws<System.ArgumentException>(() => validator.Validate(1));
}
[Fact]
public void Returns_False_If_Value_Is_Null()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenNumericRangeValidatorTestDouble>();
component.SetParametersAndRender(parameters =>
{
component.SetParametersAndRender(parameters => parameters.Add(p => p.Min, 0).Add(p => p.Max, 10));
});
Assert.False(component.Instance.Validate(null));
}
[Fact]
public void Returns_False_If_Value_Overflows()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenNumericRangeValidatorTestDouble>();
component.SetParametersAndRender(parameters =>
{
component.SetParametersAndRender(parameters => parameters.Add(p => p.Min, 0).Add(p => p.Max, 10));
});
Assert.False(component.Instance.Validate(long.MaxValue));
}
[Fact]
public void Returns_True_If_Value_Is_Greater_Than_Min()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenNumericRangeValidatorTestDouble>();
component.SetParametersAndRender(parameters => parameters.Add(p => p.Min, 0));
Assert.True(component.Instance.Validate(1));
}
[Fact]
public void Returns_True_If_Value_Is_Equal_To_Min()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenNumericRangeValidatorTestDouble>();
component.SetParametersAndRender(parameters => parameters.Add(p => p.Min, 0));
Assert.True(component.Instance.Validate(0));
}
[Fact]
public void Returns_True_If_Value_Is_Less_Than_Max()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenNumericRangeValidatorTestDouble>();
component.SetParametersAndRender(parameters => parameters.Add(p => p.Max, 10));
Assert.True(component.Instance.Validate(9));
}
[Fact]
public void Returns_True_If_Value_Is_Equal_To_Max()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenNumericRangeValidatorTestDouble>();
component.SetParametersAndRender(parameters => parameters.Add(p => p.Max, 10));
Assert.True(component.Instance.Validate(10));
}
[Fact]
public void Returns_True_If_Value_Is_Between_Min_And_Max()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenNumericRangeValidatorTestDouble>();
component.SetParametersAndRender(parameters => parameters.Add(p => p.Min, 0).Add(p => p.Max, 10));
Assert.True(component.Instance.Validate(5));
}
[Fact]
public void Returns_True_If_Value_Is_Between_Min_And_Max_And_They_Are_Nullable()
{
int? min = 0;
int? max = 10;
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenNumericRangeValidatorTestDouble>();
component.SetParametersAndRender(parameters => parameters.Add(p => p.Min, min).Add(p => p.Max, max));
Assert.True(component.Instance.Validate(5));
}
[Fact]
public void Returns_True_When_Value_Is_Of_DifferentType()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenNumericRangeValidatorTestDouble>();
component.SetParametersAndRender(parameters => parameters.Add(p => p.Min, 0m).Add(p => p.Max, 10m));
Assert.True(component.Instance.Validate(5));
}
[Fact]
public void Returns_False_If_Cannot_Conert_Value()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenNumericRangeValidatorTestDouble>();
component.SetParametersAndRender(parameters => parameters.Add(p => p.Min, 0m).Add(p => p.Max, 10m));
Assert.False(component.Instance.Validate(DateTime.Now));
}
}
}

View File

@@ -193,6 +193,34 @@ namespace Radzen.Blazor.Tests
Assert.Contains(@$"autocomplete=""on""", component.Markup);
}
[Fact]
public void Numeric_Renders_TypedAutoCompleteParameter()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenNumeric<double>>();
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, false));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.On));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.Off));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.BdayMonth));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.BdayMonth.GetAutoCompleteValue()}""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.BdayYear));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.BdayYear.GetAutoCompleteValue()}""", component.Markup);
}
[Fact]
public void Numeric_Raises_ChangedEvent()
{

View File

@@ -76,5 +76,38 @@ namespace Radzen.Blazor.Tests
Assert.DoesNotContain(@$"rz-paginator-summary", component.Markup);
}
[Fact]
public void RadzenPager_Renders_PagerDensityDefault()
{
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);
parameters.Add<Density>(p => p.Density, Density.Default);
});
Assert.DoesNotContain(@$"rz-density-compact", component.Markup);
}
[Fact]
public void RadzenPager_Renders_PagerDensityCompact()
{
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);
parameters.Add<Density>(p => p.Density, Density.Compact);
});
Assert.Contains(@$"rz-density-compact", component.Markup);
}
}
}

View File

@@ -128,6 +128,34 @@ namespace Radzen.Blazor.Tests
Assert.Contains(@$"autocomplete=""on""", component.Markup);
}
[Fact]
public void Password_Renders_TypedAutoCompleteParameter()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenPassword>();
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, false));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.On));
Assert.Contains(@$"autocomplete=""new-password""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.Off));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.CurrentPassword));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.CurrentPassword.GetAutoCompleteValue()}""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.NewPassword));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.NewPassword.GetAutoCompleteValue()}""", component.Markup);
}
[Fact]
public void Password_Renders_UnmatchedParameter()
{

View File

@@ -18,7 +18,9 @@ namespace Radzen.Blazor.Tests
component.SetParametersAndRender(parameters => parameters.Add<double>(p => p.Value, value));
Assert.Contains(@$"<div class=""rz-progressbar-label"">{value}", component.Markup);
Assert.Contains(@$"<div class=""rz-progressbar-label"">", component.Markup);
Assert.Contains(@$"{value}%", component.Markup);
Assert.Contains(@$"aria-valuenow=""{value}""", component.Markup);
Assert.Contains(@$"aria-valuemin=""0""", component.Markup);
}
@@ -50,13 +52,13 @@ namespace Radzen.Blazor.Tests
component.Render();
Assert.Contains(@$"%</div>", component.Markup);
Assert.Contains(@$"0%", component.Markup);
var value = "mm";
var unit = "mm";
component.SetParametersAndRender(parameters => parameters.Add(p => p.Unit, value));
component.SetParametersAndRender(parameters => parameters.Add(p => p.Unit, unit));
Assert.Contains(@$"{value}</div>", component.Markup);
Assert.Contains(@$"0{unit}", component.Markup);
}
[Fact]
@@ -118,5 +120,27 @@ namespace Radzen.Blazor.Tests
Assert.Contains(@$"style=""width: {Math.Min(value / max * 100, 100).ToInvariantString()}%;""", component.Markup);
}
[Fact]
public void ProgressBar_Renders_ProgressBarStyle()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenProgressBar>();
component.SetParametersAndRender(parameters=>parameters.Add(p=>p.ProgressBarStyle, ProgressBarStyle.Success));
Assert.Contains(@$"rz-progressbar-success", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add(p => p.ProgressBarStyle, ProgressBarStyle.Info));
Assert.Contains(@$"rz-progressbar-info", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add(p => p.ProgressBarStyle, ProgressBarStyle.Success));
component.SetParametersAndRender(parameters => parameters.Add(p => p.Mode, ProgressBarMode.Indeterminate));
Assert.Contains(@$"rz-progressbar-success", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add(p => p.ProgressBarStyle, ProgressBarStyle.Info));
component.SetParametersAndRender(parameters => parameters.Add(p => p.Mode, ProgressBarMode.Indeterminate));
Assert.Contains(@$"rz-progressbar-info", component.Markup);
}
}
}

View File

@@ -0,0 +1,120 @@
using AngleSharp.Css;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using Xunit;
namespace Radzen.Blazor.Tests
{
public class PropertyAccessTests
{
public partial class TestData
{
public string PROPERTY { get; set; }
public string Property { get; set; }
}
[Fact]
public void Getter_With_DifferentTargetType()
{
var o = new TestData { Property = "test" };
var getter = PropertyAccess.Getter<object, object>(nameof(TestData.Property), typeof(TestData));
var value = getter(o);
Assert.Equal(o.Property, value);
}
[Fact]
public void Getter_With_Members_That_Differ_Only_In_Casing()
{
var o = new TestData { PROPERTY = nameof(TestData.PROPERTY), Property = nameof(TestData.Property) };
var getter = PropertyAccess.Getter<TestData, string>(nameof(TestData.PROPERTY));
var value = getter(o);
Assert.Equal(nameof(TestData.PROPERTY), value);
}
[Fact]
public void Getter_Resolves_Property_On_Simple_Object()
{
var o = new SimpleObject() { Prop1 = "TestString" };
var getter = PropertyAccess.Getter<SimpleObject, string>("Prop1");
var value = getter(o);
Assert.Equal("TestString", value);
}
[Fact]
public void Getter_Resolves_Property_On_Simple_Object_QueryableType()
{
var _data = new List<SimpleObject>()
{
new SimpleObject() { Prop1 = "TestString" },
};
Func<object, object> getter = PropertyAccess.Getter<object, object>("Prop1", typeof(SimpleObject));
var value = getter(_data[0]);
Assert.Equal("TestString", value);
}
[Fact]
public void Getter_Resolves_Property_On_Nested_Object()
{
var o = new NestedObject() { Obj = new SimpleObject { Prop1 = "TestString" } };
var getter = PropertyAccess.Getter<NestedObject, string>("Obj.Prop1");
var value = getter(o);
Assert.Equal("TestString", value);
}
[Fact]
public void Getter_Resolves_Property_From_Array()
{
var o = new ArrayObject() { Values = new string[] { "1", "2", "3" } };
var getter = PropertyAccess.Getter<ArrayObject, string>("Values[1]");
var value = getter(o);
Assert.Equal("2", value);
}
[Fact]
public void Getter_Resolves_Property_From_Nested_Array()
{
var o = new NestedArrayObject() { Obj = new ArrayObject() { Values = new string[] { "1", "2", "3" } } };
var getter = PropertyAccess.Getter<NestedArrayObject, string>("Obj.Values[2]");
var value = getter(o);
Assert.Equal("3", value);
}
[Fact]
public void Getter_Resolves_Property_From_List()
{
var o = new ListObject() { Values = new List<string>() { "1", "2", "3" } };
var getter = PropertyAccess.Getter<ListObject, string>("Values[1]");
var value = getter(o);
Assert.Equal("2", value);
}
public class SimpleObject
{
public string Prop1 { get; set; }
}
public class NestedObject
{
public SimpleObject Obj { get; set; }
}
public class ArrayObject
{
public string[] Values { get; set; }
}
public class NestedArrayObject
{
public ArrayObject Obj { get; set; }
}
public class ListObject
{
public List<string> Values { get; set; }
}
}
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6</TargetFramework>
<TargetFramework>net7</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>

View File

@@ -0,0 +1,25 @@
using System.Collections.Generic;
using Radzen.Blazor.Rendering;
using Xunit;
namespace Radzen.Blazor.Tests.Rendering;
public class StepGeneratorTests
{
[Fact]
public void Renders_Path_Correctly()
{
var data = new List<Point>
{
new() { X = 10, Y = 10 },
new() { X = 20, Y = 15 },
new() { X = 30, Y = 20 },
new() { X = 40, Y = 25 },
new() { X = 50, Y = 50 }
};
var path = new StepGenerator().Path(data);
Assert.Equal("10 10 H 20 V 15 H 30 V 20 H 40 V 25 H 50 V 50", path);
}
}

View File

@@ -0,0 +1,197 @@
using Bunit;
using Xunit;
namespace Radzen.Blazor.Tests
{
public class SpeechToTextButtonTests
{
[Fact]
public void SpeechToTextButton_Renders_Record_Button_When_Visible()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenSpeechToTextButton>();
component.Render();
var recordButton = component.Find("button.rz-button-icon-only.rz-speech-to-text-button");
Assert.NotNull(recordButton);
}
[Fact]
public void SpeechToTextButton_Does_Not_Renders_Record_Button_When_Visible_False()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenSpeechToTextButton>();
component.SetParametersAndRender(parameters =>
{
parameters.Add(p => p.Visible, false);
});
Assert.Throws<ElementNotFoundException>(() => component.Find("button.rz-button-icon-only.rz-speech-to-text-button"));
}
[Fact]
public void SpeechToTextButton_Renders_Additional_Css()
{
using var ctx = new TestContext();
var component =
ctx.RenderComponent<RadzenSpeechToTextButton>(ComponentParameter.CreateParameter("class", "another-class"));
var recordButton = component.Find("button.rz-button-icon-only.rz-speech-to-text-button.another-class");
Assert.NotNull(recordButton);
}
[Fact]
public void SpeechToTextButton_Can_Override_Default_Title_And_Aria_Label()
{
using var ctx = new TestContext();
var component =
ctx.RenderComponent<RadzenSpeechToTextButton>(
ComponentParameter.CreateParameter("title", "title override"),
ComponentParameter.CreateParameter("aria-label", "aria-label override"));
var recordButton = component.Find("button.rz-button-icon-only.rz-speech-to-text-button");
Assert.NotNull(recordButton);
Assert.Equal("title override", recordButton.GetAttribute("title"));
Assert.Equal("aria-label override", recordButton.GetAttribute("aria-label"));
}
[Fact]
public void SpeechToTextButton_Sets_Record_Button_Css_When_Record_Button_Clicked()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenSpeechToTextButton>();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
component.Render();
var recordButton = component.Find("button.rz-button-icon-only.rz-speech-to-text-button");
Assert.NotNull(recordButton);
recordButton.Click();
component.Render();
var blinkingRecordButton = component.Find("button.rz-button-icon-only.rz-speech-to-text-button-recording");
Assert.NotNull(blinkingRecordButton);
}
[Fact]
public void SpeechToTextButton_Sets_StopTitle_When_Record_Button_Clicked()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenSpeechToTextButton>();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
component.Render();
var recordButton = component.Find("button.rz-button-icon-only.rz-speech-to-text-button");
Assert.NotNull(recordButton);
recordButton.Click();
component.Render();
var blinkingRecordButton = component.Find("button.rz-button-icon-only.rz-speech-to-text-button-recording");
Assert.Equal(component.Instance.StopTitle, blinkingRecordButton.GetAttribute("title"));
}
[Fact]
public void SpeechToTextButton_ChangesIconWhen_When_Record_Button_Clicked()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenSpeechToTextButton>();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
component.Render();
var recordButton = component.Find("button.rz-button-icon-only.rz-speech-to-text-button");
Assert.NotNull(recordButton);
recordButton.Click();
component.Render();
var blinkingRecordButton = component.Find("button span");
Assert.Contains("stop", blinkingRecordButton.TextContent);
Assert.DoesNotContain("mic", blinkingRecordButton.TextContent);
}
[Fact]
public void SpeechToTextButton_UnSets_Record_Button_Css_When_Record_Button_Clicked_Twice()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenSpeechToTextButton>();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
component.Render();
var recordButton = component.Find("button.rz-button-icon-only.rz-speech-to-text-button");
Assert.NotNull(recordButton);
recordButton.Click();
component.Render();
const string blinkingRecordButtonSelector = "button.rz-button-icon-only.rz-speech-to-text-button-recording";
var blinkingRecordButton = component.Find(blinkingRecordButtonSelector);
Assert.NotNull(blinkingRecordButton);
blinkingRecordButton.Click();
component.Render();
Assert.Throws<ElementNotFoundException>(() => component.Find(blinkingRecordButtonSelector));
}
[Fact]
public void SpeechToTextButton_Invokes_OnResult_FromJs()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
var component = ctx.RenderComponent<RadzenSpeechToTextButton>();
string resultsFromJs = null;
component.SetParametersAndRender(parameters => parameters.Add(p => p.Change, r => resultsFromJs = r));
var recordButton = component.Find("button.rz-button-icon-only.rz-speech-to-text-button");
Assert.NotNull(recordButton);
recordButton.Click();
const string speechResults = "results from js";
component.InvokeAsync(() => component.Instance.OnResult(speechResults));
Assert.Equal(speechResults, resultsFromJs);
}
}
}

View File

@@ -127,6 +127,8 @@ namespace Radzen.Blazor.Tests
public void SplitButton_Raises_ClickEvent()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
var component = ctx.RenderComponent<RadzenSplitButton>();

View File

@@ -128,6 +128,34 @@ namespace Radzen.Blazor.Tests
Assert.Contains(@$"autocomplete=""on""", component.Markup);
}
[Fact]
public void TextBox_Renders_TypedAutoCompleteParameter()
{
using var ctx = new TestContext();
var component = ctx.RenderComponent<RadzenTextBox>();
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, false));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.On));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.Off));
Assert.Contains(@$"autocomplete=""off""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.AdditionalName));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.AdditionalName.GetAutoCompleteValue()}""", component.Markup);
component.SetParametersAndRender(parameters => parameters.Add<bool>(p => p.AutoComplete, true));
component.SetParametersAndRender(parameters => parameters.Add<AutoCompleteType>(p => p.AutoCompleteType, AutoCompleteType.FamilyName));
Assert.Contains(@$"autocomplete=""{AutoCompleteType.FamilyName.GetAutoCompleteValue()}""", component.Markup);
}
[Fact]
public void TextBox_Renders_MaxLengthParameter()
{

View File

@@ -0,0 +1,138 @@
namespace Radzen.Blazor
{
/// <summary>
/// The <c>AutomCompleteType</c> is a string-associated enum of
/// browser-supported autocomplete attribute values.
/// </summary>
/// <remarks>
/// This class lists the autocomplete attirbute options allowing
/// developers to provide the browser with guidance on how to pre-populate
/// the form fields. It is a class rather than a simpler enum to associate
/// each option with the string the browser expects. For more information
/// please review the list of options (https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete)
/// and the spec (https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill).
/// </remarks>
public enum AutoCompleteType
{
/// <summary>Autocomplete is disabled. </summary>
Off,
/// <summary>Autocomplete is enabled. The browser chooses what values to suggest. </summary>
On,
/// <summary>The field expects the value to be a person's full name.</summary>
Name,
/// <summary>The prefix or title, such as "Mrs.", "Mr.", "Miss", "Ms.", "Dr." etc.</summary>
HonorificPrefix,
/// <summary>The given (or "first") name.</summary>
GivenName,
/// <summary>The middle name.</summary>
AdditionalName,
/// <summary>The family (or "last") name.</summary>
FamilyName,
/// <summary>The suffix, such as "Jr.", "B.Sc.", "PhD.", "MBASW", etc.</summary>
HonorificSuffix,
/// <summary>The nickname or handle.</summary>
Nickname,
/// <summary>The email address.</summary>
Email,
/// <summary>The username or account name.</summary>
Username,
/// <summary>A new password. When creating a new account or changing passwords.</summary>
NewPassword,
/// <summary>A current password. When filling in an existing password.</summary>
CurrentPassword,
/// <summary>A one-time code used for verifying user identity.</summary>
OneTimeCode,
/// <summary>A job title, or the title a person has within an organization, such as "Senior Technical Writer", "President", or "Assistant Troop Leader".</summary>
OrganizationTitle,
/// <summary>A company, business, or organization name.</summary>
Organization,
/// <summary>A street address. Use multiple address lines when more space is needed.</summary>
StreetAddress,
/// <summary>The line 1 of a street address. For example, "1234 Main Street".</summary>
AddressLine1,
/// <summary>The line 2 of a street address. For example, "Apartment 123".</summary>
AddressLine2,
/// <summary>The line 3 of a street address. For example, "c/o Jane Doe".</summary>
AddressLine3,
/// <summary>The city or locality.</summary>
AddressLevel1,
/// <summary>The state, province, prefecture, or region.</summary>
AddressLevel2,
/// <summary>The zip code or postal code.</summary>
AddressLevel3,
/// <summary>The country name.</summary>
AddressLevel4,
/// <summary>The country code.</summary>
Country,
/// <summary>The country name.</summary>
CountryName,
/// <summary>The postal code.</summary>
PostalCode,
/// <summary>The full name as printed on or associated with a payment instrument such as a credit card.</summary>
CcName,
/// <summary>The given (or "first") name as printed on or associated with a payment instrument such as a credit card.</summary>
CcGivenName,
/// <summary>The middle name as printed on or associated with a payment instrument such as a credit card.</summary>
CcAdditionalName,
/// <summary>The family (or "last") name as printed on or associated with a payment instrument such as a credit card.</summary>
CcFamilyName,
/// <summary>A credit card number or other number identifying a payment method, such as an account number.</summary>
CcNumber,
/// <summary>A payment method expiration date, typically in the form "MM/YY" or "MM/YYYY".</summary>
CcExp,
/// <summary>A payment method expiration month, typically in numeric form (MM).</summary>
CcExpMonth,
/// <summary>A payment method expiration year, typically in numeric form (YYYY).</summary>
CcExpYear,
/// <summary>The security code for your payment method, such as the CVV code.</summary>
CcCsc,
/// <summary>The type of payment instrument, such as "Visa", "Master Card", "Checking", or "Savings".</summary>
CcType,
/// <summary>The currency in which the transaction was completed. Use the ISO 4217 currency codes, such as "USD" for the US dollar.</summary>
TransactionCurrency,
/// <summary>The amount, in the currency specified by the transaction currency attribute, of the transaction completed.</summary>
TransactionAmount,
/// <summary>The language in which the transaction was completed. Use the relevant BCP 47 language tag.</summary>
Language,
/// <summary>A birth date, as a full date.</summary>
Bday,
/// <summary>The day of the month of a birth date.</summary>
BdayDay,
/// <summary>The month of the year of a birth date.</summary>
BdayMonth,
/// <summary>The year of a birth date.</summary>
BdayYear,
/// <summary>A gender identity (such as "Female", "Fa'afafine", "Hijra", "Male", "Nonbinary"), as freeform text without newlines.</summary>
Sex,
/// <summary>A full telephone number, including the country code. </summary>
Tel,
/// <summary>A country code, such as "1" for the United States, Canada, and other areas in North America and parts of the Caribbean.</summary>
TelCountryCode,
/// <summary>The entire phone number without the country code component, including a country-internal prefix.</summary>
TelNational,
/// <summary>The area code, with any country-internal prefix applied if appropriate.</summary>
TelAreaCode,
/// <summary>The phone number without the country or area code.</summary>
TelLocal,
/// <summary>The extension number, if applicable.</summary>
TelExtension,
/// <summary>A URL for an instant messaging protocol endpoint, such as "xmpp:username@example.net".</summary>
Impp,
/// <summary>A URL, such as a home page or company website address as appropriate given the context of the other fields in the form.</summary>
Url,
/// <summary>The URL of an image representing the person, company, or contact information given in the other fields in the form.</summary>
Photo,
/// <summary>State.</summary>
State,
/// <summary>Province.</summary>
Province,
/// <summary>Zip code.</summary>
ZipCode,
/// <summary>Firs name.</summary>
FirstName,
/// <summary>Middle name.</summary>
MiddleName,
/// <summary>Last name.</summary>
LastName,
}
}

View File

@@ -67,7 +67,13 @@ namespace Radzen.Blazor
/// <value>The ticks.</value>
public RadzenTicks Ticks { get; set; } = new RadzenTicks();
internal int TickDistance { get; set; } = 100;
/// <summary>
/// Gets or sets the pixel distance between axis ticks. It is used to calculate the number of visible ticks depending on the available space. Set to 100 by default;
/// Setting <see cref="Step" /> will override this value.
/// </summary>
/// <value>The desired pixel distance between ticks.</value>
[Parameter]
public int TickDistance { get; set; } = 100;
/// <summary>
/// Specifies the minimum value of the axis.

View File

@@ -5,6 +5,8 @@ using System.Linq;
using System.Linq.Dynamic.Core;
using Radzen.Blazor.Rendering;
using System.Threading.Tasks;
using System.Collections;
using Microsoft.AspNetCore.Components.Rendering;
namespace Radzen.Blazor
{
@@ -14,22 +16,34 @@ namespace Radzen.Blazor
/// <typeparam name="TItem">The type of the series data.</typeparam>
public abstract class CartesianSeries<TItem> : RadzenChartComponentBase, IChartSeries, IDisposable
{
/// <summary>
/// Cache for the value returned by <see cref="Category"/> when that value is only dependent on
/// <see cref="CategoryProperty"/>.
/// </summary>
Func<TItem, double> categoryPropertyCache;
/// <summary>
/// Creates a getter function that returns a value from the specified category scale for the specified data item.
/// </summary>
/// <param name="scale">The scale.</param>
protected Func<TItem, double> Category(ScaleBase scale)
internal Func<TItem, double> Category(ScaleBase scale)
{
if (categoryPropertyCache != null)
{
return categoryPropertyCache;
}
if (IsNumeric(CategoryProperty))
{
return PropertyAccess.Getter<TItem, double>(CategoryProperty);
categoryPropertyCache = PropertyAccess.Getter<TItem, double>(CategoryProperty);
return categoryPropertyCache;
}
if (IsDate(CategoryProperty))
{
var category = PropertyAccess.Getter<TItem, DateTime>(CategoryProperty);
return (item) => category(item).Ticks;
categoryPropertyCache = (item) => category(item).Ticks;
return categoryPropertyCache;
}
if (scale is OrdinalScale ordinal)
@@ -122,6 +136,18 @@ namespace Radzen.Blazor
[Parameter]
public RenderFragment<TItem> TooltipTemplate { get; set; }
/// <summary>
/// Gets the list of overlays.
/// </summary>
/// <value>The Overlays list.</value>
public IList<IChartSeriesOverlay> Overlays { get; } = new List<IChartSeriesOverlay>();
/// <summary>
/// Gets the coordinate system of the series.
/// </summary>
/// <value>Coordinate system enum value.</value>
public virtual CoordinateSystem CoordinateSystem => CoordinateSystem.Cartesian;
/// <summary>
/// The name of the property of <typeparamref name="TItem" /> that provides the X axis (a.k.a. category axis) values.
/// </summary>
@@ -174,7 +200,7 @@ namespace Radzen.Blazor
/// </summary>
/// <value>The value.</value>
/// <exception cref="ArgumentException">ValueProperty should not be empty</exception>
protected Func<TItem, double> Value
internal Func<TItem, double> Value
{
get
{
@@ -264,7 +290,7 @@ namespace Radzen.Blazor
Output = scale.Output
};
}
var data = GetCategories();
if (scale is OrdinalScale ordinal)
@@ -311,6 +337,23 @@ namespace Radzen.Blazor
/// <inheritdoc />
public abstract RenderFragment Render(ScaleBase categoryScale, ScaleBase valueScale);
/// <inheritdoc />
public RenderFragment RenderOverlays(ScaleBase categoryScale, ScaleBase valueScale)
{
return new RenderFragment(builder =>
{
builder.OpenRegion(0);
foreach (var overlay in Overlays)
{
if (overlay.Visible)
{
builder.AddContent(1, overlay.Render(categoryScale, valueScale));
}
}
builder.CloseRegion();
});
}
/// <inheritdoc />
public abstract string Color { get; }
@@ -320,6 +363,7 @@ namespace Radzen.Blazor
var shouldRefresh = parameters.DidParameterChange(nameof(Data), Data);
var visibleChanged = parameters.DidParameterChange(nameof(Visible), Visible);
var hiddenChanged = parameters.DidParameterChange(nameof(Hidden), Hidden);
var categoryChanged = parameters.DidParameterChange(nameof(CategoryProperty), CategoryProperty);
await base.SetParametersAsync(parameters);
@@ -335,6 +379,11 @@ namespace Radzen.Blazor
shouldRefresh = true;
}
if (categoryChanged || shouldRefresh)
{
categoryPropertyCache = null;
}
if (Data != null && Data.Count() != Items.Count)
{
shouldRefresh = true;
@@ -423,7 +472,7 @@ namespace Radzen.Blazor
}
/// <inheritdoc />
public virtual RenderFragment RenderTooltip(object data, double marginLeft, double marginTop)
public virtual RenderFragment RenderTooltip(object data, double marginLeft, double marginTop, double chartHeight)
{
var item = (TItem)data;
@@ -436,10 +485,7 @@ namespace Radzen.Blazor
builder.AddAttribute(1, nameof(ChartTooltip.X), x + marginLeft);
builder.AddAttribute(2, nameof(ChartTooltip.Y), y + marginTop);
if (TooltipTemplate != null)
{
builder.AddAttribute(3, nameof(ChartTooltip.ChildContent), TooltipTemplate(item));
}
builder.AddAttribute(3, nameof(ChartTooltip.ChildContent), TooltipTemplate?.Invoke(item));
builder.AddAttribute(4, nameof(ChartTooltip.Title), TooltipTitle(item));
builder.AddAttribute(5, nameof(ChartTooltip.Label), TooltipLabel(item));
@@ -508,9 +554,81 @@ namespace Radzen.Blazor
}
}
/// <inheritdoc />
public double GetMedian()
{
return Data.Select(e => Value(e)).OrderBy(e => e).Skip(Data.Count() / 2).FirstOrDefault();
}
/// <inheritdoc />
public double GetMean()
{
return Data.Select(e => Value(e)).Average();
}
/// <inheritdoc />
public double GetMode()
{
return Data.GroupBy(e => Value(e)).Select(g => new { Value = g.Key, Count = g.Count() }).OrderByDescending(e => e.Count).FirstOrDefault().Value;
}
/// <summary>
/// https://en.wikipedia.org/wiki/Simple_linear_regression#Fitting_the_regression_line
/// </summary>
public (double a, double b) GetTrend()
{
double a, b;
Func<TItem, double> X;
Func<TItem, double> Y;
if (Chart.ShouldInvertAxes())
{
X = e => Chart.CategoryScale.Scale(Value(e));
Y = e => Chart.ValueScale.Scale(Category(Chart.ValueScale)(e));
}
else
{
X = e => Chart.CategoryScale.Scale(Category(Chart.CategoryScale)(e));
Y = e => Chart.ValueScale.Scale(Value(e));
}
var avgX = Data.Select(e => X(e)).Average();
var avgY = Data.Select(e => Y(e)).Average();
var sumXY = Data.Sum(e => (X(e) - avgX) * (Y(e) - avgY));
if (Chart.ShouldInvertAxes())
{
var sumYSq = Data.Sum(e => (Y(e) - avgY) * (Y(e) - avgY));
b = sumXY / sumYSq;
a = avgX - b * avgY;
}
else
{
var sumXSq = Data.Sum(e => (X(e) - avgX) * (X(e) - avgX));
b = sumXY / sumXSq;
a = avgY - b * avgX;
}
return (a, b);
}
private async Task OnLegendItemClick()
{
IsVisible = !IsVisible;
if (Chart.LegendClick.HasDelegate)
{
var args = new LegendClickEventArgs
{
Data = this.Data,
Title = GetTitle(),
IsVisible = IsVisible,
};
await Chart.LegendClick.InvokeAsync(args);
IsVisible = args.IsVisible;
}
await Chart.Refresh();
}
@@ -553,7 +671,7 @@ namespace Radzen.Blazor
/// Gets the X coordinate of the tooltip of the specified item.
/// </summary>
/// <param name="item">The item.</param>
protected virtual double TooltipX(TItem item)
internal virtual double TooltipX(TItem item)
{
var category = Category(Chart.CategoryScale);
return Chart.CategoryScale.Scale(category(item), true);
@@ -563,26 +681,45 @@ namespace Radzen.Blazor
/// Gets the Y coordinate of the tooltip of the specified item.
/// </summary>
/// <param name="item">The item.</param>
protected virtual double TooltipY(TItem item)
internal virtual double TooltipY(TItem item)
{
return Chart.ValueScale.Scale(Value(item), true);
}
/// <inheritdoc />
public virtual object DataAt(double x, double y)
public virtual (object, Point) DataAt(double x, double y)
{
var first = Items.FirstOrDefault();
var last = Items.LastOrDefault();
if (Items.Any())
{
var retObject = Items.Select(item =>
{
var distance = Math.Abs(TooltipX(item) - x);
return new { Item = item, Distance = distance };
}).Aggregate((a, b) => a.Distance < b.Distance ? a : b).Item;
var category = Category(Chart.CategoryScale);
return (retObject,
new Point() { X = TooltipX(retObject), Y = TooltipY(retObject)});
}
var startX = Chart.CategoryScale.Scale(category(first), true);
var endX = Chart.CategoryScale.Scale(category(last), true);
return (null, null);
}
var count = Math.Max(Items.Count() - 1, 1);
var index = Convert.ToInt32((x - startX) / ((endX - startX) / count));
/// <inheritdoc />
public virtual IEnumerable<ChartDataLabel> GetDataLabels(double offsetX, double offsetY)
{
var list = new List<ChartDataLabel>();
return Items.ElementAtOrDefault(index);
foreach (var d in Data)
{
list.Add(new ChartDataLabel
{
Position = new Point { X = TooltipX(d) + offsetX, Y = TooltipY(d) + offsetY },
TextAnchor = "middle",
Text = Chart.ValueAxis.Format(Chart.ValueScale, Value(d))
});
}
return list;
}
/// <summary>

File diff suppressed because it is too large Load Diff

View File

@@ -199,5 +199,20 @@ namespace Radzen
/// </summary>
/// <value>The value.</value>
public object Value { get; set; }
/// <summary>
/// Gets or sets the icon.
/// </summary>
/// <value>The icon.</value>
public string Icon { get; set; }
/// <summary>
/// Gets or sets the icon color.
/// </summary>
/// <value>The icon color.</value>
public string IconColor { get; set; }
/// <summary>
/// Gets or sets the image.
/// </summary>
/// <value>The image.</value>
public string Image { get; set; }
}
}

View File

@@ -1,14 +1,16 @@
using System;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Radzen.Blazor;
using Radzen.Blazor.Rendering;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Radzen.Blazor;
using Radzen.Blazor.Rendering;
namespace Radzen
{
@@ -96,11 +98,8 @@ namespace Radzen
}
set
{
if (_form != value && value != null)
{
_form = value;
_form.AddComponent(this);
}
_form = value;
_form?.AddComponent(this);
}
}
@@ -216,6 +215,32 @@ namespace Radzen
}
}
/// <summary>
/// Gets or sets the search text
/// </summary>
[Parameter]
public string SearchText
{
get
{
return searchText;
}
set
{
if (searchText != value)
{
searchText = value;
}
}
}
/// <summary>
/// Gets or sets the search text changed.
/// </summary>
/// <value>The search text changed.</value>
[Parameter]
public EventCallback<string> SearchTextChanged { get; set; }
/// <summary>
/// The search text
/// </summary>
@@ -291,20 +316,35 @@ namespace Radzen
/// <returns>A Task representing the asynchronous operation.</returns>
public override async Task SetParametersAsync(ParameterView parameters)
{
var searchTextChanged = parameters.DidParameterChange(nameof(SearchText), SearchText);
if (searchTextChanged)
{
searchText = parameters.GetValueOrDefault<string>(SearchText);
}
var dataChanged = parameters.DidParameterChange(nameof(Data), Data);
if (dataChanged)
{
await OnDataChanged();
}
var disabledChanged = parameters.DidParameterChange(nameof(Disabled), Disabled);
var result = base.SetParametersAsync(parameters);
if (EditContext != null && ValueExpression != null && FieldIdentifier.Model != EditContext.Model)
{
FieldIdentifier = FieldIdentifier.Create(ValueExpression);
EditContext.OnValidationStateChanged -= ValidationStateChanged;
EditContext.OnValidationStateChanged += ValidationStateChanged;
}
if (disabledChanged)
{
FormFieldContext?.DisabledChanged(Disabled);
}
await result;
}
@@ -337,7 +377,7 @@ namespace Radzen
/// Gets the value.
/// </summary>
/// <returns>System.Object.</returns>
public object GetValue()
public virtual object GetValue()
{
return Value;
}
@@ -350,6 +390,21 @@ namespace Radzen
/// <returns>ClassList.</returns>
protected ClassList GetClassList(string className) => ClassList.Create(className)
.AddDisabled(Disabled)
.Add(FieldIdentifier, EditContext);
.Add(FieldIdentifier, EditContext)
.Add("rz-state-empty", !HasValue);
#if NET5_0_OR_GREATER
/// <inheritdoc/>
public virtual async ValueTask FocusAsync()
{
await Element.FocusAsync();
}
#endif
/// <summary> Provides support for RadzenFormField integration. </summary>
[CascadingParameter]
public IFormFieldContext FormFieldContext { get; set; }
/// <summary> Gets the current placeholder. Returns empty string if this component is inside a RadzenFormField.</summary>
protected string CurrentPlaceholder => FormFieldContext != null ? " " : Placeholder;
}
}

View File

@@ -76,10 +76,15 @@ namespace Radzen
private void UriHelper_OnLocationChanged(object sender, Microsoft.AspNetCore.Components.Routing.LocationChangedEventArgs e)
{
if (dialogs.Count > 0)
while (dialogs.Any())
{
Close();
}
if (_sideDialogTask?.Task.IsCompleted == false)
{
CloseSide();
}
}
/// <summary>
@@ -97,6 +102,16 @@ namespace Radzen
/// </summary>
public event Action<string, Type, Dictionary<string, object>, DialogOptions> OnOpen;
/// <summary>
/// Raises the Close event for the side dialog
/// </summary>
public event Action<dynamic> OnSideClose;
/// <summary>
/// Raises the Open event for the side dialog
/// </summary>
public event Action<Type, Dictionary<string, object>, SideDialogOptions> OnSideOpen;
/// <summary>
/// Opens a dialog with the specified arguments.
/// </summary>
@@ -104,7 +119,7 @@ namespace Radzen
/// <param name="title">The text displayed in the title bar of the dialog.</param>
/// <param name="parameters">The dialog parameters. Passed as property values of <typeparamref name="T" />.</param>
/// <param name="options">The dialog options.</param>
public void Open<T>(string title, Dictionary<string, object> parameters = null, DialogOptions options = null) where T : ComponentBase
public virtual void Open<T>(string title, Dictionary<string, object> parameters = null, DialogOptions options = null) where T : ComponentBase
{
OpenDialog<T>(title, parameters, options);
}
@@ -121,6 +136,7 @@ namespace Radzen
/// The tasks
/// </summary>
protected List<TaskCompletionSource<dynamic>> tasks = new List<TaskCompletionSource<dynamic>>();
private TaskCompletionSource<dynamic> _sideDialogTask;
/// <summary>
/// Opens a dialog with the specified arguments.
@@ -130,7 +146,7 @@ namespace Radzen
/// <param name="parameters">The dialog parameters. Passed as property values of <typeparamref name="T" />.</param>
/// <param name="options">The dialog options.</param>
/// <returns>The value passed as argument to <see cref="Close" />.</returns>
public Task<dynamic> OpenAsync<T>(string title, Dictionary<string, object> parameters = null, DialogOptions options = null) where T : ComponentBase
public virtual Task<dynamic> OpenAsync<T>(string title, Dictionary<string, object> parameters = null, DialogOptions options = null) where T : ComponentBase
{
var task = new TaskCompletionSource<dynamic>();
tasks.Add(task);
@@ -140,6 +156,42 @@ namespace Radzen
return task.Task;
}
/// <summary>
/// Opens a side dialog with the specified arguments
/// </summary>
/// <typeparam name="T">The type of Blazor component which will be displayed in the side dialog.</typeparam>
/// <param name="title">The text displayed in the title bar of the side dialog.</param>
/// <param name="parameters">The dialog parameters. Passed as property values of <typeparamref name="T"/></param>
/// <param name="options">The side dialog options.</param>
/// <returns>A task that completes when the dialog is closed or a new one opened</returns>
public Task<dynamic> OpenSideAsync<T>(string title, Dictionary<string, object> parameters = null, SideDialogOptions options = null)
where T : ComponentBase
{
CloseSide();
_sideDialogTask = new TaskCompletionSource<dynamic>();
if (options == null)
{
options = new SideDialogOptions();
}
options.Title = title;
OnSideOpen?.Invoke(typeof(T), parameters ?? new Dictionary<string, object>(), options);
return _sideDialogTask.Task;
}
/// <summary>
/// Closes the side dialog
/// </summary>
/// <param name="result">The result of the Dialog</param>
public void CloseSide(dynamic result = null)
{
if (_sideDialogTask?.Task.IsCompleted == false)
{
_sideDialogTask.TrySetResult(result);
OnSideClose?.Invoke(result);
}
}
/// <summary>
/// Opens a dialog with the specified content.
/// </summary>
@@ -147,7 +199,7 @@ namespace Radzen
/// <param name="childContent">The content displayed in the dialog.</param>
/// <param name="options">The dialog options.</param>
/// <returns>The value passed as argument to <see cref="Close" />.</returns>
public Task<dynamic> OpenAsync(string title, RenderFragment<DialogService> childContent, DialogOptions options = null)
public virtual Task<dynamic> OpenAsync(string title, RenderFragment<DialogService> childContent, DialogOptions options = null)
{
var task = new TaskCompletionSource<dynamic>();
tasks.Add(task);
@@ -167,7 +219,7 @@ namespace Radzen
/// <param name="title">The text displayed in the title bar of the dialog.</param>
/// <param name="childContent">The content displayed in the dialog.</param>
/// <param name="options">The dialog options.</param>
public void Open(string title, RenderFragment<DialogService> childContent, DialogOptions options = null)
public virtual void Open(string title, RenderFragment<DialogService> childContent, DialogOptions options = null)
{
options = options ?? new DialogOptions();
@@ -200,6 +252,9 @@ namespace Radzen
AutoFocusFirstElement = options != null ? options.AutoFocusFirstElement : true,
CloseDialogOnOverlayClick = options != null ? options.CloseDialogOnOverlayClick : false,
CloseDialogOnEsc = options != null ? options.CloseDialogOnEsc : true,
CssClass = options != null ? options.CssClass : "",
WrapperCssClass = options != null ? options.WrapperCssClass : "",
CloseTabIndex = options != null ? options.CloseTabIndex : 0,
});
}
@@ -208,7 +263,7 @@ namespace Radzen
/// </summary>
/// <param name="result">The result.</param>
[JSInvokable("DialogService.Close")]
public void Close(dynamic result = null)
public virtual void Close(dynamic result = null)
{
var dialog = dialogs.LastOrDefault();
@@ -229,6 +284,9 @@ namespace Radzen
/// <inheritdoc />
public void Dispose()
{
reference?.Dispose();
reference = null;
UriHelper.LocationChanged -= UriHelper_OnLocationChanged;
}
@@ -239,11 +297,11 @@ namespace Radzen
/// <param name="title">The text displayed in the title bar of the dialog.</param>
/// <param name="options">The options.</param>
/// <returns><c>true</c> if the user clicked the OK button, <c>false</c> otherwise.</returns>
public async Task<bool?> Confirm(string message = "Confirm?", string title = "Confirm", ConfirmOptions options = null)
public virtual async Task<bool?> Confirm(string message = "Confirm?", string title = "Confirm", ConfirmOptions options = null)
{
var dialogOptions = new DialogOptions()
{
Width = options != null ? !string.IsNullOrEmpty(options.Width) ? options.Width : "355px" : "355px",
Width = options != null ? !string.IsNullOrEmpty(options.Width) ? options.Width : "" : "",
Height = options != null ? options.Height : null,
Left = options != null ? options.Left : null,
Top = options != null ? options.Top : null,
@@ -257,41 +315,89 @@ namespace Radzen
AutoFocusFirstElement = options != null ? options.AutoFocusFirstElement : true,
CloseDialogOnOverlayClick = options != null ? options.CloseDialogOnOverlayClick : false,
CloseDialogOnEsc = options != null ? options.CloseDialogOnEsc : true,
CssClass = options != null ? $"rz-dialog-confirm {options.CssClass}" : "rz-dialog-confirm",
WrapperCssClass = options != null ? $"rz-dialog-wrapper {options.WrapperCssClass}" : "rz-dialog-wrapper",
CloseTabIndex = options != null ? options.CloseTabIndex : 0,
};
await JSRuntime.InvokeAsync<string>("Radzen.openDialog", dialogOptions, Reference);
return await OpenAsync(title, ds =>
{
RenderFragment content = b =>
{
var i = 0;
b.OpenElement(i++, "div");
b.OpenElement(i++, "p");
b.AddAttribute(i++, "style", "margin-bottom: 20px;");
b.AddContent(i++, message);
b.AddAttribute(i++, "class", "rz-dialog-confirm-message");
b.AddContent(i++, (MarkupString)message);
b.CloseElement();
b.OpenElement(i++, "div");
b.AddAttribute(i++, "class", "row");
b.OpenElement(i++, "div");
b.AddAttribute(i++, "class", "col-md-12");
b.AddAttribute(i++, "class", "rz-dialog-confirm-buttons");
b.OpenComponent<Blazor.RadzenButton>(i++);
b.AddAttribute(i++, "Text", options != null ? options.OkButtonText : "Ok");
b.AddAttribute(i++, "Style", "margin-bottom: 10px; width: 150px");
b.AddAttribute(i++, "Click", EventCallback.Factory.Create<Microsoft.AspNetCore.Components.Web.MouseEventArgs>(this, () => ds.Close(true)));
b.CloseComponent();
b.OpenComponent<Blazor.RadzenButton>(i++);
b.AddAttribute(i++, "Text", options != null ? options.CancelButtonText : "Cancel");
b.AddAttribute(i++, "ButtonStyle", ButtonStyle.Secondary);
b.AddAttribute(i++, "Style", "margin-bottom: 10px; margin-left: 10px; width: 150px");
b.AddAttribute(i++, "Click", EventCallback.Factory.Create<Microsoft.AspNetCore.Components.Web.MouseEventArgs>(this, () => ds.Close(false)));
b.CloseComponent();
b.CloseElement();
};
return content;
}, dialogOptions);
}
/// <summary>
/// Displays a alert dialog.
/// </summary>
/// <param name="message">The message displayed to the user.</param>
/// <param name="title">The text displayed in the title bar of the dialog.</param>
/// <param name="options">The options.</param>
/// <returns><c>true</c> if the user clicked the OK button, <c>false</c> otherwise.</returns>
public virtual async Task<bool?> Alert(string message = "", string title = "Message", AlertOptions options = null)
{
var dialogOptions = new DialogOptions()
{
Width = options != null ? !string.IsNullOrEmpty(options.Width) ? options.Width : "" : "",
Height = options != null ? options.Height : null,
Left = options != null ? options.Left : null,
Top = options != null ? options.Top : null,
Bottom = options != null ? options.Bottom : null,
ChildContent = options != null ? options.ChildContent : null,
ShowTitle = options != null ? options.ShowTitle : true,
ShowClose = options != null ? options.ShowClose : true,
Resizable = options != null ? options.Resizable : false,
Draggable = options != null ? options.Draggable : false,
Style = options != null ? options.Style : "",
AutoFocusFirstElement = options != null ? options.AutoFocusFirstElement : true,
CloseDialogOnOverlayClick = options != null ? options.CloseDialogOnOverlayClick : false,
CloseDialogOnEsc = options != null ? options.CloseDialogOnEsc : true,
CssClass = options != null ? $"rz-dialog-alert {options.CssClass}" : "rz-dialog-alert",
WrapperCssClass = options != null ? $"rz-dialog-wrapper {options.WrapperCssClass}" : "rz-dialog-wrapper",
CloseTabIndex = options != null ? options.CloseTabIndex : 0,
};
return await OpenAsync(title, ds =>
{
RenderFragment content = b =>
{
var i = 0;
b.OpenElement(i++, "p");
b.AddAttribute(i++, "class", "rz-dialog-alert-message");
b.AddContent(i++, (MarkupString)message);
b.CloseElement();
b.OpenElement(i++, "div");
b.AddAttribute(i++, "class", "rz-dialog-alert-buttons");
b.OpenComponent<Blazor.RadzenButton>(i++);
b.AddAttribute(i++, "Text", options != null ? options.OkButtonText : "Ok");
b.AddAttribute(i++, "Click", EventCallback.Factory.Create<Microsoft.AspNetCore.Components.Web.MouseEventArgs>(this, () => ds.Close(true)));
b.CloseComponent();
b.CloseElement();
};
return content;
@@ -300,9 +406,9 @@ namespace Radzen
}
/// <summary>
/// Class DialogOptions.
/// Base Class for dialog options
/// </summary>
public class DialogOptions
public abstract class DialogOptionsBase
{
/// <summary>
/// Gets or sets a value indicating whether to show the title bar. Set to <c>true</c> by default.
@@ -315,7 +421,93 @@ namespace Radzen
/// </summary>
/// <value><c>true</c> if the close button is shown; otherwise, <c>false</c>.</value>
public bool ShowClose { get; set; } = true;
/// <summary>
/// Gets or sets the width of the dialog.
/// </summary>
/// <value>The width.</value>
public string Width { get; set; }
/// <summary>
/// Gets or sets the height of the dialog.
/// </summary>
/// <value>The height.</value>
public string Height { get; set; }
/// <summary>
/// Gets or sets the CSS style of the dialog
/// </summary>
/// <value>The style.</value>
public string Style { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the dialog should be closed by clicking the overlay.
/// </summary>
/// <value><c>true</c> if closeable; otherwise, <c>false</c>.</value>
public bool CloseDialogOnOverlayClick { get; set; } = false;
/// <summary>
/// Gets or sets dialog box custom class
/// </summary>
public string CssClass { get; set; }
/// <summary>
/// Gets or sets the CSS classes added to the dialog's wrapper element.
/// </summary>
public string WrapperCssClass { get; set; }
/// <summary>
/// Gets or sets a value the dialog escape tabindex. Set to <c>0</c> by default.
/// </summary>
public int CloseTabIndex { get; set; } = 0;
}
/// <summary>
/// Class SideDialogOptions
/// </summary>
public class SideDialogOptions : DialogOptionsBase
{
/// <summary>
/// The title displayed on the dialog.
/// </summary>
public string Title { get; set; }
/// <summary>
/// The Position on which the dialog will be positioned
/// </summary>
public DialogPosition Position { get; set; } = DialogPosition.Right;
/// <summary>
/// Whether to show a mask on the background or not
/// </summary>
public bool ShowMask { get; set; } = true;
}
/// <summary>
/// DialogPosition enum
/// </summary>
public enum DialogPosition
{
/// <summary>
/// Dialog will be positioned on the right side
/// </summary>
Right,
/// <summary>
/// Dialog will be positioned on the left side
/// </summary>
Left,
/// <summary>
/// Dialog will be positioned on the top of the page
/// </summary>
Top,
/// <summary>
/// Dialog will be positioned at the bottom of the page
/// </summary>
Bottom
}
/// <summary>
/// Class DialogOptions.
/// </summary>
public class DialogOptions : DialogOptionsBase
{
/// <summary>
/// Gets or sets a value indicating whether the dialog is resizable. Set to <c>false</c> by default.
/// </summary>
@@ -342,21 +534,6 @@ namespace Radzen
/// <value>The bottom.</value>
public string Bottom { get; set; }
/// <summary>
/// Gets or sets the width of the dialog.
/// </summary>
/// <value>The width.</value>
public string Width { get; set; }
/// <summary>
/// Gets or sets the height of the dialog.
/// </summary>
/// <value>The height.</value>
public string Height { get; set; }
/// <summary>
/// Gets or sets the CSS style of the dialog
/// </summary>
/// <value>The style.</value>
public string Style { get; set; }
/// <summary>
/// Gets or sets the child content.
/// </summary>
/// <value>The child content.</value>
@@ -365,13 +542,6 @@ namespace Radzen
/// Gets or sets a value indicating whether to focus the first focusable HTML element. Set to <c>true</c> by default.
/// </summary>
public bool AutoFocusFirstElement { get; set; } = true;
/// <summary>
/// Gets or sets a value indicating whether the dialog should be closed by clicking the overlay.
/// </summary>
/// <value><c>true</c> if closeable; otherwise, <c>false</c>.</value>
public bool CloseDialogOnOverlayClick { get; set; } = false;
/// <summary>
/// Gets or sets a value indicating whether the dialog should be closed on ESC key press.
/// </summary>
@@ -382,12 +552,19 @@ namespace Radzen
/// <summary>
/// Class ConfirmOptions.
/// </summary>
public class ConfirmOptions : DialogOptions
public class AlertOptions : DialogOptions
{
/// <summary>
/// Gets or sets the text of the OK button.
/// </summary>
public string OkButtonText { get; set; }
}
/// <summary>
/// Class ConfirmOptions.
/// </summary>
public class ConfirmOptions : AlertOptions
{
/// <summary>
/// Gets or sets the text of the Cancel button.
/// </summary>

View File

@@ -1,12 +1,13 @@
using System;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
using Microsoft.JSInterop;
using Radzen.Blazor;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
using Microsoft.JSInterop;
namespace Radzen
{
@@ -16,7 +17,13 @@ namespace Radzen
/// <typeparam name="T"></typeparam>
public class DropDownBase<T> : DataBoundFormComponent<T>
{
#if NET5
#if NET5_0_OR_GREATER
/// <summary>
/// Gets or sets a value that determines how many additional items will be rendered before and after the visible region. This help to reduce the frequency of rendering during scrolling. However, higher values mean that more elements will be present in the page.
/// </summary>
[Parameter]
public int VirtualizationOverscanCount { get; set; }
internal Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize<object> virtualize;
/// <summary>
@@ -30,6 +37,8 @@ namespace Radzen
}
}
List<object> virtualItems;
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>();
@@ -44,10 +53,12 @@ namespace Radzen
if (LoadData.HasDelegate)
{
await LoadData.InvokeAsync(new Radzen.LoadDataArgs() { Skip = request.StartIndex, Top = request.Count, Filter = await JSRuntime.InvokeAsync<string>("Radzen.getInputValue", search) });
await LoadData.InvokeAsync(new Radzen.LoadDataArgs() { Skip = request.StartIndex, Top = request.Count, Filter = searchText });
}
return new Microsoft.AspNetCore.Components.Web.Virtualization.ItemsProviderResult<object>(LoadData.HasDelegate ? Data.Cast<object>() : view.Skip(request.StartIndex).Take(top), LoadData.HasDelegate ? Count : totalItemsCount);
virtualItems = (LoadData.HasDelegate ? Data : view.Skip(request.StartIndex).Take(top)).Cast<object>().ToList();
return new Microsoft.AspNetCore.Components.Web.Virtualization.ItemsProviderResult<object>(virtualItems, LoadData.HasDelegate ? Count : totalItemsCount);
}
/// <summary>
@@ -74,13 +85,22 @@ namespace Radzen
/// <returns><c>true</c> if virtualization is allowed; otherwise, <c>false</c>.</returns>
internal bool IsVirtualizationAllowed()
{
#if NET5
#if NET5_0_OR_GREATER
return AllowVirtualization;
#else
return false;
#endif
}
internal int GetVirtualizationOverscanCount()
{
#if NET5_0_OR_GREATER
return VirtualizationOverscanCount;
#else
return 0;
#endif
}
/// <summary>
/// Renders the items.
/// </summary>
@@ -89,7 +109,7 @@ namespace Radzen
{
return new RenderFragment(builder =>
{
#if NET5
#if NET5_0_OR_GREATER
if (AllowVirtualization)
{
builder.OpenComponent(0, typeof(Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize<object>));
@@ -102,6 +122,11 @@ namespace Radzen
});
}));
if(VirtualizationOverscanCount != default(int))
{
builder.AddAttribute(3, "OverscanCount", VirtualizationOverscanCount);
}
builder.AddComponentReferenceCapture(7, c => { virtualize = (Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize<object>)c; });
builder.CloseComponent();
@@ -131,7 +156,14 @@ namespace Radzen
{
return !string.IsNullOrEmpty($"{internalValue}");
}
return internalValue != null;
else if (typeof(IEnumerable).IsAssignableFrom(typeof(T)))
{
return internalValue != null && ((IEnumerable)internalValue).Cast<object>().Any();
}
else
{
return internalValue != null;
}
}
}
@@ -149,7 +181,7 @@ namespace Radzen
internal object GetKey(object item)
{
var value = PropertyAccess.GetItemOrValueFromProperty(item, ValueProperty);
var value = GetItemOrValueFromProperty(item, ValueProperty);
if (!keys.Contains(value))
{
@@ -169,6 +201,13 @@ namespace Radzen
[Parameter]
public virtual bool AllowFiltering { get; set; }
/// <summary>
/// Gets or sets a value indicating whether filtering is allowed as you type. Set to <c>true</c> by default.
/// </summary>
/// <value><c>true</c> if filtering is allowed; otherwise, <c>false</c>.</value>
[Parameter]
public virtual bool FilterAsYouType { get; set; } = true;
/// <summary>
/// Gets or sets a value indicating whether the user can clear the value. Set to <c>false</c> by default.
/// </summary>
@@ -183,6 +222,13 @@ namespace Radzen
[Parameter]
public bool Multiple { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the user can select all values in multiple selection. Set to <c>true</c> by default.
/// </summary>
/// <value><c>true</c> if select all values is allowed; otherwise, <c>false</c>.</value>
[Parameter]
public bool AllowSelectAll { get; set; } = true;
/// <summary>
/// Gets or sets the template.
/// </summary>
@@ -197,6 +243,13 @@ namespace Radzen
[Parameter]
public string ValueProperty { get; set; }
/// <summary>
/// Gets or sets the disabled property.
/// </summary>
/// <value>The disabled property.</value>
[Parameter]
public string DisabledProperty { get; set; }
/// <summary>
/// Gets or sets the selected item changed.
/// </summary>
@@ -207,7 +260,7 @@ namespace Radzen
/// <summary>
/// The selected items
/// </summary>
protected List<object> selectedItems = new List<object>();
protected IList<object> selectedItems = new List<object>();
/// <summary>
/// The selected item
/// </summary>
@@ -223,10 +276,10 @@ namespace Radzen
return;
}
if (selectedItems.Count != View.Cast<object>().Count())
if (selectedItems.Count != View.Cast<object>().ToList().Where(i => disabledPropertyGetter != null ? disabledPropertyGetter(i) as bool? != true : true).Count())
{
selectedItems.Clear();
selectedItems = View.Cast<object>().ToList();
selectedItems = View.Cast<object>().ToList().Where(i => disabledPropertyGetter != null ? disabledPropertyGetter(i) as bool? != true : true).ToList();
}
else
{
@@ -236,7 +289,7 @@ namespace Radzen
if (!string.IsNullOrEmpty(ValueProperty))
{
System.Reflection.PropertyInfo pi = PropertyAccess.GetElementType(Data.GetType()).GetProperty(ValueProperty);
internalValue = selectedItems.Select(i => PropertyAccess.GetItemOrValueFromProperty(i, ValueProperty)).AsQueryable().Cast(pi.PropertyType);
internalValue = selectedItems.Select(i => GetItemOrValueFromProperty(i, ValueProperty)).AsQueryable().Cast(pi.PropertyType);
}
else
{
@@ -244,13 +297,47 @@ namespace Radzen
internalValue = selectedItems.AsQueryable().Cast(type);
}
await ValueChanged.InvokeAsync((T)internalValue);
if (typeof(IList).IsAssignableFrom(typeof(T)))
{
var list = (IList)Activator.CreateInstance(typeof(T));
foreach (var i in (IEnumerable)internalValue)
{
list.Add(i);
}
await ValueChanged.InvokeAsync((T)(object)list);
}
else if (typeof(T).IsGenericType && typeof(ICollection<>).MakeGenericType(typeof(T).GetGenericArguments()[0]).IsAssignableFrom(typeof(T)))
{
var list = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(typeof(T).GetGenericArguments()[0]));
foreach (var i in (IEnumerable)internalValue)
{
list.Add(i);
}
await ValueChanged.InvokeAsync((T)(object)list);
}
else
{
await ValueChanged.InvokeAsync((T)internalValue);
}
if (FieldIdentifier.FieldName != null) { EditContext?.NotifyFieldChanged(FieldIdentifier); }
await Change.InvokeAsync(internalValue);
StateHasChanged();
}
internal bool IsAllSelected()
{
if (LoadData.HasDelegate && !string.IsNullOrEmpty(ValueProperty))
{
return View != null && View.Cast<object>().ToList()
.Where(i => disabledPropertyGetter != null ? disabledPropertyGetter(i) as bool? != true : true)
.All(i => IsItemSelectedByValue(GetItemOrValueFromProperty(i, ValueProperty)));
}
return View != null && selectedItems.Count == View.Cast<object>().ToList()
.Where(i => disabledPropertyGetter != null ? disabledPropertyGetter(i) as bool? != true : true).Count();
}
/// <summary>
/// Resets this instance.
/// </summary>
@@ -269,6 +356,7 @@ namespace Radzen
return;
searchText = null;
await SearchTextChanged.InvokeAsync(searchText);
await JSRuntime.InvokeAsync<string>("Radzen.setInputValue", search, "");
internalValue = default(T);
@@ -316,13 +404,94 @@ namespace Radzen
selectedItems.Clear();
}
OnDataChanged();
StateHasChanged();
InvokeAsync(OnDataChanged);
}
}
}
/// <inheritdoc/>
protected override void OnParametersSet()
{
base.OnParametersSet();
if (_data != null)
{
var query = _data.AsQueryable();
var type = query.ElementType;
if (type == typeof(object) && typeof(EnumerableQuery).IsAssignableFrom(query.GetType()) && query.Any())
{
type = query.FirstOrDefault().GetType();
}
if (!string.IsNullOrEmpty(ValueProperty))
{
valuePropertyGetter = PropertyAccess.Getter<object, object>(ValueProperty, type);
}
if (!string.IsNullOrEmpty(TextProperty))
{
textPropertyGetter = PropertyAccess.Getter<object, object>(TextProperty, type);
}
if (!string.IsNullOrEmpty(DisabledProperty))
{
disabledPropertyGetter = PropertyAccess.Getter<object, object>(DisabledProperty, type);
}
}
}
internal Func<object, object> valuePropertyGetter;
internal Func<object, object> textPropertyGetter;
internal Func<object, object> disabledPropertyGetter;
/// <summary>
/// Gets the item or value from property.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="property">The property.</param>
/// <returns>System.Object.</returns>
public object GetItemOrValueFromProperty(object item, string property)
{
if (item != null)
{
if (property == TextProperty && textPropertyGetter != null)
{
return textPropertyGetter(item);
}
else if (property == ValueProperty && valuePropertyGetter != null)
{
return valuePropertyGetter(item);
}
else if (property == DisabledProperty && disabledPropertyGetter != null)
{
return disabledPropertyGetter(item);
}
var enumValue = item as Enum;
if (enumValue != null)
{
return Radzen.Blazor.EnumExtensions.GetDisplayDescription(enumValue);
}
}
return item;
}
#if NET5_0_OR_GREATER
/// <inheritdoc/>
protected override async Task OnDataChanged()
{
await base.OnDataChanged();
if (AllowVirtualization && Virtualize != null && !LoadData.HasDelegate)
{
await InvokeAsync(Virtualize.RefreshDataAsync);
}
}
#endif
/// <summary>
/// Gets the popup identifier.
/// </summary>
@@ -420,12 +589,33 @@ namespace Radzen
/// </summary>
/// <param name="args">The <see cref="Microsoft.AspNetCore.Components.Web.KeyboardEventArgs"/> instance containing the event data.</param>
/// <param name="isFilter">if set to <c>true</c> [is filter].</param>
private async System.Threading.Tasks.Task HandleKeyPress(Microsoft.AspNetCore.Components.Web.KeyboardEventArgs args, bool isFilter = false)
protected virtual async System.Threading.Tasks.Task HandleKeyPress(Microsoft.AspNetCore.Components.Web.KeyboardEventArgs args, bool isFilter = false)
{
if (Disabled)
return;
var items = (LoadData.HasDelegate ? Data != null ? Data : Enumerable.Empty<object>() : (View != null ? View : Enumerable.Empty<object>())).Cast<object>();
List<object> items = Enumerable.Empty<object>().ToList();
if (LoadData.HasDelegate)
{
if (Data != null)
{
items = Data.Cast<object>().ToList();
}
}
else
{
if (IsVirtualizationAllowed())
{
#if NET5_0_OR_GREATER
items = virtualItems;
#endif
}
else
{
items = View.Cast<object>().ToList();
}
}
var key = args.Code != null ? args.Code : args.Key;
@@ -433,11 +623,13 @@ namespace Radzen
{
try
{
var newSelectedIndex = await JSRuntime.InvokeAsync<int>("Radzen.focusListItem", search, list, key == "ArrowDown" || key == "ArrowRight", selectedIndex);
var currentViewIndex = Multiple ? selectedIndex : items.IndexOf(selectedItem);
var newSelectedIndex = await JSRuntime.InvokeAsync<int>("Radzen.focusListItem", search, list, key == "ArrowDown" || key == "ArrowRight", currentViewIndex);
if (!Multiple)
{
if (newSelectedIndex != selectedIndex && newSelectedIndex >= 0 && newSelectedIndex <= items.Count() - 1)
if (newSelectedIndex != currentViewIndex && newSelectedIndex >= 0 && newSelectedIndex <= items.Count() - 1)
{
selectedIndex = newSelectedIndex;
await OnSelectItem(items.ElementAt(selectedIndex), true);
@@ -445,7 +637,7 @@ namespace Radzen
}
else
{
selectedIndex = await JSRuntime.InvokeAsync<int>("Radzen.focusListItem", search, list, key == "ArrowDown", selectedIndex);
selectedIndex = await JSRuntime.InvokeAsync<int>("Radzen.focusListItem", search, list, key == "ArrowDown", currentViewIndex);
}
}
catch (Exception)
@@ -453,7 +645,7 @@ namespace Radzen
//
}
}
else if (Multiple && key == "Space")
else if (Multiple && key == "Enter")
{
if (selectedIndex >= 0 && selectedIndex <= items.Count() - 1)
{
@@ -469,7 +661,7 @@ namespace Radzen
{
await JSRuntime.InvokeVoidAsync("Radzen.closePopup", PopupID);
}
else if (key == "Delete")
else if (key == "Delete" && AllowClear)
{
if (!Multiple && selectedItem != null)
{
@@ -482,7 +674,7 @@ namespace Radzen
Debounce(DebounceFilter, FilterDelay);
}
}
else if(AllowFiltering && isFilter)
else if (AllowFiltering && isFilter && FilterAsYouType)
{
Debounce(DebounceFilter, FilterDelay);
}
@@ -504,17 +696,16 @@ namespace Radzen
{
if (!LoadData.HasDelegate)
{
searchText = await JSRuntime.InvokeAsync<string>("Radzen.getInputValue", search);
_view = null;
if (IsVirtualizationAllowed())
{
#if NET5
#if NET5_0_OR_GREATER
if (virtualize != null)
{
await virtualize.RefreshDataAsync();
}
await InvokeAsync(() => { StateHasChanged(); });
#endif
#endif
}
else
{
@@ -525,28 +716,32 @@ namespace Radzen
{
if (IsVirtualizationAllowed())
{
#if NET5
#if NET5_0_OR_GREATER
if (virtualize != null)
{
await InvokeAsync(virtualize.RefreshDataAsync);
}
await InvokeAsync(() => { StateHasChanged(); });
#endif
#endif
}
else
{
await LoadData.InvokeAsync(await GetLoadDataArgs());
}
}
}
if (Multiple)
selectedIndex = -1;
await JSRuntime.InvokeAsync<string>("Radzen.repositionPopup", Element, PopupID);
await SearchTextChanged.InvokeAsync(SearchText);
}
/// <summary>
/// Handles the <see cref="E:KeyPress" /> event.
/// </summary>
/// <param name="args">The <see cref="Microsoft.AspNetCore.Components.Web.KeyboardEventArgs"/> instance containing the event data.</param>
protected async System.Threading.Tasks.Task OnKeyPress(Microsoft.AspNetCore.Components.Web.KeyboardEventArgs args)
protected virtual async System.Threading.Tasks.Task OnKeyPress(Microsoft.AspNetCore.Components.Web.KeyboardEventArgs args)
{
await HandleKeyPress(args);
}
@@ -576,17 +771,17 @@ namespace Radzen
/// <returns>LoadDataArgs.</returns>
internal virtual async System.Threading.Tasks.Task<LoadDataArgs> GetLoadDataArgs()
{
#if NET5
#if NET5_0_OR_GREATER
if (AllowVirtualization)
{
return new Radzen.LoadDataArgs() { Skip = 0, Top = PageSize, Filter = await JSRuntime.InvokeAsync<string>("Radzen.getInputValue", search) };
return await Task.FromResult(new Radzen.LoadDataArgs() { Skip = 0, Top = PageSize, Filter = searchText });
}
else
{
return new Radzen.LoadDataArgs() { Filter = await JSRuntime.InvokeAsync<string>("Radzen.getInputValue", search) };
return await Task.FromResult(new Radzen.LoadDataArgs() { Filter = searchText });
}
#else
return new Radzen.LoadDataArgs() { Filter = await JSRuntime.InvokeAsync<string>("Radzen.getInputValue", search) };
return await Task.FromResult(new Radzen.LoadDataArgs() { Filter = searchText });
#endif
}
@@ -622,7 +817,7 @@ namespace Radzen
/// <returns>A Task representing the asynchronous operation.</returns>
public override async Task SetParametersAsync(ParameterView parameters)
{
#if NET5
#if NET5_0_OR_GREATER
var pageSize = parameters.GetValueOrDefault<int>(nameof(PageSize));
if(pageSize != default(int))
{
@@ -666,7 +861,7 @@ namespace Radzen
if (valueAsEnumerable != null)
{
if (valueAsEnumerable.OfType<object>().Count() != selectedItems.Count)
if (!valueAsEnumerable.Cast<object>().SequenceEqual(selectedItems.Select(i => GetItemOrValueFromProperty(i, ValueProperty))))
{
selectedItems.Clear();
}
@@ -691,15 +886,22 @@ namespace Radzen
/// </summary>
/// <param name="item">The item.</param>
/// <returns><c>true</c> if the specified item is selected; otherwise, <c>false</c>.</returns>
internal bool isSelected(object item)
internal bool IsSelected(object item)
{
if (Multiple)
if (!string.IsNullOrEmpty(ValueProperty))
{
return selectedItems.IndexOf(item) != -1;
return IsItemSelectedByValue(GetItemOrValueFromProperty(item, ValueProperty));
}
else
{
return item == selectedItem;
if (Multiple)
{
return selectedItems.IndexOf(item) != -1;
}
else
{
return object.Equals(item, selectedItem);
}
}
}
@@ -723,6 +925,13 @@ namespace Radzen
}
}
/// <summary>
/// Gets or sets the item separator for Multiple dropdown.
/// </summary>
/// <value>Item separator</value>
[Parameter]
public string Separator { get; set; } = ",";
/// <summary>
/// Gets the items.
/// </summary>
@@ -768,7 +977,35 @@ namespace Radzen
query.Add($"{Enum.GetName(typeof(StringFilterOperator), FilterOperator)}(@0)");
_view = Query.Where(String.Join(".", query), ignoreCase ? searchText.ToLower() : searchText);
var search = ignoreCase ? searchText.ToLower() : searchText;
if (Query.ElementType == typeof(Enum))
{
_view = Query.Cast<Enum>()
.Where((Func<Enum, bool>)(i =>
{
var value = ignoreCase ? i.GetDisplayDescription().ToLower() : i.GetDisplayDescription();
if (FilterOperator == StringFilterOperator.Contains)
{
return value.Contains(search);
}
else if (FilterOperator == StringFilterOperator.StartsWith)
{
return value.StartsWith(search);
}
else if (FilterOperator == StringFilterOperator.EndsWith)
{
return value.EndsWith(search);
}
return value == search;
})).AsQueryable();
}
else
{
_view = Query.Where(String.Join(".", query), search);
}
}
else
{
@@ -828,6 +1065,11 @@ namespace Radzen
/// <param name="raiseChange">if set to <c>true</c> [raise change].</param>
public async System.Threading.Tasks.Task SelectItem(object item, bool raiseChange = true)
{
if (disabledPropertyGetter != null && disabledPropertyGetter(item) as bool? == true)
{
return;
}
if (!Multiple)
{
if (object.Equals(item, selectedItem))
@@ -849,24 +1091,23 @@ namespace Radzen
}
else
{
if (selectedItems.IndexOf(item) == -1)
{
selectedItems.Add(item);
}
else
{
selectedItems.Remove(item);
}
UpdateSelectedItems(item);
if (!string.IsNullOrEmpty(ValueProperty))
{
System.Reflection.PropertyInfo pi = PropertyAccess.GetElementType(Data.GetType()).GetProperty(ValueProperty);
internalValue = selectedItems.Select(i => PropertyAccess.GetItemOrValueFromProperty(i, ValueProperty)).AsQueryable().Cast(pi.PropertyType);
internalValue = selectedItems.Select(i => GetItemOrValueFromProperty(i, ValueProperty)).AsQueryable().Cast(pi.PropertyType);
}
else
{
var firstElement = Data.Cast<object>().FirstOrDefault();
var elementType = firstElement != null ? firstElement.GetType() : null;
var query = Data.AsQueryable();
var elementType = query.ElementType;
if (elementType == typeof(object) && typeof(EnumerableQuery).IsAssignableFrom(query.GetType()) && query.Any())
{
elementType = query.FirstOrDefault().GetType();
}
if (elementType != null)
{
internalValue = selectedItems.AsQueryable().Cast(elementType);
@@ -879,32 +1120,107 @@ namespace Radzen
}
if (raiseChange)
{
await ValueChanged.InvokeAsync(object.Equals(internalValue, null) ? default(T) : (T)internalValue);
if (ValueChanged.HasDelegate)
{
if (typeof(IList).IsAssignableFrom(typeof(T)))
{
if (object.Equals(internalValue, null))
{
await ValueChanged.InvokeAsync(default(T));
}
else
{
var list = (IList)Activator.CreateInstance(typeof(T));
foreach (var i in (IEnumerable)internalValue)
{
list.Add(i);
}
await ValueChanged.InvokeAsync((T)(object)list);
}
}
else if (typeof(T).IsGenericType && typeof(ICollection<>).MakeGenericType(typeof(T).GetGenericArguments()[0]).IsAssignableFrom(typeof(T)))
{
if (object.Equals(internalValue, null))
{
await ValueChanged.InvokeAsync(default(T));
}
else
{
var list = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(typeof(T).GetGenericArguments()[0]));
foreach (var i in (IEnumerable)internalValue)
{
list.Add(i);
}
await ValueChanged.InvokeAsync((T)(object)list);
}
}
else
{
await ValueChanged.InvokeAsync(object.Equals(internalValue, null) ? default(T) : (T)internalValue);
}
}
if (FieldIdentifier.FieldName != null) { EditContext?.NotifyFieldChanged(FieldIdentifier); }
await Change.InvokeAsync(internalValue);
}
StateHasChanged();
}
/// <inheritdoc />
public override object GetValue()
{
return internalValue;
}
internal void UpdateSelectedItems(object item)
{
if (!string.IsNullOrEmpty(ValueProperty))
{
var value = GetItemOrValueFromProperty(item, ValueProperty);
if (!IsItemSelectedByValue(value))
{
selectedItems.Add(item);
}
else
{
selectedItems = selectedItems.AsQueryable().Where($@"!object.Equals(it.{ValueProperty},@0)", value).ToList();
}
}
else
{
if (!selectedItems.Any(i => object.Equals(i, item)))
{
selectedItems.Add(item);
}
else
{
selectedItems = selectedItems.Where(i => !object.Equals(i, item)).ToList();
}
}
}
/// <summary>
/// Selects the item from value.
/// </summary>
/// <param name="value">The value.</param>
protected virtual void SelectItemFromValue(object value)
{
if (value != null && View != null)
var view = LoadData.HasDelegate ? Data : View;
if (value != null && view != null)
{
if (!Multiple)
{
if (!string.IsNullOrEmpty(ValueProperty))
{
if (typeof(EnumerableQuery).IsAssignableFrom(View.GetType()))
if (typeof(EnumerableQuery).IsAssignableFrom(view.GetType()))
{
SelectedItem = View.OfType<object>().Where(i => object.Equals(PropertyAccess.GetValue(i, ValueProperty), value)).FirstOrDefault();
SelectedItem = view.OfType<object>().Where(i => object.Equals(GetItemOrValueFromProperty(i, ValueProperty), value)).FirstOrDefault();
}
else
{
SelectedItem = View.AsQueryable().Where($@"{ValueProperty} == @0", value).FirstOrDefault();
SelectedItem = view.AsQueryable().Where($@"{ValueProperty} == @0", value).FirstOrDefault();
}
}
else
@@ -918,25 +1234,25 @@ namespace Radzen
}
else
{
var values = value as dynamic;
var values = value as IEnumerable;
if (values != null)
{
if (!string.IsNullOrEmpty(ValueProperty))
{
foreach (object v in values)
foreach (object v in values.ToDynamicList())
{
dynamic item;
if (typeof(EnumerableQuery).IsAssignableFrom(View.GetType()))
if (typeof(EnumerableQuery).IsAssignableFrom(view.GetType()))
{
item = View.OfType<object>().Where(i => object.Equals(PropertyAccess.GetValue(i, ValueProperty), v)).FirstOrDefault();
item = view.OfType<object>().Where(i => object.Equals(GetItemOrValueFromProperty(i, ValueProperty), v)).FirstOrDefault();
}
else
{
item = View.AsQueryable().Where($@"{ValueProperty} == @0", v).FirstOrDefault();
item = view.AsQueryable().Where($@"{ValueProperty} == @0", v).FirstOrDefault();
}
if (!object.Equals(item, null) && selectedItems.IndexOf(item) == -1)
if (!object.Equals(item, null) && !selectedItems.AsQueryable().Where($@"object.Equals(it.{ValueProperty},@0)", v).Any())
{
selectedItems.Add(item);
}
@@ -956,6 +1272,21 @@ namespace Radzen
}
}
internal bool IsItemSelectedByValue(object v)
{
switch (internalValue)
{
case string s:
return object.Equals(s, v);
case IEnumerable enumerable:
return enumerable.Cast<object>().Contains(v);
case null:
return false;
default:
return object.Equals(internalValue, v);
}
}
/// <inheritdoc />
public override void Dispose()
{

View File

@@ -0,0 +1,69 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text.RegularExpressions;
using System.Xml.Linq;
namespace Radzen.Blazor
{
/// <summary>
/// Class EnumExtensions.
/// </summary>
public static class EnumExtensions
{
/// <summary>
/// Gets enum description.
/// </summary>
public static string GetDisplayDescription(this Enum enumValue)
{
var enumValueAsString = enumValue.ToString();
var val = enumValue.GetType().GetMember(enumValueAsString).FirstOrDefault();
return val?.GetCustomAttribute<DisplayAttribute>()?.GetDescription() ?? enumValueAsString;
}
/// <summary>
/// Converts Enum to IEnumerable of Value/Text.
/// </summary>
public static IEnumerable<object> EnumAsKeyValuePair(Type enumType)
{
return Enum.GetValues(enumType).Cast<Enum>().Distinct().Select(val => new { Value = Convert.ToInt32(val), Text = val.GetDisplayDescription() });
}
/// <summary>
/// Converts the autocomplete type enum value to the expected
/// autocomplete attribute value.
/// </summary>
/// <returns>The autocomplete attribute string value.</returns>
public static string GetAutoCompleteValue(this AutoCompleteType typeValue)
{
// Handle synonyms.
switch (typeValue)
{
case AutoCompleteType.FirstName:
return "given-name";
case AutoCompleteType.LastName:
return "family-name";
case AutoCompleteType.MiddleName:
return "additional-name";
case AutoCompleteType.ZipCode:
return "postal-code";
case AutoCompleteType.Province:
return "address-level1";
case AutoCompleteType.State:
return "address-level1";
}
// Handle standard values.
var value = typeValue.ToString();
value = Regex.Replace(value, "([^A-Z])([A-Z])", "$1-$2");
return Regex.Replace(value, "([A-Z]+)([A-Z][^A-Z$])", "$1-$2")
.Trim().ToLower();
}
}
}

View File

@@ -5,6 +5,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Web;
using Radzen.Blazor;
using Radzen.Blazor.Rendering;
namespace Radzen
@@ -72,11 +73,8 @@ namespace Radzen
}
set
{
if (_form != value && value != null)
{
_form = value;
_form.AddComponent(this);
}
_form = value;
_form?.AddComponent(this);
}
}
@@ -165,6 +163,8 @@ namespace Radzen
/// <returns>Task.</returns>
public override Task SetParametersAsync(ParameterView parameters)
{
var disabledChanged = parameters.DidParameterChange(nameof(Disabled), Disabled);
var result = base.SetParametersAsync(parameters);
if (EditContext != null && ValueExpression != null && FieldIdentifier.Model != EditContext.Model)
@@ -174,6 +174,11 @@ namespace Radzen
EditContext.OnValidationStateChanged += ValidationStateChanged;
}
if (disabledChanged)
{
FormFieldContext?.DisabledChanged(Disabled);
}
return result;
}
@@ -233,6 +238,21 @@ namespace Radzen
/// <returns>ClassList.</returns>
protected ClassList GetClassList(string className) => ClassList.Create(className)
.AddDisabled(Disabled)
.Add(FieldIdentifier, EditContext);
.Add(FieldIdentifier, EditContext)
.Add("rz-state-empty", !HasValue);
/// <summary> Provides support for RadzenFormField integration. </summary>
[CascadingParameter]
public IFormFieldContext FormFieldContext { get; set; }
/// <summary> Gets the current placeholder. Returns empty string if this component is inside a RadzenFormField.</summary>
protected string CurrentPlaceholder => FormFieldContext != null ? " " : Placeholder;
#if NET5_0_OR_GREATER
/// <inheritdoc/>
public virtual async ValueTask FocusAsync()
{
await Element.FocusAsync();
}
#endif
}
}

View File

@@ -1,5 +1,9 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Radzen.Blazor.Rendering;
namespace Radzen.Blazor
{
@@ -40,13 +44,21 @@ namespace Radzen.Blazor
/// <returns>RenderFragment.</returns>
RenderFragment Render(ScaleBase categoryScale, ScaleBase valueScale);
/// <summary>
/// Renders the series overlays with the specified category and value scales.
/// </summary>
/// <param name="categoryScale">The category scale.</param>
/// <param name="valueScale">The value scale.</param>
/// <returns>RenderFragment.</returns>
RenderFragment RenderOverlays(ScaleBase categoryScale, ScaleBase valueScale);
/// <summary>
/// Renders the series tooltip.
/// </summary>
/// <param name="data">The data.</param>
/// <param name="marginLeft">The left margin.</param>
/// <param name="marginTop">The right margin.</param>
/// <param name="chartHeight">Height of the whole char area.</param>
/// <returns>RenderFragment.</returns>
RenderFragment RenderTooltip(object data, double marginLeft, double marginTop);
RenderFragment RenderTooltip(object data, double marginLeft, double marginTop, double chartHeight);
/// <summary>
/// Renders the legend item.
/// </summary>
@@ -85,7 +97,35 @@ namespace Radzen.Blazor
/// </summary>
/// <param name="x">The x.</param>
/// <param name="y">The y.</param>
object DataAt(double x, double y);
(object, Point) DataAt(double x, double y);
/// <summary>
/// Returns data chart position
/// </summary>
IEnumerable<ChartDataLabel> GetDataLabels(double offsetX, double offsetY);
/// <summary>
/// Returns series median
/// </summary>
double GetMedian();
/// <summary>
/// Returns series mean
/// </summary>
double GetMean();
/// <summary>
/// Returns series mode
/// </summary>
double GetMode();
/// <summary>
/// Returns series trend
/// </summary>
(double a, double b) GetTrend();
/// <summary>
/// Series coordinate system
/// </summary>
CoordinateSystem CoordinateSystem { get; }
/// <summary>
/// Series overlays
/// </summary>
IList<IChartSeriesOverlay> Overlays{ get; }
/// <summary>
/// Gets or sets the title of the series. The title is displayed in tooltips and the legend.
/// </summary>

View File

@@ -0,0 +1,33 @@
using Microsoft.AspNetCore.Components;
namespace Radzen.Blazor
{
/// <summary>
/// Interface for chart overlays
/// </summary>
public interface IChartSeriesOverlay
{
/// <summary>
/// Render overlay
/// </summary>
/// <param name="categoryScale"></param>
/// <param name="valueScale"></param>
/// <returns>RenderFragment</returns>
RenderFragment Render(ScaleBase categoryScale, ScaleBase valueScale);
/// <summary>
/// Gets overlay visibility state
/// </summary>
bool Visible { get; }
/// <summary>
/// Hit test
/// </summary>
bool Contains(double mouseX, double mouseY, int tolerance);
/// <summary>
/// Renders tooltip
/// </summary>
RenderFragment RenderTooltip(double mouseX, double mouseY, double marginLeft, double marginTop);
}
}

View File

@@ -0,0 +1,20 @@
using System.Collections.Generic;
namespace Radzen.Blazor
{
/// <summary>
/// Marker interface for <see cref="RadzenStackedBarSeries{TItem}" />.
/// </summary>
public interface IChartStackedBarSeries : IChartBarSeries
{
/// <summary>
/// Gets the value at the specified index.
/// </summary>
double ValueAt(int index);
/// <summary>
/// Gets the values for category.
/// </summary>
IEnumerable<double> ValuesForCategory(double category);
}
}

View File

@@ -0,0 +1,26 @@
using System.Collections.Generic;
namespace Radzen.Blazor
{
/// <summary>
/// Marker interface for <see cref="RadzenStackedColumnSeries{TItem}" />.
/// </summary>
public interface IChartStackedColumnSeries
{
/// <summary>
/// Gets the count.
/// </summary>
/// <value>The count.</value>
int Count { get; }
/// <summary>
/// Gets the values for category.
/// </summary>
IEnumerable<double> ValuesForCategory(double category);
/// <summary>
/// Gets the value at the specified index.
/// </summary>
double ValueAt(int index);
}
}

View File

@@ -59,6 +59,20 @@ namespace Radzen.Blazor
/// <param name="end">The end.</param>
Task SelectSlot(DateTime start, DateTime end);
/// <summary>
/// Selects the specified slot.
/// </summary>
/// <param name="start">The start.</param>
/// <param name="end">The end.</param>
/// <param name="appointments">The appointments for this range.</param>
Task<bool> SelectSlot(DateTime start, DateTime end, IEnumerable<AppointmentData> appointments);
/// <summary>
/// Selects the specified more link.
/// </summary>
/// <param name="start">The start.</param>
/// <param name="end">The end.</param>
/// <param name="appointments">The appointments for this range.</param>
Task<bool> SelectMore(DateTime start, DateTime end, IEnumerable<AppointmentData> appointments);
/// <summary>
/// Gets the appointment HTML attributes.
/// </summary>
/// <param name="item">The appointment.</param>

View File

@@ -0,0 +1,22 @@
namespace Radzen.Blazor
{
/// <summary>
/// Specifies the interpolation mode of lines between data points. Used by <see cref="RadzenAreaSeries{TItem}"/> and <see cref="RadzenLineSeries{TItem}"/>.
/// </summary>
public enum Interpolation
{
/// <summary>
/// Points are connected by a straight line.
/// </summary>
Line,
/// <summary>
/// Points are connected by a smooth curve.
/// </summary>
Spline,
/// <summary>
/// Points are connected by horizontal and vertical lines only.
/// </summary>
Step
}
}

View File

@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2018-2022 Radzen Ltd
Copyright (c) 2018-2023 Radzen Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -65,7 +65,13 @@ namespace Radzen.Blazor
if (start == end)
{
start = 0;
end = end + NiceNumber(end / ticks, false);
end += NiceNumber(end / ticks, false);
}
if (Round && end < 0)
{
end = 0;
start += NiceNumber(start / ticks, false);
}
var range = end - start;

View File

@@ -1,4 +1,6 @@
using System;
using Microsoft.AspNetCore.Components;
using Radzen.Blazor;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
@@ -35,7 +37,11 @@ namespace Radzen
Severity = message.Severity,
Summary = message.Summary,
Detail = message.Detail,
Style = message.Style
Style = message.Style,
Click = message.Click,
Close = message.Close,
CloseOnClick = message.CloseOnClick,
Payload = message.Payload
};
if (!Messages.Contains(newMessage))
@@ -51,14 +57,22 @@ namespace Radzen
/// <param name="summary">The summary.</param>
/// <param name="detail">The detail.</param>
/// <param name="duration">The duration.</param>
public void Notify(NotificationSeverity severity = NotificationSeverity.Info, string summary = "", string detail = "", double duration = 3000)
/// <param name="click">The click event.</param>
/// <param name="closeOnClick">If true, then the notification will be closed when clicked on.</param>
/// <param name="payload">Used to store a custom payload that can be retreived later in the click event handler.</param>
/// <param name="close">Action to be executed on close.</param>
public void Notify(NotificationSeverity severity = NotificationSeverity.Info, string summary = "", string detail = "", double duration = 3000, Action<NotificationMessage> click = null, bool closeOnClick = false, object payload = null, Action<NotificationMessage> close = null)
{
var newMessage = new NotificationMessage()
{
Duration = duration,
Severity = severity,
Summary = summary,
Detail = detail
Detail = detail,
Click = click,
Close = close,
CloseOnClick = closeOnClick,
Payload = payload
};
if (!Messages.Contains(newMessage))
@@ -98,5 +112,24 @@ namespace Radzen
/// </summary>
/// <value>The style.</value>
public string Style { get; set; }
}
/// <summary>
/// Gets or sets the click event.
/// </summary>
/// <value>This event handler is called when the notification is clicked on.</value>
public Action<NotificationMessage> Click { get; set; }
/// <summary>
/// Get or set the event for when the notification is closed
/// </summary>
public Action<NotificationMessage> Close { get; set; }
/// <summary>
/// Gets or sets click on close action.
/// </summary>
/// <value>If true, then the notification will be closed when clicked on.</value>
public bool CloseOnClick { get; set; }
/// <summary>
/// Gets or sets notification payload.
/// </summary>
/// <value>Used to store a custom payload that can be retreived later in the click event handler.</value>
public object Payload { get; set; }
}
}

View File

@@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Web;
using System.Globalization;
namespace Radzen
{
@@ -211,7 +212,7 @@ namespace Radzen
/// <param name="options">The options.</param>
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"));
writer.WriteStringValue(value.ToString("yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture));
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
@@ -35,6 +36,12 @@ namespace Radzen
[Parameter]
public HorizontalAlign PagerHorizontalAlign { get; set; } = HorizontalAlign.Justify;
/// <summary>
/// Gets or sets a value indicating pager density.
/// </summary>
[Parameter]
public Density Density { get; set; } = Density.Default;
/// <summary>
/// Gets or sets a value indicating whether paging is allowed. Set to <c>false</c> by default.
/// </summary>
@@ -56,10 +63,24 @@ namespace Radzen
}
set
{
_PageSize = value;
if (_PageSize != value)
{
_PageSize = value;
InvokeAsync(() => OnPageSizeChanged(value));
}
}
}
internal int GetPageSize()
{
return _PageSize;
}
internal void SetPageSize(int value)
{
_PageSize = value;
}
/// <summary>
/// Gets or sets the page numbers count.
/// </summary>
@@ -86,6 +107,13 @@ namespace Radzen
[Parameter]
public RenderFragment<T> Template { get; set; }
/// <summary>
/// Gets or sets the loading template.
/// </summary>
/// <value>The loading template.</value>
[Parameter]
public RenderFragment LoadingTemplate { get; set; }
/// <summary>
/// The data
/// </summary>
@@ -107,12 +135,37 @@ namespace Radzen
if (_data != value)
{
_data = value;
if (_data != null && _data is INotifyCollectionChanged)
{
((INotifyCollectionChanged)_data).CollectionChanged += OnCollectionChanged;
}
OnDataChanged();
StateHasChanged();
}
}
}
/// <summary>
/// Called when INotifyCollectionChanged CollectionChanged is raised.
/// </summary>
protected virtual void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
{
}
/// <inheritdoc />
public override void Dispose()
{
base.Dispose();
if (_data != null && _data is INotifyCollectionChanged)
{
((INotifyCollectionChanged)_data).CollectionChanged -= OnCollectionChanged;
}
}
/// <summary>
/// Gets or sets the page size options.
/// </summary>
@@ -142,9 +195,66 @@ namespace Radzen
public string PagingSummaryFormat { get; set; } = "Page {0} of {1} ({2} items)";
/// <summary>
/// The view
/// Gets or sets the pager's first page button's title attribute.
/// </summary>
protected IQueryable<T> _view = null;
[Parameter]
public string FirstPageTitle { get; set; } = "First page.";
/// <summary>
/// Gets or sets the pager's first page button's aria-label attribute.
/// </summary>
[Parameter]
public string FirstPageAriaLabel { get; set; } = "Go to first page.";
/// <summary>
/// Gets or sets the pager's previous page button's title attribute.
/// </summary>
[Parameter]
public string PrevPageTitle { get; set; } = "Previous page";
/// <summary>
/// Gets or sets the pager's previous page button's aria-label attribute.
/// </summary>
[Parameter]
public string PrevPageAriaLabel { get; set; } = "Go to previous page.";
/// <summary>
/// Gets or sets the pager's last page button's title attribute.
/// </summary>
[Parameter]
public string LastPageTitle { get; set; } = "Last page";
/// <summary>
/// Gets or sets the pager's last page button's aria-label attribute.
/// </summary>
[Parameter]
public string LastPageAriaLabel { get; set; } = "Go to last page.";
/// <summary>
/// Gets or sets the pager's next page button's title attribute.
/// </summary>
[Parameter]
public string NextPageTitle { get; set; } = "Next page";
/// <summary>
/// Gets or sets the pager's next page button's aria-label attribute.
/// </summary>
[Parameter]
public string NextPageAriaLabel { get; set; } = "Go to next page.";
/// <summary>
/// Gets or sets the pager's numeric page number buttons' title attributes.
/// </summary>
[Parameter]
public string PageTitleFormat { get; set; } = "Page {0}";
/// <summary>
/// Gets or sets the pager's numeric page number buttons' aria-label attributes.
/// </summary>
[Parameter]
public string PageAriaLabelFormat { get; set; } = "Go to page {0}.";
internal IQueryable<T> _view = null;
/// <summary>
/// Gets the paged view.
/// </summary>
@@ -259,7 +369,10 @@ namespace Radzen
{
this.firstRender = firstRender;
await ReloadOnFirstRender();
if (firstRender)
{
await ReloadOnFirstRender();
}
await base.OnAfterRenderAsync(firstRender);
}
@@ -308,16 +421,19 @@ namespace Radzen
await InvokeAsync(Reload);
}
int? pageSize;
internal int? pageSize;
/// <summary>
/// Called when [page size changed].
/// </summary>
/// <param name="value">The value.</param>
protected async Task OnPageSizeChanged(int value)
protected virtual async Task OnPageSizeChanged(int value)
{
pageSize = value;
await InvokeAsync(Reload);
if (pageSize != value && !this.firstRender)
{
pageSize = value;
await InvokeAsync(Reload);
}
}
/// <summary>
@@ -342,16 +458,17 @@ namespace Radzen
/// Goes to page.
/// </summary>
/// <param name="page">The page.</param>
public async Task GoToPage(int page)
/// <param name="forceReload">if set to <c>true</c> [force reload].</param>
public async Task GoToPage(int page, bool forceReload = false)
{
if (topPager != null)
{
await topPager.GoToPage(page);
await topPager.GoToPage(page, forceReload);
}
if (bottomPager != null)
{
await bottomPager.GoToPage(page);
await bottomPager.GoToPage(page, forceReload);
}
}
@@ -361,14 +478,21 @@ namespace Radzen
/// <param name="forceReload">if set to <c>true</c> [force reload].</param>
public async Task FirstPage(bool forceReload = false)
{
var shouldReload = forceReload && CurrentPage == 0;
if (topPager != null)
{
await topPager.FirstPage(forceReload);
await topPager.FirstPage();
}
if (bottomPager != null)
{
await bottomPager.FirstPage(forceReload);
await bottomPager.FirstPage();
}
if (shouldReload)
{
await InvokeAsync(Reload);
}
}

View File

@@ -2,6 +2,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Linq.Dynamic.Core;
@@ -44,8 +45,13 @@ namespace Radzen
{FilterOperator.EndsWith, "EndsWith"},
{FilterOperator.Contains, "Contains"},
{FilterOperator.DoesNotContain, "DoesNotContain"},
{FilterOperator.In, "In"},
{FilterOperator.NotIn, "NotIn"},
{FilterOperator.IsNull, "=="},
{FilterOperator.IsNotNull, "!="}
{FilterOperator.IsEmpty, "=="},
{FilterOperator.IsNotNull, "!="},
{FilterOperator.IsNotEmpty, "!="},
{FilterOperator.Custom, ""}
};
/// <summary>
@@ -64,7 +70,12 @@ namespace Radzen
{FilterOperator.Contains, "contains"},
{FilterOperator.DoesNotContain, "DoesNotContain"},
{FilterOperator.IsNull, "eq"},
{FilterOperator.IsNotNull, "ne"}
{FilterOperator.IsEmpty, "eq"},
{FilterOperator.IsNotNull, "ne"},
{FilterOperator.IsNotEmpty, "ne"},
{FilterOperator.In, "in"},
{FilterOperator.NotIn, "in"},
{FilterOperator.Custom, ""}
};
/// <summary>
@@ -140,8 +151,10 @@ namespace Radzen
public static string ToFilterString<T>(this IEnumerable<RadzenDataGridColumn<T>> columns)
{
Func<RadzenDataGridColumn<T>, bool> canFilter = (c) => c.Filterable && c.FilterPropertyType != null &&
(!(c.GetFilterValue() == null || c.GetFilterValue() as string == string.Empty) || c.GetFilterOperator() == FilterOperator.IsNotNull || c.GetFilterOperator() == FilterOperator.IsNull)
&& c.GetFilterProperty() != null;
(!(c.GetFilterValue() == null || c.GetFilterValue() as string == string.Empty) || c.GetFilterOperator() == FilterOperator.IsNotNull
|| c.GetFilterOperator() == FilterOperator.IsNull || c.GetFilterOperator() == FilterOperator.IsEmpty
|| c.GetFilterOperator() == FilterOperator.IsNotEmpty)
&& c.GetFilterProperty() != null;
if (columns.Where(canFilter).Any())
{
@@ -161,11 +174,11 @@ namespace Radzen
{
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") : "";
value = v is DateTime ? ((DateTime)v).ToString("yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture) : v is DateTimeOffset ? ((DateTimeOffset)v).UtcDateTime.ToString("yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture) : "";
}
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") : "";
secondValue = sv is DateTime ? ((DateTime)sv).ToString("yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture) : sv is DateTimeOffset ? ((DateTimeOffset)sv).UtcDateTime.ToString("yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture) : "";
}
}
else if (PropertyAccess.IsEnum(column.FilterPropertyType) || PropertyAccess.IsNullableEnum(column.FilterPropertyType))
@@ -179,12 +192,12 @@ namespace Radzen
secondValue = ((int)sv).ToString();
}
}
else if (typeof(IEnumerable).IsAssignableFrom(column.FilterPropertyType) && column.FilterPropertyType != typeof(string))
else if (IsEnumerable(column.FilterPropertyType) && column.FilterPropertyType != typeof(string))
{
var enumerableValue = ((IEnumerable)(v != null ? v : Enumerable.Empty<object>())).AsQueryable();
var enumerableSecondValue = ((IEnumerable)(sv != null ? sv : Enumerable.Empty<object>())).AsQueryable();
var enumerableValueAsString = "new []{" + String.Join(",",
var enumerableValueAsString = "new []{" + String.Join(",",
(enumerableValue.ElementType == typeof(string) ? enumerableValue.Cast<string>().Select(i => $@"""{i}""").Cast<object>() : enumerableValue.Cast<object>())) + "}";
var enumerableSecondValueAsString = "new []{" + String.Join(",",
@@ -228,11 +241,14 @@ namespace Radzen
}
else
{
value = (string)Convert.ChangeType(column.GetFilterValue(), typeof(string));
secondValue = (string)Convert.ChangeType(column.GetSecondFilterValue(), typeof(string));
value = (string)Convert.ChangeType(column.GetFilterValue(), typeof(string), CultureInfo.InvariantCulture);
secondValue = (string)Convert.ChangeType(column.GetSecondFilterValue(), typeof(string), CultureInfo.InvariantCulture);
}
if (!string.IsNullOrEmpty(value) || column.GetFilterOperator() == FilterOperator.IsNotNull || column.GetFilterOperator() == FilterOperator.IsNull)
if (!string.IsNullOrEmpty(value) || column.GetFilterOperator() == FilterOperator.IsNotNull
|| column.GetFilterOperator() == FilterOperator.IsNull
|| column.GetFilterOperator() == FilterOperator.IsEmpty
|| column.GetFilterOperator() == FilterOperator.IsNotEmpty)
{
var linqOperator = LinqFilterOperators[column.GetFilterOperator()];
if (linqOperator == null)
@@ -288,8 +304,9 @@ namespace Radzen
linqOperator = "==";
}
var value = !second ? (string)Convert.ChangeType(column.FilterValue, typeof(string)) :
var value = !second ? (string)Convert.ChangeType(column.FilterValue, typeof(string)) :
(string)Convert.ChangeType(column.SecondFilterValue, typeof(string));
value = value?.Replace("\"", "\\\"");
var columnType = column.Type;
var columnFormat = column.Format;
@@ -300,11 +317,11 @@ namespace Radzen
if (columnFormat == "date-time" || columnFormat == "date")
{
var dateTimeValue = DateTime.Parse(value, null, System.Globalization.DateTimeStyles.RoundtripKind);
var dateTimeValue = DateTime.Parse(value, CultureInfo.InvariantCulture, 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 dateFormat = dateTimeValue.TimeOfDay == TimeSpan.Zero ? "yyyy-MM-dd" : "yyyy-MM-ddTHH:mm:ss.fffZ";
return $@"{property} {linqOperator} DateTime(""{finalDate.ToString(dateFormat)}"")";
return $@"{property} {linqOperator} DateTime(""{finalDate.ToString(dateFormat, CultureInfo.InvariantCulture)}"")";
}
else if (columnFormat == "time")
{
@@ -370,6 +387,11 @@ namespace Radzen
var columnFilterOperator = !second ? column.GetFilterOperator() : column.GetSecondFilterOperator();
if (columnFilterOperator == FilterOperator.Custom)
{
return "";
}
var linqOperator = LinqFilterOperators[columnFilterOperator];
if (linqOperator == null)
{
@@ -379,7 +401,8 @@ namespace Radzen
if (column.FilterPropertyType == typeof(string))
{
string filterCaseSensitivityOperator = column.Grid.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ? ".ToLower()" : "";
value = value?.Replace("\"", "\\\"");
if (!string.IsNullOrEmpty(value) && columnFilterOperator == FilterOperator.Contains)
{
return $@"({property} == null ? """" : {property}){filterCaseSensitivityOperator}.Contains(""{value}""{filterCaseSensitivityOperator})";
@@ -408,6 +431,14 @@ namespace Radzen
{
return $@"np({property}) == null";
}
else if (columnFilterOperator == FilterOperator.IsEmpty)
{
return $@"np({property}) == """"";
}
else if (columnFilterOperator == FilterOperator.IsNotEmpty)
{
return $@"np({property}) != """"";
}
else if (columnFilterOperator == FilterOperator.IsNotNull)
{
return $@"np({property}) != null";
@@ -415,32 +446,40 @@ namespace Radzen
}
else if (PropertyAccess.IsNumeric(column.FilterPropertyType))
{
if (column.GetFilterOperator() == FilterOperator.IsNull || column.GetFilterOperator() == FilterOperator.IsNotNull)
if (columnFilterOperator == FilterOperator.IsNull || columnFilterOperator == FilterOperator.IsNotNull)
{
return $"{property} {linqOperator} null";
}
else if (columnFilterOperator == FilterOperator.IsEmpty || columnFilterOperator == FilterOperator.IsNotEmpty)
{
return $@"{property} {linqOperator} """"";
}
else
{
return $"{property} {linqOperator} {value}";
}
}
else if (column.FilterPropertyType == typeof(DateTime) ||
else if (column.FilterPropertyType == typeof(DateTime) ||
column.FilterPropertyType == typeof(DateTime?) ||
column.FilterPropertyType == typeof(DateTimeOffset) ||
column.FilterPropertyType == typeof(DateTimeOffset) ||
column.FilterPropertyType == typeof(DateTimeOffset?))
{
if (column.GetFilterOperator() == FilterOperator.IsNull || column.GetFilterOperator() == FilterOperator.IsNotNull)
if (columnFilterOperator == FilterOperator.IsNull || columnFilterOperator == FilterOperator.IsNotNull)
{
return $"{property} {linqOperator} null";
}
else if (columnFilterOperator == FilterOperator.IsEmpty || columnFilterOperator == FilterOperator.IsNotEmpty)
{
return $@"{property} {linqOperator} """"";
}
else
{
var dateTimeValue = DateTime.Parse(value, null, System.Globalization.DateTimeStyles.RoundtripKind);
var dateTimeValue = DateTime.Parse(value, CultureInfo.InvariantCulture, 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 dateFormat = dateTimeValue.TimeOfDay == TimeSpan.Zero ? "yyyy-MM-dd" : "yyyy-MM-ddTHH:mm:ss.fffZ";
var dateFunction = column.FilterPropertyType == typeof(DateTimeOffset) || column.FilterPropertyType == typeof(DateTimeOffset?) ? "DateTimeOffset" : "DateTime";
return $@"{property} {linqOperator} {dateFunction}(""{finalDate.ToString(dateFormat)}"")";
return $@"{property} {linqOperator} {dateFunction}(""{finalDate.ToString(dateFormat, CultureInfo.InvariantCulture)}"")";
}
}
else if (column.FilterPropertyType == typeof(bool) || column.FilterPropertyType == typeof(bool?))
@@ -449,10 +488,14 @@ namespace Radzen
}
else if (column.FilterPropertyType == typeof(Guid) || column.FilterPropertyType == typeof(Guid?))
{
if (column.GetFilterOperator() == FilterOperator.IsNull || column.GetFilterOperator() == FilterOperator.IsNotNull)
if (columnFilterOperator == FilterOperator.IsNull || columnFilterOperator == FilterOperator.IsNotNull)
{
return $"{property} {linqOperator} null";
}
else if (columnFilterOperator == FilterOperator.IsEmpty || columnFilterOperator == FilterOperator.IsNotEmpty)
{
return $@"{property} {linqOperator} """"";
}
else
{
return $@"{property} {linqOperator} Guid(""{value}"")";
@@ -490,7 +533,7 @@ namespace Radzen
{
if (columnFormat == "date-time" || columnFormat == "date")
{
return $"{property} {columnFilterOperator} {DateTime.Parse(value, null, System.Globalization.DateTimeStyles.RoundtripKind).ToString("yyyy-MM-ddTHH:mm:ss.fffZ")}";
return $"{property} {columnFilterOperator} {DateTime.Parse(value, CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.RoundtripKind).ToString("yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture)}";
}
else if (columnFormat == "time")
{
@@ -502,8 +545,8 @@ namespace Radzen
}
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == "contains")
{
return column.Grid.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ?
$"contains({property}, tolower('{value}'))" :
return column.Grid.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ?
$"contains({property}, tolower('{value}'))" :
$"contains({property}, '{value}')";
}
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == "DoesNotContain")
@@ -514,14 +557,14 @@ namespace Radzen
}
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == "startswith")
{
return column.Grid.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ?
return column.Grid.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ?
$"startswith({property}, tolower('{value}'))" :
$"startswith({property}, '{value}')";
}
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == "endswith")
{
return column.Grid.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ?
$"endswith({property}, tolower('{value}'))" :
$"endswith({property}, tolower('{value}'))" :
$"endswith({property}, '{value}')";
}
else if (!string.IsNullOrEmpty(value) && columnFilterOperator == "eq")
@@ -554,25 +597,29 @@ namespace Radzen
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="column">The column.</param>
/// <param name="second">if set to <c>true</c> [second].</param>
/// <param name="filterValue">The specific value to filter by</param>
/// <param name="columnFilterOperator">The operator used to compare to <paramref name="filterValue"/></param>
/// <returns>System.String.</returns>
private static string GetColumnODataFilter<T>(RadzenDataGridColumn<T> column, bool second = false)
internal static string GetColumnODataFilter<T>(RadzenDataGridColumn<T> column, object filterValue, FilterOperator columnFilterOperator)
{
var property = column.GetFilterProperty().Replace('.', '/');
var columnFilterOperator = !second ? column.GetFilterOperator() : column.GetSecondFilterOperator();
var odataFilterOperator = ODataFilterOperators[columnFilterOperator];
var value = typeof(IEnumerable).IsAssignableFrom(column.FilterPropertyType) && column.FilterPropertyType != typeof(string) ? null :
!second ? (string)Convert.ChangeType(column.GetFilterValue(), typeof(string)) :
(string)Convert.ChangeType(column.GetSecondFilterValue(), typeof(string));
var value = IsEnumerable(column.FilterPropertyType) && column.FilterPropertyType != typeof(string)
? null
: (string)Convert.ChangeType(filterValue, typeof(string), CultureInfo.InvariantCulture);
if (column.Grid.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive && column.FilterPropertyType == typeof(string))
{
property = $"tolower({property})";
}
if (column.FilterPropertyType == typeof(string))
if (PropertyAccess.IsEnum(column.FilterPropertyType) || PropertyAccess.IsNullableEnum(column.FilterPropertyType))
{
return $"{property} {odataFilterOperator} '{value}'";
}
else if (column.FilterPropertyType == typeof(string))
{
if (!string.IsNullOrEmpty(value) && columnFilterOperator == FilterOperator.Contains)
{
@@ -614,16 +661,22 @@ namespace Radzen
{
return $"{property} {odataFilterOperator} null";
}
else if (columnFilterOperator == FilterOperator.IsEmpty || columnFilterOperator == FilterOperator.IsNotEmpty)
{
return $"{property} {odataFilterOperator} ''";
}
}
else if (typeof(IEnumerable).IsAssignableFrom(column.FilterPropertyType) && column.FilterPropertyType != typeof(string))
else if (IsEnumerable(column.FilterPropertyType) && column.FilterPropertyType != typeof(string))
{
var v = !second ? column.GetFilterValue() : column.GetSecondFilterValue();
var enumerableValue = ((IEnumerable)(v != null ? v : Enumerable.Empty<object>())).AsQueryable();
var enumerableValue = ((IEnumerable)(filterValue != null ? filterValue : Enumerable.Empty<object>())).AsQueryable();
var enumerableValueAsString = "(" + String.Join(",",
(enumerableValue.ElementType == typeof(string) ? enumerableValue.Cast<string>().Select(i => $@"'{i}'").Cast<object>() : enumerableValue.Cast<object>())) + ")";
var enumerableValueAsStringOrForAny = String.Join(" or ",
(enumerableValue.ElementType == typeof(string) ? enumerableValue.Cast<string>()
.Select(i => $@"i/{property} eq '{i}'").Cast<object>() : enumerableValue.Cast<object>().Select(i => $@"i/{property} eq {i}").Cast<object>()));
if (enumerableValue.Any() && columnFilterOperator == FilterOperator.Contains)
{
return $"{property} in {enumerableValueAsString}";
@@ -632,6 +685,14 @@ namespace Radzen
{
return $"not({property} in {enumerableValueAsString})";
}
else if (enumerableValue.Any() && columnFilterOperator == FilterOperator.In)
{
return $"{column.Property}/any(i:{enumerableValueAsStringOrForAny})";
}
else if (enumerableValue.Any() && columnFilterOperator == FilterOperator.NotIn)
{
return $"not({column.Property}/any(i: {enumerableValueAsStringOrForAny}))";
}
}
else if (PropertyAccess.IsNumeric(column.FilterPropertyType))
{
@@ -643,6 +704,10 @@ namespace Radzen
{
return $"{property} {odataFilterOperator} null";
}
else if (columnFilterOperator == FilterOperator.IsEmpty || columnFilterOperator == FilterOperator.IsNotEmpty)
{
return $"{property} {odataFilterOperator} ''";
}
else
{
return $"{property} eq {value.ToLower()}";
@@ -657,9 +722,13 @@ namespace Radzen
{
return $"{property} {odataFilterOperator} null";
}
else if (columnFilterOperator == FilterOperator.IsEmpty || columnFilterOperator == FilterOperator.IsNotEmpty)
{
return $"{property} {odataFilterOperator} ''";
}
else
{
return $"{property} {odataFilterOperator} {DateTime.Parse(value, null, System.Globalization.DateTimeStyles.RoundtripKind).ToString("yyyy-MM-ddTHH:mm:ss.fffZ")}";
return $"{property} {odataFilterOperator} {DateTime.Parse(value, CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.RoundtripKind).ToString("yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture)}";
}
}
else if (column.FilterPropertyType == typeof(Guid) || column.FilterPropertyType == typeof(Guid?))
@@ -733,8 +802,10 @@ namespace Radzen
public static string ToODataFilterString<T>(this IEnumerable<RadzenDataGridColumn<T>> columns)
{
Func<RadzenDataGridColumn<T>, bool> canFilter = (c) => c.Filterable && c.FilterPropertyType != null &&
(!(c.GetFilterValue() == null || c.GetFilterValue() as string == string.Empty) || c.GetFilterOperator() == FilterOperator.IsNotNull || c.GetFilterOperator() == FilterOperator.IsNull)
&& c.GetFilterProperty() != null;
(!(c.GetFilterValue() == null || c.GetFilterValue() as string == string.Empty)
|| c.GetFilterOperator() == FilterOperator.IsNotNull || c.GetFilterOperator() == FilterOperator.IsNull
|| c.GetFilterOperator() == FilterOperator.IsEmpty || c.GetFilterOperator() == FilterOperator.IsNotEmpty)
&& c.GetFilterProperty() != null;
if (columns.Where(canFilter).Any())
{
@@ -749,7 +820,8 @@ namespace Radzen
var value = column.GetFilterValue();
var secondValue = column.GetSecondFilterValue();
if (value != null || column.GetFilterOperator() == FilterOperator.IsNotNull || column.GetFilterOperator() == FilterOperator.IsNull)
if (value != null || column.GetFilterOperator() == FilterOperator.IsNotNull || column.GetFilterOperator() == FilterOperator.IsNull
|| column.GetFilterOperator() == FilterOperator.IsEmpty || column.GetFilterOperator() == FilterOperator.IsNotEmpty)
{
var linqOperator = ODataFilterOperators[column.GetFilterOperator()];
if (linqOperator == null)
@@ -761,11 +833,11 @@ namespace Radzen
if (secondValue == null)
{
whereList.Add(GetColumnODataFilter(column));
whereList.Add(column.GetColumnODataFilter());
}
else
{
whereList.Add($"({GetColumnODataFilter(column)} {booleanOperator} {GetColumnODataFilter(column, true)})");
{
whereList.Add($"({column.GetColumnODataFilter()} {booleanOperator} {column.GetColumnODataFilter(second: true)})");
}
}
}
@@ -834,7 +906,7 @@ namespace Radzen
index++;
}
}
else
else
{
var firstFilter = comparison == "StartsWith" || comparison == "EndsWith" || comparison == "Contains" ?
$@"{property}{filterCaseSensitivityOperator}.{comparison}(@{index}{filterCaseSensitivityOperator})" :
@@ -859,6 +931,14 @@ namespace Radzen
return source;
}
/// <summary>
/// Gets if type is IEnumerable.
/// </summary>
public static bool IsEnumerable(Type type)
{
return typeof(IEnumerable).IsAssignableFrom(type) || typeof(IEnumerable<>).IsAssignableFrom(type);
}
/// <summary>
/// Wheres the specified columns.
/// </summary>
@@ -869,8 +949,10 @@ namespace Radzen
public static IQueryable<T> Where<T>(this IQueryable<T> source, IEnumerable<RadzenDataGridColumn<T>> columns)
{
Func<RadzenDataGridColumn<T>, bool> canFilter = (c) => c.Filterable && c.FilterPropertyType != null &&
(!(c.GetFilterValue() == null || c.GetFilterValue() as string == string.Empty) || c.GetFilterOperator() == FilterOperator.IsNotNull || c.GetFilterOperator() == FilterOperator.IsNull)
&& c.GetFilterProperty() != null;
(!(c.GetFilterValue() == null || c.GetFilterValue() as string == string.Empty)
|| c.GetFilterOperator() == FilterOperator.IsNotNull || c.GetFilterOperator() == FilterOperator.IsNull
|| c.GetFilterOperator() == FilterOperator.IsEmpty || c.GetFilterOperator() == FilterOperator.IsNotEmpty)
&& c.GetFilterProperty() != null;
if (columns.Where(canFilter).Any())
{
@@ -888,14 +970,18 @@ namespace Radzen
property = $"({property})";
}
if (column.FilterPropertyType == typeof(string) && !(column.GetFilterOperator() == FilterOperator.IsNotNull || column.GetFilterOperator() == FilterOperator.IsNull))
if (column.FilterPropertyType == typeof(string) &&
!(column.GetFilterOperator() == FilterOperator.IsNotNull || column.GetFilterOperator() == FilterOperator.IsNull
|| column.GetFilterOperator() == FilterOperator.IsEmpty || column.GetFilterOperator() == FilterOperator.IsNotEmpty))
{
property = $@"({property} == null ? """" : {property})";
}
string filterCaseSensitivityOperator = column.FilterPropertyType == typeof(string)
&& column.GetFilterOperator() != FilterOperator.IsNotNull && column.GetFilterOperator() != FilterOperator.IsNull &&
column.Grid.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ? ".ToLower()" : "";
string filterCaseSensitivityOperator = column.FilterPropertyType == typeof(string)
&& column.GetFilterOperator() != FilterOperator.IsNotNull && column.GetFilterOperator() != FilterOperator.IsNull
&& column.GetFilterOperator() != FilterOperator.IsEmpty && column.GetFilterOperator() != FilterOperator.IsNotEmpty
&& column.Grid.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ? ".ToLower()" : "";
var comparison = LinqFilterOperators[column.GetFilterOperator()];
@@ -905,7 +991,7 @@ namespace Radzen
{
if (comparison == "StartsWith" || comparison == "EndsWith" || comparison == "Contains")
{
if (typeof(IEnumerable).IsAssignableFrom(column.FilterPropertyType) && column.FilterPropertyType != typeof(string) && comparison == "Contains")
if (IsEnumerable(column.FilterPropertyType) && column.FilterPropertyType != typeof(string) && comparison == "Contains")
{
whereList.Add($@"(@{index}).Contains({property})", new object[] { column.GetFilterValue() });
}
@@ -913,12 +999,12 @@ namespace Radzen
{
whereList.Add($@"{property}{filterCaseSensitivityOperator}.{comparison}(@{index}{filterCaseSensitivityOperator})", new object[] { column.GetFilterValue() });
}
index++;
}
else if (comparison == "DoesNotContain")
{
if (typeof(IEnumerable).IsAssignableFrom(column.FilterPropertyType) && column.FilterPropertyType != typeof(string) && comparison == "DoesNotContain")
if (IsEnumerable(column.FilterPropertyType) && column.FilterPropertyType != typeof(string) && comparison == "DoesNotContain")
{
whereList.Add($@"!(@{index}).Contains({property})", new object[] { column.GetFilterValue() });
}
@@ -926,10 +1012,25 @@ namespace Radzen
{
whereList.Add($@"!{property}{filterCaseSensitivityOperator}.Contains(@{index}{filterCaseSensitivityOperator})", new object[] { column.GetFilterValue() });
}
index++;
}
else
else if (comparison == "In" || comparison == "NotIn")
{
if (IsEnumerable(column.FilterPropertyType) && column.FilterPropertyType != typeof(string) &&
IsEnumerable(column.PropertyType) && column.PropertyType != typeof(string))
{
whereList.Add($@"{(comparison == "NotIn" ? "!" : "")}{property}.Any(i => i in @{index})", new object[] { column.GetFilterValue() });
index++;
}
else if (IsEnumerable(column.FilterPropertyType) && column.FilterPropertyType != typeof(string) &&
column.Property != column.FilterProperty && !string.IsNullOrEmpty(column.FilterProperty))
{
whereList.Add($@"{(comparison == "NotIn" ? "!" : "")}{column.Property}.Any(i => i.{column.FilterProperty} in @{index})", new object[] { column.GetFilterValue() });
index++;
}
}
else if (!(IsEnumerable(column.FilterPropertyType) && column.FilterPropertyType != typeof(string)))
{
whereList.Add($@"{property}{filterCaseSensitivityOperator} {comparison} @{index}{filterCaseSensitivityOperator}", new object[] { column.GetFilterValue() });
index++;
@@ -939,8 +1040,8 @@ namespace Radzen
{
var secondComparison = LinqFilterOperators[column.GetSecondFilterOperator()];
if (typeof(IEnumerable).IsAssignableFrom(column.FilterPropertyType) && column.FilterPropertyType != typeof(string) &&
(comparison == "Contains" || comparison == "DoesNotContain") &&
if (IsEnumerable(column.FilterPropertyType) && column.FilterPropertyType != typeof(string) &&
(comparison == "Contains" || comparison == "DoesNotContain") &&
(secondComparison == "Contains" || secondComparison == "DoesNotContain"))
{
var firstFilter = $@"{(comparison == "DoesNotContain" ? "!" : "")}(@{index}).Contains({property})";
@@ -970,12 +1071,294 @@ namespace Radzen
}
}
return source.Where(string.Join($" {gridBooleanOperator} ", whereList.Keys), whereList.Values.SelectMany(i => i.ToArray()).ToArray());
return whereList.Keys.Any() ?
source.Where(string.Join($" {gridBooleanOperator} ", whereList.Keys), whereList.Values.SelectMany(i => i.ToArray()).ToArray())
: source;
}
return source;
}
/// <summary>
/// Wheres the specified filters.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source">The source.</param>
/// <param name="dataFilter">The DataFilter.</param>
/// <returns>IQueryable&lt;T&gt;.</returns>
public static IQueryable<T> Where<T>(this IQueryable<T> source, RadzenDataFilter<T> dataFilter)
{
Func<CompositeFilterDescriptor, bool> canFilter = (c) => dataFilter.properties.Where(col => col.Property == c.Property).FirstOrDefault()?.FilterPropertyType != null &&
(!(c.FilterValue == null || c.FilterValue as string == string.Empty)
|| c.FilterOperator == FilterOperator.IsNotNull || c.FilterOperator == FilterOperator.IsNull
|| c.FilterOperator == FilterOperator.IsEmpty || c.FilterOperator == FilterOperator.IsNotEmpty)
&& c.Property != null;
if (dataFilter.Filters.Concat(dataFilter.Filters.SelectManyRecursive(i => i.Filters ?? Enumerable.Empty<CompositeFilterDescriptor>())).Where(canFilter).Any())
{
var index = 0;
var filterExpressions = new List<string>();
var filterValues = new List<object[]>();
foreach (var filter in dataFilter.Filters)
{
AddWhereExpression(canFilter, filter, ref filterExpressions, ref filterValues, ref index, dataFilter);
}
return filterExpressions.Any() ?
source.Where(string.Join($" {dataFilter.LogicalFilterOperator.ToString().ToLower()} ", filterExpressions), filterValues.SelectMany(i => i.ToArray()).ToArray())
: source;
}
return source;
}
private static void AddWhereExpression<T>(Func<CompositeFilterDescriptor, bool> canFilter, CompositeFilterDescriptor filter, ref List<string> filterExpressions, ref List<object[]> filterValues, ref int index, RadzenDataFilter<T> dataFilter)
{
if (filter.Filters != null)
{
var innerFilterExpressions = new List<string>();
foreach (var f in filter.Filters)
{
AddWhereExpression(canFilter, f, ref innerFilterExpressions, ref filterValues, ref index, dataFilter);
}
if (innerFilterExpressions.Any())
{
filterExpressions.Add("(" + string.Join($" {filter.LogicalFilterOperator.ToString().ToLower()} ", innerFilterExpressions) + ")");
}
}
else
{
if (filter.Property == null || (filter.FilterValue == null &&
filter.FilterOperator != FilterOperator.IsNull && filter.FilterOperator != FilterOperator.IsNotNull))
{
return;
}
var property = PropertyAccess.GetProperty(filter.Property);
if (property.IndexOf(".") != -1)
{
property = $"({property})";
}
var column = dataFilter.properties.Where(c => c.Property == filter.Property).FirstOrDefault();
if (column == null) return;
if (column.FilterPropertyType == typeof(string) &&
!(filter.FilterOperator == FilterOperator.IsNotNull || filter.FilterOperator == FilterOperator.IsNull
|| filter.FilterOperator == FilterOperator.IsEmpty || filter.FilterOperator == FilterOperator.IsNotEmpty))
{
property = $@"({property} == null ? """" : {property})";
}
string filterCaseSensitivityOperator = column.FilterPropertyType == typeof(string)
&& filter.FilterOperator != FilterOperator.IsNotNull && filter.FilterOperator != FilterOperator.IsNull
&& filter.FilterOperator != FilterOperator.IsEmpty && filter.FilterOperator != FilterOperator.IsNotEmpty
&& dataFilter.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ? ".ToLower()" : "";
var comparison = LinqFilterOperators[filter.FilterOperator];
if (comparison == "StartsWith" || comparison == "EndsWith" || comparison == "Contains")
{
if (column.FilterPropertyType == typeof(string) && filter.FilterValue == null)
{
filter.FilterValue = "";
}
if (IsEnumerable(column.FilterPropertyType) && column.FilterPropertyType != typeof(string) && comparison == "Contains")
{
filterExpressions.Add($@"(@{index}).Contains({property})");
filterValues.Add(new object[] { filter.FilterValue });
}
else
{
filterExpressions.Add($@"{property}{filterCaseSensitivityOperator}.{comparison}(@{index}{filterCaseSensitivityOperator})");
filterValues.Add(new object[] { filter.FilterValue });
}
index++;
}
else if (comparison == "DoesNotContain")
{
if (column.FilterPropertyType == typeof(string) && filter.FilterValue == null)
{
filter.FilterValue = "";
}
if (IsEnumerable(column.FilterPropertyType) && column.FilterPropertyType != typeof(string) && comparison == "DoesNotContain")
{
filterExpressions.Add($@"!(@{index}).Contains({property})");
filterValues.Add(new object[] { filter.FilterValue });
}
else
{
filterExpressions.Add($@"!{property}{filterCaseSensitivityOperator}.Contains(@{index}{filterCaseSensitivityOperator})");
filterValues.Add(new object[] { filter.FilterValue });
}
index++;
}
else if (!(IsEnumerable(column.FilterPropertyType) && column.FilterPropertyType != typeof(string)))
{
var value = filter.FilterValue;
if (column.FilterPropertyType == typeof(DateTimeOffset) || column.FilterPropertyType == typeof(DateTimeOffset?))
{
value = filter.FilterValue != null ? (object)(new DateTimeOffset((DateTime)filter.FilterValue, TimeSpan.Zero)) : null;
}
filterExpressions.Add($@"{property}{filterCaseSensitivityOperator} {comparison} @{index}{filterCaseSensitivityOperator}");
filterValues.Add(new object[] { value });
index++;
}
}
}
/// <summary>
/// Converts to OData filter expression.
/// </summary>
/// <param name="dataFilter">The DataFilter.</param>
/// <returns>System.String.</returns>
public static string ToODataFilterString<T>(this RadzenDataFilter<T> dataFilter)
{
Func<CompositeFilterDescriptor, bool> canFilter = (c) => dataFilter.properties.Where(col => col.Property == c.Property).FirstOrDefault()?.FilterPropertyType != null &&
(!(c.FilterValue == null || c.FilterValue as string == string.Empty)
|| c.FilterOperator == FilterOperator.IsNotNull || c.FilterOperator == FilterOperator.IsNull
|| c.FilterOperator == FilterOperator.IsEmpty || c.FilterOperator == FilterOperator.IsNotEmpty)
&& c.Property != null;
if (dataFilter.Filters.Concat(dataFilter.Filters.SelectManyRecursive(i => i.Filters ?? Enumerable.Empty<CompositeFilterDescriptor>())).Where(canFilter).Any())
{
var filterExpressions = new List<string>();
foreach (var filter in dataFilter.Filters)
{
AddODataExpression(canFilter, filter, ref filterExpressions, dataFilter);
}
return filterExpressions.Any() ?
string.Join($" {dataFilter.LogicalFilterOperator.ToString().ToLower()} ", filterExpressions)
: "";
}
return "";
}
private static void AddODataExpression<T>(Func<CompositeFilterDescriptor, bool> canFilter, CompositeFilterDescriptor filter, ref List<string> filterExpressions, RadzenDataFilter<T> dataFilter)
{
if (filter.Filters != null)
{
var innerFilterExpressions = new List<string>();
foreach (var f in filter.Filters)
{
AddODataExpression(canFilter, f, ref innerFilterExpressions, dataFilter);
}
if (innerFilterExpressions.Any())
{
filterExpressions.Add("(" + string.Join($" {filter.LogicalFilterOperator.ToString().ToLower()} ", innerFilterExpressions) + ")");
}
}
else
{
if (filter.Property == null || (filter.FilterValue == null &&
filter.FilterOperator != FilterOperator.IsNull && filter.FilterOperator != FilterOperator.IsNotNull))
{
return;
}
var property = filter.Property.Replace('.', '/');
var column = dataFilter.properties.Where(c => c.Property == filter.Property).FirstOrDefault();
if (column == null) return;
if (dataFilter.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive && column.FilterPropertyType == typeof(string))
{
property = $"tolower({property})";
}
if (filter.FilterOperator == FilterOperator.StartsWith || filter.FilterOperator == FilterOperator.EndsWith
|| filter.FilterOperator == FilterOperator.Contains || filter.FilterOperator == FilterOperator.DoesNotContain)
{
if (IsEnumerable(column.FilterPropertyType) && column.FilterPropertyType != typeof(string) &&
(filter.FilterOperator == FilterOperator.Contains || filter.FilterOperator == FilterOperator.DoesNotContain))
{
var enumerableValue = ((IEnumerable)(filter.FilterValue != null ? filter.FilterValue : Enumerable.Empty<object>())).AsQueryable();
var firstItemType = enumerableValue.Any() ? enumerableValue.FirstOrDefault().GetType() : typeof(object);
var enumerableValueAsString = "(" + String.Join(",",
(enumerableValue.ElementType == typeof(string) || firstItemType == typeof(string) ? enumerableValue.Cast<string>().Select(i => $@"'{i}'").Cast<object>() : enumerableValue.Cast<object>())) + ")";
if (enumerableValue.Any() && filter.FilterOperator == FilterOperator.Contains)
{
filterExpressions.Add($"{property} in {enumerableValueAsString}");
}
else if (enumerableValue.Any() && filter.FilterOperator == FilterOperator.DoesNotContain)
{
filterExpressions.Add($"not({property} in {enumerableValueAsString})");
}
}
else
{
var expression = dataFilter.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ?
$"{ODataFilterOperators[filter.FilterOperator]}({property}, tolower('{filter.FilterValue}'))" :
$"{ODataFilterOperators[filter.FilterOperator]}({property}, '{filter.FilterValue}')";
if (filter.FilterOperator == FilterOperator.DoesNotContain)
{
expression = $"not({expression})";
}
filterExpressions.Add(expression);
}
}
else
{
if (IsEnumerable(column.FilterPropertyType) && column.FilterPropertyType != typeof(string))
return;
var value = $"{filter.FilterValue}";
if (filter.FilterOperator == FilterOperator.IsNull || filter.FilterOperator == FilterOperator.IsNotNull)
{
value = $"null";
}
else if (filter.FilterOperator == FilterOperator.IsEmpty || filter.FilterOperator == FilterOperator.IsNotEmpty)
{
value = $"''";
}
else if (column.FilterPropertyType == typeof(string) || PropertyAccess.IsEnum(column.FilterPropertyType) || PropertyAccess.IsNullableEnum(column.FilterPropertyType))
{
value = $"'{value}'";
}
else if (column.FilterPropertyType == typeof(DateTime) || column.FilterPropertyType == typeof(DateTime?))
{
try
{
value = Convert.ToDateTime(filter.FilterValue).ToString(CultureInfo.InvariantCulture);
}
catch
{
//
}
value = $"{DateTime.Parse(value, CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.RoundtripKind).ToString("yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture)}";
}
else if (column.FilterPropertyType == typeof(bool) || column.FilterPropertyType == typeof(bool?))
{
value = $"{value?.ToLower()}";
}
filterExpressions.Add($@"{property} {ODataFilterOperators[filter.FilterOperator]} {value}");
}
}
}
/// <summary>
/// Ases the o data enumerable.
/// </summary>

105
Radzen.Blazor/README.md Normal file
View File

@@ -0,0 +1,105 @@
## Radzen Blazor is a set of 70+ free native Blazor UI controls packed with DataGrid, Scheduler, Charts and robust theming including Material design and Fluent UI.
![Radzen Blazor Components](https://raw.githubusercontent.com/radzenhq/radzen-blazor/master/RadzenBlazorDemos/wwwroot/images/radzen-blazor-components.png)
## Why choose Radzen Blazor Components?
### :sparkles: Free
Radzen Blazor Components are open source and free for commercial use. You can install them from [nuget](https://www.nuget.org/packages/Radzen.Blazor) or build your own copy from source.
Paid support is available as part of the [Radzen Professional subscription](https://www.radzen.com/blazor-studio/pricing/).
### :computer: Native
The components are implemented in C# and take full advantage of the Blazor framework. They do not depend on or wrap existing JavaScript frameworks or libraries.
Blazor Server and Blazor WebAssembly are fully supported.
### :seedling: Growing
We add new components and features on a regular basis.
Short development cycle. We release as soon as new stuff is available. No more quarterly releases.
## Support exceeding your expectations
### :speech_balloon: Community Support
Everybody is welcome to visit the [Radzen Community forum](https://forum.radzen.com/). Join the growing community and participate in the discussions!
### :dart: Dedicated Support
The Radzen team monitors the forum threads, but does not guarantee a response to every question. For guaranteed responses you may consider the dedicated support option.
Dedicated support for the Radzen Blazor Components is available as part of the [Radzen Professional subscription](https://www.radzen.com/blazor-studio/pricing/).
Our flagship product [Radzen Blazor Studio](https://www.radzen.com/blazor-studio/) provides tons of productivity features for Blazor developers:
- An industry-leading WYSIWYG Blazor design time canvas
- Scaffolding a complete CRUD applications from a database
- Built-in security - authentication and authorization
- Visual Studio Code and Professional support
- Deployment to IIS and Azure
- Dedicated support with 24 hour guaranteed response time
## Get started with Radzen Blazor Components
### 1. Install
Radzen Blazor Components are distributed as a [Radzen.Blazor nuget package](https://www.nuget.org/packages/Radzen.Blazor). You can add them to your project in one of the following ways
- Install the package from command line by running `dotnet add package Radzen.Blazor`
- Add the project from the Visual Nuget Package Manager
- Manually edit the .csproj file and add a project reference
### 2. Import the namespace
Open the `_Imports.razor` file of your Blazor application and add this line `@using Radzen.Blazor`.
### 3. Include a theme
Radzen Blazor components come with five free themes: Material, Standard, Default, Dark, Software and Humanistic.
To use a theme
1. Pick a theme. The [online demos](https://blazor.radzen.com/colors) allow you to preview the available options via the theme dropdown located in the header. The Material theme is currently selected by default.
1. Include the theme CSS file in your Blazor application. Open `Pages\_Layout.cshtml` (Blazor Server .NET 6), `Pages\_Host.cshtml` (Blazor Server .NET 7) or `wwwroot/index.html` (Blazor WebAssembly) and include a theme CSS file by adding this snippet
```html
<link rel="stylesheet" href="_content/Radzen.Blazor/css/material-base.css">
```
To include a different theme (i.e. Standard) just change the name of the CSS file:
```
<link rel="stylesheet" href="_content/Radzen.Blazor/css/standard-base.css">
```
### 4. Include Radzen.Blazor.js
Open `Pages\_Layout.cshtml` (Blazor Server .NET 6), `Pages\_Host.cshtml` (Blazor Server .NET 7) or `wwwroot/index.html` (Blazor WebAssembly) and include this snippet:
```html
<script src="_content/Radzen.Blazor/Radzen.Blazor.js"></script>
```
### 5. Use a component
Use any Radzen Blazor component by typing its tag name in a Blazor page e.g.
```html
<RadzenButton Text="Hi"></RadzenButton>
```
#### Data-binding a property
```razor
<RadzenButton Text=@text />
<RadzenTextBox @bind-Value=@text />
@code {
string text = "Hi";
}
```
#### Handing events
```razor
<RadzenButton Click="@ButtonClicked" Text="Hi"></RadzenButton>
@code {
void ButtonClicked()
{
}
}
```

View File

@@ -1,18 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<NoWarn>BL9993</NoWarn>
<TargetFrameworks>netstandard2.1;net5.0</TargetFrameworks>
<NoWarn>BL9993;BL0007;BL0005</NoWarn>
<TargetFrameworks>netstandard2.1;net5.0;net6.0;net7.0</TargetFrameworks>
<RazorLangVersion>3.0</RazorLangVersion>
<LangVersion>7.3</LangVersion>
<OutputType>Library</OutputType>
<IsPackable>true</IsPackable>
<PackageId>Radzen.Blazor</PackageId>
<Product>Radzen.Blazor</Product>
<Version>3.18.6</Version>
<Version>4.20.2</Version>
<Copyright>Radzen Ltd.</Copyright>
<Authors>Radzen Ltd.</Authors>
<Description>Native Blazor UI components by Radzen Ltd.</Description>
<PackageTags>blazor blazor-component blazor-grid blazor-datagrid</PackageTags>
<Description>Radzen Blazor is a set of 70+ free native Blazor UI controls packed with DataGrid, Scheduler, Charts and robust theming including Material design and Fluent UI.</Description>
<PackageTags>blazor material design fluent fluentui components datagrid scheduler charts</PackageTags>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageProjectUrl>https://www.radzen.com</PackageProjectUrl>
<PackageIcon>icon.png</PackageIcon>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
@@ -20,22 +21,24 @@
<RepositoryUrl>https://github.com/radzenhq/radzen-blazor</RepositoryUrl>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net5.0'">
<DefineConstants>NET5</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="LibSassBuilder" Version="2.0.1" />
<PackageReference Include="DartSassBuilder" Version="1.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components" Condition="'$(TargetFramework)' == 'netstandard2.1'" Version="3.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Condition="'$(TargetFramework)' == 'netstandard2.1'" Version="3.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Components" Condition="'$(TargetFramework)' == 'net5.0'" Version="5.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Condition="'$(TargetFramework)' == 'net5.0'" Version="5.0.0" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.2.12" />
<PackageReference Include="Microsoft.AspNetCore.Components" Condition="'$(TargetFramework)' == 'net6.0'" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Condition="'$(TargetFramework)' == 'net6.0'" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components" Condition="'$(TargetFramework)' == 'net7.0'" Version="7.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Condition="'$(TargetFramework)' == 'net7.0'" Version="7.0.0" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" Condition="'$(TargetFramework)' == 'netstandard2.1'" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.3.0" />
</ItemGroup>
<ItemGroup>
<None Include="LICENSE.txt" Pack="true" PackagePath="" />
<None Include="icon.png" Pack="true" PackagePath="" />
<None Include="README.md" Pack="true" PackagePath="\" />
</ItemGroup>
<ItemGroup>
@@ -45,24 +48,24 @@
</ItemGroup>
<PropertyGroup>
<LibSassOutputStyle>expanded</LibSassOutputStyle>
<EnableDefaultSassItems>false</EnableDefaultSassItems>
<DartSassOutputStyle>expanded</DartSassOutputStyle>
<EnableDefaultSassItems>false</EnableDefaultSassItems>
</PropertyGroup>
<ItemGroup>
<Sass Include="$(MSBuildProjectDirectory)/themes/*.scss" Exclude="$(MSBuildProjectDirectory)/themes/_*.scss" Condition="'$(TargetFramework)' == 'net5.0'" />
<Sass Include="$(MSBuildProjectDirectory)/themes/*.scss" Exclude="$(MSBuildProjectDirectory)/themes/_*.scss" Condition="'$(TargetFramework)' == 'net6.0'" />
</ItemGroup>
<Target Name="Sass" BeforeTargets="BeforeBuild" Condition="'$(TargetFramework)' == 'net5.0'">
<Target Name="Sass" BeforeTargets="BeforeBuild" Condition="'$(TargetFramework)' == 'net6.0'">
<PropertyGroup>
<_SassFileList>@(Sass->'&quot;%(FullPath)&quot;', ' ')</_SassFileList>
<LibSassBuilderArgs>files $(_SassFileList) --outputstyle $(LibSassOutputStyle) --level $(LibSassOutputLevel)</LibSassBuilderArgs>
<DartSassBuilderArgs>files $(_SassFileList) --outputstyle $(DartSassOutputStyle) --level $(DartSassOutputLevel)</DartSassBuilderArgs>
</PropertyGroup>
<Message Text="$(LibSassBuilderArgs)" Importance="$(LibSassMessageLevel)" />
<Message Text="Converted SassFile list to argument" Importance="$(LibSassMessageLevel)" />
<Message Text="$(DartSassBuilderArgs)" Importance="$(DartSassMessageLevel)" />
<Message Text="Converted SassFile list to argument" Importance="$(DartSassMessageLevel)" />
</Target>
<Target Name="MoveCss" AfterTargets="AfterCompile" Condition="'$(TargetFramework)' == 'net5.0'" >
<Target Name="MoveCss" AfterTargets="AfterCompile" Condition="'$(TargetFramework)' == 'net6.0'">
<ItemGroup>
<CssFile Include="$(MSBuildProjectDirectory)/themes/*.css" />
</ItemGroup>

View File

@@ -10,15 +10,15 @@
}
@if (Visible)
{
<div @ref="@Element" role="tablist" @attributes="Attributes" class="@GetCssClass()" id="@GetId()">
<div @ref="@Element" role="tablist" style=@Style @attributes="Attributes" class="@GetCssClass()" id="@GetId()">
@for (var i = 0; i < items.Count; i++)
{
var item = items[i];
var item = items[i];
if (!item.Visible)
continue;
<div class="rz-accordion-header" @attributes="item.Attributes" style="@item.Style">
<a @onclick="@((args) => SelectItem(item))" href="javascript:void(0)" role="tab" tabindex="0"
<div @ref="@item.Element" id="@item.GetItemId()" @attributes="item.Attributes" class="@item.GetItemCssClass()" style="@item.Style">
<a @onclick="@((args) => SelectItem(item))" aria-label="@ItemAriaLabel(i, item)" title="@ItemTitle(i, item)" href="javascript:void(0)" role="tab" tabindex="0"
id="@($"rz-accordiontab-{items.IndexOf(item)}")" aria-controls="@($"rz-accordiontab-{items.IndexOf(item)}-content")" aria-expanded="true">
@if (IsSelected(i, item))
{
@@ -30,11 +30,11 @@
}
@if (!string.IsNullOrEmpty(item.Icon))
{
<i class="rzi">@((MarkupString)item.Icon)</i>
<i class="rzi" style="@(!string.IsNullOrEmpty(item.IconColor) ? $"color:{item.IconColor}" : null)">@((MarkupString)item.Icon)</i>
}
@if (!string.IsNullOrEmpty(item.Text))
{
<span>@item.Text</span>
<span>@((MarkupString)item.Text)</span>
}
</a>
</div>

View File

@@ -130,6 +130,38 @@ namespace Radzen.Blazor
List<int> expandedIdexes = new List<int>();
/// <summary>
/// Gets the item's title attribute value.
/// </summary>
/// <param name="index">The index.</param>
/// <param name="item">The item.</param>
/// <returns>The item's collapse or expand title value depending on if the item is expanded or collapsed.
/// If the relevant title is null or whitespace this method returns "Expand" or "Collapse".</returns>
protected string ItemTitle(int index, RadzenAccordionItem item)
{
if (IsSelected(index, item))
{
return string.IsNullOrWhiteSpace(item.CollapseTitle) ? "Collapse" : item.CollapseTitle;
}
return string.IsNullOrWhiteSpace(item.ExpandTitle) ? "Expand" : item.ExpandTitle;
}
/// <summary>
/// Gets the item's aria-label attribute value.
/// </summary>
/// <param name="index">The index.</param>
/// <param name="item">The item.</param>
/// <returns>The item's collapse or expand aria-label value depending on if the item is expanded or collapsed.
/// If the relevant aria-label is null or whitespace this method returns "Expand" or "Collapse".</returns>
protected string ItemAriaLabel(int index, RadzenAccordionItem item)
{
if (IsSelected(index, item))
{
return string.IsNullOrWhiteSpace(item.CollapseAriaLabel) ? "Collapse" : item.CollapseAriaLabel;
}
return string.IsNullOrWhiteSpace(item.ExpandAriaLabel) ? "Expand" : item.ExpandAriaLabel;
}
internal async System.Threading.Tasks.Task SelectItem(RadzenAccordionItem item)
{
await CollapseAll(item);

View File

@@ -22,6 +22,13 @@ namespace Radzen.Blazor
[Parameter]
public string Icon { get; set; }
/// <summary>
/// Gets or sets the icon color.
/// </summary>
/// <value>The icon color.</value>
[Parameter]
public string IconColor { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this <see cref="RadzenAccordionItem"/> is selected.
/// </summary>
@@ -29,14 +36,41 @@ namespace Radzen.Blazor
[Parameter]
public bool Selected { get; set; }
/// <summary>
/// Gets or sets the title attribute of the expand button.
/// </summary>
/// <value>The title attribute value of the expand button.</value>
[Parameter]
public string ExpandTitle { get; set; }
/// <summary>
/// Gets or sets the title attribute of the collapse button.
/// </summary>
/// <value>The title attribute value of the collapse button.</value>
[Parameter]
public string CollapseTitle { get; set; }
/// <summary>
/// Gets or sets the aria-label attribute of the expand button.
/// </summary>
/// <value>The aria-label attribute value of the expand button.</value>
[Parameter]
public string ExpandAriaLabel { get; set; }
/// <summary>
/// Gets or sets the aria-label attribute of the collapse button.
/// </summary>
/// <value>The aria-label attribute value of the collapse button.</value>
[Parameter]
public string CollapseAriaLabel { get; set; }
/// <summary>
/// Gets or sets the child content.
/// </summary>
/// <value>The child content.</value>
[Parameter]
public RenderFragment ChildContent { get; set; }
bool _visible = true;
/// <summary>
/// Gets or sets a value indicating whether this <see cref="RadzenAccordionItem"/> is visible.
@@ -54,7 +88,10 @@ namespace Radzen.Blazor
if (_visible != value)
{
_visible = value;
Accordion.Refresh();
if (Accordion != null)
{
Accordion.Refresh();
}
}
}
}
@@ -106,5 +143,21 @@ namespace Radzen.Blazor
Accordion?.RemoveItem(this);
}
internal string GetItemId()
{
return GetId();
}
internal string GetItemCssClass()
{
return GetCssClass();
}
/// <inheritdoc />
protected override string GetComponentCssClass()
{
return "rz-accordion-header";
}
}
}

View File

@@ -0,0 +1,89 @@
@inherits RadzenComponentWithChildren
@if (GetVisible())
{
<div @ref="@Element" style="@Style" @attributes="Attributes" class="@GetCssClass()" id="@GetId()" aria-live="polite">
<div class="rz-alert-item">
@if (ShowIcon)
{
<RadzenIcon Icon="@getIcon()" IconColor="@IconColor" Class="rz-alert-icon" />
}
<div class="rz-alert-message">
@if (!string.IsNullOrEmpty(Title))
{
<div class="rz-alert-title">@Title</div>
}
<div class="rz-alert-content">
@if(ChildContent != null)
{
@ChildContent
}
else
{
@Text
}
</div>
</div>
</div>
@if (AllowClose)
{
if (Shade == Shade.Light || Shade == Shade.Lighter)
{
if (AlertStyle == AlertStyle.Primary)
{
<RadzenButton Click=@Close Icon="close" Variant="Variant.Text" ButtonStyle="ButtonStyle.Primary" Shade="Shade.Darker" Size="@GetCloseButtonSize()" />
}
else if (AlertStyle == AlertStyle.Secondary)
{
<RadzenButton Click=@Close Icon="close" Variant="Variant.Text" ButtonStyle="ButtonStyle.Secondary" Shade="Shade.Darker" Size="@GetCloseButtonSize()" />
}
else if (AlertStyle == AlertStyle.Light)
{
<RadzenButton Click=@Close Icon="close" Variant="Variant.Text" ButtonStyle="ButtonStyle.Dark" Shade="Shade.Darker" Size="@GetCloseButtonSize()" />
}
else if (AlertStyle == AlertStyle.Base)
{
<RadzenButton Click=@Close Icon="close" Variant="Variant.Text" ButtonStyle="ButtonStyle.Dark" Shade="Shade.Darker" Size="@GetCloseButtonSize()" />
}
else if (AlertStyle == AlertStyle.Dark)
{
<RadzenButton Click=@Close Icon="close" Variant="Variant.Text" ButtonStyle="ButtonStyle.Light" Shade="Shade.Darker" Size="@GetCloseButtonSize()" />
}
else if (AlertStyle == AlertStyle.Success)
{
<RadzenButton Click=@Close Icon="close" Variant="Variant.Text" ButtonStyle="ButtonStyle.Success" Shade="Shade.Darker" Size="@GetCloseButtonSize()" />
}
else if (AlertStyle == AlertStyle.Danger)
{
<RadzenButton Click=@Close Icon="close" Variant="Variant.Text" ButtonStyle="ButtonStyle.Danger" Shade="Shade.Darker" Size="@GetCloseButtonSize()" />
}
else if (AlertStyle == AlertStyle.Warning)
{
<RadzenButton Click=@Close Icon="close" Variant="Variant.Text" ButtonStyle="ButtonStyle.Warning" Shade="Shade.Darker" Size="@GetCloseButtonSize()" />
}
else if (AlertStyle == AlertStyle.Info)
{
<RadzenButton Click=@Close Icon="close" Variant="Variant.Text" ButtonStyle="ButtonStyle.Info" Shade="Shade.Darker" Size="@GetCloseButtonSize()" />
}
}
else
{
if (AlertStyle == AlertStyle.Light)
{
<RadzenButton Click=@Close Icon="close" Variant="Variant.Text" ButtonStyle="ButtonStyle.Dark" Size="@GetCloseButtonSize()" />
}
else if (AlertStyle == AlertStyle.Base)
{
<RadzenButton Click=@Close Icon="close" Variant="Variant.Text" ButtonStyle="ButtonStyle.Dark" Size="@GetCloseButtonSize()" />
}
else if (AlertStyle == AlertStyle.Dark)
{
<RadzenButton Click=@Close Icon="close" Variant="Variant.Text" ButtonStyle="ButtonStyle.Light" Size="@GetCloseButtonSize()" />
}
else
{
<RadzenButton Click=@Close Icon="close" Variant="Variant.Text" ButtonStyle="ButtonStyle.Light" Size="@GetCloseButtonSize()" />
}
}
}
</div>
}

View File

@@ -0,0 +1,165 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using System;
using System.Threading.Tasks;
namespace Radzen.Blazor
{
/// <summary>
/// RadzenAlert component.
/// </summary>
/// <example>
/// <code>
/// &lt;RadzenAlert&gt;
/// &lt;ChildContent&gt;
/// Content
/// &lt;/ChildContent&gt;
/// &lt;/RadzenAlert&gt;
/// </code>
/// </example>
public partial class RadzenAlert : RadzenComponentWithChildren
{
private string GetAlertSize()
{
return Size == AlertSize.Medium ? "md" : Size == AlertSize.Large ? "lg" : Size == AlertSize.Small ? "sm" : "xs";
}
/// <summary>
/// Gets or sets a value indicating whether close is allowed. Set to <c>true</c> by default.
/// </summary>
/// <value><c>true</c> if close is allowed; otherwise, <c>false</c>.</value>
[Parameter]
public bool AllowClose { get; set; } = true;
/// <summary>
/// Gets or sets a value indicating whether icon should be shown. Set to <c>true</c> by default.
/// </summary>
/// <value><c>true</c> if icon is shown; otherwise, <c>false</c>.</value>
[Parameter]
public bool ShowIcon { get; set; } = true;
/// <summary>
/// Gets or sets the title.
/// </summary>
/// <value>The title.</value>
[Parameter]
public string Title { get; set; }
/// <summary>
/// Gets or sets the text of the alert. Overriden by <see cref="RadzenComponentWithChildren.ChildContent" />.
/// </summary>
/// <value>The title.</value>
[Parameter]
public string Text { get; set; }
/// <summary>
/// Gets or sets the icon.
/// </summary>
/// <value>The icon.</value>
[Parameter]
public string Icon { get; set; }
/// <summary>
/// Gets or sets the icon color.
/// </summary>
/// <value>The icon color.</value>
[Parameter]
public string IconColor { get; set; }
/// <summary>
/// Gets or sets the severity.
/// </summary>
/// <value>The severity.</value>
[Parameter]
public AlertStyle AlertStyle { get; set; } = AlertStyle.Base;
/// <summary>
/// Gets or sets the design variant of the alert.
/// </summary>
/// <value>The variant of the alert.</value>
[Parameter]
public Variant Variant { get; set; } = Variant.Filled;
/// <summary>
/// Gets or sets the color shade of the alert.
/// </summary>
/// <value>The color shade of the alert.</value>
[Parameter]
public Shade Shade { get; set; } = Shade.Default;
/// <summary>
/// Gets or sets the size.
/// </summary>
/// <value>The size.</value>
[Parameter]
public AlertSize Size { get; set; } = AlertSize.Medium;
ButtonSize GetCloseButtonSize()
{
return Size == AlertSize.ExtraSmall ? ButtonSize.ExtraSmall : ButtonSize.Small;
}
bool? visible;
bool GetVisible()
{
return visible ?? Visible;
}
/// <inheritdoc />
protected override string GetComponentCssClass()
{
return $"rz-alert rz-alert-{GetAlertSize()} rz-variant-{Enum.GetName(typeof(Variant), Variant).ToLowerInvariant()} rz-{Enum.GetName(typeof(AlertStyle), AlertStyle).ToLowerInvariant()} rz-shade-{Enum.GetName(typeof(Shade), Shade).ToLowerInvariant()}";
}
string getIcon()
{
if (!string.IsNullOrEmpty(Icon))
{
return Icon;
}
else if (AlertStyle == AlertStyle.Primary)
{
return "lightbulb_outline";
}
else if (AlertStyle == AlertStyle.Secondary)
{
return "lightbulb_outline";
}
else if (AlertStyle == AlertStyle.Light)
{
return "lightbulb_outline";
}
else if (AlertStyle == AlertStyle.Base)
{
return "lightbulb_outline";
}
else if (AlertStyle == AlertStyle.Dark)
{
return "lightbulb_outline";
}
else if (AlertStyle == AlertStyle.Success)
{
return "check_circle_outline";
}
else if (AlertStyle == AlertStyle.Danger)
{
return "error_outline";
}
else if (AlertStyle == AlertStyle.Warning)
{
return "warning_amber";
}
else if (AlertStyle == AlertStyle.Info)
{
return "info_outline";
}
return "";
}
void Close()
{
visible = false;
}
}
}

View File

@@ -12,18 +12,9 @@
var value = ComposeValue(valueScale);
IPathGenerator pathGenerator;
if (Smooth)
{
pathGenerator = new SplineGenerator();
}
else
{
pathGenerator = new LineGenerator();
}
var pathGenerator = GetPathGenerator();
var data = Items.Select(item =>
var data = Items.Select(item =>
{
var x = category(item);
var y = value(item);
@@ -35,7 +26,7 @@
var index = Chart.Series.IndexOf(this);
var className = $"rz-area-series rz-series-{index}";
return
return
@<g class="@className">
@if (Items.Any())
{
@@ -52,7 +43,7 @@
<path @key="@area" style="@style" d="@area" fill="@Fill" stroke="none"></path>
<Path @key="@line" D="@line" Stroke="@Stroke" StrokeWidth="@StrokeWidth" LineType="@LineType" Style="@style" Fill="none" />
}
<Markers Data="@Items" Category="@category" Value="@value" MarkerType="@MarkerType" Stroke="@Markers.Stroke" Fill="@(Markers.Fill ?? Stroke)" StrokeWidth="@Markers.StrokeWidth" Size="@Markers.Size" />
<Markers Series="@this" Data="@Items" Category="@category" Value="@value" MarkerType="@MarkerType" Stroke="@Markers.Stroke" Fill="@(Markers.Fill ?? Stroke)" StrokeWidth="@Markers.StrokeWidth" Size="@Markers.Size" />
</g>;
}
}

View File

@@ -1,5 +1,7 @@
using Microsoft.AspNetCore.Components;
using Radzen.Blazor.Rendering;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Radzen.Blazor
@@ -40,7 +42,17 @@ namespace Radzen.Blazor
/// Specifies whether to render a smooth line. Set to <c>false</c> by default.
/// </summary>
[Parameter]
public bool Smooth { get; set; }
public bool Smooth
{
get => Interpolation == Interpolation.Spline;
set => Interpolation = value ? Interpolation.Spline : Interpolation.Line;
}
/// <summary>
/// Specifies how to render lines between data points. Set to <see cref="Line"/> by default
/// </summary>
[Parameter]
public Interpolation Interpolation { get; set; } = Interpolation.Line;
/// <inheritdoc />
public override string Color
@@ -82,19 +94,17 @@ namespace Radzen.Blazor
var valueTicks = Chart.ValueScale.Ticks(Chart.ValueAxis.TickDistance);
var axisY = Chart.ValueScale.Scale(Math.Max(0, valueTicks.Start));
if (points.Any())
if (points.Length > 0)
{
for (var i = 0; i < points.Length - 1; i++)
if (points.Length == 1)
{
var start = points[i];
var end = points[i + 1];
var point = points[0];
var polygon = new[]
{
new Point { X = start.X, Y = start.Y - tolerance },
new Point { X = end.X, Y = end.Y - tolerance },
new Point { X = end.X, Y = axisY },
new Point { X = start.X, Y = axisY },
var polygon = new[] {
new Point { X = point.X - tolerance, Y = point.Y - tolerance },
new Point { X = point.X - tolerance, Y = point.Y + tolerance },
new Point { X = point.X + tolerance, Y = point.Y + tolerance },
new Point { X = point.X + tolerance, Y = point.Y - tolerance },
};
if (InsidePolygon(new Point { X = x, Y = y }, polygon))
@@ -102,9 +112,51 @@ namespace Radzen.Blazor
return true;
}
}
else
{
for (var i = 0; i < points.Length - 1; i++)
{
var start = points[i];
var end = points[i + 1];
var polygon = new[]
{
new Point { X = start.X, Y = start.Y - tolerance },
new Point { X = end.X, Y = end.Y - tolerance },
new Point { X = end.X, Y = axisY },
new Point { X = start.X, Y = axisY },
};
if (InsidePolygon(new Point { X = x, Y = y }, polygon))
{
return true;
}
}
}
}
return false;
}
/// <inheritdoc />
public override IEnumerable<ChartDataLabel> GetDataLabels(double offsetX, double offsetY)
{
return base.GetDataLabels(offsetX, offsetY - 16);
}
private IPathGenerator GetPathGenerator()
{
switch(Interpolation)
{
case Interpolation.Line:
return new LineGenerator();
case Interpolation.Spline:
return new SplineGenerator();
case Interpolation.Step:
return new StepGenerator();
default:
throw new NotSupportedException($"Interpolation {Interpolation} is not supported yet.");
}
}
}
}
}

View File

@@ -10,19 +10,39 @@
@if (Visible)
{
<div @ref="@Element" style="@($"{Style};display:inline-block;")" @attributes="Attributes" class="@GetCssClass()" id="@GetId()">
<input @ref="@search" @onkeydown="@OnFilterKeyPress" value="@Value" disabled="@Disabled"
onfocus="@OpenScript()" onkeypress="@OpenScript()" tabindex="@TabIndex" @onchange="@OnChange"
@if (Multiline)
{
<textarea @ref="@search" @attributes="InputAttributes" @onkeydown="@OnFilterKeyPress" value="@Value" disabled="@Disabled"
oninput="@OpenScript()" tabindex="@(Disabled ? "-1" : $"{TabIndex}")" @onchange="@OnChange"
aria-autocomplete="list" aria-haspopup="true" autocomplete="off" role="combobox"
class="@InputClassList"
type="text" id="@Name" aria-expanded="true" placeholder="@Placeholder" />
<div id="@PopupID" class="rz-autocomplete-panel" style="display:none; transform: none; box-sizing: border-box; max-height: 200px;">
class="@InputClassList" onblur="Radzen.activeElement = null"
id="@Name" aria-expanded="true" placeholder="@CurrentPlaceholder" />
}
else
{
<input @ref="@search" @attributes="InputAttributes" @onkeydown="@OnFilterKeyPress" value="@Value" disabled="@Disabled"
oninput="@OpenScript()" tabindex="@(Disabled ? "-1" : $"{TabIndex}")" @onchange="@OnChange"
aria-autocomplete="list" aria-haspopup="true" autocomplete="off" role="combobox"
class="@InputClassList" onblur="Radzen.activeElement = null"
type="text" id="@Name" aria-expanded="true" placeholder="@CurrentPlaceholder" />
}
<div id="@PopupID" class="rz-autocomplete-panel" style="@PopupStyle">
<ul @ref="@list" class="rz-autocomplete-items rz-autocomplete-list" role="listbox">
@if (!string.IsNullOrEmpty(searchText) || !string.IsNullOrEmpty(customSearchText))
{
@foreach (var item in LoadData.HasDelegate ? Data != null ? Data : Enumerable.Empty<object>() : (View != null ? View : Enumerable.Empty<object>()))
{
<li role="option" class="rz-autocomplete-list-item" @onclick="@(() => OnSelectItem(item))" onmousedown="Radzen.activeElement = null">
<span>@PropertyAccess.GetItemOrValueFromProperty(item, TextProperty)</span>
<span>
@if (Template != null)
{
@Template(item)
}
else
{
@PropertyAccess.GetItemOrValueFromProperty(item, TextProperty)
}
</span>
</li>
}
}

View File

@@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Components.Web;
using System.Linq;
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace Radzen.Blazor
{
@@ -22,6 +23,33 @@ namespace Radzen.Blazor
/// </example>
public partial class RadzenAutoComplete : DataBoundFormComponent<string>
{
/// <summary>
/// Specifies additional custom attributes that will be rendered by the input.
/// </summary>
/// <value>The attributes.</value>
public IReadOnlyDictionary<string, object> InputAttributes { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this <see cref="RadzenAutoComplete"/> is multiline.
/// </summary>
/// <value><c>true</c> if multiline; otherwise, <c>false</c>.</value>
[Parameter]
public bool Multiline { get; set; }
/// <summary>
/// Gets or sets the Popup height.
/// </summary>
/// <value>The number Popup height.</value>
[Parameter]
public string PopupStyle { get; set; } = "display:none; transform: none; box-sizing: border-box; max-height: 200px;";
/// <summary>
/// Gets or sets the template.
/// </summary>
/// <value>The template.</value>
[Parameter]
public RenderFragment<dynamic> Template { get; set; }
/// <summary>
/// Gets or sets the minimum length.
/// </summary>
@@ -95,7 +123,10 @@ namespace Radzen.Blazor
var value = await JSRuntime.InvokeAsync<string>("Radzen.getInputValue", search);
if (value.Length < MinLength)
{
await JSRuntime.InvokeVoidAsync("Radzen.closePopup", PopupID);
return;
}
if (!LoadData.HasDelegate)
{
@@ -148,7 +179,9 @@ namespace Radzen.Blazor
{
string filterCaseSensitivityOperator = FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ? ".ToLower()" : "";
return Query.Where($"{TextProperty}{filterCaseSensitivityOperator}.{Enum.GetName(typeof(StringFilterOperator), FilterOperator)}(@0)",
string textProperty = string.IsNullOrEmpty(TextProperty) ? string.Empty : $".{TextProperty}";
return Query.Where($"o=>o{textProperty}{filterCaseSensitivityOperator}.{Enum.GetName(typeof(StringFilterOperator), FilterOperator)}(@0)",
FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ? searchText.ToLower() : searchText);
}
@@ -249,5 +282,15 @@ namespace Radzen.Blazor
await JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", PopupID);
}
}
#if NET5_0_OR_GREATER
/// <summary>
/// Sets the focus on the input element.
/// </summary>
public override async ValueTask FocusAsync()
{
await search.FocusAsync();
}
#endif
}
}

View File

@@ -20,6 +20,8 @@ namespace Radzen.Blazor
classList.Add("rz-badge");
classList.Add($"rz-badge-{BadgeStyle.ToString().ToLowerInvariant()}");
classList.Add($"rz-variant-{Variant.ToString().ToLowerInvariant()}");
classList.Add($"rz-shade-{Shade.ToString().ToLowerInvariant()}");
if (IsPill)
{
@@ -50,6 +52,20 @@ namespace Radzen.Blazor
[Parameter]
public BadgeStyle BadgeStyle { get; set; }
/// <summary>
/// Gets or sets the badge variant.
/// </summary>
/// <value>The badge variant.</value>
[Parameter]
public Variant Variant { get; set; } = Variant.Filled;
/// <summary>
/// Gets or sets the badge shade color.
/// </summary>
/// <value>The badge shade color.</value>
[Parameter]
public Shade Shade { get; set; } = Shade.Default;
/// <summary>
/// Gets or sets a value indicating whether this instance is pill.
/// </summary>

View File

@@ -21,6 +21,13 @@ namespace Radzen.Blazor
[Parameter]
public double Margin { get; set; } = 10;
/// <summary>
/// Gets or sets the height of all bars in pixels. By default it is automatically calculated depending on the chart height.
/// </summary>
/// <value>The pixel height of the bar. By default set to <c>null</c></value>
[Parameter]
public double? Height { get; set;}
/// <inheritdoc />
protected override void Initialize()
{
@@ -30,7 +37,9 @@ namespace Radzen.Blazor
/// <inheritdoc />
protected override bool ShouldRefreshChart(ParameterView parameters)
{
return DidParameterChange(parameters, nameof(Radius), Radius) || DidParameterChange(parameters, nameof(Margin), Margin);
return DidParameterChange(parameters, nameof(Radius), Radius) ||
DidParameterChange(parameters, nameof(Height), Height) ||
DidParameterChange(parameters, nameof(Margin), Margin);
}
}
}

View File

@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Components;
using Radzen.Blazor.Rendering;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -120,9 +121,18 @@ namespace Radzen.Blazor
{
get
{
var availableHeight = Chart.ValueScale.OutputSize; // - (Chart.ValueAxis.Padding * 2);
var bands = VisibleBarSeries.Cast<IChartBarSeries>().Max(series => series.Count) + 2;
return availableHeight / bands;
var barSeries = VisibleBarSeries;
if (Chart.BarOptions.Height.HasValue)
{
return Chart.BarOptions.Height.Value * barSeries.Count;
}
else
{
var availableHeight = Chart.ValueScale.OutputSize; // - (Chart.ValueAxis.Padding * 2);
var bands = barSeries.Cast<IChartBarSeries>().Max(series => series.Count) + 2;
return availableHeight / bands;
}
}
}
@@ -137,11 +147,11 @@ namespace Radzen.Blazor
/// <inheritdoc />
public override bool Contains(double x, double y, double tolerance)
{
return DataAt(x, y) != null;
return DataAt(x, y).Item1 != null;
}
/// <inheritdoc />
protected override double TooltipX(TItem item)
internal override double TooltipX(TItem item)
{
var value = Chart.CategoryScale.Compose(Value);
var x = value(item);
@@ -163,7 +173,7 @@ namespace Radzen.Blazor
}
/// <inheritdoc />
public override object DataAt(double x, double y)
public override (object, Point) DataAt(double x, double y)
{
var value = ComposeValue(Chart.CategoryScale);
var category = ComposeCategory(Chart.ValueScale);
@@ -186,15 +196,15 @@ namespace Radzen.Blazor
if (startX <= x && x <= endX && startY <= y && y <= endY)
{
return data;
return (data, new Point() { X = x, Y = y });
}
}
return null;
return (null, null);
}
/// <inheritdoc />
protected override double TooltipY(TItem item)
internal override double TooltipY(TItem item)
{
var category = ComposeCategory(Chart.ValueScale);
var barSeries = VisibleBarSeries;
@@ -206,5 +216,23 @@ namespace Radzen.Blazor
return y + height / 2;
}
/// <inheritdoc />
public override IEnumerable<ChartDataLabel> GetDataLabels(double offsetX, double offsetY)
{
var list = new List<ChartDataLabel>();
foreach (var d in Data)
{
list.Add(new ChartDataLabel
{
Position = new Point() { X = TooltipX(d) + offsetX + 8, Y = TooltipY(d) + offsetY },
TextAnchor = "start",
Text = Chart.ValueAxis.Format(Chart.CategoryScale, Value(d))
});
}
return list;
}
}
}

View File

@@ -25,8 +25,7 @@ namespace Radzen.Blazor
protected override string GetComponentCssClass()
{
var classList = ClassList.Create("rz-body")
.Add("body")
.Add("body-expanded", Expanded);
.Add("rz-body-expanded", Expanded);
return classList.ToString();
}

View File

@@ -3,7 +3,11 @@
@if (Visible)
{
<div class="@GetCssClass()" id="@GetId()" style="@Style" @attributes="@Attributes">
@if (Template != null)
@if (ChildContent != null)
{
@ChildContent
}
else if (Template != null)
{
@Template(this)
}
@@ -11,13 +15,13 @@
{
@if (!string.IsNullOrWhiteSpace(Path))
{
<RadzenLink Icon="@Icon" Path="@Path" Text="@Text" />
<RadzenLink Icon="@Icon" IconColor="@IconColor" Path="@Path" Text="@Text" />
}
else
{
@if (!string.IsNullOrWhiteSpace(Icon))
{
<RadzenIcon Icon="@Icon" />
<RadzenIcon Icon="@Icon" IconColor="@IconColor" />
}
<RadzenLabel Text="@Text" />
}

View File

@@ -8,7 +8,7 @@ namespace Radzen.Blazor
public partial class RadzenBreadCrumbItem : RadzenComponent
{
/// <summary>
/// Cascaded TEmplate Parameter from <see cref="RadzenBreadCrumb"/> Component
/// Cascaded Template Parameter from <see cref="RadzenBreadCrumb"/> Component
/// </summary>
[CascadingParameter]
public RenderFragment<RadzenBreadCrumbItem> Template { get; set; }
@@ -31,6 +31,20 @@ namespace Radzen.Blazor
[Parameter]
public string Icon { get; set; }
/// <summary>
/// Gets or sets the icon color.
/// </summary>
/// <value>The icon color.</value>
[Parameter]
public string IconColor { get; set; }
/// <summary>
/// Template Parameter used only for this Item
/// Note: this overrides the <see cref="Template"/> Cascading Parameter
/// </summary>
[Parameter]
public RenderFragment ChildContent { get; set; }
/// <inheritdoc/>
protected override string GetComponentCssClass()
{

View File

@@ -6,35 +6,37 @@
type="@Enum.GetName(typeof(ButtonType), ButtonType).ToLower()"
@attributes="Attributes" class="@GetCssClass()" id="@GetId()"
@onclick="@OnClick">
@if (ChildContent != null)
{
@ChildContent
}
else
{
@if (IsBusy)
<span class="rz-button-box">
@if (ChildContent != null)
{
<RadzenIcon Icon="refresh" Style="animation: rotation 700ms linear infinite" />
@if (!string.IsNullOrEmpty(BusyText))
{
<span class="rz-button-text">@BusyText</span>
}
@ChildContent
}
else
{
@if (!string.IsNullOrEmpty(@Icon))
@if (IsBusy)
{
<i class="rz-button-icon-left rzi">@((MarkupString)Icon)</i>
<RadzenIcon Icon="refresh" Style="animation: rotation 700ms linear infinite" />
@if (!string.IsNullOrEmpty(BusyText))
{
<span class="rz-button-text">@BusyText</span>
}
}
@if (!string.IsNullOrEmpty(Image))
else
{
<img class="rz-button-icon-left rzi" src="@Image" />
}
@if (!string.IsNullOrEmpty(Text))
{
<span class="rz-button-text">@Text</span>
@if (!string.IsNullOrEmpty(@Icon))
{
<i class="rz-button-icon-left rzi" style="@(!string.IsNullOrEmpty(IconColor) ? $"color:{IconColor}" : null)">@((MarkupString)Icon)</i>
}
@if (!string.IsNullOrEmpty(Image))
{
<img class="rz-button-icon-left rzi" src="@Image" />
}
@if (!string.IsNullOrEmpty(Text))
{
<span class="rz-button-text">@Text</span>
}
}
}
}
</span>
</button>
}

View File

@@ -15,9 +15,9 @@ namespace Radzen.Blazor
/// </example>
public partial class RadzenButton : RadzenComponent
{
private string getButtonSize()
internal string getButtonSize()
{
return Size == ButtonSize.Medium ? "md" : "sm";
return Size == ButtonSize.Medium ? "md" : Size == ButtonSize.Large ? "lg" : Size == ButtonSize.Small ? "sm" : "xs";
}
/// <summary>
@@ -41,6 +41,13 @@ namespace Radzen.Blazor
[Parameter]
public string Icon { get; set; }
/// <summary>
/// Gets or sets the icon color.
/// </summary>
/// <value>The icon color.</value>
[Parameter]
public string IconColor { get; set; }
/// <summary>
/// Gets or sets the image.
/// </summary>
@@ -62,6 +69,20 @@ namespace Radzen.Blazor
[Parameter]
public ButtonType ButtonType { get; set; } = ButtonType.Button;
/// <summary>
/// Gets or sets the design variant of the button.
/// </summary>
/// <value>The variant of the button.</value>
[Parameter]
public Variant Variant { get; set; } = Variant.Filled;
/// <summary>
/// Gets or sets the color shade of the button.
/// </summary>
/// <value>The color shade of the button.</value>
[Parameter]
public Shade Shade { get; set; } = Shade.Default;
/// <summary>
/// Gets or sets the size.
/// </summary>
@@ -109,7 +130,7 @@ namespace Radzen.Blazor
/// Handles the <see cref="E:Click" /> event.
/// </summary>
/// <param name="args">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
public async Task OnClick(MouseEventArgs args)
public virtual async Task OnClick(MouseEventArgs args)
{
if (clicking)
{
@@ -131,7 +152,7 @@ namespace Radzen.Blazor
/// <inheritdoc />
protected override string GetComponentCssClass()
{
return $"rz-button rz-button-{getButtonSize()} btn-{Enum.GetName(typeof(ButtonStyle), ButtonStyle).ToLowerInvariant()}{(IsDisabled ? " rz-state-disabled" : "")}{(string.IsNullOrEmpty(Text) && !string.IsNullOrEmpty(Icon) ? " rz-button-icon-only" : "")}";
return $"rz-button rz-button-{getButtonSize()} rz-variant-{Enum.GetName(typeof(Variant), Variant).ToLowerInvariant()} rz-{Enum.GetName(typeof(ButtonStyle), ButtonStyle).ToLowerInvariant()} rz-shade-{Enum.GetName(typeof(Shade), Shade).ToLowerInvariant()}{(IsDisabled ? " rz-state-disabled" : "")}{(string.IsNullOrEmpty(Text) && !string.IsNullOrEmpty(Icon) ? " rz-button-icon-only" : "")}";
}
}
}

View File

@@ -2,6 +2,7 @@
using Microsoft.AspNetCore.Components.Web;
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace Radzen.Blazor
{
@@ -13,7 +14,18 @@ namespace Radzen.Blazor
/// <inheritdoc />
protected override string GetComponentCssClass()
{
return "rz-card card";
var classList = new List<string>();
classList.Add("rz-card");
classList.Add($"rz-variant-{Variant.ToString().ToLowerInvariant()}");
return string.Join(" ", classList);
}
/// <summary>
/// Gets or sets the card variant.
/// </summary>
/// <value>The card variant.</value>
[Parameter]
public Variant Variant { get; set; } = Variant.Filled;
}
}
}

View File

@@ -26,6 +26,7 @@
@if (series.Visible)
{
@series.Render(CategoryScale, ValueScale);
@series.RenderOverlays(CategoryScale, ValueScale);
}
}
</g>
@@ -37,10 +38,13 @@
@donut.RenderTitle(MarginLeft, MarginTop)
}
}
@if (tooltip != null)
{
@tooltip
}
<ChartTooltipContainer @ref="@chartTooltipContainer">
@if (tooltip != null)
{
@tooltip
}
</ChartTooltipContainer>
</CascadingValue>
}
</div>

View File

@@ -42,11 +42,16 @@ namespace Radzen.Blazor
public ColorScheme ColorScheme { get; set; }
/// <summary>
/// A callback that will be invoked when the user clicks on a series.
/// A callback that will be invoked when the user clicks on a series.
/// </summary>
[Parameter]
public EventCallback<SeriesClickEventArgs> SeriesClick { get; set; }
/// <summary>
/// A callback that will be invoked when the user clicks on a legend.
/// </summary>
[Parameter]
public EventCallback<LegendClickEventArgs> LegendClick { get; set; }
double? Width { get; set; }
double? Height { get; set; }
@@ -202,12 +207,7 @@ namespace Radzen.Blazor
ValueScale.Fit(ValueAxis.TickDistance);
CategoryScale.Fit(CategoryAxis.TickDistance);
var stateHasChanged = false;
if (!ValueScale.IsEqualTo(valueScale))
{
stateHasChanged = true;
}
var stateHasChanged = !ValueScale.IsEqualTo(valueScale);
if (!CategoryScale.IsEqualTo(categoryScale))
{
@@ -249,6 +249,7 @@ namespace Radzen.Blazor
}
}
ChartTooltipContainer chartTooltipContainer;
RenderFragment tooltip;
object tooltipData;
double mouseX;
@@ -268,6 +269,18 @@ namespace Radzen.Blazor
await DisplayTooltip();
}
/// <summary>
/// The minimum pixel distance from a data point to the mouse cursor required for the SeriesClick event to fire. Set to 25 by default.
/// </summary>
[Parameter]
public int ClickTolerance { get; set; } = 25;
/// <summary>
/// The minimum pixel distance from a data point to the mouse cursor required by the tooltip to show. Set to 25 by default.
/// </summary>
[Parameter]
public int TooltipTolerance { get; set; } = 25;
/// <summary>
/// Invoked via interop when the user clicks the RadzenChart. Raises the <see cref="SeriesClick" /> handler.
/// </summary>
@@ -276,20 +289,37 @@ namespace Radzen.Blazor
[JSInvokable]
public async Task Click(double x, double y)
{
IChartSeries closestSeries = null;
object closestSeriesData = null;
double closestSeriesDistanceSquared = ClickTolerance * ClickTolerance;
var queryX = x - MarginLeft;
var queryY = y - MarginTop;
foreach (var series in Series)
{
if (series.Visible && series.Contains(mouseX - MarginLeft, mouseY - MarginTop, 5))
if (series.Visible)
{
var data = series.DataAt(mouseX - MarginLeft, mouseY - MarginTop);
if (data != null)
var (seriesData, seriesDataPoint) = series.DataAt(queryX, queryY);
if (seriesData != null)
{
await series.InvokeClick(SeriesClick, data);
double xDelta = queryX - seriesDataPoint.X;
double yDelta = queryY - seriesDataPoint.Y;
double squaredDistance = xDelta * xDelta + yDelta * yDelta;
if (squaredDistance < closestSeriesDistanceSquared)
{
closestSeries = series;
closestSeriesData = seriesData;
closestSeriesDistanceSquared = squaredDistance;
}
}
return;
}
}
if (closestSeriesData != null)
{
await closestSeries.InvokeClick(SeriesClick, closestSeriesData);
}
}
internal async Task DisplayTooltip()
@@ -297,31 +327,64 @@ namespace Radzen.Blazor
if (Tooltip.Visible)
{
var orderedSeries = Series.OrderBy(s => s.RenderingOrder).Reverse();
IChartSeries closestSeries = null;
object closestSeriesData = null;
double closestSeriesDistanceSquared = TooltipTolerance * TooltipTolerance;
var queryX = mouseX - MarginLeft;
var queryY = mouseY - MarginTop;
foreach (var series in orderedSeries)
{
if (series.Visible && series.Contains(mouseX - MarginLeft, mouseY - MarginTop, 25))
if (series.Visible)
{
var data = series.DataAt(mouseX - MarginLeft, mouseY - MarginTop);
if (data != tooltipData)
foreach (var overlay in series.Overlays.Reverse())
{
tooltipData = data;
tooltip = series.RenderTooltip(data, MarginLeft, MarginTop);
StateHasChanged();
await Task.Yield();
if (overlay.Visible && overlay.Contains(mouseX - MarginLeft, mouseY - MarginTop, TooltipTolerance))
{
tooltipData = null;
tooltip = overlay.RenderTooltip(mouseX, mouseY, MarginLeft, MarginTop);
chartTooltipContainer.Refresh();
await Task.Yield();
return;
}
}
return;
var (seriesData, seriesDataPoint) = series.DataAt(queryX, queryY);
if (seriesData != null)
{
double xDelta = queryX - seriesDataPoint.X;
double yDelta = queryY - seriesDataPoint.Y;
double squaredDistance = xDelta * xDelta + yDelta * yDelta;
if (squaredDistance < closestSeriesDistanceSquared)
{
closestSeries = series;
closestSeriesData = seriesData;
closestSeriesDistanceSquared = squaredDistance;
}
}
}
}
if (closestSeriesData != null)
{
if (closestSeriesData != tooltipData)
{
tooltipData = closestSeriesData;
tooltip = closestSeries.RenderTooltip(closestSeriesData, MarginLeft, MarginTop, Height ?? 0);
chartTooltipContainer.Refresh();
await Task.Yield();
}
return;
}
if (tooltip != null)
{
tooltipData = null;
tooltip = null;
StateHasChanged();
chartTooltipContainer.Refresh();
await Task.Yield();
}
}

View File

@@ -5,10 +5,10 @@
@inherits FormComponent<TValue>
@if (Visible)
{
<div @ref="@Element" @attributes="Attributes" class="@GetCssClass()" @onkeypress=@OnKeyPress @onkeypress:preventDefault style="@Style" tabindex="@TabIndex" id="@GetId()">
<div @ref="@Element" @attributes="Attributes" class="@GetCssClass()" @onkeypress=@OnKeyPress @onkeypress:preventDefault style="@Style" tabindex="@(Disabled || ReadOnly ? "-1" : $"{TabIndex}")" id="@GetId()">
<div class="rz-helper-hidden-accessible">
<input type="checkbox" @onchange=@Toggle value=@CheckBoxValue name=@Name id=@Name checked=@CheckBoxChecked
tabindex="-1">
tabindex="-1" readonly="@ReadOnly">
</div>
<div class=@BoxClassList @onclick=@Toggle @onclick:preventDefault>
<span class=@IconClassList></span>

View File

@@ -49,9 +49,16 @@ namespace Radzen.Blazor
}
}
/// <summary>
/// Gets or sets a value indicating whether is read only.
/// </summary>
/// <value><c>true</c> if is read only; otherwise, <c>false</c>.</value>
[Parameter]
public bool ReadOnly { get; set; }
async Task Toggle()
{
if (Disabled)
if (Disabled || ReadOnly)
{
return;
}

View File

@@ -15,18 +15,25 @@
@if (Visible)
{
<div @ref="@Element" style="@Style" @attributes="Attributes" class="@GetCssClass()" id="@GetId()">
@if (AllowSelectAll)
{
<div class="rz-multiselect-header rz-helper-clearfix" @onclick:preventDefault>
<RadzenCheckBox ReadOnly="@ReadOnly" Disabled="@Disabled" Name="SelectAll" TValue="bool?" Value="@IsAllSelected()" Change="@SelectAll" />
<RadzenLabel Component="SelectAll" Text="@SelectAllText" class="rz-chkbox-label" />
</div>
}
@foreach (var item in allItems.Where(i => i.Visible))
{
<div class="rz-checkbox" @onclick="@(args => SelectItem(item))" @attributes="item.Attributes" style="@item.Style">
<div class="rz-chkbox " @onkeypress="@(async args => { if (args.Code == "Space") { await SelectItem(item); } })" tabindex="@TabIndex">
<div @ref="@item.Element" id="@item.GetItemId()" @onclick="@(args => SelectItem(item))" @attributes="item.Attributes" class="@item.GetItemCssClass()" style="@item.Style">
<div class="rz-chkbox " @onkeypress="@(async args => { if (args.Code == "Space") { await SelectItem(item); } })" tabindex="@(Disabled || ReadOnly || item.Disabled || item.ReadOnly ? "-1" : $"{TabIndex}")">
<div class="rz-helper-hidden-accessible">
<input type="checkbox" name="@Name" value="@item.Value" disabled="@Disabled" tabindex="-1">
<input type="checkbox" name="@Name" value="@item.Value" disabled="@Disabled" readonly="@ReadOnly" tabindex="-1">
</div>
<div class=@ItemClassList(item)>
<span class=@IconClassList(item)></span>
</div>
</div>
<label class="rz-chkbox-label">@item.Text</label>
<label class="rz-chkbox-label">@((MarkupString)item.Text)</label>
</div>
}
</div>

View File

@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Radzen.Blazor.Rendering;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
@@ -45,6 +46,20 @@ namespace Radzen.Blazor
[Parameter]
public string TextProperty { get; set; }
/// <summary>
/// Gets or sets the disabled property.
/// </summary>
/// <value>The disabled property.</value>
[Parameter]
public string DisabledProperty { get; set; }
/// <summary>
/// Gets or sets the read-only property.
/// </summary>
/// <value>The read-only property.</value>
[Parameter]
public string ReadOnlyProperty { get; set; }
IEnumerable<RadzenCheckBoxListItem<TValue>> allItems
{
get
@@ -54,12 +69,77 @@ namespace Radzen.Blazor
var item = new RadzenCheckBoxListItem<TValue>();
item.SetText((string)PropertyAccess.GetItemOrValueFromProperty(i, TextProperty));
item.SetValue((TValue)PropertyAccess.GetItemOrValueFromProperty(i, ValueProperty));
if (DisabledProperty != null && PropertyAccess.TryGetItemOrValueFromProperty<bool>(i, DisabledProperty, out var disabledResult))
{
item.SetDisabled(disabledResult);
}
if (ReadOnlyProperty != null && PropertyAccess.TryGetItemOrValueFromProperty<bool>(i, ReadOnlyProperty, out var readOnlyResult))
{
item.SetReadOnly(readOnlyResult);
}
return item;
}));
}
}
/// <summary>
/// Gets or sets a value indicating whether the user can select all values. Set to <c>false</c> by default.
/// </summary>
/// <value><c>true</c> if select all values is allowed; otherwise, <c>false</c>.</value>
[Parameter]
public bool AllowSelectAll { get; set; } = false;
/// <summary>
/// Gets or sets the select all text.
/// </summary>
/// <value>The select all text.</value>
[Parameter]
public string SelectAllText { get; set; }
async Task SelectAll(bool? value)
{
if (Disabled || ReadOnly)
{
return;
}
if (value == true)
{
Value = allItems.Select(i => i.Value);
}
else if (value == false)
{
Value = null;
}
await ValueChanged.InvokeAsync(Value);
if (FieldIdentifier.FieldName != null) { EditContext?.NotifyFieldChanged(FieldIdentifier); }
await Change.InvokeAsync(Value);
StateHasChanged();
}
bool? IsAllSelected()
{
Func<RadzenCheckBoxListItem<TValue>, bool> predicate = i => Value != null && Value.Contains(i.Value);
var all = allItems.All(predicate);
var any = allItems.Any(predicate);
if (all)
{
return true;
}
else
{
return any ? null : (bool?)false;
}
}
IEnumerable _data = null;
/// <summary>
/// Gets or sets the data used to generate items.
/// </summary>
@@ -81,6 +161,13 @@ namespace Radzen.Blazor
}
}
/// <summary>
/// Gets or sets a value indicating whether is read only.
/// </summary>
/// <value><c>true</c> if is read only; otherwise, <c>false</c>.</value>
[Parameter]
public bool ReadOnly { get; set; }
/// <inheritdoc />
protected override string GetComponentCssClass()
{
@@ -160,7 +247,7 @@ namespace Radzen.Blazor
/// <param name="item">The item.</param>
protected async System.Threading.Tasks.Task SelectItem(RadzenCheckBoxListItem<TValue> item)
{
if (Disabled || item.Disabled)
if (Disabled || item.Disabled || ReadOnly || item.ReadOnly)
return;
List<TValue> selectedValues = new List<TValue>(Value != null ? Value : Enumerable.Empty<TValue>());
@@ -182,10 +269,5 @@ namespace Radzen.Blazor
StateHasChanged();
}
private string getDisabledState(RadzenCheckBoxListItem<TValue> item)
{
return Disabled || item.Disabled ? " rz-state-disabled" : "";
}
}
}

View File

@@ -29,6 +29,13 @@ namespace Radzen.Blazor
[Parameter]
public virtual bool Disabled { get; set; }
/// <summary>
/// Gets or sets a value indicating whether is read only.
/// </summary>
/// <value><c>true</c> if is read only; otherwise, <c>false</c>.</value>
[Parameter]
public bool ReadOnly { get; set; }
RadzenCheckBoxList<TValue> _checkBoxList;
/// <summary>
@@ -70,5 +77,31 @@ namespace Radzen.Blazor
{
Value = value;
}
internal void SetDisabled(bool value)
{
Disabled = value;
}
internal void SetReadOnly(bool value)
{
ReadOnly = value;
}
internal string GetItemId()
{
return GetId();
}
internal string GetItemCssClass()
{
return GetCssClass();
}
/// <inheritdoc />
protected override string GetComponentCssClass()
{
return "rz-checkbox";
}
}
}

View File

@@ -6,19 +6,19 @@
@if (Visible)
{
<div @ref=@Element style=@Style @onclick=@Toggle @attributes=@Attributes class=@GetCssClass() id=@GetId()>
@if(Icon != null)
@if (Icon != null)
{
<i class="rzi">@Icon</i>
<i class="rzi" style="@(!string.IsNullOrEmpty(IconColor) ? $"color:{IconColor}" : null)">@Icon</i>
}
<div class="rz-colorpicker-value" style="background-color: @Color" ></div>
<div class="rz-colorpicker-value" style="background-color: @Value" ></div>
<button type="button" tabindex="-1" class="rz-colorpicker-trigger" disabled=@Disabled @onclick:preventDefault><i class="rzi" /></button>
<Popup @ref=@Popup class="rz-colorpicker-popup" Close=@Close Open=@Open>
<Popup Lazy=@(PopupRenderMode == PopupRenderMode.OnDemand) @ref=@Popup class="rz-colorpicker-popup" Close=@OnClosePopup Open=@Open>
@if (ShowHSV)
{
<Draggable class="rz-saturation-picker rz-colorpicker-section" style=@($"background-color: {HSV.ToRGB().ToCSS()}") Drag=@OnSaturationMove>
<Draggable class="rz-saturation-picker rz-colorpicker-section" style=@($"background-color: hsl({(HueHandleLeft * 360).ToInvariantString()}, 100%, 50%)") Drag=@OnSaturationMove>
<div class="rz-saturation-white">
<div class="rz-saturation-black"></div>
<div class="rz-saturation-handle" style=@($"top: {(SaturationHandleTop*100).ToInvariantString()}%; left: {(SaturationHandleLeft * 100).ToInvariantString()}%")></div>
<div class="rz-saturation-handle" style=@($"top: {(SaturationHandleTop * 100).ToInvariantString()}%; left: {(SaturationHandleLeft * 100).ToInvariantString()}%")></div>
</div>
</Draggable>
<div class="rz-colorpicker-preview-area rz-colorpicker-section">
@@ -107,7 +107,7 @@
</div>
}
@if(ShowButton)
@if (ShowButton)
{
<div class="rz-colorpicker-button rz-colorpicker-section">
<RadzenButton ButtonStyle="ButtonStyle.Primary" Click=@OnClick Text=@ButtonText @onclick:preventDefault />

View File

@@ -37,6 +37,13 @@ namespace Radzen.Blazor
[Parameter]
public string Icon { get; set; }
/// <summary>
/// Gets or sets the icon color.
/// </summary>
/// <value>The icon color.</value>
[Parameter]
public string IconColor { get; set; }
/// <summary>
/// Gets or sets the hexadecimal color label text.
/// </summary>
@@ -151,16 +158,24 @@ namespace Radzen.Blazor
}
}
void UpdateColorUsingHsvHandles()
{
var hsv = new HSV {
Hue = HueHandleLeft,
Saturation = SaturationHandleLeft,
Value = 1 - SaturationHandleTop,
Alpha = AlphaHandleLeft
};
Color = hsv.ToRGB().ToCSS();
TriggerChange();
}
void OnSaturationMove(DraggableEventArgs args)
{
SaturationHandleLeft = Math.Clamp((args.ClientX - args.Rect.Left) / args.Rect.Width, 0, 1);
SaturationHandleTop = Math.Clamp((args.ClientY - args.Rect.Top) / args.Rect.Height, 0, 1);
var hsv = new HSV { Hue = HSV.Hue, Saturation = SaturationHandleLeft, Value = 1 - SaturationHandleTop, Alpha = AlphaHandleLeft };
Color = hsv.ToRGB().ToCSS();
TriggerChange();
UpdateColorUsingHsvHandles();
}
void TriggerChange()
@@ -176,23 +191,17 @@ namespace Radzen.Blazor
void ChangeRGB(object value)
{
SetValue(value as string);
}
void SetValue(string value)
{
var rgb = RGB.Parse(value);
var rgb = RGB.Parse(value as string);
if (rgb != null)
{
Color = rgb.ToCSS();
rgb.Alpha = AlphaHandleLeft;
UpdateColor(rgb);
}
}
internal async Task SelectColor(string value)
{
SetValue(value);
UpdateColor(RGB.Parse(value));
if (!ShowButton)
{
@@ -204,11 +213,12 @@ namespace Radzen.Blazor
{
Color = rgb.ToCSS();
HSV = rgb.ToHSV();
var hsv = rgb.ToHSV();
SaturationHandleLeft = HSV.Saturation;
SaturationHandleTop = 1 - HSV.Value;
HueHandleLeft = HSV.Hue;
SaturationHandleLeft = hsv.Saturation;
SaturationHandleTop = 1 - hsv.Value;
HueHandleLeft = hsv.Hue;
AlphaHandleLeft = hsv.Alpha;
TriggerChange();
}
@@ -258,25 +268,14 @@ namespace Radzen.Blazor
{
AlphaHandleLeft = Math.Round(Math.Clamp((args.ClientX - args.Rect.Left) / args.Rect.Width, 0, 1), 2);
HSV.Alpha = AlphaHandleLeft;
var hsv = new HSV { Hue = HSV.Hue, Saturation = SaturationHandleLeft, Value = 1 - SaturationHandleTop, Alpha = AlphaHandleLeft };
Color = hsv.ToRGB().ToCSS();
TriggerChange();
UpdateColorUsingHsvHandles();
}
void OnHueMove(DraggableEventArgs args)
{
HueHandleLeft = Math.Clamp((args.ClientX - args.Rect.Left) / args.Rect.Width, 0, 1);
HSV.Hue = HueHandleLeft;
var hsv = new HSV { Hue = HSV.Hue, Saturation = SaturationHandleLeft, Value = 1 - SaturationHandleTop, Alpha = AlphaHandleLeft };
Color = hsv.ToRGB().ToCSS();
TriggerChange();
UpdateColorUsingHsvHandles();
}
async Task OnClick()
@@ -286,6 +285,15 @@ namespace Radzen.Blazor
await Popup.CloseAsync();
}
async Task OnClosePopup()
{
if (ShowButton)
{
SetInitialValue();
}
await Close.InvokeAsync(null);
}
/// <summary>
/// Gets or sets a value indicating whether button is shown.
/// </summary>
@@ -321,11 +329,17 @@ namespace Radzen.Blazor
[Parameter]
public RenderFragment ChildContent { get; set; }
double SaturationHandleLeft { get; set; }
double HueHandleLeft { get; set; }
/// <summary>
/// Gets or sets the render mode.
/// </summary>
/// <value>The render mode.</value>
[Parameter]
public PopupRenderMode PopupRenderMode { get; set; } = PopupRenderMode.Initial;
double SaturationHandleLeft { get; set; } = 0;
double SaturationHandleTop { get; set; } = 0;
double HueHandleLeft { get; set; } = 0;
double AlphaHandleLeft { get; set; } = 1;
double SaturationHandleTop { get; set; }
HSV HSV { get; set; } = new HSV { Hue = 0, Saturation = 1, Value = 1 };
string Color { get; set; } = "rgb(255, 255, 255)";
async Task Toggle()
@@ -342,7 +356,7 @@ namespace Radzen.Blazor
if (Disabled)
{
classList.Add("rz-disabled");
classList.Add("rz-state-disabled");
}
return string.Join(" ", classList);
@@ -351,15 +365,16 @@ namespace Radzen.Blazor
/// <inheritdoc />
protected override void OnInitialized()
{
Init();
SetInitialValue();
base.OnInitialized();
}
void Init()
void SetInitialValue()
{
var value = Value;
if (String.IsNullOrEmpty(Value))
if (String.IsNullOrEmpty(Value) || RGB.Parse(Value) == null)
{
value = "rgb(255, 255, 255)";
}
@@ -368,17 +383,11 @@ namespace Radzen.Blazor
{
Color = value;
HSV = RGB.Parse(Color).ToHSV();
SaturationHandleLeft = HSV.Saturation;
SaturationHandleTop = 1 - HSV.Value;
HSV.Saturation = 1;
HSV.Value = 1;
HueHandleLeft = HSV.Hue;
if (value.StartsWith("rgba"))
{
AlphaHandleLeft = HSV.Alpha;
}
var hsv = RGB.Parse(Color).ToHSV();
SaturationHandleLeft = hsv.Saturation;
SaturationHandleTop = 1 - hsv.Value;
HueHandleLeft = hsv.Hue;
AlphaHandleLeft = hsv.Alpha;
}
}
@@ -391,7 +400,7 @@ namespace Radzen.Blazor
if (valueChanged)
{
Init();
SetInitialValue();
}
}
}

View File

@@ -0,0 +1,6 @@
@inherits RadzenComponentWithChildren
@if (Visible)
{
<div @ref="@Element" @attributes="Attributes" class="@GetCssClass()" style="@GetStyle()" id="@GetId()">@ChildContent</div>
}

View File

@@ -0,0 +1,245 @@
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
namespace Radzen.Blazor
{
/// <summary>
/// RadzenColumn component.
/// </summary>
public partial class RadzenColumn : RadzenComponentWithChildren
{
/// <summary>
/// Gets or sets the size.
/// </summary>
/// <value>The size.</value>
[Parameter]
public int? Size { get; set; }
/// <summary>
/// Gets or sets the XS size.
/// </summary>
/// <value>The XS size.</value>
[Parameter]
public int? SizeXS { get; set; }
/// <summary>
/// Gets or sets the SM size.
/// </summary>
/// <value>The SM size.</value>
[Parameter]
public int? SizeSM { get; set; }
/// <summary>
/// Gets or sets the MD size.
/// </summary>
/// <value>The MD size.</value>
[Parameter]
public int? SizeMD { get; set; }
/// <summary>
/// Gets or sets the LG size.
/// </summary>
/// <value>The LG size.</value>
[Parameter]
public int? SizeLG { get; set; }
/// <summary>
/// Gets or sets the XL size.
/// </summary>
/// <value>The XL size.</value>
[Parameter]
public int? SizeXL { get; set; }
/// <summary>
/// Gets or sets the XX size.
/// </summary>
/// <value>The XX size.</value>
[Parameter]
public int? SizeXX { get; set; }
/// <summary>
/// Gets or sets the offset.
/// </summary>
/// <value>The offset.</value>
[Parameter]
public int? Offset { get; set; }
/// <summary>
/// Gets or sets the XS offset.
/// </summary>
/// <value>The XS offset.</value>
[Parameter]
public int? OffsetXS { get; set; }
/// <summary>
/// Gets or sets the SM offset.
/// </summary>
/// <value>The SM offset.</value>
[Parameter]
public int? OffsetSM { get; set; }
/// <summary>
/// Gets or sets the MD offset.
/// </summary>
/// <value>The MD offset.</value>
[Parameter]
public int? OffsetMD { get; set; }
/// <summary>
/// Gets or sets the LG offset.
/// </summary>
/// <value>The LG offset.</value>
[Parameter]
public int? OffsetLG { get; set; }
/// <summary>
/// Gets or sets the XL offset.
/// </summary>
/// <value>The XL offset.</value>
[Parameter]
public int? OffsetXL { get; set; }
/// <summary>
/// Gets or sets the XX offset.
/// </summary>
/// <value>The XX offset.</value>
[Parameter]
public int? OffsetXX { get; set; }
/// <summary>
/// Gets or sets the order.
/// </summary>
/// <value>The order.</value>
[Parameter]
public string Order { get; set; }
/// <summary>
/// Gets or sets the XS order.
/// </summary>
/// <value>The XS order.</value>
[Parameter]
public string OrderXS { get; set; }
/// <summary>
/// Gets or sets the SM order.
/// </summary>
/// <value>The SM order.</value>
[Parameter]
public string OrderSM { get; set; }
/// <summary>
/// Gets or sets the MD order.
/// </summary>
/// <value>The MD order.</value>
[Parameter]
public string OrderMD { get; set; }
/// <summary>
/// Gets or sets the LG order.
/// </summary>
/// <value>The LG order.</value>
[Parameter]
public string OrderLG { get; set; }
/// <summary>
/// Gets or sets the XL order.
/// </summary>
/// <value>The XL order.</value>
[Parameter]
public string OrderXL { get; set; }
/// <summary>
/// Gets or sets the XX order.
/// </summary>
/// <value>The XX order.</value>
[Parameter]
public string OrderXX { get; set; }
/// <summary>
/// Gets the final CSS style rendered by the component. Combines it with a <c>style</c> custom attribute.
/// </summary>
protected string GetStyle()
{
if (Attributes != null && Attributes.TryGetValue("style", out var style) && !string.IsNullOrEmpty(Convert.ToString(@style)))
{
return $"{GetComponentStyle()} {@style}";
}
return GetComponentStyle();
}
/// <summary>
/// Gets the component CSS style.
/// </summary>
protected string GetComponentStyle()
{
return $"{Style}{(!string.IsNullOrEmpty(Style) && !Style.EndsWith(";") ? ";" : "")}";
}
/// <inheritdoc />
protected override string GetComponentCssClass()
{
var list = new List<string>
{
Size != null ? $"rz-col-{GetColumnValue("Size", Size)}" : "rz-col"
};
if (Offset != null)
{
list.Add($"rz-offset-{GetColumnValue("Offset", Offset)}");
}
if (!string.IsNullOrEmpty(Order))
{
list.Add($"rz-order-{GetOrderValue("Order", Order)}");
}
var breakPoints = new string[] { "xs", "sm", "md", "lg", "xl", "xx" };
var properties = GetType().GetProperties()
.Where(p => breakPoints.Any(bp => p.Name.ToLower().EndsWith(bp)))
.Select(p => new { p.Name, BreakPoint = string.Concat(p.Name.ToLower().TakeLast(2)), Value = p.GetValue(this) });
foreach (var p in properties)
{
if (p.Value != null)
{
list.Add($"rz-{(!p.Name.StartsWith("Size") ? p.Name.ToLower().Replace(p.BreakPoint, "") + "-" : "col-")}{p.BreakPoint}-{GetColumnValue(p.Name, p.Value)}");
}
}
return string.Join(" ", list);
}
string GetColumnValue(string name, object value)
{
if (name.StartsWith("Order"))
{
return GetOrderValue(name, value.ToString());
}
if ((int)value < 0 || (int)value > 12)
{
throw new Exception($"Property {name} value should be between 0 and 12.");
}
return $"{value}";
}
string GetOrderValue(string name, string value)
{
var orders = Enumerable.Range(0, 12).Select(i => $"{i}").ToArray().Concat(new string[] { "first", "last" });
if (!orders.Contains(value))
{
throw new Exception($"Property {name} value should be between 0 and 12 or first/last.");
}
return value;
}
}
}

View File

@@ -21,6 +21,13 @@ namespace Radzen.Blazor
[Parameter]
public double Margin { get; set; } = 10;
/// <summary>
/// Gets or sets the width of all columns in pixels. By default it is automatically calculated depending on the chart width.
/// </summary>
/// <value>The pixel width of the column. By default set to <c>null</c></value>
[Parameter]
public double? Width { get; set;}
/// <inheritdoc />
protected override void Initialize()
{
@@ -30,7 +37,9 @@ namespace Radzen.Blazor
/// <inheritdoc />
protected override bool ShouldRefreshChart(ParameterView parameters)
{
return DidParameterChange(parameters, nameof(Radius), Radius) || DidParameterChange(parameters, nameof(Margin), Margin);
return DidParameterChange(parameters, nameof(Radius), Radius) ||
DidParameterChange(parameters, nameof(Width), Width) ||
DidParameterChange(parameters, nameof(Margin), Margin);
}
}
}

View File

@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Components;
using Radzen.Blazor.Rendering;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -115,20 +116,29 @@ namespace Radzen.Blazor
{
get
{
var availableWidth = Chart.CategoryScale.OutputSize - (Chart.CategoryAxis.Padding * 2);
var bands = VisibleColumnSeries.Cast<IChartColumnSeries>().Max(series => series.Count) + 2;
return availableWidth / bands;
var columnSeries = VisibleColumnSeries;
if (Chart.ColumnOptions.Width.HasValue)
{
return Chart.ColumnOptions.Width.Value * columnSeries.Count + Chart.ColumnOptions.Margin * (columnSeries.Count - 1);
}
else
{
var availableWidth = Chart.CategoryScale.OutputSize - (Chart.CategoryAxis.Padding * 2);
var bands = columnSeries.Cast<IChartColumnSeries>().Max(series => series.Count) + 2;
return availableWidth / bands;
}
}
}
/// <inheritdoc />
public override bool Contains(double x, double y, double tolerance)
{
return DataAt(x, y) != null;
return DataAt(x, y).Item1 != null;
}
/// <inheritdoc />
protected override double TooltipX(TItem item)
internal override double TooltipX(TItem item)
{
var columnSeries = VisibleColumnSeries;
var index = columnSeries.IndexOf(this);
@@ -142,7 +152,7 @@ namespace Radzen.Blazor
}
/// <inheritdoc />
protected override double TooltipY(TItem item)
internal override double TooltipY(TItem item)
{
var y = base.TooltipY(item);
var ticks = Chart.ValueScale.Ticks(Chart.ValueAxis.TickDistance);
@@ -152,7 +162,7 @@ namespace Radzen.Blazor
}
/// <inheritdoc />
public override object DataAt(double x, double y)
public override (object, Point) DataAt(double x, double y)
{
var category = ComposeCategory(Chart.CategoryScale);
var value = ComposeValue(Chart.ValueScale);
@@ -163,7 +173,7 @@ namespace Radzen.Blazor
var index = columnSeries.IndexOf(this);
var padding = Chart.ColumnOptions.Margin;
var bandWidth = BandWidth;
var width = bandWidth / columnSeries.Count() - padding + padding / columnSeries.Count();
var width = Chart.ColumnOptions.Width ?? bandWidth / columnSeries.Count() - padding + padding / columnSeries.Count();
foreach (var data in Items)
{
@@ -175,11 +185,17 @@ namespace Radzen.Blazor
if (startX <= x && x <= endX && startY <= y && y <= endY)
{
return data;
return (data, new Point() { X = x, Y = y });
}
}
return null;
return (null, null);
}
/// <inheritdoc />
public override IEnumerable<ChartDataLabel> GetDataLabels(double offsetX, double offsetY)
{
return base.GetDataLabels(offsetX, offsetY - 16);
}
}
}

View File

@@ -22,7 +22,7 @@ namespace Radzen
/// <summary>
/// Gets a reference to the HTML element rendered by the component.
/// </summary>
public ElementReference Element { get; internal set; }
public ElementReference Element { get; protected internal set; }
/// <summary>
/// A callback that will be invoked when the user hovers the component. Commonly used to display a tooltip via
@@ -233,17 +233,17 @@ namespace Radzen
{
if (ContextMenu.HasDelegate)
{
await JSRuntime.InvokeVoidAsync("Radzen.addContextMenu", UniqueID, Reference);
await JSRuntime.InvokeVoidAsync("Radzen.addContextMenu", GetId(), Reference);
}
if (MouseEnter.HasDelegate)
{
await JSRuntime.InvokeVoidAsync("Radzen.addMouseEnter", UniqueID, Reference);
await JSRuntime.InvokeVoidAsync("Radzen.addMouseEnter", GetId(), Reference);
}
if (MouseLeave.HasDelegate)
{
await JSRuntime.InvokeVoidAsync("Radzen.addMouseLeave", UniqueID, Reference);
await JSRuntime.InvokeVoidAsync("Radzen.addMouseLeave", GetId(), Reference);
}
}
}
@@ -347,4 +347,4 @@ namespace Radzen
}
}
}
}
}

View File

@@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Components;
#if NET5_0_OR_GREATER
namespace Radzen
{
/// <summary>
/// Allows the developer to replace a component with another. Useful to specify default values for component properties.
/// </summary>
/// <example>
/// <code>
/// var builder = WebApplication.CreateBuilder(args);
/// var activator = new RadzenComponentActivator();
/// // Replace RadzenButton with MyButton
/// activator.Override&lt;RadzenButton, MyButton&gt;();
/// // Replace RadzenDataGrid with MyDataGrid
/// activator.Override(typeof(RadzenDataGrid&lt;&gt;), typeof(MyDataGrid&lt;&gt;));
/// // Register the activator
/// builder.Services.AddSingleton&lt;IComponentActivator&gt;(activator);
/// </code>
/// </example>
public class RadzenComponentActivator : IComponentActivator
{
private readonly Dictionary<Type, Type> replacedTypes = new Dictionary<Type, Type>();
/// <summary>
/// Replaces the specified component type with another.
/// </summary>
/// <typeparam name="TOriginal"></typeparam>
/// <typeparam name="TOverride"></typeparam>
public void Override<TOriginal, TOverride>()
{
Override(typeof(TOriginal), typeof(TOverride));
}
/// <summary>
/// Replaces the specified component type with another.
/// </summary>
/// <param name="original"></param>
/// <param name="override"></param>
public void Override(Type original, Type @override)
{
replacedTypes.Add(original, @override);
}
/// <summary>
/// Creates a component of the specified type.
/// </summary>
/// <param name="componentType"></param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public IComponent CreateInstance(Type componentType)
{
if (!typeof(IComponent).IsAssignableFrom(componentType))
{
throw new ArgumentException($"The type {componentType.FullName} does not implement {nameof(IComponent)}.", nameof(componentType));
}
if (replacedTypes.ContainsKey(componentType))
{
componentType = replacedTypes[componentType];
}
else if (componentType.IsGenericType)
{
var genericTypeDefinition = componentType.GetGenericTypeDefinition();
if (replacedTypes.ContainsKey(genericTypeDefinition))
{
componentType = replacedTypes[genericTypeDefinition].MakeGenericType(componentType.GetGenericArguments());
}
}
return (IComponent)Activator.CreateInstance(componentType);
}
}
}
#endif

View File

@@ -0,0 +1,4 @@
<RadzenDialog />
<RadzenNotification />
<RadzenContextMenu />
<RadzenTooltip />

View File

@@ -1,4 +1,4 @@
@implements IDisposable
@implements IAsyncDisposable
@using Microsoft.JSInterop
@inject IJSRuntime JSRuntime
@@ -17,7 +17,7 @@
<RadzenMenu Click="@(args => { if (menu.Options.Click != null) { menu.Options.Click(args); } })" Responsive="false">
@foreach (var item in menu.Options.Items)
{
<RadzenMenuItem Text="@item.Text" Value="@item.Value"></RadzenMenuItem>
<RadzenMenuItem Text="@item.Text" Value="@item.Value" Icon="@item.Icon" IconColor="@item.IconColor" Image="@item.Image"></RadzenMenuItem>
}
</RadzenMenu>
</div>

View File

@@ -35,7 +35,7 @@ namespace Radzen.Blazor
/// }
/// </code>
/// </example>
public partial class RadzenContextMenu
public partial class RadzenContextMenu : IAsyncDisposable
{
/// <summary>
/// Gets or sets the unique identifier.
@@ -77,7 +77,28 @@ namespace Radzen.Blazor
await JSRuntime.InvokeVoidAsync("Radzen.openContextMenu",
menu.MouseEventArgs.ClientX,
menu.MouseEventArgs.ClientY,
UniqueID);
UniqueID,
Reference,
"RadzenContextMenu.CloseMenu");
}
}
private DotNetObjectReference<RadzenContextMenu> reference;
/// <summary>
/// Gets the reference for the current component.
/// </summary>
/// <value>The reference.</value>
protected DotNetObjectReference<RadzenContextMenu> Reference
{
get
{
if (reference == null)
{
reference = DotNetObjectReference.Create(this);
}
return reference;
}
}
@@ -96,12 +117,34 @@ namespace Radzen.Blazor
await InvokeAsync(() => { StateHasChanged(); });
}
/// <inheritdoc />
public void Dispose()
/// <summary>
/// Closes this instance.
/// </summary>
[JSInvokable("RadzenContextMenu.CloseMenu")]
public void CloseMenu()
{
Service.Close();
}
/// <inheritdoc />
public async ValueTask DisposeAsync()
{
while (menus.Count != 0)
{
await Close();
}
reference?.Dispose();
reference = null;
if (IsJSRuntimeAvailable)
{
JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", UniqueID);
try
{
await JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", UniqueID);
}
catch
{ }
}
Service.OnOpen -= OnOpen;

View File

@@ -0,0 +1,52 @@
using System;
using Microsoft.AspNetCore.Components;
namespace Radzen.Blazor
{
/// <summary>
/// A validator component which compares a component value with a specified value.
/// Must be placed inside a <see cref="RadzenTemplateForm{TItem}" />
/// </summary>
/// <example>
/// <code>
/// &lt;RadzenTemplateForm TItem="Model" Data=@model&gt;
/// &lt;RadzenTextBox Name="Email" @bind-Value=@model.Email /&gt;
/// &lt;RadzenCustomValidator Value=@model.Email Component="Email" Text="Email must be unique" Validator="@(() => ValidateNewEmail(model.Email))" Style="position: absolute" /&gt;
/// &lt;/RadzenTemplateForm&gt;
/// @code {
/// class Model
/// {
/// public string Email { get; set; }
/// }
/// Model model = new Model();
///
/// string[] emails = new string[] { "andy@smith" };
///
/// bool ValidateNewEmail(string email)
/// {
/// return !emails.Any(e => e.ToUpper().Equals(email.ToUpper()));
/// }
/// }
/// </code>
/// </example>
public class RadzenCustomValidator : ValidatorBase
{
/// <summary>
/// Gets or sets the message displayed when the component is invalid. Set to <c>"Value should match"</c> by default.
/// </summary>
[Parameter]
public override string Text { get; set; } = "Value should match";
/// <summary>
/// Specifies the function which validates the component value. Must return <c>true</c> if the component is valid.
/// </summary>
[Parameter]
public Func<bool> Validator { get; set; } = () => true;
/// <inheritdoc />
protected override bool Validate(IRadzenFormComponent component)
{
return Validator();
}
}
}

View File

@@ -0,0 +1,38 @@
@using System.Linq.Expressions
@typeparam TItem
@inherits RadzenComponent
@if (Properties != null)
{
<CascadingValue Value=this>
@Properties
</CascadingValue>
}
@if (Visible)
{
<div @ref="@Element" style="@Style" @attributes="Attributes" class="@GetCssClass()" id="@GetId()">
<RadzenSelectBar @bind-Value=LogicalFilterOperator Change="@((LogicalFilterOperator args) => { InvokeAsync(ChangeState); if(Auto) { InvokeAsync(Filter); } })" Size="ButtonSize.Small" class="rz-datafilter-operator-bar">
<Items>
<RadzenSelectBarItem Text="@AndOperatorText" Value="LogicalFilterOperator.And" title="@AndOperatorText" />
<RadzenSelectBarItem Text="@OrOperatorText" Value="LogicalFilterOperator.Or" title="@OrOperatorText" />
</Items>
</RadzenSelectBar>
<RadzenButton title="@ClearFilterText" class="rz-datafilter-item-clear rz-datafilter-all-items-clear" Icon="clear" Click="@(args => ClearFilters())" Visible=@(Filters.Any()) Variant="Variant.Text" Size="ButtonSize.Small" ButtonStyle="ButtonStyle.Dark" />
<ul class="rz-datafilter-group">
@foreach(var filter in Filters)
{
<li class="rz-datafilter-item @(filter.Filters != null ? "rz-datafilter-group-item" : "")">
<RadzenDataFilterItem @key=@filter.GetHashCode() DataFilter="@this" Filter="@filter" />
</li>
}
<li class="rz-datafilter-item rz-datafilter-bar">
<RadzenSplitButton Icon="add" Click="@(args => AddFilter(args?.Value == "group"))" Size="ButtonSize.Small" Variant="Variant.Flat" ButtonStyle="ButtonStyle.Primary" Shade="Shade.Lighter">
<RadzenSplitButtonItem Icon="add" Text="@AddFilterText" />
<RadzenSplitButtonItem Icon="playlist_add" Value="group" Text="@AddFilterGroupText" />
</RadzenSplitButton>
</li>
</ul>
</div>
}

View File

@@ -0,0 +1,410 @@
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Radzen.Blazor
{
/// <summary>
/// RadzenDataFilter component.
/// </summary>
/// <typeparam name="TItem">The type of the item.</typeparam>
public partial class RadzenDataFilter<TItem> : RadzenComponent
{
/// <inheritdoc />
protected override string GetComponentCssClass()
{
return "rz-datafilter";
}
/// <summary>
/// Gets or sets the properties.
/// </summary>
/// <value>The properties.</value>
[Parameter]
public RenderFragment Properties { get; set; }
/// <summary>
/// The data
/// </summary>
IEnumerable<TItem> _data;
/// <summary>
/// Gets or sets the data.
/// </summary>
/// <value>The data.</value>
[Parameter]
public IEnumerable<TItem> Data
{
get
{
return _data;
}
set
{
if (_data != value)
{
_data = value;
StateHasChanged();
}
}
}
IQueryable<TItem> _view = null;
/// <summary>
/// Gets the view.
/// </summary>
/// <value>The view.</value>
public virtual IQueryable<TItem> View
{
get
{
if (_view == null)
{
_view = Data != null ? Data.AsQueryable().Where<TItem>(this) : Enumerable.Empty<TItem>().AsQueryable();
}
return _view;
}
}
/// <summary>
/// Gets or sets a value indicating whether this filter is automatic.
/// </summary>
/// <value><c>true</c> if filter automatic; otherwise, <c>false</c>.</value>
[Parameter]
public bool Auto { get; set; } = true;
/// <summary>
/// Gets or sets the filters.
/// </summary>
/// <value>The filters.</value>
public IEnumerable<CompositeFilterDescriptor> Filters { get; set; } = Enumerable.Empty<CompositeFilterDescriptor>();
/// <summary>
/// Gets or sets the logical filter operator.
/// </summary>
/// <value>The logical filter operator.</value>
[Parameter]
public LogicalFilterOperator LogicalFilterOperator { get; set; } = LogicalFilterOperator.And;
/// <summary>
/// Gets or sets the filter case sensitivity.
/// </summary>
/// <value>The filter case sensitivity.</value>
[Parameter]
public FilterCaseSensitivity FilterCaseSensitivity { get; set; } = FilterCaseSensitivity.Default;
/// <summary>
/// Gets or sets the filter text.
/// </summary>
/// <value>The filter text.</value>
[Parameter]
public string FilterText { get; set; } = "Filter";
/// <summary>
/// Gets or sets the enum filter select text.
/// </summary>
/// <value>The enum filter select text.</value>
[Parameter]
public string EnumFilterSelectText { get; set; } = "Select...";
/// <summary>
/// Gets or sets the and operator text.
/// </summary>
/// <value>The and operator text.</value>
[Parameter]
public string AndOperatorText { get; set; } = "And";
/// <summary>
/// Gets or sets the or operator text.
/// </summary>
/// <value>The or operator text.</value>
[Parameter]
public string OrOperatorText { get; set; } = "Or";
/// <summary>
/// Gets or sets the apply filter text.
/// </summary>
/// <value>The apply filter text.</value>
[Parameter]
public string ApplyFilterText { get; set; } = "Apply";
/// <summary>
/// Gets or sets the clear filter text.
/// </summary>
/// <value>The clear filter text.</value>
[Parameter]
public string ClearFilterText { get; set; } = "Clear all";
/// <summary>
/// Gets or sets the add filter text.
/// </summary>
/// <value>The add filter text.</value>
[Parameter]
public string AddFilterText { get; set; } = "Add filter";
/// <summary>
/// Gets or sets the remove filter text.
/// </summary>
/// <value>The remove filter text.</value>
[Parameter]
public string RemoveFilterText { get; set; } = "Remove filter";
/// <summary>
/// Gets or sets the add filter group text.
/// </summary>
/// <value>The add filter group text.</value>
[Parameter]
public string AddFilterGroupText { get; set; } = "Add filter group";
/// <summary>
/// Gets or sets the equals text.
/// </summary>
/// <value>The equals text.</value>
[Parameter]
public string EqualsText { get; set; } = "Equals";
/// <summary>
/// Gets or sets the not equals text.
/// </summary>
/// <value>The not equals text.</value>
[Parameter]
public string NotEqualsText { get; set; } = "Not equals";
/// <summary>
/// Gets or sets the less than text.
/// </summary>
/// <value>The less than text.</value>
[Parameter]
public string LessThanText { get; set; } = "Less than";
/// <summary>
/// Gets or sets the less than or equals text.
/// </summary>
/// <value>The less than or equals text.</value>
[Parameter]
public string LessThanOrEqualsText { get; set; } = "Less than or equals";
/// <summary>
/// Gets or sets the greater than text.
/// </summary>
/// <value>The greater than text.</value>
[Parameter]
public string GreaterThanText { get; set; } = "Greater than";
/// <summary>
/// Gets or sets the greater than or equals text.
/// </summary>
/// <value>The greater than or equals text.</value>
[Parameter]
public string GreaterThanOrEqualsText { get; set; } = "Greater than or equals";
/// <summary>
/// Gets or sets the ends with text.
/// </summary>
/// <value>The ends with text.</value>
[Parameter]
public string EndsWithText { get; set; } = "Ends with";
/// <summary>
/// Gets or sets the contains text.
/// </summary>
/// <value>The contains text.</value>
[Parameter]
public string ContainsText { get; set; } = "Contains";
/// <summary>
/// Gets or sets the does not contain text.
/// </summary>
/// <value>The does not contain text.</value>
[Parameter]
public string DoesNotContainText { get; set; } = "Does not contain";
/// <summary>
/// Gets or sets the starts with text.
/// </summary>
/// <value>The starts with text.</value>
[Parameter]
public string StartsWithText { get; set; } = "Starts with";
/// <summary>
/// Gets or sets the not null text.
/// </summary>
/// <value>The not null text.</value>
[Parameter]
public string IsNotNullText { get; set; } = "Is not null";
/// <summary>
/// Gets or sets the is null text.
/// </summary>
/// <value>The null text.</value>
[Parameter]
public string IsNullText { get; set; } = "Is null";
/// <summary>
/// Gets or sets the is empty text.
/// </summary>
/// <value>The empty text.</value>
[Parameter]
public string IsEmptyText { get; set; } = "Is empty";
/// <summary>
/// Gets or sets the is not empty text.
/// </summary>
/// <value>The not empty text.</value>
[Parameter]
public string IsNotEmptyText { get; set; } = "Is not empty";
/// <summary>
/// Gets or sets a value indicating whether the columns can be filtered.
/// </summary>
/// <value><c>true</c> if columns can be filtered; otherwise, <c>false</c>.</value>
[Parameter]
public bool AllowColumnFiltering { get; set; }
/// <summary>
/// Gets or sets a value indicating whether properties can be reused in the filter.
/// </summary>
/// <value><c>true</c>, if there is only one filter by property; otherwise <c>false</c>.</value>
[Parameter]
public bool UniqueFilters { get; set; }
/// <summary>
/// Gets the properties collection.
/// </summary>
/// <value>The properties collection.</value>
public IList<RadzenDataFilterProperty<TItem>> PropertiesCollection
{
get
{
return properties;
}
}
internal List<RadzenDataFilterProperty<TItem>> properties = new List<RadzenDataFilterProperty<TItem>>();
internal void AddProperty(RadzenDataFilterProperty<TItem> property)
{
if (!properties.Contains(property))
{
properties.Add(property);
}
StateHasChanged();
}
internal void RemoveProperty(RadzenDataFilterProperty<TItem> property)
{
if (properties.Contains(property))
{
properties.Remove(property);
}
if (!disposed)
{
try { InvokeAsync(StateHasChanged); } catch { }
}
}
/// <summary>
/// Recreates View using current Filters.
/// </summary>
public async Task Filter()
{
_view = null;
await ViewChanged.InvokeAsync(View);
}
/// <summary>
/// Gets or sets the view changed callback.
/// </summary>
/// <value>The view changed callback.</value>
[Parameter]
public EventCallback<IQueryable<TItem>> ViewChanged { get; set; }
internal async Task ChangeState()
{
await InvokeAsync(StateHasChanged);
}
/// <summary>
/// Gets or sets the filter date format.
/// </summary>
/// <value>The filter date format.</value>
[Parameter]
public string FilterDateFormat { get; set; }
internal async Task AddFilter(bool isGroup)
{
if (UniqueFilters && properties.All(f => f.IsSelected))
{
return;
}
if (isGroup)
{
Filters = Filters.Concat(new CompositeFilterDescriptor[]
{
new CompositeFilterDescriptor()
{
Filters = Enumerable.Empty<CompositeFilterDescriptor>()
}
}
);
}
else
{
Filters = Filters.Concat(new CompositeFilterDescriptor[] { new CompositeFilterDescriptor() });
}
if (Auto)
{
await Filter();
}
}
/// <summary>
/// Clear filters.
/// </summary>
public async Task ClearFilters()
{
Filters = Enumerable.Empty<CompositeFilterDescriptor>();
properties.ForEach(p => p.IsSelected = false);
if (Auto)
{
await Filter();
}
}
/// <summary>
/// Add filter.
/// </summary>
public async Task AddFilter(CompositeFilterDescriptor filter)
{
Filters = Filters.Concat(new CompositeFilterDescriptor[] { filter });
if (Auto)
{
await Filter();
}
}
/// <summary>
/// Remove filter.
/// </summary>
public async Task RemoveFilter(CompositeFilterDescriptor filter)
{
Filters = Filters.Where(f => f != filter);
if (Auto)
{
await Filter();
}
}
}
}

View File

@@ -0,0 +1,316 @@
@typeparam TItem
@if (Filter.Filters != null)
{
<RadzenSelectBar @bind-Value=Filter.LogicalFilterOperator Change="@((LogicalFilterOperator args) => { InvokeAsync(ChangeState); InvokeAsync(ApplyFilter); })" Size="ButtonSize.Small">
<Items>
<RadzenSelectBarItem Text="@DataFilter.AndOperatorText" Value="LogicalFilterOperator.And" title="@DataFilter.AndOperatorText" />
<RadzenSelectBarItem Text="@DataFilter.OrOperatorText" Value="LogicalFilterOperator.Or" title="@DataFilter.OrOperatorText" />
</Items>
</RadzenSelectBar>
<RadzenButton title="@DataFilter.RemoveFilterText" class="rz-datafilter-item-clear" Icon="clear" Click="@RemoveFilter" Variant="Variant.Text" Size="ButtonSize.Small" ButtonStyle="ButtonStyle.Dark"/>
<ul class="rz-datafilter-group">
@foreach(var filter in Filter.Filters)
{
<li class="rz-datafilter-item @(filter.Filters != null ? "rz-datafilter-group-item" : "")">
<RadzenDataFilterItem DataFilter="@this.DataFilter" Filter="@filter" Parent=@this />
</li>
}
<li class="rz-datafilter-item rz-datafilter-bar">
<RadzenSplitButton Icon="add" Click="@(args => AddFilter(args?.Value == "group"))" Size="ButtonSize.Small" Variant="Variant.Flat" ButtonStyle="ButtonStyle.Primary" Shade="Shade.Lighter">
<RadzenSplitButtonItem Icon="add" Text="@DataFilter.AddFilterText" />
<RadzenSplitButtonItem Icon="playlist_add" Value="group" Text="@DataFilter.AddFilterGroupText" />
</RadzenSplitButton>
</li>
</ul>
}
else
{
<RadzenDropDown @bind-Value="@Filter.Property" Data="@(DataFilter?.properties)" TextProperty="Title" ValueProperty="Property" TValue="string"
DisabledProperty="@(DataFilter?.UniqueFilters == true ? nameof(property.IsSelected) : null)"
Change="@OnPropertyChange" AllowFiltering="@(DataFilter?.AllowColumnFiltering ?? false)" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" class="rz-datafilter-property">
<Template>
@{
var property = (RadzenDataFilterProperty<TItem>)context;
}
@(property.Title ?? property.Property)
</Template>
</RadzenDropDown>
if (property != null)
{
<RadzenDropDown @onclick:preventDefault="true" Data="@(property.GetFilterOperators().Select(t => new { Value = property.GetFilterOperatorText(t), Key = t }))"
TextProperty="Value" ValueProperty="Key" TValue="FilterOperator" @bind-Value="@Filter.FilterOperator" Change="@OnOperatorChange" class="rz-datafilter-operator" />
@if (property.FilterTemplate != null)
{
<div class="rz-datafilter-editor" style="display:flex">
@property.FilterTemplate(Filter)
</div>
}
else if (PropertyAccess.IsNullableEnum(property.FilterPropertyType) || PropertyAccess.IsEnum(property.FilterPropertyType))
{
<RadzenDropDown Disabled="@IsOperatorNullOrEmpty()" AllowClear="false" AllowFiltering="false" TValue="@object" class="rz-datafilter-editor"
@bind-Value=@Filter.FilterValue Multiple="false" Placeholder="@DataFilter.EnumFilterSelectText" TextProperty="Text" ValueProperty="Value"
Data=@EnumExtensions.EnumAsKeyValuePair(Nullable.GetUnderlyingType(property.FilterPropertyType) ?? property.FilterPropertyType) Change=@(args => InvokeAsync(ApplyFilter))/>
}
else if (PropertyAccess.IsNumeric(property.FilterPropertyType))
{
@(DrawNumericFilter())
}
else if (PropertyAccess.IsDate(property.FilterPropertyType))
{
<RadzenDatePicker Disabled="@IsOperatorNullOrEmpty()" @bind-Value=@Filter.FilterValue TValue="@object" ShowTime="true" class="rz-datafilter-editor"
ShowTimeOkButton="true" DateFormat="@getFilterDateFormat()" Change=@(args => InvokeAsync(ApplyFilter)) />
}
else if (property.FilterPropertyType == typeof(bool) || property.FilterPropertyType == typeof(bool?))
{
<RadzenCheckBox Disabled="@IsOperatorNullOrEmpty()" TriState="true" TValue="@object" @bind-Value=@Filter.FilterValue Change=@(args => InvokeAsync(ApplyFilter)) class="rz-datafilter-check" />
}
else
{
<RadzenTextBox Disabled="@IsOperatorNullOrEmpty()" class="rz-datafilter-editor" Value="@($"{Filter.FilterValue}")" Change=@(args => { Filter.FilterValue = args; InvokeAsync(ApplyFilter); }) />
}
<RadzenButton title="@DataFilter.RemoveFilterText" class="rz-datafilter-item-clear" Icon="clear" Click="@RemoveFilter" Variant="Variant.Text" Size="ButtonSize.Small" ButtonStyle="ButtonStyle.Dark"/>
}
}
@code {
[Parameter]
public RadzenDataFilter<TItem> DataFilter { get; set; }
[Parameter]
public RadzenDataFilterItem<TItem> Parent { get; set; }
CompositeFilterDescriptor _filter;
[Parameter]
public CompositeFilterDescriptor Filter
{
get
{
return _filter;
}
set
{
_filter = value;
if (property == null && Filter.Filters == null)
{
if (Filter.Property != null)
{
property = DataFilter?.properties.FirstOrDefault(f => object.Equals(f.Property, Filter.Property));
}
else if (property == null && DataFilter?.UniqueFilters == true)
{
property = DataFilter?.properties.FirstOrDefault(f => f.IsSelected == false);
}
else
{
property = DataFilter?.properties.FirstOrDefault();
}
if (property != null)
{
property.FilterValueChange -= OnFilterValueChange;
property.FilterValueChange += OnFilterValueChange;
if (DataFilter?.UniqueFilters == true)
{
property.IsSelected = true;
}
Filter.Property = property.Property;
if (!property.GetFilterOperators().Contains(Filter.FilterOperator))
{
Filter.FilterOperator = property.GetFilterOperators().FirstOrDefault();
}
var v = property.GetFilterValue();
if (v != null)
{
Filter.FilterValue = v;
}
}
}
}
}
void OnFilterValueChange(object value)
{
if (property != null)
{
Filter.FilterValue = property.GetFilterValue();
}
}
RadzenDataFilterProperty<TItem> property;
async Task ApplyFilter()
{
if (DataFilter.Auto)
{
await DataFilter.Filter();
}
}
async Task OnPropertyChange(object p)
{
property.FilterValueChange -= OnFilterValueChange;
property.IsSelected = false;
property = DataFilter.properties.Where(c => object.Equals(c.Property, p)).FirstOrDefault();
property.FilterValueChange += OnFilterValueChange;
if (DataFilter?.UniqueFilters == true)
{
property.IsSelected = true;
}
Filter.FilterValue = null;
var defaultOperator = typeof(System.Collections.IEnumerable).IsAssignableFrom(property.FilterPropertyType) ? FilterOperator.Contains : default(FilterOperator);
if (property.GetFilterOperators().Any(o => o == property.FilterOperator))
{
Filter.FilterOperator = property.FilterOperator;
}
else if (property.GetFilterOperators().Contains(defaultOperator))
{
Filter.FilterOperator = defaultOperator;
}
else
{
Filter.FilterOperator = property.GetFilterOperators().FirstOrDefault();
}
await ApplyFilter();
}
bool IsOperatorNullOrEmpty()
{
if (Filter != null)
{
return Filter.FilterOperator == FilterOperator.IsEmpty || Filter.FilterOperator == FilterOperator.IsNotEmpty ||
Filter.FilterOperator == FilterOperator.IsNull || Filter.FilterOperator == FilterOperator.IsNotNull;
}
return false;
}
async Task OnOperatorChange(object p)
{
if (IsOperatorNullOrEmpty())
{
Filter.FilterValue = null;
}
await ApplyFilter();
}
async Task AddFilter(bool isGroup)
{
if (DataFilter?.UniqueFilters == true && DataFilter.properties.All(f => f.IsSelected))
{
return;
}
if (isGroup)
{
Filter.Filters = Filter.Filters.Concat(new CompositeFilterDescriptor[]
{
new CompositeFilterDescriptor()
{
Filters = Enumerable.Empty<CompositeFilterDescriptor>()
}
}
);
}
else
{
Filter.Filters = Filter.Filters.Concat(new CompositeFilterDescriptor[] { new CompositeFilterDescriptor() });
}
if (DataFilter.Auto)
{
await DataFilter.Filter();
}
}
async Task RemoveFilter()
{
if (property != null)
{
property.IsSelected = false;
}
property = null;
if (Parent != null)
{
Parent.Filter.Filters = Parent.Filter.Filters.Where(f => f != Filter).ToList();
await Parent.ChangeState();
}
else
{
DataFilter.Filters = DataFilter.Filters.Where(f => f != Filter).ToList();
await DataFilter.ChangeState();
}
await ApplyFilter();
}
internal async Task ChangeState()
{
await InvokeAsync(StateHasChanged);
}
RenderFragment DrawNumericFilter()
{
return new RenderFragment(builder =>
{
var type = Nullable.GetUnderlyingType(property.FilterPropertyType) != null ?
property.FilterPropertyType : typeof(Nullable<>).MakeGenericType(property.FilterPropertyType);
var numericType = typeof(RadzenNumeric<>).MakeGenericType(type);
builder.OpenComponent(0, numericType);
builder.AddAttribute(1, "Value", Filter.FilterValue);
builder.AddAttribute(2, "class", "rz-datafilter-editor");
builder.AddAttribute(3, "Disabled", IsOperatorNullOrEmpty());
Action<object> action = args =>
{
Filter.FilterValue = args; InvokeAsync(ApplyFilter);
};
var eventCallbackGenericCreate = typeof(NumericFilterEventCallback).GetMethod("Create").MakeGenericMethod(type);
var eventCallbackGenericAction = typeof(NumericFilterEventCallback).GetMethod("Action").MakeGenericMethod(type);
builder.AddAttribute(3, "Change", eventCallbackGenericCreate.Invoke(this,
new object[] { this, eventCallbackGenericAction.Invoke(this, new object[] { action }) }));
builder.CloseComponent();
});
}
internal class NumericFilterEventCallback
{
public static EventCallback<T> Create<T>(object receiver, Action<T> action)
{
return EventCallback.Factory.Create<T>(receiver, action);
}
public static Action<T> Action<T>(Action<object> action)
{
return args => action(args);
}
}
internal string getFilterDateFormat()
{
if (property != null && !string.IsNullOrEmpty(property.FormatString))
{
return property.FormatString.Replace("{0:", "").Replace("}", "");
}
return DataFilter.FilterDateFormat;
}
}

View File

@@ -0,0 +1,411 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Common;
using System.Globalization;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
namespace Radzen.Blazor
{
/// <summary>
/// RadzenDataFilterProperty component.
/// Must be placed inside a <see cref="RadzenDataFilter{TItem}" />
/// </summary>
/// <typeparam name="TItem">The type of the DataFilter item.</typeparam>
public partial class RadzenDataFilterProperty<TItem> : ComponentBase, IDisposable
{
internal event Action<object> FilterValueChange;
/// <summary>
/// Gets or sets the DataFilter.
/// </summary>
/// <value>The DataFilter.</value>
[CascadingParameter]
public RadzenDataFilter<TItem> DataFilter { get; set; }
/// <summary>
/// Gets or sets the format string.
/// </summary>
/// <value>The format string.</value>
[Parameter]
public string FormatString { get; set; }
internal void RemoveColumn(RadzenDataFilterProperty<TItem> property)
{
if (DataFilter.properties.Contains(property))
{
DataFilter.properties.Remove(property);
if (!DataFilter.disposed)
{
try { InvokeAsync(StateHasChanged); } catch { }
}
}
}
/// <summary>
/// Called when initialized.
/// </summary>
protected override void OnInitialized()
{
if (DataFilter != null)
{
DataFilter.AddProperty(this);
var property = GetFilterProperty();
if (!string.IsNullOrEmpty(property) && Type == null)
{
if (!string.IsNullOrEmpty(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;
}
}
}
/// <summary>
/// Gets or sets a value indicating whether this <see cref="RadzenDataGridColumn{TItem}"/> is visible.
/// </summary>
/// <value><c>true</c> if visible; otherwise, <c>false</c>.</value>
[Parameter]
public bool Visible { get; set; } = true;
bool? _visible;
/// <summary>
/// Gets if the property is visible or not.
/// </summary>
/// <returns>System.Boolean.</returns>
public bool GetVisible()
{
return _visible ?? Visible;
}
internal void SetVisible(bool? value)
{
_visible = value;
}
/// <summary>
/// Gets or sets the title.
/// </summary>
/// <value>The title.</value>
[Parameter]
public string Title { get; set; }
/// <summary>
/// Gets or sets the property name.
/// </summary>
/// <value>The property name.</value>
[Parameter]
public string Property { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this property is selected in the filter.
/// </summary>
/// <value><c>true</c>, if already selected; otherwise <c>false</c>.</value>
[Parameter]
public bool IsSelected { get; set; }
/// <summary>
/// Gets or sets the filter value.
/// </summary>
/// <value>The filter value.</value>
[Parameter]
public object FilterValue { get; set; }
/// <summary>
/// Gets or sets the filter template.
/// </summary>
/// <value>The filter template.</value>
[Parameter]
public RenderFragment<CompositeFilterDescriptor> FilterTemplate { get; set; }
/// <summary>
/// Gets or sets the data type.
/// </summary>
/// <value>The data type.</value>
[Parameter]
public Type Type { get; set; }
Func<TItem, object> propertyValueGetter;
internal object GetHeader()
{
if (!string.IsNullOrEmpty(Title))
{
return Title;
}
else
{
return Property;
}
}
/// <summary>
/// Gets the filter property.
/// </summary>
/// <returns>System.String.</returns>
public string GetFilterProperty()
{
return Property;
}
Type _filterPropertyType;
/// <summary>
/// Gets the filter property type.
/// </summary>
public Type FilterPropertyType
{
get
{
return _filterPropertyType;
}
}
object filterValue;
FilterOperator? filterOperator;
/// <summary>
/// Set parameters as an asynchronous operation.
/// </summary>
/// <param name="parameters">The parameters.</param>
/// <returns>A Task representing the asynchronous operation.</returns>
public override async Task SetParametersAsync(ParameterView parameters)
{
if (parameters.DidParameterChange(nameof(FilterValue), FilterValue))
{
var value = parameters.GetValueOrDefault<object>(nameof(FilterValue));
if (filterValue != value)
{
filterValue = value;
if (FilterTemplate != null)
{
if (FilterValueChange != null)
{
FilterValueChange(filterValue);
}
await DataFilter.Filter();
return;
}
}
}
await base.SetParametersAsync(parameters);
}
/// <summary>
/// Get property filter value.
/// </summary>
public object GetFilterValue()
{
return filterValue ?? FilterValue;
}
/// <summary>
/// Get property filter operator.
/// </summary>
public FilterOperator GetFilterOperator()
{
return filterOperator ?? FilterOperator;
}
/// <summary>
/// Set property filter value.
/// </summary>
public void SetFilterValue(object value)
{
if ((FilterPropertyType == typeof(DateTimeOffset) || FilterPropertyType == typeof(DateTimeOffset?)) && value != null && value is DateTime?)
{
DateTimeOffset? offset = DateTime.SpecifyKind((DateTime)value, DateTimeKind.Utc);
value = offset;
}
filterValue = value;
}
internal bool CanSetFilterValue()
{
return GetFilterOperator() == FilterOperator.IsNull
|| GetFilterOperator() == FilterOperator.IsNotNull
|| GetFilterOperator() == FilterOperator.IsEmpty
|| GetFilterOperator() == FilterOperator.IsNotEmpty;
}
/// <summary>
/// Sets to default property filter values and operators.
/// </summary>
public void ClearFilters()
{
SetFilterValue(null);
SetFilterOperator(null);
FilterValue = null;
var defaultOperator = typeof(System.Collections.IEnumerable).IsAssignableFrom(FilterPropertyType) ? FilterOperator.Contains : default(FilterOperator);
FilterOperator = GetFilterOperators().Contains(defaultOperator) ? defaultOperator : GetFilterOperators().FirstOrDefault();
}
/// <summary>
/// Gets or sets the filter operator.
/// </summary>
/// <value>The filter operator.</value>
[Parameter]
public FilterOperator FilterOperator { get; set; }
/// <summary>
/// Set property filter operator.
/// </summary>
public void SetFilterOperator(FilterOperator? value)
{
if (value == FilterOperator.IsEmpty || value == FilterOperator.IsNotEmpty || value == FilterOperator.IsNull || value == FilterOperator.IsNotNull)
{
filterValue = value == FilterOperator.IsEmpty || value == FilterOperator.IsNotEmpty ? string.Empty : null;
}
filterOperator = value;
}
/// <summary>
/// Get possible property filter operators.
/// </summary>
public virtual IEnumerable<FilterOperator> GetFilterOperators()
{
if (PropertyAccess.IsEnum(FilterPropertyType))
return new FilterOperator[] { FilterOperator.Equals, FilterOperator.NotEquals };
if (PropertyAccess.IsNullableEnum(FilterPropertyType))
return new FilterOperator[] { FilterOperator.Equals, FilterOperator.NotEquals, FilterOperator.IsNull, FilterOperator.IsNotNull };
if ((typeof(IEnumerable).IsAssignableFrom(FilterPropertyType) || typeof(IEnumerable<>).IsAssignableFrom(FilterPropertyType))
&& FilterPropertyType != typeof(string))
{
return new FilterOperator[]
{
FilterOperator.Contains,
FilterOperator.DoesNotContain,
FilterOperator.Equals,
FilterOperator.NotEquals,
FilterOperator.IsNull,
FilterOperator.IsNotNull,
FilterOperator.IsEmpty,
FilterOperator.IsNotEmpty
};
}
return Enum.GetValues(typeof(FilterOperator)).Cast<FilterOperator>().Where(o => o != FilterOperator.In && o != FilterOperator.NotIn).Where(o => {
var isStringOperator = o == FilterOperator.Contains || o == FilterOperator.DoesNotContain
|| o == FilterOperator.StartsWith || o == FilterOperator.EndsWith || o == FilterOperator.IsEmpty || o == FilterOperator.IsNotEmpty;
return FilterPropertyType == typeof(string) ? isStringOperator
|| o == FilterOperator.Equals || o == FilterOperator.NotEquals
|| o == FilterOperator.IsNull || o == FilterOperator.IsNotNull
: !isStringOperator;
});
}
internal string GetFilterOperatorText(FilterOperator filterOperator)
{
switch (filterOperator)
{
case FilterOperator.Contains:
return DataFilter?.ContainsText;
case FilterOperator.DoesNotContain:
return DataFilter?.DoesNotContainText;
case FilterOperator.EndsWith:
return DataFilter?.EndsWithText;
case FilterOperator.Equals:
return DataFilter?.EqualsText;
case FilterOperator.GreaterThan:
return DataFilter?.GreaterThanText;
case FilterOperator.GreaterThanOrEquals:
return DataFilter?.GreaterThanOrEqualsText;
case FilterOperator.LessThan:
return DataFilter?.LessThanText;
case FilterOperator.LessThanOrEquals:
return DataFilter?.LessThanOrEqualsText;
case FilterOperator.StartsWith:
return DataFilter?.StartsWithText;
case FilterOperator.NotEquals:
return DataFilter?.NotEqualsText;
case FilterOperator.IsNull:
return DataFilter?.IsNullText;
case FilterOperator.IsEmpty:
return DataFilter?.IsEmptyText;
case FilterOperator.IsNotNull:
return DataFilter?.IsNotNullText;
case FilterOperator.IsNotEmpty:
return DataFilter?.IsNotEmptyText;
default:
return $"{filterOperator}";
}
}
internal string GetFilterOperatorSymbol(FilterOperator filterOperator)
{
var symbol = DataFilter.FilterCaseSensitivity == FilterCaseSensitivity.CaseInsensitive ? "a" : "A";
switch (filterOperator)
{
case FilterOperator.Contains:
return $"*{symbol}*";
case FilterOperator.DoesNotContain:
return $"*{symbol}*";
case FilterOperator.StartsWith:
return $"{symbol}**";
case FilterOperator.EndsWith:
return $"**{symbol}";
case FilterOperator.Equals:
return "=";
case FilterOperator.GreaterThan:
return ">";
case FilterOperator.GreaterThanOrEquals:
return "≥";
case FilterOperator.LessThan:
return "<";
case FilterOperator.LessThanOrEquals:
return "≤";
case FilterOperator.NotEquals:
return "≠";
case FilterOperator.IsNull:
return "∅";
case FilterOperator.IsNotNull:
return "!∅";
case FilterOperator.IsEmpty:
return "= ''";
case FilterOperator.IsNotEmpty:
return "≠ ''";
default:
return $"{filterOperator}";
}
}
/// <summary>
/// Disposes this instance.
/// </summary>
public void Dispose()
{
DataFilter?.RemoveProperty(this);
}
}
}

View File

@@ -1,4 +1,4 @@
@using System.Linq.Dynamic.Core
@using System.Linq.Dynamic.Core
@using Microsoft.JSInterop
@using Microsoft.AspNetCore.Components.Forms
@using Radzen
@@ -17,23 +17,29 @@
var visibleColumns = columns.Where(c => c.GetVisible()).ToList();
<div @ref=@Element style="@Style" @attributes="Attributes" class="rz-data-grid @GetCssClass()" id="@GetId()">
@if(AllowGrouping || AllowColumnPicking)
@if (AllowGrouping || AllowColumnPicking)
{
<div class="rz-group-header" @onmouseup=@(args => EndColumnDropToGroup())>
@if(AllowGrouping)
@if (@HeaderTemplate != null)
{
@if(Groups.Any())
<div class="rz-custom-header">
@HeaderTemplate
</div>
}
@if (AllowGrouping)
{
@if (Groups.Any())
{
<div class="rz-group-header-items">
@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 => RemoveGroup(gd)) role="button" class="rz-dialog-titlebar-icon rz-dialog-titlebar-close">
<span class="rzi rzi-times"></span>
</a>
</div>
}
@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 => RemoveGroupAsync(gd)) role="button" class="rz-dialog-titlebar-icon rz-dialog-titlebar-close">
<span class="rzi rzi-times"></span>
</a>
</div>
}
</div>
}
else
@@ -42,124 +48,145 @@
}
}
@if(AllowColumnPicking)
@if (AllowColumnPicking)
{
<div class="rz-column-picker">
<RadzenDropDown SelectAllText="@AllColumnsText"
MaxSelectedLabels="2"
SelectedItemsText="@ColumnsShowingText" Change=@ToggleColumns
@bind-Value="@selectedColumns"
Multiple="true"
Placeholder="@ColumnsText"
Data="allPickableColumns"
TextProperty="Title" />
<RadzenDropDown SelectAllText="@AllColumnsText" AllowSelectAll="@AllowPickAllColumns"
MaxSelectedLabels="@ColumnsPickerMaxSelectedLabels"
SelectedItemsText="@ColumnsShowingText" Change=@ToggleColumns
@bind-Value="@selectedColumns" FilterCaseSensitivity=FilterCaseSensitivity.CaseInsensitive
Multiple="true" AllowFiltering="@ColumnsPickerAllowFiltering"
Placeholder="@ColumnsText"
Data="allPickableColumns"
TextProperty="ColumnPickerTitle" />
</div>
}
</div>
}
else
{
@if (@HeaderTemplate != null)
{
<div class="rz-group-header">
<div class="rz-custom-header">
@HeaderTemplate
</div>
</div>
}
}
@if (AllowPaging && (PagerPosition == PagerPosition.Top || PagerPosition == PagerPosition.TopAndBottom))
{
<RadzenPager HorizontalAlign="@PagerHorizontalAlign" AlwaysVisible="@PagerAlwaysVisible" @ref="topPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@OnPageChanged" PageSizeChanged="@OnPageSizeChanged" PageSizeOptions="@PageSizeOptions" ShowPagingSummary="@ShowPagingSummary" PagingSummaryFormat="@PagingSummaryFormat" PageSizeText="@PageSizeText" />
<RadzenPager HorizontalAlign="@PagerHorizontalAlign" AlwaysVisible="@PagerAlwaysVisible" @ref="topPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@ChangePage" PageSizeChanged="@OnPageSizeChanged" PageSizeOptions="@PageSizeOptions" ShowPagingSummary="@ShowPagingSummary" PagingSummaryFormat="@PagingSummaryFormat" PageSizeText="@PageSizeText" Density="@Density" FirstPageTitle="@FirstPageTitle" FirstPageAriaLabel="@FirstPageAriaLabel" PrevPageAriaLabel="@PrevPageAriaLabel" PrevPageTitle="@PrevPageTitle" NextPageAriaLabel="@NextPageAriaLabel" NextPageTitle="@NextPageTitle" LastPageAriaLabel="@LastPageAriaLabel" LastPageTitle="@LastPageTitle" PageAriaLabelFormat="@PageAriaLabelFormat" PageTitleFormat="@PageTitleFormat" />
}
<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 && ShowExpandColumn)
{
<col>
}
@foreach (var column in visibleColumns)
{
<col id=@(getColumnResizerId(visibleColumns.IndexOf(column)) + "-col") style="@column.GetStyle()">
}
</colgroup>
<thead>
@for(var i = 0; i < deepestChildColumnLevel + 1; i++)
{
<tr>
@foreach(var g in Groups)
<div class="rz-data-grid-data">
<table class="rz-grid-table rz-grid-table-fixed @(AllowAlternatingRows ? "rz-grid-table-striped" : "") @(allColumns.Any(c => c.Parent != null) ? "rz-grid-table-composite" : "") @(getGridLinesCSSClass())">
<colgroup>
@foreach (var g in Groups)
{
<th class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
<span class="rz-column-title"></span>
</th>
<col>
}
@if (Template != null && ShowExpandColumn)
{
<th class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
<span class="rz-column-title"></span>
</th>
<col>
}
@for (var j = 0; j < visibleColumns.Count; j++)
@foreach (var column in visibleColumns)
{
var column = visibleColumns[j];
var cellAttr = HeaderCellAttributes(column);
object colspan;
cellAttr.TryGetValue("colspan", out colspan);
if (colspan != null)
{
j = j + (int)Convert.ChangeType(colspan, TypeCode.Int32) - 1;
}
var columnIndex = visibleColumns.IndexOf(column);
var sortableClass = AllowSorting && column.Sortable ? "rz-sortable-column" : "";
<RadzenDataGridHeaderCell RowIndex="@i" Grid="@this" Column="@column" ColumnIndex="@columnIndex" CssClass="@($"rz-unselectable-text {sortableClass} {column.HeaderCssClass} {getFrozenColumnClass(column, visibleColumns)} {(column.Columns != null || column.Parent != null ? "rz-composite-cell" : "")}".Trim())" Attributes="@(cellAttr)" />
<col id=@(getColumnUniqueId(visibleColumns.IndexOf(column)) + "-col") style="@column.GetStyle()">
}
</tr>
}
@if (AllowFiltering && (FilterMode == FilterMode.Simple || FilterMode == FilterMode.SimpleWithMenu) && 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" rowspan=@(deepestChildColumnLevel + 1)>
<span class="rz-column-title"></span>
</th>
}
@if (Template != null && ShowExpandColumn)
{
<th class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
<span class="rz-column-title"></span>
</th>
}
@foreach (var column in visibleColumns)
{
<th colspan="@column.GetColSpan()" class="@($" rz-unselectable-text")" scope="col" style="@column.GetStyle(true, true)">
@if (AllowFiltering && column.Filterable && column.Columns == null && (!string.IsNullOrEmpty(column.GetFilterProperty()) || column.FilterTemplate != null))
</colgroup>
<thead>
@for (var i = 0; i < deepestChildColumnLevel + 1; i++)
{
<tr>
@if (i == 0) // Only add the th elements for the first row
{
@foreach (var g in Groups)
{
<th class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
<span class="rz-column-title"></span>
</th>
}
@if (Template != null && ShowExpandColumn && i == 0)
{
<th class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
<span class="rz-column-title"></span>
</th>
}
}
@for (var j = 0; j < visibleColumns.Count; j++)
{
var column = visibleColumns[j];
var cellAttr = HeaderCellAttributes(column);
object colspan;
cellAttr.TryGetValue("colspan", out colspan);
if (colspan != null)
{
<div class="rz-cell-filter">
<div class="rz-cell-filter-content">
@if (column.FilterTemplate != null)
{
@column.FilterTemplate(column)
}
else
{
<label class="rz-cell-filter-label" style="height:35px" onclick="event.preventDefault()">
@if (column.FilterPropertyType == typeof(DateTime) || column.FilterPropertyType == typeof(DateTime?) || column.FilterPropertyType == typeof(DateTimeOffset) || column.FilterPropertyType == typeof(DateTimeOffset?))
{
j = j + (int)Convert.ChangeType(colspan, TypeCode.Int32) - 1;
}
var columnIndex = visibleColumns.IndexOf(column);
var sortableClass = AllowSorting && column.Sortable ? "rz-sortable-column" : "";
<RadzenDataGridHeaderCell RowIndex="@i" Grid="@this" Column="@column" ColumnIndex="@columnIndex" CssClass="@($"rz-unselectable-text {sortableClass} {column.HeaderCssClass} {getFrozenColumnClass(column, visibleColumns)} {getCompositeCellCSSClass(column)} {getColumnAlignClass(column)}".Trim())" Attributes="@(cellAttr)" />
}
</tr>
}
@if (AllowFiltering && (FilterMode == FilterMode.Simple || FilterMode == FilterMode.SimpleWithMenu) && 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" rowspan=@(deepestChildColumnLevel + 1)>
<span class="rz-column-title"></span>
</th>
}
@if (Template != null && ShowExpandColumn )
{
<th class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
<span class="rz-column-title"></span>
</th>
}
@foreach (var column in visibleColumns)
{
<th colspan="@column.GetColSpan()" class="@($"rz-unselectable-text {getFrozenColumnClass(column, visibleColumns)} {column.HeaderCssClass}")" scope="col" style="@column.GetStyle(true, true)">
@if (AllowFiltering && column.Filterable && column.Columns == null && (!string.IsNullOrEmpty(column.GetFilterProperty()) || column.FilterTemplate != null))
{
<div class="rz-cell-filter">
<div class="rz-cell-filter-content">
@if (column.FilterTemplate != null)
{
@column.FilterTemplate(column)
}
else
{
<label class="rz-cell-filter-label" style="height:35px; width:100%;" onclick="event.preventDefault()">
@if (PropertyAccess.IsDate(column.FilterPropertyType))
{
if (FilterMode == FilterMode.Simple)
{
<button class="rz-button rz-button-md rz-button-icon-only btn-light" onclick="@($"Radzen.togglePopup(this.parentNode, '{PopupID}{column.GetFilterProperty()}')")">
<button class="rz-button rz-button-md rz-button-icon-only rz-variant-flat rz-light" onclick="@($"Radzen.togglePopup(this.parentNode, '{PopupID}{column.GetFilterProperty()}')")">
<i class="rzi">date_range</i>
</button>
var filterValue = column.GetFilterValue();
@if (filterValue != null)
var filterOperator = column.GetFilterOperator();
@if (filterValue != null && filters.Any(d => d.Property == column.GetFilterProperty()))
{
<span class="rz-current-filter">@string.Format("{0:" + getFilterDateFormat(column) + "}", filterValue)</span>
<i @onclick="@((args) => ClearFilter(column))" class="rzi rz-cell-filter-clear">close</i>
}
else if ((filterOperator == FilterOperator.IsNull || filterOperator == FilterOperator.IsNotNull) && filters.Any(d => d.Property == column.GetFilterProperty()))
{
<span class="rz-current-filter">@column.GetFilterOperatorText(filterOperator)</span>
<i @onclick="@((args) => ClearFilter(column))" class="rzi rz-cell-filter-clear">close</i>
}
<div id="@($"{PopupID}{column.GetFilterProperty()}")" class="rz-overlaypanel"
style="display:none;width:550px;" tabindex="0">
style="display:none;width:550px;" tabindex="0">
<div class="rz-overlaypanel-content">
<div class="rz-date-filter">
@@ -167,37 +194,73 @@
<div class="rz-listbox rz-inputtext ">
<div class="rz-listbox-list-wrapper">
<ul class="rz-listbox-list">
<li class="@(DateFilterOperatorStyle(column, FilterOperator.Equals))" @onclick="@((args) => ApplyDateFilterByFilterOperator(column, FilterOperator.Equals))" style="display: block;">
<span>@EqualsText</span>
</li>
<li class="@(DateFilterOperatorStyle(column, FilterOperator.NotEquals))" @onclick="@((args) => ApplyDateFilterByFilterOperator(column, FilterOperator.NotEquals))" style="display: block;">
<span>@NotEqualsText</span>
</li>
<li class="@(DateFilterOperatorStyle(column, FilterOperator.LessThan))" @onclick="@((args) => ApplyDateFilterByFilterOperator(column, FilterOperator.LessThan))" style="display: block;">
<span>@LessThanText</span>
</li>
<li class="@(DateFilterOperatorStyle(column, FilterOperator.LessThanOrEquals))" @onclick="@((args) => ApplyDateFilterByFilterOperator(column, FilterOperator.LessThanOrEquals))" style="display: block;">
<span>@LessThanOrEqualsText</span>
</li>
<li class="@(DateFilterOperatorStyle(column, FilterOperator.GreaterThan))" @onclick="@((args) => ApplyDateFilterByFilterOperator(column, FilterOperator.GreaterThan))" style="display: block;">
<span>@GreaterThanText</span>
</li>
<li class="@(DateFilterOperatorStyle(column, FilterOperator.GreaterThanOrEquals))" @onclick="@((args) => ApplyDateFilterByFilterOperator(column, FilterOperator.GreaterThanOrEquals))" style="display: block;">
<span>@GreaterThanOrEqualsText</span>
</li>
<li class="@(DateFilterOperatorStyle(column, FilterOperator.IsNull))" @onclick="@((args) => ApplyDateFilterByFilterOperator(column, FilterOperator.IsNull))" style="display: block;">
<span>@IsNullText</span>
</li>
<li class="@(DateFilterOperatorStyle(column, FilterOperator.IsNotNull))" @onclick="@((args) => ApplyDateFilterByFilterOperator(column, FilterOperator.IsNotNull))" style="display: block;">
<span>@IsNotNullText</span>
</li>
@if (column.GetFilterOperators().Contains(FilterOperator.Equals))
{
<li class="@(DateFilterOperatorStyle(column, FilterOperator.Equals))" @onclick="@((args) => ApplyDateFilterByFilterOperator(column, FilterOperator.Equals))" style="display: block;">
<span>@EqualsText</span>
</li>
}
@if (column.GetFilterOperators().Contains(FilterOperator.NotEquals))
{
<li class="@(DateFilterOperatorStyle(column, FilterOperator.NotEquals))" @onclick="@((args) => ApplyDateFilterByFilterOperator(column, FilterOperator.NotEquals))" style="display: block;">
<span>@NotEqualsText</span>
</li>
}
@if (column.GetFilterOperators().Contains(FilterOperator.LessThan))
{
<li class="@(DateFilterOperatorStyle(column, FilterOperator.LessThan))" @onclick="@((args) => ApplyDateFilterByFilterOperator(column, FilterOperator.LessThan))" style="display: block;">
<span>@LessThanText</span>
</li>
}
@if (column.GetFilterOperators().Contains(FilterOperator.LessThanOrEquals))
{
<li class="@(DateFilterOperatorStyle(column, FilterOperator.LessThanOrEquals))" @onclick="@((args) => ApplyDateFilterByFilterOperator(column, FilterOperator.LessThanOrEquals))" style="display: block;">
<span>@LessThanOrEqualsText</span>
</li>
}
@if (column.GetFilterOperators().Contains(FilterOperator.GreaterThan))
{
<li class="@(DateFilterOperatorStyle(column, FilterOperator.GreaterThan))" @onclick="@((args) => ApplyDateFilterByFilterOperator(column, FilterOperator.GreaterThan))" style="display: block;">
<span>@GreaterThanText</span>
</li>
}
@if (column.GetFilterOperators().Contains(FilterOperator.GreaterThanOrEquals))
{
<li class="@(DateFilterOperatorStyle(column, FilterOperator.GreaterThanOrEquals))" @onclick="@((args) => ApplyDateFilterByFilterOperator(column, FilterOperator.GreaterThanOrEquals))" style="display: block;">
<span>@GreaterThanOrEqualsText</span>
</li>
}
@if (column.GetFilterOperators().Contains(FilterOperator.IsEmpty))
{
<li class="@(DateFilterOperatorStyle(column, FilterOperator.IsEmpty))" @onclick="@((args) => ApplyDateFilterByFilterOperator(column, FilterOperator.IsEmpty))" style="display: block;">
<span>@IsEmptyText</span>
</li>
}
@if (column.GetFilterOperators().Contains(FilterOperator.IsNotEmpty))
{
<li class="@(DateFilterOperatorStyle(column, FilterOperator.IsNotEmpty))" @onclick="@((args) => ApplyDateFilterByFilterOperator(column, FilterOperator.IsNotEmpty))" style="display: block;">
<span>@IsNotEmptyText</span>
</li>
}
@if (column.GetFilterOperators().Contains(FilterOperator.IsNull))
{
<li class="@(DateFilterOperatorStyle(column, FilterOperator.IsNull))" @onclick="@((args) => ApplyDateFilterByFilterOperator(column, FilterOperator.IsNull))" style="display: block;">
<span>@IsNullText</span>
</li>
}
@if (column.GetFilterOperators().Contains(FilterOperator.IsNotNull))
{
<li class="@(DateFilterOperatorStyle(column, FilterOperator.IsNotNull))" @onclick="@((args) => ApplyDateFilterByFilterOperator(column, FilterOperator.IsNotNull))" style="display: block;">
<span>@IsNotNullText</span>
</li>
}
</ul>
</div>
</div>
<RadzenDatePicker TValue="@object"
ShowTime="true" ShowTimeOkButton="false" Inline="true" DateFormat="@getFilterDateFormat(column)"
Value="@column.GetFilterValue()" Change="@(args => column.SetFilterValue(args.Value))" />
<RadzenDatePicker TValue="@object" AllowInput=@(AllowFilterDateInput)
ShowTime="@column.ShowTimeForDateTimeFilter()" ShowTimeOkButton="false" Inline="true" DateFormat="@getFilterDateFormat(column)"
Value="@column.GetFilterValue()" Change="@(args => { column.SetFilterValue(args.Value); SaveSettings(); })" />
</div>
<div class="rz-date-filter-buttons">
@@ -215,123 +278,516 @@
else
{
<RadzenDataGridFilterMenu Grid="@this" Column="@column" />
<RadzenDatePicker Disabled=@column.CanSetFilterValue() TValue="@object" Style="width:100%" AllowInput="false" AllowClear="true"
ShowTime="false" ShowTimeOkButton="false" DateFormat="@getFilterDateFormat(column)"
Value="@column.GetFilterValue()" Change="@(args => { if(!args.HasValue) { ClearFilter(column, true); } else {column.SetFilterValue(args.Value); ApplyFilter(column, true);} })" />
<RadzenDatePicker Disabled=@column.CanSetFilterValue() TValue="@object" Style="width:100%" AllowInput=@(AllowFilterDateInput) AllowClear="true"
ShowTime="false" ShowTimeOkButton="false" DateFormat="@getFilterDateFormat(column)"
Value="@column.GetFilterValue()" Change="@(args => { if(!args.HasValue) { InvokeAsync(() => ClearFilter(column, true)); } else {column.SetFilterValue(args.Value); InvokeAsync(() => ApplyFilter(column, true));} })" />
}
}
else if (PropertyAccess.IsNumeric(column.FilterPropertyType))
{
if(FilterMode == FilterMode.SimpleWithMenu)
else if (PropertyAccess.IsNullableEnum(column.FilterPropertyType) || PropertyAccess.IsEnum(column.FilterPropertyType))
{
<RadzenDataGridFilterMenu Grid="@this" Column="@column" />
<RadzenDropDown Style="width:100%" AllowClear="true" AllowFiltering="false" TValue="@object"
Value=@column.GetFilterValue() Multiple="false" Placeholder="@EnumFilterSelectText" TextProperty="Text" ValueProperty="Value"
Data=@((PropertyAccess.IsNullableEnum(column.FilterPropertyType) ? new object[]{ new { Value = -1, Text = EnumNullFilterText}} : Enumerable.Empty<object>()).Concat(EnumExtensions.EnumAsKeyValuePair(Nullable.GetUnderlyingType(column.FilterPropertyType) ?? column.FilterPropertyType)))
Change="@(args => {column.SetFilterValue(args);column.SetFilterOperator(object.Equals(args, -1) ? FilterOperator.IsNull : FilterOperator.Equals);InvokeAsync(() => ApplyFilter(column, true));})" />
}
@(DrawNumericFilter(column))
}
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
{
if(FilterMode == FilterMode.SimpleWithMenu)
else if (PropertyAccess.IsNumeric(column.FilterPropertyType))
{
<RadzenDataGridFilterMenu Grid="@this" Column="@column" />
if (FilterMode == FilterMode.SimpleWithMenu)
{
<RadzenDataGridFilterMenu Grid="@this" Column="@column" />
}
@(DrawNumericFilter(column))
}
<input disabled=@column.CanSetFilterValue() id="@(getFilterInputId(column))" @onchange="@((args) => OnFilter(args, column))" @onkeydown="@((args) => OnFilterKeyPress(args, column))" value="@column.GetFilterValue()" type="text" class="rz-textbox" style="width: 100%;" />
}
</label>
}
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
{
if (FilterMode == FilterMode.SimpleWithMenu)
{
<RadzenDataGridFilterMenu Grid="@this" Column="@column" />
}
<input disabled=@column.CanSetFilterValue() id="@(getFilterInputId(column))" @onchange="@((args) => OnFilter(args, column))" @onkeydown="@((args) => OnFilterKeyPress(args, column))" value="@column.GetFilterValue()" type="text" placeholder="@column.GetFilterPlaceholder()" class="rz-textbox" style="width: 100%;" />
@if (column.GetFilterValue() != null && filters.Any(d => d.Property == column.GetFilterProperty()))
{
<i @onclick="@((args) => ClearFilter(column))" class="rzi rz-cell-filter-clear" style="position:absolute;right:10px;">close</i>
}
}
</label>
}
</div>
</div>
</div>
}
</th>
}
</tr>
}
</thead>
<tbody>
@if (Data != null)
{
@if (Count > 0 || !AllowPaging && LoadData.HasDelegate && Count == 0)
}
</th>
}
</tr>
}
</thead>
<tbody>
@if (Data != null)
{
if (columns.Count > 0)
@if (!ShowEmptyMessage || Count > 0 && (IsVirtualizationAllowed() ? Data.Any() : true) || LoadData.HasDelegate && Data != null && Data.Any())
{
@DrawRows(visibleColumns)
if (columns.Count > 0)
{
@DrawRows(visibleColumns)
}
}
else
{
<tr class=" rz-datatable-emptymessage-row">
<td class="rz-datatable-emptymessage" colspan="@(visibleColumns.Sum(c => c.GetColSpan()) + (Template != null && ShowExpandColumn ? 1 : 0))">
@if (EmptyTemplate != null)
{
@EmptyTemplate
}
else
{
<span style="white-space: normal">@EmptyText</span>
}
</td>
</tr>
}
}
</tbody>
@if (visibleColumns.Where(c => c.FooterTemplate != null).Any())
{
<tfoot class="rz-datatable-tfoot">
@for (var i = 0; i < deepestChildColumnLevel + 1; i++)
{
<tr class="">
@if (i == 0) // Only add the th elements for the first row
{
@foreach (var g in Groups)
{
<td class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
<span class="rz-column-title"></span>
</td>
}
@if (Template != null && ShowExpandColumn && i == 0)
{
<td class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
<span class="rz-column-title"></span>
</td>
}
}
@for (var j = 0; j < visibleColumns.Count; j++)
{
var column = visibleColumns[j];
var cellAttr = FooterCellAttributes(column);
object colspan;
cellAttr.TryGetValue("colspan", out colspan);
if (colspan != null)
{
j = j + (int)Convert.ChangeType(colspan, TypeCode.Int32) - 1;
}
<RadzenDataGridFooterCell RowIndex="@i" Grid="@this" Column="@column"
CssClass="@($"{column.FooterCssClass} {getFrozenColumnClass(column, visibleColumns)} {getCompositeCellCSSClass(column)}".Trim())"
Attributes="@(cellAttr)" />
}
</tr>
}
</tfoot>
}
</table>
@if (IsLoading)
{
<div class="rz-datatable-loading"></div>
<div class="rz-datatable-loading-content">
@if(LoadingTemplate != null)
{
@LoadingTemplate
}
else
{
<tr class=" rz-datatable-emptymessage-row">
<td class="rz-datatable-emptymessage" colspan="@(visibleColumns.Count + (Template != null && ShowExpandColumn ? 1 : 0))">
@if (EmptyTemplate != null)
{
@EmptyTemplate
}
else
{
<span style="white-space: normal">@EmptyText</span>
}
</td>
</tr>
<i class="rzi-circle-o-notch"></i>
}
}
</tbody>
@if (visibleColumns.Where(c => c.FooterTemplate != null).Any())
{
<tfoot class="rz-datatable-tfoot">
@for(var i = 0; i < deepestChildColumnLevel + 1; i++)
{
<tr class="">
@foreach(var g in Groups)
{
<td class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
<span class="rz-column-title"></span>
</td>
}
@if (Template != null && ShowExpandColumn)
{
<td class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
<span class="rz-column-title"></span>
</td>
}
@for (var j = 0; j < visibleColumns.Count; j++)
{
var column = visibleColumns[j];
var cellAttr = FooterCellAttributes(column);
object colspan;
cellAttr.TryGetValue("colspan", out colspan);
if (colspan != null)
{
j = j + (int)Convert.ChangeType(colspan, TypeCode.Int32) - 1;
}
<RadzenDataGridFooterCell RowIndex="@i" Grid="@this" Column="@column"
CssClass="@($"{column.FooterCssClass} {getFrozenColumnClass(column, visibleColumns)} {(column.Columns != null || column.Parent != null ? "rz-composite-cell" : "")}".Trim())"
Attributes="@(cellAttr)" />
}
</tr>
}
</tfoot>
</div>
}
</table>
@if (IsLoading)
{
<div class="rz-datatable-loading"></div>
<div class="rz-datatable-loading-content">
<i class="rzi-circle-o-notch"></i>
</div>
}
</div>
</div>
@if (AllowPaging && (PagerPosition == PagerPosition.Bottom || PagerPosition == PagerPosition.TopAndBottom))
{
<RadzenPager HorizontalAlign="@PagerHorizontalAlign" AlwaysVisible="@PagerAlwaysVisible" @ref="bottomPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@OnPageChanged" PageSizeChanged="@OnPageSizeChanged" PageSizeOptions="@PageSizeOptions" ShowPagingSummary="@ShowPagingSummary" PagingSummaryFormat="@PagingSummaryFormat" PageSizeText="@PageSizeText" />
<RadzenPager HorizontalAlign="@PagerHorizontalAlign" AlwaysVisible="@PagerAlwaysVisible" @ref="bottomPager" Count="@Count" PageSize="@PageSize" PageNumbersCount="@PageNumbersCount" PageChanged="@ChangePage" PageSizeChanged="@OnPageSizeChanged" PageSizeOptions="@PageSizeOptions" ShowPagingSummary="@ShowPagingSummary" PagingSummaryFormat="@PagingSummaryFormat" PageSizeText="@PageSizeText" Density="@Density" FirstPageTitle="@FirstPageTitle" FirstPageAriaLabel="@FirstPageAriaLabel" PrevPageAriaLabel="@PrevPageAriaLabel" PrevPageTitle="@PrevPageTitle" NextPageAriaLabel="@NextPageAriaLabel" NextPageTitle="@NextPageTitle" LastPageAriaLabel="@LastPageAriaLabel" LastPageTitle="@LastPageTitle" PageAriaLabelFormat="@PageAriaLabelFormat" PageTitleFormat="@PageTitleFormat" />
}
</div>
}
@code {
internal RenderFragment RenderCell(RadzenDataGridColumn<TItem> column, TItem Item, IReadOnlyDictionary<string, object> Attributes, Tuple<Radzen.RowRenderEventArgs<TItem>, IReadOnlyDictionary<string, object>> rowArgs, int RowIndex)
{
var cellAttributes = new Dictionary<string, object>(Attributes);
if (CellClick.HasDelegate)
{
cellAttributes.Add("onclick", EventCallback.Factory.Create<MouseEventArgs>(receiver: this, callback: (eventArgs) => OnClick(column, Item, eventArgs)));
}
if (CellDoubleClick.HasDelegate)
{
cellAttributes.Add("ondblclick", EventCallback.Factory.Create<MouseEventArgs>(receiver: this, callback: (eventArgs) => OnDblClick(column, Item, eventArgs)));
}
if (CellContextMenu.HasDelegate)
{
cellAttributes.Add("oncontextmenu", EventCallback.Factory.Create<MouseEventArgs>(receiver: this, callback: (eventArgs) => OnContextMenu(column, Item, eventArgs)));
}
IReadOnlyDictionary<string, object> CellAttributes = new System.Collections.ObjectModel.ReadOnlyDictionary<string, object>(cellAttributes);
return __builder => {
<text>
@if (this.AllowCompositeDataCells ? RowIndex == column.GetLevel() : (column.Parent != null && RowIndex == column.GetLevel() || column.Columns == null))
{
<td rowspan="@(column.GetRowSpan(true))" colspan="@(column.GetColSpan(true))" @attributes="@CellAttributes" style="@GetCellStyle(column, Attributes)" class="@GetCellCssClass(column, Attributes)" @oncontextmenu:preventDefault="@this.CellContextMenu.HasDelegate">
@if (this.Responsive)
{
<span class="rz-column-title">
@if (column.HeaderTemplate != null)
{
@column.HeaderTemplate
}
else
{
@column.GetTitle()
}
</span>
}
@if (this.LoadChildData.HasDelegate && this.ShowExpandColumn && this.allColumns.IndexOf(column) == 0)
{
<span class="rz-cell-toggle">
<a class="@(getExpandIconCssClass(this, Item))" style="@(getExpandIconStyle(this, Item, rowArgs.Item1.Expandable))" href="javascript:void(0)" @onclick="_ => this.ExpandItem(Item)" @onclick:stopPropagation>
<span class="@(this.ExpandedItemStyle(Item))"></span>
</a>
<span class="rz-cell-data" title="@(column.Template == null ? column.GetValue(Item) : "")">
@if (Item != null)
{
@if (this.IsRowInEditMode(Item) && column.EditTemplate != null)
{
@column.EditTemplate(Item)
}
else if (column.Template != null)
{
@column.Template(Item)
}
else
{
@column.GetValue(Item)
}
}
</span>
</span>
}
else
{
<span class="rz-cell-data" title="@(column.Template == null && this.ShowCellDataAsTooltip ? column.GetValue(Item) : "")">
@if (Item != null)
{
@if (this.IsRowInEditMode(Item) && column.EditTemplate != null)
{
@column.EditTemplate(Item)
}
else if (column.Template != null)
{
@column.Template(Item)
}
else
{
@column.GetValue(Item)
}
}
</span>
}
</td>
}
else
{
@foreach (var c in this.childColumns.Where(c => c.GetVisible() && c.Parent == column))
{
@RenderCell(c, Item, Attributes, rowArgs, RowIndex)
}
}
</text>
};
}
string GetCellStyle(RadzenDataGridColumn<TItem> column, IReadOnlyDictionary<string, object> Attributes)
{
var columnStyle = column.GetStyle(true);
if (Attributes != null && Attributes.TryGetValue("style", out var style) == true && !string.IsNullOrEmpty(Convert.ToString(style)))
{
return String.IsNullOrEmpty(columnStyle) ? $"{style}" : $"{columnStyle.TrimEnd(';')};{style}";
}
return columnStyle;
}
string GetCellCssClass(RadzenDataGridColumn<TItem> column, IReadOnlyDictionary<string, object> Attributes)
{
var CssClass = column.CssClass + " " + getFrozenColumnClass(column, columns.Where(c => c.GetVisible()).ToList()) + " " + getCompositeCellCSSClass(column);
if (Attributes != null && Attributes.TryGetValue("class", out var @class) && !string.IsNullOrEmpty(Convert.ToString(@class)))
{
return $"{CssClass} {@class}".Trim();
}
return String.IsNullOrWhiteSpace(CssClass) ? null : CssClass;
}
async Task OnContextMenu(RadzenDataGridColumn<TItem> Column, TItem Item, MouseEventArgs args)
{
#if NET5_0_OR_GREATER
await OnCellContextMenu(new DataGridCellMouseEventArgs<TItem>
{
Data = Item,
AltKey = args.AltKey,
Button = args.Button,
Buttons = args.Buttons,
ClientX = args.ClientX,
ClientY = args.ClientY,
CtrlKey = args.CtrlKey,
Detail = args.Detail,
MetaKey = args.MetaKey,
OffsetX = args.OffsetX,
OffsetY = args.OffsetY,
ScreenX = args.ScreenX,
ScreenY = args.ScreenY,
ShiftKey = args.ShiftKey,
Type = args.Type,
Column = Column
});
#else
await OnCellContextMenu(new DataGridCellMouseEventArgs<TItem>
{
Data = Item,
AltKey = args.AltKey,
Button = args.Button,
Buttons = args.Buttons,
ClientX = args.ClientX,
ClientY = args.ClientY,
CtrlKey = args.CtrlKey,
Detail = args.Detail,
MetaKey = args.MetaKey,
ScreenX = args.ScreenX,
ScreenY = args.ScreenY,
ShiftKey = args.ShiftKey,
Type = args.Type,
Column = Column
});
#endif
}
bool clicking;
async Task OnClick(RadzenDataGridColumn<TItem> Column, TItem Item, MouseEventArgs args)
{
if (clicking)
{
return;
}
try
{
clicking = true;
#if NET5_0_OR_GREATER
await OnCellClick(new DataGridCellMouseEventArgs<TItem>
{
Data = Item,
AltKey = args.AltKey,
Button = args.Button,
Buttons = args.Buttons,
ClientX = args.ClientX,
ClientY = args.ClientY,
CtrlKey = args.CtrlKey,
Detail = args.Detail,
MetaKey = args.MetaKey,
OffsetX = args.OffsetX,
OffsetY = args.OffsetY,
ScreenX = args.ScreenX,
ScreenY = args.ScreenY,
ShiftKey = args.ShiftKey,
Type = args.Type,
Column = Column
});
#else
await OnCellClick(new DataGridCellMouseEventArgs<TItem>
{
Data = Item,
AltKey = args.AltKey,
Button = args.Button,
Buttons = args.Buttons,
ClientX = args.ClientX,
ClientY = args.ClientY,
CtrlKey = args.CtrlKey,
Detail = args.Detail,
MetaKey = args.MetaKey,
ScreenX = args.ScreenX,
ScreenY = args.ScreenY,
ShiftKey = args.ShiftKey,
Type = args.Type,
Column = Column
});
#endif
#if NET5_0_OR_GREATER
await OnRowClick(new DataGridRowMouseEventArgs<TItem>
{
Data = Item,
AltKey = args.AltKey,
Button = args.Button,
Buttons = args.Buttons,
ClientX = args.ClientX,
ClientY = args.ClientY,
CtrlKey = args.CtrlKey,
Detail = args.Detail,
MetaKey = args.MetaKey,
OffsetX = args.OffsetX,
OffsetY = args.OffsetY,
ScreenX = args.ScreenX,
ScreenY = args.ScreenY,
ShiftKey = args.ShiftKey,
Type = args.Type
});
#else
await OnRowClick(new DataGridRowMouseEventArgs<TItem>
{
Data = Item,
AltKey = args.AltKey,
Button = args.Button,
Buttons = args.Buttons,
ClientX = args.ClientX,
ClientY = args.ClientY,
CtrlKey = args.CtrlKey,
Detail = args.Detail,
MetaKey = args.MetaKey,
ScreenX = args.ScreenX,
ScreenY = args.ScreenY,
ShiftKey = args.ShiftKey,
Type = args.Type
});
#endif
}
finally
{
clicking = false;
}
}
async Task OnDblClick(RadzenDataGridColumn<TItem> Column, TItem Item, MouseEventArgs args)
{
#if NET5_0_OR_GREATER
await OnCellDblClick(new DataGridCellMouseEventArgs<TItem>
{
Data = Item,
AltKey = args.AltKey,
Button = args.Button,
Buttons = args.Buttons,
ClientX = args.ClientX,
ClientY = args.ClientY,
CtrlKey = args.CtrlKey,
Detail = args.Detail,
MetaKey = args.MetaKey,
OffsetX = args.OffsetX,
OffsetY = args.OffsetY,
ScreenX = args.ScreenX,
ScreenY = args.ScreenY,
ShiftKey = args.ShiftKey,
Type = args.Type,
Column = Column
});
#else
await OnCellDblClick(new DataGridCellMouseEventArgs<TItem>
{
Data = Item,
AltKey = args.AltKey,
Button = args.Button,
Buttons = args.Buttons,
ClientX = args.ClientX,
ClientY = args.ClientY,
CtrlKey = args.CtrlKey,
Detail = args.Detail,
MetaKey = args.MetaKey,
ScreenX = args.ScreenX,
ScreenY = args.ScreenY,
ShiftKey = args.ShiftKey,
Type = args.Type,
Column = Column
});
#endif
#if NET5_0_OR_GREATER
await OnRowDblClick(new DataGridRowMouseEventArgs<TItem>
{
Data = Item,
AltKey = args.AltKey,
Button = args.Button,
Buttons = args.Buttons,
ClientX = args.ClientX,
ClientY = args.ClientY,
CtrlKey = args.CtrlKey,
Detail = args.Detail,
MetaKey = args.MetaKey,
OffsetX = args.OffsetX,
OffsetY = args.OffsetY,
ScreenX = args.ScreenX,
ScreenY = args.ScreenY,
ShiftKey = args.ShiftKey,
Type = args.Type
});
#else
await OnRowDblClick(new DataGridRowMouseEventArgs<TItem>
{
Data = Item,
AltKey = args.AltKey,
Button = args.Button,
Buttons = args.Buttons,
ClientX = args.ClientX,
ClientY = args.ClientY,
CtrlKey = args.CtrlKey,
Detail = args.Detail,
MetaKey = args.MetaKey,
ScreenX = args.ScreenX,
ScreenY = args.ScreenY,
ShiftKey = args.ShiftKey,
Type = args.Type
});
#endif
}
static string getExpandIconStyle(RadzenDataGrid<TItem> Grid, TItem Item, bool expandable)
{
var rules = new List<string>();
if (!expandable)
{
rules.Add("visibility:hidden");
}
var child = Grid.childData.Any() ? Grid.childData.Where(c => c.Value?.Data?.Contains(Item) == true).FirstOrDefault() :
default(KeyValuePair<TItem, DataGridChildData<TItem>>);
var level = !object.Equals(child, default(KeyValuePair<TItem, DataGridChildData<TItem>>)) ? child.Value.Level : 0;
if (level > 0)
{
rules.Add($"margin-left: {level}rem");
}
return string.Join(';', rules);
}
static string getExpandIconCssClass(RadzenDataGrid<TItem> Grid, TItem Item)
{
var child = Grid.childData.Any() ? Grid.childData.Where(c => c.Value?.Data?.Contains(Item) == true).FirstOrDefault() :
default(KeyValuePair<TItem, DataGridChildData<TItem>>);
var level = !object.Equals(child, default(KeyValuePair<TItem, DataGridChildData<TItem>>)) ? child.Value.Level : 0;
return $"rz-cell-toggle-level{level}";
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,239 +0,0 @@
@typeparam TItem
@using Microsoft.AspNetCore.Components.Forms
<CascadingValue Value=@EditContext>
<CascadingValue Value=Row>
@if (Grid.AllowCompositeDataCells ? RowIndex == Column.GetLevel() : (Column.Parent != null && RowIndex == Column.GetLevel() || Column.Columns == null))
{
<td rowspan="@(Column.GetRowSpan(true))" colspan="@(Column.GetColSpan(true))" @attributes="@Attributes" style="@GetStyle()" class="@GetCssClass()" @onclick="@OnClick" @ondblclick="@OnDblClick" @oncontextmenu="@OnContextMenu" @oncontextmenu:preventDefault="@Grid.CellContextMenu.HasDelegate">
<CascadingValue Value=this>
@ChildContent
</CascadingValue>
</td>
}
else
{
@foreach(var column in Grid.childColumns.Where(c => c.GetVisible() && c.Parent == Column))
{
<RadzenDataGridCell Row=@Row EditContext=EditContext RowIndex="@RowIndex" Grid="@Grid" Column="@column" Item="@Item"
Style="@column.GetStyle(true)" CssClass="@(column.CssClass + " " + Grid.getFrozenColumnClass(column, Grid.ColumnsCollection) + " " + (column.Columns != null || column.Parent != null ? "rz-composite-cell" : ""))" Attributes="@(Grid.CellAttributes(Item, column))">
@if (Grid.Responsive)
{
<span class="rz-column-title">
@if (column.HeaderTemplate != null)
{
@column.HeaderTemplate
}
else
{
@column.Title
}
</span>
}
<span class="rz-cell-data" title="@(column.Template == null ? column.GetValue(Item) : "")">
@if (Item != null)
{
@if (Grid.IsRowInEditMode(Item) && column.EditTemplate != null)
{
@column.EditTemplate(Item)
}
else if (column.Template != null)
{
@column.Template(Item)
}
else
{
@column.GetValue(Item)
}
}
</span>
</RadzenDataGridCell>
}
}
</CascadingValue>
</CascadingValue>
@code {
[Parameter(CaptureUnmatchedValues = true)]
public IReadOnlyDictionary<string, object> Attributes { get; set; }
[Parameter]
public int RowIndex { get; set; }
[Parameter]
public RadzenDataGridRow<TItem> Row { get; set; }
[Parameter]
public EditContext EditContext { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter]
public string CssClass { get; set; }
[Parameter]
public string Style { get; set; }
[Parameter]
public TItem Item { get; set; }
[Parameter]
public RadzenDataGridColumn<TItem> Column { get; set; }
[Parameter]
public RadzenDataGrid<TItem> Grid { get; set; }
async Task OnContextMenu(MouseEventArgs args)
{
if (Grid != null)
{
#if NET5
await Grid.OnCellContextMenu(new DataGridCellMouseEventArgs<TItem>
{
Data = Item,
AltKey = args.AltKey,
Button = args.Button,
Buttons = args.Buttons,
ClientX = args.ClientX,
ClientY = args.ClientY,
CtrlKey = args.CtrlKey,
Detail = args.Detail,
MetaKey = args.MetaKey,
OffsetX = args.OffsetX,
OffsetY = args.OffsetY,
ScreenX = args.ScreenX,
ScreenY = args.ScreenY,
ShiftKey = args.ShiftKey,
Type = args.Type,
Column = Column
});
#else
await Grid.OnCellContextMenu(new DataGridCellMouseEventArgs<TItem>
{
Data = Item,
AltKey = args.AltKey,
Button = args.Button,
Buttons = args.Buttons,
ClientX = args.ClientX,
ClientY = args.ClientY,
CtrlKey = args.CtrlKey,
Detail = args.Detail,
MetaKey = args.MetaKey,
ScreenX = args.ScreenX,
ScreenY = args.ScreenY,
ShiftKey = args.ShiftKey,
Type = args.Type,
Column = Column
});
#endif
}
}
async Task OnClick(MouseEventArgs args)
{
if (Grid != null)
{
#if NET5
await Grid.OnRowClick(new DataGridRowMouseEventArgs<TItem>
{
Data = Item,
AltKey = args.AltKey,
Button = args.Button,
Buttons = args.Buttons,
ClientX = args.ClientX,
ClientY = args.ClientY,
CtrlKey = args.CtrlKey,
Detail = args.Detail,
MetaKey = args.MetaKey,
OffsetX = args.OffsetX,
OffsetY = args.OffsetY,
ScreenX = args.ScreenX,
ScreenY = args.ScreenY,
ShiftKey = args.ShiftKey,
Type = args.Type
});
#else
await Grid.OnRowClick(new DataGridRowMouseEventArgs<TItem>
{
Data = Item,
AltKey = args.AltKey,
Button = args.Button,
Buttons = args.Buttons,
ClientX = args.ClientX,
ClientY = args.ClientY,
CtrlKey = args.CtrlKey,
Detail = args.Detail,
MetaKey = args.MetaKey,
ScreenX = args.ScreenX,
ScreenY = args.ScreenY,
ShiftKey = args.ShiftKey,
Type = args.Type
});
#endif
}
}
async Task OnDblClick(MouseEventArgs args)
{
if (Grid != null)
{
#if NET5
await Grid.OnRowDblClick(new DataGridRowMouseEventArgs<TItem>
{
Data = Item,
AltKey = args.AltKey,
Button = args.Button,
Buttons = args.Buttons,
ClientX = args.ClientX,
ClientY = args.ClientY,
CtrlKey = args.CtrlKey,
Detail = args.Detail,
MetaKey = args.MetaKey,
OffsetX = args.OffsetX,
OffsetY = args.OffsetY,
ScreenX = args.ScreenX,
ScreenY = args.ScreenY,
ShiftKey = args.ShiftKey,
Type = args.Type
});
#else
await Grid.OnRowDblClick(new DataGridRowMouseEventArgs<TItem>
{
Data = Item,
AltKey = args.AltKey,
Button = args.Button,
Buttons = args.Buttons,
ClientX = args.ClientX,
ClientY = args.ClientY,
CtrlKey = args.CtrlKey,
Detail = args.Detail,
MetaKey = args.MetaKey,
ScreenX = args.ScreenX,
ScreenY = args.ScreenY,
ShiftKey = args.ShiftKey,
Type = args.Type
});
#endif
}
}
string GetCssClass()
{
if (Attributes != null && Attributes.TryGetValue("class", out var @class) && !string.IsNullOrEmpty(Convert.ToString(@class)))
{
return $"{CssClass} {@class}".Trim();
}
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;
}
}

View File

@@ -49,6 +49,18 @@ namespace Radzen.Blazor
}
}
/// <summary>
/// Gets the child columns.
/// </summary>
/// <value>The child columns.</value>
public IList<RadzenDataGridColumn<TItem>> ColumnsCollection
{
get
{
return Grid.childColumns.Where(c => c.Parent == this).ToList();
}
}
internal int GetLevel()
{
int i = 0;
@@ -91,6 +103,16 @@ namespace Radzen.Blazor
return Columns == null && Parent == null ? Grid.deepestChildColumnLevel + 1 : 1;
}
Type _propertyType;
internal Type PropertyType => _propertyType;
/// <summary>
/// Gets or sets the unique identifier.
/// </summary>
/// <value>The unique identifier.</value>
[Parameter]
public string UniqueID { get; set; }
/// <summary>
/// Called when initialized.
/// </summary>
@@ -100,14 +122,16 @@ namespace Radzen.Blazor
{
Grid.AddColumn(this);
if (!string.IsNullOrEmpty(FilterProperty) || Type == null)
{
var property = GetFilterProperty();
var property = GetFilterProperty();
if (!string.IsNullOrEmpty(property))
{
_filterPropertyType = PropertyAccess.GetPropertyType(typeof(TItem), property);
}
if (!string.IsNullOrEmpty(property))
{
_propertyType = PropertyAccess.GetPropertyType(typeof(TItem), property);
}
if (!string.IsNullOrEmpty(property) && Type == null)
{
_filterPropertyType = _propertyType;
}
if (_filterPropertyType == null)
@@ -135,7 +159,10 @@ namespace Radzen.Blazor
[Parameter]
public int? OrderIndex { get; set; }
internal int? GetOrderIndex()
/// <summary>
/// Gets the order index.
/// </summary>
public int? GetOrderIndex()
{
return orderIndex ?? OrderIndex;
}
@@ -152,12 +179,32 @@ namespace Radzen.Blazor
[Parameter]
public SortOrder? SortOrder { get; set; }
bool visible = true;
/// <summary>
/// Gets or sets a value indicating whether this <see cref="RadzenDataGridColumn{TItem}"/> is visible.
/// </summary>
/// <value><c>true</c> if visible; otherwise, <c>false</c>.</value>
[Parameter]
public bool Visible { get; set; } = true;
public bool Visible
{
get
{
return visible;
}
set
{
if (visible != value)
{
visible = value;
_visible = visible;
if (Grid != null)
{
Grid.UpdatePickableColumn(this, visible);
InvokeAsync(Grid.ChangeState);
}
}
}
}
bool? _visible;
@@ -173,6 +220,11 @@ namespace Radzen.Blazor
internal void SetVisible(bool? value)
{
_visible = value;
if (Grid != null && Pickable)
{
Grid.UpdatePickableColumn(this, _visible == true);
}
}
/// <summary>
@@ -182,6 +234,39 @@ namespace Radzen.Blazor
[Parameter]
public string Title { get; set; }
string _title;
/// <summary>
/// Gets the column title.
/// </summary>
/// <returns>System.String.</returns>
public string GetTitle()
{
return _title ?? Title;
}
/// <summary>
/// Sets the column title.
/// </summary>
public void SetTitle(string value)
{
_title = value;
}
/// <summary>
/// Gets or sets the title in column picker.
/// Value of Title is used when ColumnPickerTitle is not set
/// </summary>
/// <value>The column picker title.</value>
[Parameter]
public string ColumnPickerTitle
{
get => _columnPickerTitle ?? Title;
set => _columnPickerTitle = value;
}
string _columnPickerTitle;
/// <summary>
/// Gets or sets the property name.
/// </summary>
@@ -217,6 +302,22 @@ namespace Radzen.Blazor
[Parameter]
public object FilterValue { get; set; }
/// <summary>
/// Gets or sets the filter placeholder.
/// </summary>
/// <value>The filter placeholder value.</value>
[Parameter]
public string FilterPlaceholder { get; set; }
/// <summary>
/// Gets the filter placeholder.
/// </summary>
/// <returns>System.String.</returns>
public string GetFilterPlaceholder()
{
return FilterPlaceholder ?? string.Empty;
}
/// <summary>
/// Gets or sets the second filter value.
/// </summary>
@@ -290,10 +391,17 @@ namespace Radzen.Blazor
/// <summary>
/// Gets or sets a value indicating whether this <see cref="RadzenDataGridColumn{TItem}"/> is frozen.
/// </summary>
/// <value><c>true</c> if frozen; otherwise, <c>false</c>.</value>
/// <value><c>true</c> if frozen will disable horizontal scroll for the column; otherwise, <c>false</c>.</value>
[Parameter]
public bool Frozen { get; set; }
/// <summary>
/// Gets or sets the frozen position this <see cref="RadzenDataGridColumn{TItem}"/>
/// </summary>
/// <value><see cref="FrozenColumnPosition.Left"/> or <see cref="FrozenColumnPosition.Right"/>.</value>
[Parameter]
public FrozenColumnPosition FrozenPosition { get; set; } = FrozenColumnPosition.Left;
/// <summary>
/// Gets or sets a value indicating whether this <see cref="RadzenDataGridColumn{TItem}"/> is resizable.
/// </summary>
@@ -371,6 +479,20 @@ namespace Radzen.Blazor
[Parameter]
public RenderFragment<RadzenDataGridColumn<TItem>> FilterTemplate { get; set; }
/// <summary>
/// Gets or sets the filter value template.
/// </summary>
/// <value>The filter value template.</value>
[Parameter]
public RenderFragment<RadzenDataGridColumn<TItem>> FilterValueTemplate { get; set; }
/// <summary>
/// Gets or sets the second filter value template.
/// </summary>
/// <value>The second filter value template.</value>
[Parameter]
public RenderFragment<RadzenDataGridColumn<TItem>> SecondFilterValueTemplate { get; set; }
/// <summary>
/// Gets or sets the logical filter operator.
/// </summary>
@@ -392,11 +514,20 @@ namespace Radzen.Blazor
/// </summary>
/// <param name="item">The item.</param>
/// <returns>System.Object.</returns>
public object GetValue(TItem item)
public virtual object GetValue(TItem item)
{
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, Grid?.Culture ?? CultureInfo.CurrentCulture) : Convert.ToString(value, Grid?.Culture ?? CultureInfo.CurrentCulture);
if ((PropertyAccess.IsEnum(FilterPropertyType) || PropertyAccess.IsNullableEnum(FilterPropertyType)) && value != null)
{
var enumValue = value as Enum;
if (enumValue != null)
{
value = EnumExtensions.GetDisplayDescription(enumValue);
}
}
return !string.IsNullOrEmpty(FormatString) ? string.Format(Grid?.Culture ?? CultureInfo.CurrentCulture, FormatString, value) : Convert.ToString(value, Grid?.Culture ?? CultureInfo.CurrentCulture);
}
internal object GetHeader()
@@ -405,9 +536,9 @@ namespace Radzen.Blazor
{
return HeaderTemplate;
}
else if (!string.IsNullOrEmpty(Title))
else if (!string.IsNullOrEmpty(GetTitle()))
{
return Title;
return GetTitle();
}
else
{
@@ -421,20 +552,15 @@ namespace Radzen.Blazor
/// <param name="forCell">if set to <c>true</c> [for cell].</param>
/// <param name="isHeaderOrFooterCell">if set to <c>true</c> [is header or footer cell].</param>
/// <returns>System.String.</returns>
public string GetStyle(bool forCell = false, bool isHeaderOrFooterCell = false)
public virtual string GetStyle(bool forCell = false, bool isHeaderOrFooterCell = false)
{
var style = new List<string>();
var width = GetWidth();
if (width != null)
var width = GetWidthOrGridSetting()?.Trim();
if (!string.IsNullOrEmpty(width))
{
style.Add($"width:{width}");
}
else if (Grid != null && Grid.ColumnWidth != null)
{
style.Add($"width:{Grid.ColumnWidth}");
}
if (forCell && TextAlign != TextAlign.Left)
{
@@ -443,23 +569,10 @@ namespace Radzen.Blazor
if (forCell && IsFrozen())
{
var visibleColumns = Grid.ColumnsCollection.Where(c => c.GetVisible()).ToList();
var left = visibleColumns
.TakeWhile((c, i) => visibleColumns.IndexOf(this) > i && c.IsFrozen())
.Sum(c => {
var w = !string.IsNullOrEmpty(c.GetWidth()) ? c.GetWidth() : Grid.ColumnWidth;
var cw = 200;
if (!string.IsNullOrEmpty(w) && w.Contains("px"))
{
int.TryParse(w.Replace("px", ""), out cw);
}
return cw;
});
style.Add($"left:{left}px");
style.Add(GetStackedStyleForFrozen());
}
if ((isHeaderOrFooterCell && IsFrozen() || isHeaderOrFooterCell && !IsFrozen() || !isHeaderOrFooterCell && IsFrozen()) && Grid.ColumnsCollection.Where(c => c.GetVisible() && c.IsFrozen()).Any())
if (!isHeaderOrFooterCell && IsFrozen() || (isHeaderOrFooterCell && Grid.ColumnsCollection.Where(c => c.GetVisible() && c.IsFrozen()).Any()))
{
style.Add($"z-index:{(isHeaderOrFooterCell && IsFrozen() ? 2 : 1)}");
}
@@ -472,6 +585,59 @@ namespace Radzen.Blazor
return string.Join(";", style);
}
private string GetStackedStyleForFrozen()
{
var visibleFrozenColumns = Grid.ColumnsCollection.Where(c => c.GetVisible() && c.IsFrozen() && c.FrozenPosition == FrozenPosition).ToList();
if (FrozenPosition == FrozenColumnPosition.Left)
{
var stackColumns = visibleFrozenColumns.Where((c, i) => visibleFrozenColumns.IndexOf(this) > i);
return GetStackedStyleForFrozen(stackColumns, "left");
}
else
{
var stackColumns = visibleFrozenColumns.Where((c, i) => visibleFrozenColumns.IndexOf(this) < i);
return GetStackedStyleForFrozen(stackColumns, "right");
}
}
private static string GetStackedStyleForFrozen(IEnumerable<RadzenDataGridColumn<TItem>> stackColumns, string position)
{
if (!stackColumns.Any())
{
return $"{position}:0";
}
var widths = new List<string>();
foreach (var column in stackColumns)
{
var w = column.GetWidthOrGridSetting()?.Trim();
if (string.IsNullOrEmpty(w))
{
widths.Add("200px");
continue;
}
if (w.StartsWith("calc(") && w.EndsWith(")"))
{
var calcExpression = w.Remove(w.Length - 1).Substring("calc(".Length);
widths.Add(calcExpression);
continue;
}
widths.Add(w);
}
if (widths.Count == 1)
{
return $"{position}:{widths.First()}";
}
return $"{position}:calc({string.Join(" + ", widths)})";
}
internal bool IsFrozen()
{
return Frozen && Parent == null && Columns == null;
@@ -503,6 +669,37 @@ namespace Radzen.Blazor
}
internal void SetSortOrder(SortOrder? order)
{
var descriptor = Grid.sorts.Where(d => d.Property == GetSortProperty()).FirstOrDefault();
if (descriptor == null)
{
descriptor = new SortDescriptor() { Property = GetSortProperty() };
}
if (order.HasValue)
{
SetSortOrderInternal(order.Value);
descriptor.SortOrder = order.Value;
}
else
{
SetSortOrderInternal(null);
if (Grid.sorts.Where(d => d.Property == GetSortProperty()).Any())
{
Grid.sorts.Remove(descriptor);
}
descriptor = null;
}
if (descriptor != null && !Grid.sorts.Where(d => d.Property == GetSortProperty()).Any())
{
Grid.sorts.Add(descriptor);
}
sortOrder = new SortOrder?[] { order };
}
internal void SetSortOrderInternal(SortOrder? order)
{
sortOrder = new SortOrder?[] { order };
}
@@ -546,7 +743,10 @@ namespace Radzen.Blazor
Type _filterPropertyType;
internal Type FilterPropertyType
/// <summary>
/// Gets the filter property type.
/// </summary>
public Type FilterPropertyType
{
get
{
@@ -593,9 +793,32 @@ namespace Radzen.Blazor
}
}
if (parameters.DidParameterChange(nameof(Pickable), Pickable))
{
var newPickable = parameters.GetValueOrDefault<bool>(nameof(Pickable));
Pickable = newPickable;
if (Grid != null)
{
Grid.UpdatePickableColumns();
await Grid.ChangeState();
}
}
if (parameters.DidParameterChange(nameof(SortOrder), SortOrder))
{
sortOrder = new SortOrder?[] { parameters.GetValueOrDefault<SortOrder?>(nameof(SortOrder)) };
if (Grid != null)
{
var descriptor = Grid.sorts.Where(d => d.Property == GetSortProperty()).FirstOrDefault();
if (descriptor == null)
{
Grid.sorts.Add(new SortDescriptor() { Property = GetSortProperty(), SortOrder = sortOrder.FirstOrDefault() });
Grid._view = null;
}
}
}
if (parameters.DidParameterChange(nameof(FilterValue), FilterValue))
@@ -605,9 +828,36 @@ namespace Radzen.Blazor
if (FilterTemplate != null)
{
FilterValue = filterValue;
Grid.SaveSettings();
if (Grid.IsVirtualizationAllowed())
{
#if NET5
#if NET5_0_OR_GREATER
if (Grid.virtualize != null)
{
await Grid.virtualize.RefreshDataAsync();
}
#endif
}
else
{
await Grid.Reload();
}
return;
}
}
if (parameters.DidParameterChange(nameof(SecondFilterValue), SecondFilterValue))
{
secondFilterValue = parameters.GetValueOrDefault<object>(nameof(SecondFilterValue));
if (FilterTemplate != null)
{
SecondFilterValue = secondFilterValue;
Grid.SaveSettings();
if (Grid.IsVirtualizationAllowed())
{
#if NET5_0_OR_GREATER
if (Grid.virtualize != null)
{
await Grid.virtualize.RefreshDataAsync();
@@ -646,37 +896,58 @@ namespace Radzen.Blazor
await base.SetParametersAsync(parameters);
}
internal SortOrder? GetSortOrder()
/// <summary>
/// Get column sort order.
/// </summary>
public SortOrder? GetSortOrder()
{
return sortOrder.Any() ? sortOrder.FirstOrDefault() : SortOrder;
}
internal object GetFilterValue()
/// <summary>
/// Get column filter value.
/// </summary>
public object GetFilterValue()
{
return filterValue ?? FilterValue;
}
internal FilterOperator GetFilterOperator()
/// <summary>
/// Get column filter operator.
/// </summary>
public FilterOperator GetFilterOperator()
{
return filterOperator ?? FilterOperator;
}
internal object GetSecondFilterValue()
/// <summary>
/// Get column second filter value.
/// </summary>
public object GetSecondFilterValue()
{
return secondFilterValue ?? SecondFilterValue;
}
internal FilterOperator GetSecondFilterOperator()
/// <summary>
/// Get column second filter operator.
/// </summary>
public FilterOperator GetSecondFilterOperator()
{
return secondFilterOperator ?? SecondFilterOperator;
}
internal LogicalFilterOperator GetLogicalFilterOperator()
/// <summary>
/// Get column logical filter operator.
/// </summary>
public LogicalFilterOperator GetLogicalFilterOperator()
{
return logicalFilterOperator ?? LogicalFilterOperator;
}
internal void SetFilterValue(object value, bool isFirst = true)
/// <summary>
/// Set column filter value.
/// </summary>
public void SetFilterValue(object value, bool isFirst = true)
{
if ((FilterPropertyType == typeof(DateTimeOffset) || FilterPropertyType == typeof(DateTimeOffset?)) && value != null && value is DateTime?)
{
@@ -694,12 +965,30 @@ namespace Radzen.Blazor
}
}
internal bool CanSetFilterValue()
{
return GetFilterOperator() == FilterOperator.IsNull || GetFilterOperator() == FilterOperator.IsNotNull;
/// <summary>
/// Set column filter value and reload grid.
/// </summary>
/// <param name="value">Filter value.</param>
/// <param name="isFirst"><c>true</c> if FilterValue; <c>false</c> for SecondFilterValue</param>
public async Task SetFilterValueAsync(object value, bool isFirst = true)
{
SetFilterValue(value, isFirst);
Grid.SaveSettings();
await Grid.FirstPage(true);
}
internal void ClearFilters()
internal bool CanSetFilterValue()
{
return GetFilterOperator() == FilterOperator.IsNull
|| GetFilterOperator() == FilterOperator.IsNotNull
|| GetFilterOperator() == FilterOperator.IsEmpty
|| GetFilterOperator() == FilterOperator.IsNotEmpty;
}
/// <summary>
/// Sets to default column filter values and operators.
/// </summary>
public void ClearFilters()
{
SetFilterValue(null);
SetFilterValue(null, false);
@@ -708,7 +997,11 @@ namespace Radzen.Blazor
FilterValue = null;
SecondFilterValue = null;
FilterOperator = default(FilterOperator);
FilterOperator = FilterOperator == FilterOperator.Custom
? FilterOperator.Custom
: typeof(System.Collections.IEnumerable).IsAssignableFrom(FilterPropertyType)
? FilterOperator.Contains
: default(FilterOperator);
SecondFilterOperator = default(FilterOperator);
LogicalFilterOperator = default(LogicalFilterOperator);
}
@@ -727,17 +1020,36 @@ namespace Radzen.Blazor
[Parameter]
public FilterOperator SecondFilterOperator { get; set; }
internal void SetFilterOperator(FilterOperator? value)
/// <summary>
/// Set column filter operator.
/// </summary>
public void SetFilterOperator(FilterOperator? value)
{
if (value == FilterOperator.IsEmpty || value == FilterOperator.IsNotEmpty || value == FilterOperator.IsNull || value == FilterOperator.IsNotNull)
{
filterValue = value == FilterOperator.IsEmpty || value == FilterOperator.IsNotEmpty ? string.Empty : null;
}
filterOperator = value;
}
internal void SetSecondFilterOperator(FilterOperator? value)
/// <summary>
/// Set column second filter operator.
/// </summary>
public void SetSecondFilterOperator(FilterOperator? value)
{
if (value == FilterOperator.IsEmpty || value == FilterOperator.IsNotEmpty || value == FilterOperator.IsNull || value == FilterOperator.IsNotNull)
{
secondFilterValue = value == FilterOperator.IsEmpty || value == FilterOperator.IsNotEmpty ? string.Empty : null;
}
secondFilterOperator = value;
}
internal void SetLogicalFilterOperator(LogicalFilterOperator value)
/// <summary>
/// Set column second logical operator.
/// </summary>
public void SetLogicalFilterOperator(LogicalFilterOperator value)
{
LogicalFilterOperator = value;
}
@@ -748,38 +1060,75 @@ namespace Radzen.Blazor
/// </summary>
public async Task CloseFilter()
{
if (Grid.FilterPopupRenderMode == PopupRenderMode.OnDemand && headerCell != null)
{
await headerCell.CloseFilter();
}
await Grid.GetJSRuntime().InvokeVoidAsync("Radzen.closePopup", $"{Grid.PopupID}{GetFilterProperty()}");
}
string runtimeWidth;
internal void SetWidth(string value)
/// <summary>
/// Set column width.
/// </summary>
public void SetWidth(string value)
{
runtimeWidth = value;
if (IsFrozen())
{
InvokeAsync(() => Grid.ChangeState());
}
}
internal string GetWidth()
/// <summary>
/// Get column width.
/// </summary>
public string GetWidth()
{
return !string.IsNullOrEmpty(runtimeWidth) ? runtimeWidth : Width;
}
internal IEnumerable<FilterOperator> GetFilterOperators()
/// <summary>
/// Get column width if it's set, otherwise get a column width set on the grid.
/// </summary>
internal string GetWidthOrGridSetting()
{
var internalWidth = GetWidth();
return !string.IsNullOrWhiteSpace(internalWidth) ? internalWidth : Grid?.ColumnWidth;
}
/// <summary>
/// Get possible column filter operators.
/// </summary>
public virtual IEnumerable<FilterOperator> GetFilterOperators()
{
if (PropertyAccess.IsEnum(FilterPropertyType))
return new FilterOperator[] { FilterOperator.Equals, FilterOperator.NotEquals };
if (PropertyAccess.IsNullableEnum(FilterPropertyType))
return new FilterOperator[] { FilterOperator.Equals, FilterOperator.NotEquals, FilterOperator.IsNull, FilterOperator.IsNotNull };
return Enum.GetValues(typeof(FilterOperator)).Cast<FilterOperator>().Where(o => {
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 || o == FilterOperator.IsNull || o == FilterOperator.IsNotNull
: !isStringOperator;
return Enum.GetValues(typeof(FilterOperator)).Cast<FilterOperator>().Where(o =>
{
var isStringOperator = o == FilterOperator.Contains || o == FilterOperator.DoesNotContain
|| o == FilterOperator.StartsWith || o == FilterOperator.EndsWith || o == FilterOperator.IsEmpty || o == FilterOperator.IsNotEmpty;
if ((FilterPropertyType == typeof(string) || !QueryableExtension.IsEnumerable(FilterPropertyType)) &&
(o == FilterOperator.In || o == FilterOperator.NotIn)) return false;
return FilterPropertyType == typeof(string) || QueryableExtension.IsEnumerable(FilterPropertyType) ? isStringOperator
|| o == FilterOperator.Equals || o == FilterOperator.NotEquals
|| o == FilterOperator.IsNull || o == FilterOperator.IsNotNull
: !isStringOperator;
});
}
internal string GetFilterOperatorText(FilterOperator filterOperator)
/// <summary>
/// Get filter operator text
/// </summary>
public string GetFilterOperatorText(FilterOperator filterOperator)
{
switch (filterOperator)
{
@@ -793,7 +1142,7 @@ namespace Radzen.Blazor
return Grid?.EqualsText;
case FilterOperator.GreaterThan:
return Grid?.GreaterThanText;
case FilterOperator. GreaterThanOrEquals:
case FilterOperator.GreaterThanOrEquals:
return Grid?.GreaterThanOrEqualsText;
case FilterOperator.LessThan:
return Grid?.LessThanText;
@@ -805,8 +1154,12 @@ namespace Radzen.Blazor
return Grid?.NotEqualsText;
case FilterOperator.IsNull:
return Grid?.IsNullText;
case FilterOperator.IsEmpty:
return Grid?.IsEmptyText;
case FilterOperator.IsNotNull:
return Grid?.IsNotNullText;
case FilterOperator.IsNotEmpty:
return Grid?.IsNotEmptyText;
default:
return $"{filterOperator}";
}
@@ -841,11 +1194,52 @@ namespace Radzen.Blazor
return "∅";
case FilterOperator.IsNotNull:
return "!∅";
case FilterOperator.IsEmpty:
return "= ''";
case FilterOperator.IsNotEmpty:
return "≠ ''";
default:
return $"{filterOperator}";
}
}
/// <summary>
/// Gets value indicating if the user can specify time in DateTime column filter.
/// </summary>
public virtual bool ShowTimeForDateTimeFilter()
{
return true;
}
/// <summary>
/// Gets value indicating if up and down buttons are displayed in numeric column filter.
/// </summary>
public virtual bool ShowUpDownForNumericFilter()
{
return true;
}
/// <summary>
/// Gets an OData expression to filter by this column.
/// </summary>
/// <param name="second">Whether to use <see cref="SecondFilterValue"/> instead of <see cref="FilterValue"/></param>
/// <returns>An OData expression to filter by this column.</returns>
public string GetColumnODataFilter(bool second = false)
{
return GetColumnODataFilter(second ? GetSecondFilterValue() : GetFilterValue(), second ? GetSecondFilterOperator() : GetFilterOperator());
}
/// <summary>
/// Gets an OData expression to filter by this column.
/// </summary>
/// <param name="filterValue">The specific value to filter by</param>
/// <param name="filterOperator">The operator used to compare to <paramref name="filterValue"/></param>
/// <returns>An OData expression to filter by this column.</returns>
protected virtual string GetColumnODataFilter(object filterValue, FilterOperator filterOperator)
{
return QueryableExtension.GetColumnODataFilter(this, filterValue, filterOperator);
}
/// <summary>
/// Disposes this instance.
/// </summary>
@@ -853,5 +1247,24 @@ namespace Radzen.Blazor
{
Grid?.RemoveColumn(this);
}
internal int? getSortIndex()
{
var descriptor = Grid.sorts.Where(s => s.Property == GetSortProperty()).FirstOrDefault();
if (descriptor != null)
{
return Grid.sorts.IndexOf(descriptor);
}
return null;
}
internal string getSortIndexAsString()
{
var index = getSortIndex();
return index != null ? $"{getSortIndex() + 1}" : "";
}
internal RadzenDataGridHeaderCell<TItem> headerCell;
}
}
}

View File

@@ -3,7 +3,7 @@
@using Microsoft.JSInterop
@inject IJSRuntime JSRuntime
<button title=@Column.GetFilterOperatorText(Column.GetFilterOperator()) class="@FilterIconStyle()" onclick="@($"Radzen.togglePopup(this.parentNode, '{Grid.PopupID}{Column.GetFilterProperty()}')")">
<i class="rzi">filter_alt</i>
<i class="rzi">@Grid.FilterIcon</i>
@if (Column.GetFilterOperator() == FilterOperator.DoesNotContain)
{
<s>@Column.GetFilterOperatorSymbol(Column.GetFilterOperator())</s>
@@ -16,46 +16,97 @@
<div id="@($"{Grid.PopupID}{Column.GetFilterProperty()}")" class="rz-overlaypanel"
style="display:none;" tabindex="0">
<div class="rz-overlaypanel-content">
<ul class="rz-listbox-list" style="margin:5px">
<ul class="rz-listbox-list">
@if (Column.FilterPropertyType == typeof(string))
{
@if (Column.GetFilterOperators().Contains(FilterOperator.Contains))
{
<li class="@(FilterOperatorStyle(Column, FilterOperator.Contains))" @onclick="@(args => ApplyFilter(FilterOperator.Contains))" style="display: block;">
<span class="rz-filter-menu-symbol">@Column.GetFilterOperatorSymbol(FilterOperator.Contains)</span><span>@Grid.ContainsText</span>
</li>
}
@if (Column.GetFilterOperators().Contains(FilterOperator.DoesNotContain))
{
<li class="@(FilterOperatorStyle(Column, FilterOperator.DoesNotContain))" @onclick="@(args => ApplyFilter(FilterOperator.DoesNotContain))" style="display: block;">
<span class="rz-filter-menu-symbol"><s>@Column.GetFilterOperatorSymbol(FilterOperator.DoesNotContain)</s></span><span>@Grid.DoesNotContainText</span>
</li>
}
@if (Column.GetFilterOperators().Contains(FilterOperator.StartsWith))
{
<li class="@(FilterOperatorStyle(Column, FilterOperator.StartsWith))" @onclick="@(args => ApplyFilter(FilterOperator.StartsWith))" style="display: block;">
<span class="rz-filter-menu-symbol">@Column.GetFilterOperatorSymbol(FilterOperator.StartsWith)</span><span>@Grid.StartsWithText</span>
</li>
}
@if (Column.GetFilterOperators().Contains(FilterOperator.EndsWith))
{
<li class="@(FilterOperatorStyle(Column, FilterOperator.EndsWith))" @onclick="@(args => ApplyFilter(FilterOperator.EndsWith))" style="display: block;">
<span class="rz-filter-menu-symbol">@Column.GetFilterOperatorSymbol(FilterOperator.EndsWith)</span><span>@Grid.EndsWithText</span>
</li>
}
@if (Column.GetFilterOperators().Contains(FilterOperator.IsEmpty))
{
<li class="@(FilterOperatorStyle(Column, FilterOperator.IsEmpty))" @onclick="@(args => ApplyFilter(FilterOperator.IsEmpty))" style="display: block;">
<span class="rz-filter-menu-symbol">@Column.GetFilterOperatorSymbol(FilterOperator.IsEmpty)</span><span>@Grid.IsEmptyText</span>
</li>
}
@if (Column.GetFilterOperators().Contains(FilterOperator.IsNotEmpty))
{
<li class="@(FilterOperatorStyle(Column, FilterOperator.IsNotEmpty))" @onclick="@(args => ApplyFilter(FilterOperator.IsNotEmpty))" style="display: block;">
<span class="rz-filter-menu-symbol">@Column.GetFilterOperatorSymbol(FilterOperator.IsNotEmpty)</span><span>@Grid.IsNotEmptyText</span>
</li>
}
}
@if (Column.GetFilterOperators().Contains(FilterOperator.Equals))
{
<li class="@(FilterOperatorStyle(Column, FilterOperator.Equals))" @onclick="@(args => ApplyFilter(FilterOperator.Equals))" style="display: block;">
<span class="rz-filter-menu-symbol">@Column.GetFilterOperatorSymbol(FilterOperator.Equals)</span><span>@Grid.EqualsText</span>
</li>
}
@if (Column.GetFilterOperators().Contains(FilterOperator.NotEquals))
{
<li class="@(FilterOperatorStyle(Column, FilterOperator.NotEquals))" @onclick="@(args => ApplyFilter(FilterOperator.NotEquals))" style="display: block;">
<span class="rz-filter-menu-symbol">@Column.GetFilterOperatorSymbol(FilterOperator.NotEquals)</span><span>@Grid.NotEqualsText</span>
</li>
}
@if (Column.GetFilterOperators().Contains(FilterOperator.LessThan))
{
<li class="@(FilterOperatorStyle(Column, FilterOperator.LessThan))" @onclick="@(args => ApplyFilter(FilterOperator.LessThan))" style="display: block;">
<span class="rz-filter-menu-symbol">@Column.GetFilterOperatorSymbol(FilterOperator.LessThan)</span><span>@Grid.LessThanText</span>
</li>
}
@if (Column.GetFilterOperators().Contains(FilterOperator.LessThanOrEquals))
{
<li class="@(FilterOperatorStyle(Column, FilterOperator.LessThanOrEquals))" @onclick="@(args => ApplyFilter(FilterOperator.LessThanOrEquals))" style="display: block;">
<span class="rz-filter-menu-symbol">@Column.GetFilterOperatorSymbol(FilterOperator.LessThanOrEquals)</span><span>@Grid.LessThanOrEqualsText</span>
</li>
}
@if (Column.GetFilterOperators().Contains(FilterOperator.GreaterThan))
{
<li class="@(FilterOperatorStyle(Column, FilterOperator.GreaterThan))" @onclick="@(args => ApplyFilter(FilterOperator.GreaterThan))" style="display: block;">
<span class="rz-filter-menu-symbol">@Column.GetFilterOperatorSymbol(FilterOperator.GreaterThan)</span><span>@Grid.GreaterThanText</span>
</li>
}
@if (Column.GetFilterOperators().Contains(FilterOperator.GreaterThanOrEquals))
{
<li class="@(FilterOperatorStyle(Column, FilterOperator.GreaterThanOrEquals))" @onclick="@(args => ApplyFilter(FilterOperator.GreaterThanOrEquals))" style="display: block;">
<span class="rz-filter-menu-symbol">@Column.GetFilterOperatorSymbol(FilterOperator.GreaterThanOrEquals)</span><span>@Grid.GreaterThanOrEqualsText</span>
</li>
}
@if (Column.GetFilterOperators().Contains(FilterOperator.IsNull))
{
<li class="@(FilterOperatorStyle(Column, FilterOperator.IsNull))" @onclick="@(args => ApplyFilter(FilterOperator.IsNull))" style="display: block;">
<span class="rz-filter-menu-symbol">@Column.GetFilterOperatorSymbol(FilterOperator.IsNull)</span><span>@Grid.IsNullText</span>
</li>
}
@if (Column.GetFilterOperators().Contains(FilterOperator.IsNotNull))
{
<li class="@(FilterOperatorStyle(Column, FilterOperator.IsNotNull))" @onclick="@(args => ApplyFilter(FilterOperator.IsNotNull))" style="display: block;">
<span class="rz-filter-menu-symbol">@Column.GetFilterOperatorSymbol(FilterOperator.IsNotNull)</span><span>@Grid.IsNotNullText</span>
</li>
}
<li class="rz-multiselect-item" @onclick="@(args => ClearFilter())" style="display:block;">
<span class="rz-filter-menu-symbol">x</span><span>@Grid.ClearFilterText</span>
</li>
</ul>
</div>
</div>
@@ -76,21 +127,25 @@
protected string FilterIconStyle()
{
var additionalStyle = Column.GetFilterValue() != null || Column.GetSecondFilterValue() != null ||
Column.GetFilterOperator() == FilterOperator.IsNotNull || Column.GetFilterOperator() == FilterOperator.IsNull
? "rz-grid-filter-active" : "";
return $"rz-filter-button rz-button rz-button-md rz-button-icon-only btn-light {additionalStyle}";
Column.GetFilterOperator() == FilterOperator.IsNotNull || Column.GetFilterOperator() == FilterOperator.IsNull
|| Column.GetFilterOperator() == FilterOperator.IsEmpty || Column.GetFilterOperator() == FilterOperator.IsNotEmpty
? "rz-grid-filter-active" : "";
return $"rz-filter-button rz-button rz-button-md rz-button-icon-only rz-variant-flat rz-light {additionalStyle}";
}
protected async Task ApplyFilter(FilterOperator value)
{
if (value == FilterOperator.IsNull || value == FilterOperator.IsNotNull)
if (value == FilterOperator.IsNull || value == FilterOperator.IsNotNull
|| value == FilterOperator.IsEmpty || value == FilterOperator.IsNotEmpty)
{
Column.SetFilterValue(null);
Column.SetFilterValue(value == FilterOperator.IsEmpty || value == FilterOperator.IsNotEmpty ? string.Empty : null);
Column.SetFilterValue(null, false);
}
Column.SetFilterOperator(value);
Grid.SaveSettings();
await Grid.Filter.InvokeAsync(new DataGridColumnFilterEventArgs<TItem>()
{
Column = Column,
@@ -102,6 +157,27 @@
});
await JSRuntime.InvokeVoidAsync("Radzen.closePopup", $"{Grid.PopupID}{Column.GetFilterProperty()}");
await Grid.Reload();
await Grid.ReloadInternal();
}
}
protected async Task ClearFilter()
{
Column.ClearFilters();
Grid.SaveSettings();
await JSRuntime.InvokeVoidAsync("Radzen.closePopup", $"{Grid.PopupID}{Column.GetFilterProperty()}");
await Grid.FilterCleared.InvokeAsync(new DataGridColumnFilterEventArgs<TItem>()
{
Column = Column,
FilterValue = Column.GetFilterValue(),
SecondFilterValue = Column.GetSecondFilterValue(),
FilterOperator = Column.GetFilterOperator(),
SecondFilterOperator = Column.GetSecondFilterOperator(),
LogicalFilterOperator = Column.GetLogicalFilterOperator()
});
await Grid.ReloadInternal();
}
}

Some files were not shown because too many files have changed in this diff Show More