DotVVM.AutoUI
4.3.3
dotnet add package DotVVM.AutoUI --version 4.3.3
NuGet\Install-Package DotVVM.AutoUI -Version 4.3.3
<PackageReference Include="DotVVM.AutoUI" Version="4.3.3" />
paket add DotVVM.AutoUI --version 4.3.3
#r "nuget: DotVVM.AutoUI, 4.3.3"
// Install DotVVM.AutoUI as a Cake Addin #addin nuget:?package=DotVVM.AutoUI&version=4.3.3 // Install DotVVM.AutoUI as a Cake Tool #tool nuget:?package=DotVVM.AutoUI&version=4.3.3
DotVVM Auto UI
Automatically generated forms, tables and more from type metadata.
Data Annotations
The main goal of this library is to generate user interface from metadata. It should be able to create reasonable UI from just the type information, for more control control over it you can use the following attributes.
[Display(Name = "X")]
- sets the property display name[Display(Prompt = "enter your email")]
- sets the placeholder text of a textbox[Display(Description = "Longer description of the data collected")]
- sets longer description. It will be set into thetitle
attribute, and shown as sub-heading in some forms[Display(Order = 10)]
- by default, the properties are in the order as they are defined in C#. This attribute allows you to change the order[Display(GroupName = "A")]
- makes this field visible in form withGroupName
property set toA
[Display(AutoGenerateField = false)]
- hide the field from forms. Note that a malicious user might still be able to see it and change it in the viewmodel, unless you also apply[Protect(ProtectMode.EncryptData)]
,[Bind(Direction.None)]
or[JsonIgnore]
[DisplayFormat(DataFormatString = "dd. MM. yyyy")]
- controls the format string used in textbox and literals[DataType(...)]
- controls which input type will be generated for the specified propertyDataType.MultilineText
-<textarea>
DataType.Password
-<input type=password>
DataType.Date
-<input type=date>
. Note that this works for bothDateTime
andstring
propertiesDataType.Time
-<input type=time>
DataType.DateTime
-<input type=datetime-local>
- You can add support for more by implementing the
IFormEditorProvider
interface
[Style(...)]
- allows adding additional CSS classes to different parts of the forms, or tables[Editable(AllowEdit = false)]
- makes the read only. Note that without[Protect(ProtectMode.Sign]
anyone can change the underlying viewmodel anyway.[Visible(Roles = "Developer & !Manger")]
- makes the field visible only to authenticated users with theDeveloper
roles and without theManager
role[Visible(ViewNames = "Insert | Edit")]
- makes the field visible in forms with ViewName property set toInsert
orEdit
[Enabled(...)]
- makes the field editable under some conditions (similar API to[Visible(...)]
)[UIHint(...)]
- currently not used by AutoUI, but can be used for matching custom providers
Example
public class EmployeeDTO
{
[Display(AutoGenerateField = false)] // this field will be hidden
public int Id { get; set; }
[Required]
[Display(GroupName = "Basic Info")]
public string UserName { get; set; }
[Required]
[Display(GroupName = "Basic Info")]
public string FirstName { get; set; }
[Required]
[Display(GroupName = "Basic Info")]
public string LastName { get; set; }
[Display(GroupName = "Basic Info")]
public DateTime BirthDate { get; set; }
[Display(Name = "E-mail", GroupName = "Contact Info")]
[EmailAddress] // use <input type=email>
public string PersonalEmail { get; set; }
[Display(Name = "Phone", GroupName = "Contact Info")]
[DataType(DataType.PhoneNumber)] // use <input type=tel>
public string PersonalPhone { get; set; }
}
Configuration API
The metadata can be also controlled using a configuration API:
services.AddAutoUI(config => {
// for all properties with a certain name
config.PropertyMetadataRules
.For("IsCompany", r => r.SetDisplayName(""))
.For("ProductId", r => r.UseSelection<ProductSelection>());
})
The metadata provider can be easily extended by implementing and registering these two interfaces:
IPropertyDisplayMetadataProvider
provides basic information about properties - all information listed above.IViewModelValidationMetadataProvider
retrieves validation attributes for each property.
Initialization
First, install the DotVVM.AutoUI
NuGet package in your project.
dotnet add package DotVVM.AutoUI
To use AutoUI, add the following line to the Startup.cs
file.
// ASP.NET Core (place this snippet in the ConfigureServices method)
services.AddDotVVM(options =>
{
options.AddAutoUI(config => {
// configuration options
});
});
// OWIN
app.UseDotVVM<DotvvmStartup>(applicationPhysicalPath, options: options =>
{ // set up config
options.AddAutoUI(config => {
// configuration options
});
});
This will allow to provide UI metadata using the standard .NET Data Annotations attributes.
<br />
GridView
- data tables
When your view model class is decorated with data annotation attributes, you can auto-generate GridView columns.
DotVVM AutoUI brings the auto:GridViewColumns
control, it is a special grid column which gets replaced by a separate column for each property.
It can be used with the built-in dot:GridView
, and also with the GridView
s in DotVVM component packages
<bs:GridView Type="Bordered" DataSource="{value: Employees}">
<auto:GridViewColumns />
<dot:GridViewTemplateColumn>
<a href='{value: $"/people/edit/{_this.Id}"}'> <bs:GlyphIcon Icon="Pencil" /> Edit</a>
</dot:GridViewTemplateColumn>
</bs:GridView>
Number of properties can be used to customize the auto:GridViewColumns
behavior. Most notably:
Property-LastAccessTime={value: _this.LastContactTime.ToBrowserLocalTime()}
- passes the LastContactTime property through the
ToBrowserLocalTime
function
- passes the LastContactTime property through the
Property-Name={value: FirstName + " " + LastName}
- adds new column with the specified value binding
Header-LastContactTime="Last Seen"
- sets custom display name for the column
ExcludeProperties="FirstName, LastName"
- removes the FirstName and LastName columns from the table
IncludeProperties="Name, Email"
- only the listed properties will be included in the table
<ContentTemplate-Id> <a href='{value: $"/people/detail/{Id}"}'> {{value: Id}} </a> </ContentTemplate-Id>
- sets a custom HTML template for the
Id
column
- sets a custom HTML template for the
IsEditable-Id=false
- marks the
Id
property as not editable (only in this GridView's inline edit mode)
- marks the
<EditorTemplate-MyProperty> ...
- similar toContentTemplate-X
There is also similar auto:GridViewColumn
which is used for a single property.
Forms
DotVVM AutoUI contains the auto:Form
control for basic forms.
We also include auto:BootstrapForm
and auto:BulmaForm
for use with the bootstrap or bulma CSS frameworks.
If you have another favorite CSS framework, it's not hard to make a Form for your needs.
Our BootstrapForm
and BulmaForm
are both under 200 lines, and you can start by copying its code.
The following code with create a simple form
<auto:Form DataContext="{value: EditedEmployee}" />
The control takes the edited view model as DataContext
and generates form fields for all properties of the object using the metadata from data annotation attributes.
As with grid columns, there is a similar set of properties to customize the form behavior:
ExcludeProperties="Id, CreatedTime"
- Removes the FirstName and LastName columns from the form
IncludeProperties="FirstName, LastName, Email"
- Only the listed properties will be included in the form
ViewName=Insert
/GroupName=Group1
- Include only properties from the specified group and view
Label-LastContactTime="Last Seen"
- Sets custom display name for the field
Visible-BirthDate={value: IsPerson}
- Only display this field if the condition is true
Enabled-InvoiceAmount={value: !IsClosed}
- Only allow editing this field if the condition is true
Changed-Email={staticCommand: _parent.IsEmailUnique = service.IsEmailUnique(Email)}
- Event fired when a field changes. May be used to reload some data related to this field
<FieldTemplate-X>
- overrides the entire field layout (including label, validation, ...)
<EditorTemplate-X>
- use the template instead of the default editor
If you want to layout the form into multiple parts, you can use the group names to render each group separately. If you specify the GroupName
property, the Form
will render
only fields from this group.
<div class="row">
<div class="col-md-6">
<auto:BootstrapForm DataContext="{value: EditedEmployee}" GroupName="Basic Info" />
</div>
<div class="col-md-6">
<auto:BootstrapForm DataContext="{value: EditedEmployee}" GroupName="Contact Info" />
</div>
</div>
If you have implemented your own form control and there is a chance that it might be useful for other people, please send us PR and we'll be happy to include as part of the library.
Custom Editors
Currently, the framework supports TextBox
, CheckBox
and ComboBox
editors, which can edit string, numeric, date-time and boolean values.
If you want to support any other data type, you can implement your own editor and grid column.
You need to implement the IFormEditorProvider to implement a custom editor in the form, and the IGridColumnProvider to implement about custom GridView column.
Then, you have to register the editor in the DotvvmStartup.cs
file. Please note that the order of editor providers and grid columns matters.
AutoUI will use the first provider which returns CanHandleProperty = true
for the property.
autouiConfig.FormEditorProviders.Add(new YourEditorProvider());
autouiConfig.GridColumnProviders.Add(new YourGridColumnProvider());
Loading Metadata from Resource Files
Decorating every field with the [Display(Name = "Whatever")]
is not very effective when it comes to localization - you need to specify the resource file type and resource key.
Also, if you have multiple entities with the FirstName
property, you'll probably want to use the same field name for all of them.
That's why DotVVM Auto UI comes with the resource-based metadata providers. They can be registered in the DotvvmStartup.cs
like this:
config.RegisterResourceMetadataProvider(typeof(Resources.ErrorMessages), typeof(Resources.PropertyDisplayNames));
The ErrorMessages
and PropertyDisplayNames
are RESX files in the Resources
folder and they contain the default error messages and display names of the properties.
Localizing Error Messages
If you use the [Required]
attribute and you don't specify the ErrorMessage
or ErrorMessageResourceName
on it, the resource provider will look in the ErrorMessages.resx
file
and if it finds the Required
key there, it'll use this resource item to provide the error message.
Your ErrorMessages.resx
file may look like this:
Resource Key Value
-------------------------------------------------------------------------------------
Required {0} is required!
EmailAddress {0} is not a valid e-mail address!
...
Localizing Property Display Names
The second resource file PropertyDisplayNames.resx
contains the display names. If the property doesn't have the [Display(Name = "Something")]
attribute, the provider will look in the
resource file for the following values (in this order). If it finds an item with that key, it'll use the value as a display name of the field
TypeName_PropertyName
PropertyName
So if you want to use the text "Given Name" for the FirstName
property in all classes, with the exception of the ManagerDTO
class where you need to use the "First Name" text, your resource file
should look like this:
Resource Key Value
-------------------------------------------------------------------------------------
FirstName Given Name
ManagerDTO_FirstName First Name
...
<br />
Roadmap
Here is a brief list of features that are already done, and features that are planned for the future releases.
Implemented
DisplayAttribute
(Name
,Order
,GroupName
,AutoGenerateField
)DisplayFormatAttribute
(DataFormatString
)- Validation Attributes
- Resource lookup for validation error messages and property display names
- HTML table layout for Forms
- TextBox and CheckBox editors
- ComboBox editor with support of conventions
DisplayFormatAttribute
(NullDisplayText
)auto:Editor
control for editing individual fields
In Progress
- More form layouts
- Page templates
Future
- Auto-generating filters on top of the GridView
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.1 is compatible. |
.NET Framework | net472 is compatible. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.7.2
- DotVVM (>= 4.3.3)
- DotVVM.AutoUI.Annotations (>= 4.3.3)
- Humanizer.Core (>= 2.14.1)
-
.NETStandard 2.1
- DotVVM (>= 4.3.3)
- DotVVM.AutoUI.Annotations (>= 4.3.3)
- Humanizer.Core (>= 2.14.1)
-
net6.0
- DotVVM (>= 4.3.3)
- DotVVM.AutoUI.Annotations (>= 4.3.3)
- Humanizer.Core (>= 2.14.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
4.3.3 | 90 | 11/3/2024 |
4.3.2 | 78 | 10/27/2024 |
4.3.0 | 151 | 9/14/2024 |
4.3.0-preview06-final | 76 | 9/8/2024 |
4.3.0-preview05-final | 106 | 8/19/2024 |
4.3.0-preview04-final | 96 | 6/9/2024 |
4.3.0-preview03-final | 110 | 2/27/2024 |
4.3.0-preview02-final | 98 | 2/8/2024 |
4.3.0-preview01-final | 107 | 1/14/2024 |
4.2.8 | 139 | 8/18/2024 |
4.2.7 | 104 | 6/26/2024 |
4.2.6 | 177 | 2/21/2024 |
4.2.5 | 140 | 1/31/2024 |
4.2.4 | 140 | 1/14/2024 |
4.2.3 | 217 | 12/15/2023 |
4.2.2 | 202 | 12/4/2023 |
4.2.1 | 178 | 11/21/2023 |
4.2.0 | 198 | 11/11/2023 |
4.2.0-preview09-final | 148 | 10/22/2023 |
4.2.0-preview08-final | 123 | 10/12/2023 |
4.2.0-preview07-final | 145 | 10/1/2023 |
4.2.0-preview06-final | 138 | 9/10/2023 |
4.2.0-preview05-final | 157 | 9/3/2023 |
4.2.0-preview04-final | 141 | 8/4/2023 |
4.2.0-preview03-final | 153 | 6/20/2023 |
4.2.0-preview02-final | 143 | 6/14/2023 |
4.2.0-preview01-final | 154 | 4/5/2023 |
4.1.8 | 186 | 10/22/2023 |
4.1.7 | 307 | 4/5/2023 |
4.1.6 | 257 | 3/29/2023 |
4.1.5 | 246 | 3/22/2023 |
4.1.4 | 281 | 3/16/2023 |
4.1.3 | 268 | 3/9/2023 |
4.1.2 | 269 | 3/8/2023 |
4.1.1 | 250 | 3/6/2023 |
4.1.0 | 355 | 2/6/2023 |
4.1.0-preview21-final | 167 | 2/1/2023 |
4.1.0-preview19-final | 170 | 1/23/2023 |
4.1.0-preview18-final | 182 | 1/17/2023 |
4.1.0-preview14-final | 213 | 11/14/2022 |
4.1.0-preview13-final | 157 | 11/9/2022 |
4.1.0-preview12-final | 188 | 10/31/2022 |
4.1.0-preview11-final | 159 | 10/11/2022 |
4.1.0-preview10-final | 162 | 9/7/2022 |
4.1.0-preview09-final | 151 | 9/1/2022 |