- {
- new() { Id = 1 }
- }
- };
-
- public async Task SubmitOrder(FormContext context)
- {
- var success = context.Validate();
- if (success)
- {
- // do something
- }
- }
-
-}
diff --git a/docs/Masa.Blazor.Docs/Examples/components/forms/ValidateOnDemo.razor b/docs/Masa.Blazor.Docs/Examples/components/forms/ValidateOnDemo.razor
new file mode 100644
index 0000000000..5bdf21d693
--- /dev/null
+++ b/docs/Masa.Blazor.Docs/Examples/components/forms/ValidateOnDemo.razor
@@ -0,0 +1,59 @@
+@using System.ComponentModel.DataAnnotations
+@using System.ComponentModel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Submit
+
+
+@code {
+
+ class Model
+ {
+ [Display(Name = "Username")]
+ [Required]
+ [MinLength(5)]
+ public string Name { get; set; }
+
+ [Display(Name = "Favorite sport")]
+ [Required] public string Item { get; set; }
+
+ [Display(Name = "Age")]
+ [Range(18, 60)]
+ public int Age { get; set; }
+ }
+
+ private bool _valid = true;
+ private Model _model = new();
+ private ValidateOn _validateOn;
+
+ List _sports = new()
+ {
+ "Basketball",
+ "Football",
+ "Tennis",
+ "Swimming"
+ };
+
+}
\ No newline at end of file
diff --git a/docs/Masa.Blazor.Docs/Masa.Blazor.Docs.csproj b/docs/Masa.Blazor.Docs/Masa.Blazor.Docs.csproj
index aa884510b4..8e4350fa19 100644
--- a/docs/Masa.Blazor.Docs/Masa.Blazor.Docs.csproj
+++ b/docs/Masa.Blazor.Docs/Masa.Blazor.Docs.csproj
@@ -15,7 +15,6 @@
-
diff --git a/docs/Masa.Blazor.Docs/wwwroot/data/apis/forms/MForm-en-US.json b/docs/Masa.Blazor.Docs/wwwroot/data/apis/forms/MForm-en-US.json
index 063da13931..6158861275 100644
--- a/docs/Masa.Blazor.Docs/wwwroot/data/apis/forms/MForm-en-US.json
+++ b/docs/Masa.Blazor.Docs/wwwroot/data/apis/forms/MForm-en-US.json
@@ -4,7 +4,9 @@
"enableValidation": "Enable form validation.",
"model": "Objects that require form validation.",
"readonly": "",
- "value": "Whether the verification is successful."
+ "value": "Whether the verification is successful.",
+ "autoLabel": "Whether to automatically generate labels for form items.",
+ "validateOn": "Validation timing, options: input, blur, submit."
},
"events": {
"onInvalidSubmit": "",
diff --git a/docs/Masa.Blazor.Docs/wwwroot/data/apis/forms/MForm-zh-CN.json b/docs/Masa.Blazor.Docs/wwwroot/data/apis/forms/MForm-zh-CN.json
index b17aef5976..9a05eb3f14 100644
--- a/docs/Masa.Blazor.Docs/wwwroot/data/apis/forms/MForm-zh-CN.json
+++ b/docs/Masa.Blazor.Docs/wwwroot/data/apis/forms/MForm-zh-CN.json
@@ -4,7 +4,9 @@
"enableValidation": "开启表单校验",
"model": "需要表单校验的对象",
"readonly": "",
- "value": "是否校验成功"
+ "value": "是否校验成功",
+ "validateOn": "校验时机,可选输入时验证、失去光标时验证和提交时验证",
+ "autoLabel": "是否自动添加标签"
},
"events": {
"onInvalidSubmit": "",
diff --git a/docs/Masa.Blazor.Docs/wwwroot/pages/components/forms/en-US.md b/docs/Masa.Blazor.Docs/wwwroot/pages/components/forms/en-US.md
index 9f5560d59d..17323a5e84 100644
--- a/docs/Masa.Blazor.Docs/wwwroot/pages/components/forms/en-US.md
+++ b/docs/Masa.Blazor.Docs/wwwroot/pages/components/forms/en-US.md
@@ -23,6 +23,19 @@ Rules allow you to apply custom validation on all form components. These are ver
+#### Auto label {released-on=v1.7.0}
+
+When `AutoLabel` is `true`, **MForm** will automatically get the value of the `[Display]` or `[DisplayName]` attribute of the form field as the label.
+By default, it resolves the `[Display]` attribute, and you can also configure the `AttributeType` to resolve the `[DisplayName]` attribute by setting the `Masa.Blazor.Components.Form.AutoLabelOptions` subcomponent.
+
+
+
+#### Validate on {released-on=v1.7.0}
+
+The `ValidateOn` prop is used to specify when to validate the form, with optional values of `Input`, `Blur` and `Submit`.
+
+
+
### Misc
#### Model validation
@@ -37,31 +50,21 @@ Validate a single field using the `Validate` method of the **MForm** instance.
-#### Validation with submit and clear {updated-in=v1.6.0}
+#### Submit and clear {#submit-and-clear updated-in=v1.6.0}
You can use the methods provided by `Context` in the content of **MForm**, or use the component instance provided by `@ref` outside of **MForm**.
-#### Enable I18n {updated-in=v1.6.0}
+#### DataAnnotations with I18n {#enable-i18n updated-in=v1.6.0}
Enable [I18n](/blazor/features/internationalization) to support multilingual validation messages. Locale resources used in the example can be found in [GitHub](https://github.com/masastack/MASA.Blazor/blob/0f4a450479bceb816d58bbbb7b8f8ca7655e2f94/docs/Masa.Docs.Shared/wwwroot/locale/en-US.json#L128).
-
+
-#### Validate complex type with DataAnnotations
-
-Use `[ValidateComplexType]` attribute and `` to validate complex types.
-
-```xml Project.csproj
-
-```
-
-
-
-#### Validate with FluentValidation
+#### Validate with FluentValidation {#fluent-validation}
@@ -69,7 +72,7 @@ Use `[ValidateComplexType]` attribute and `
-#### Parse external validation result
+#### Parse external validation result {#parse-form-validation}
**MForm** supports parsing of `ValidationResult` , which users can use as `FormContext.ParseFormValidation' parameter that displays the validation results in a front-end form, using the validation collection as an example.
diff --git a/docs/Masa.Blazor.Docs/wwwroot/pages/components/forms/zh-CN.md b/docs/Masa.Blazor.Docs/wwwroot/pages/components/forms/zh-CN.md
index 8134e71621..58b7690e05 100644
--- a/docs/Masa.Blazor.Docs/wwwroot/pages/components/forms/zh-CN.md
+++ b/docs/Masa.Blazor.Docs/wwwroot/pages/components/forms/zh-CN.md
@@ -7,61 +7,64 @@ related:
- /blazor/components/text-fields
---
-## 使用
+## 使用 {#usage}
内部的 **MForm** 组件可以很容易地向表单输入添加验证。所有输入组件都有一个 `Rules` 参数,该参数接受类型为 `Func` 的列表。这允许您指定输入有效或无效的条件。每当输入值改变时,数组中的每个函数都会收到一个新值,并且每个数组元素都会被评分。如果函数或数组元素返回 `false` 或 `string`,表示验证失败,则将字符串值显示为错误消息。
-## 示例
+## 示例 {#examples}
-### 属性
+### 属性 {#props}
-#### 规则
+#### 规则 {#rules}
规则允许您对所有表单组件应用自定义验证。这些是按顺序验证的,一次最多显示 1 个错误,因此请确保相应地对规则进行排序。
-### 其他
+#### 自动标签 {#auto-label released-on=v1.7.0}
-#### 模型验证
+当 `AutoLabel` 为 `true` 时,**MForm** 会自动获取表单对象字段的 `[Display]` 或 `[DisplayName]` 特性的值作为 Label。
+默认解析 `[Display]` attribute,也可以通过 `Masa.Blazor.Components.Form.AutoLabelOptions` 子组件配置 `AttributeType` 为 `typeof(DisplayNameAttribute)` 解析 `[DisplayName]` attribute。
+
+
+
+#### 验证时机 {#validate-on released-on=v1.7.0}
+
+`ValidateOn` 属性用于指定何时验证表单,可选值为 `Input`,`Blur` 和 `Submit`。
+
+
+
+### 其他 {#misc}
+
+#### 模型验证 {#model-validation}
除了在每个输入组件上通过 `Rules` 属性进行验证之外,还可以对单个对象模型进行验证。
-#### 验证单个字段 {released-on=v1.6.0}
+#### 验证单个字段 {#validate-single-field released-on=v1.6.0}
-使用**MForm**实例的`Validate`方法验证单个字段。
+使用 **MForm** 实例的 `Validate` 方法验证单个字段。
-#### 通过提交和清除进行验证 {updated-in=v1.6.0}
+#### 通过提交和清除进行验证 {#submit-and-clear updated-in=v1.6.0}
在 **MForm** 的内容里可以使用 `Context` 提供的方法,在 **MForm** 外部可以使用 `@ref` 拿到组件实例提供的方法。
-#### 启用 I18n {updated-in=v1.6.0}
+#### DataAnnotations 本地化 {#enable-i18n updated-in=v1.7.0}
通过 `EnableI18n` 属性启用 [I18n](/blazor/features/internationalization) 以支持验证信息多语言。示例使用的本地话资源你能在 [GitHub](https://github.com/masastack/MASA.Blazor/blob/0f4a450479bceb816d58bbbb7b8f8ca7655e2f94/docs/Masa.Docs.Shared/wwwroot/locale/zh-CN.json#L129) 中找到。
-
+
-#### 通过 DataAnnotations 验证复杂类型
-
-使用 `[ValidateComplexType]` 属性和 ``,可以验证复杂类型。
-
-```xml Project.csproj
-
-```
-
-
-
-#### 使用 FluentValidation 验证
+#### 使用 FluentValidation 验证 {#fluent-validation}
**MForm** 支持 **FluentValidation** 验证。
@@ -69,7 +72,7 @@ related:
-#### 解析外部验证结果
+#### 解析外部验证结果 {#parse-form-validation}
**MForm** 支持解析 `ValidationResult`,用户可以将服务端表单验证返回的 `ValidationResult` 作为 `FormContext.ParseFormValidation` 的参数,将验证结果在前端表单展示,以验证集合为示例。
diff --git a/docs/Masa.Blazor.Docs/wwwroot/pages/getting-started/upgrade-guide/en-US.md b/docs/Masa.Blazor.Docs/wwwroot/pages/getting-started/upgrade-guide/en-US.md
index 06db7975b2..f7693baefa 100644
--- a/docs/Masa.Blazor.Docs/wwwroot/pages/getting-started/upgrade-guide/en-US.md
+++ b/docs/Masa.Blazor.Docs/wwwroot/pages/getting-started/upgrade-guide/en-US.md
@@ -2,9 +2,9 @@
## Upgrading form v1.6.x to v1.7.0
-### Components
+### Components {#v1-7-0-components}
-#### Pagination
+#### Pagination {#v1-7-0-pagination}
A mini style UI has been added, now when the browser window is less than *600px*, it will automatically use it. If you don't want to use the mini style, you can manually set it through the `MiniVariant` property.
@@ -15,6 +15,40 @@ A mini style UI has been added, now when the browser window is less than *600px*
>
```
+#### Form {#v1-7-0-form}
+
+DataAnnotations validation now natively supports complex types, no need to reference additional libraries and code.
+
+```diff .csproj
+-
+```
+
+```diff .razor
+
+-
+ @foreach (var person in _order.Persons)
+ {
+
+ }
+
+
+ @code {
+ public class Order
+ {
+- [ValidateComplexType]
+ public List Persons { get; set; }
+ }
+
+ public class Person
+ {
+ [Required]
+ public string Name { get; set; }
+ }
+
+ private Order _order = new() { Persons = [] };
+ }
+```
+
## Upgrading form v1.5.x to v1.6.0
### Change the script
diff --git a/docs/Masa.Blazor.Docs/wwwroot/pages/getting-started/upgrade-guide/zh-CN.md b/docs/Masa.Blazor.Docs/wwwroot/pages/getting-started/upgrade-guide/zh-CN.md
index c7b49920ba..3d5d1752ac 100644
--- a/docs/Masa.Blazor.Docs/wwwroot/pages/getting-started/upgrade-guide/zh-CN.md
+++ b/docs/Masa.Blazor.Docs/wwwroot/pages/getting-started/upgrade-guide/zh-CN.md
@@ -2,9 +2,9 @@
## 从 v1.6.x 升级到 v1.7.0 {#upgrading-from-v1-6-x-to-v1-7-0}
-### 组件 {#components}
+### 组件 {#v1-7-0-components}
-#### Pagination
+#### Pagination {#v1-7-0-pagination}
新增了一个迷你样式的UI,现在当浏览器窗口小于 *600px* 时,会自动使用。如果不想使用迷你样式,可以通过 `MiniVariant` 属性手动设置。
@@ -15,6 +15,40 @@
>
```
+#### Form {#v1-7-0-form}
+
+DataAnnotations 验证现在内置支持复杂类型,不需要引用额外的类库和代码。
+
+```diff .csproj
+-
+```
+
+```diff .razor
+
+-
+ @foreach (var person in _order.Persons)
+ {
+
+ }
+
+
+ @code {
+ public class Order
+ {
+- [ValidateComplexType]
+ public List Persons { get; set; }
+ }
+
+ public class Person
+ {
+ [Required]
+ public string Name { get; set; }
+ }
+
+ private Order _order = new() { Persons = [] };
+ }
+```
+
## 从 v1.5.x 升级到 v1.6.0
### 更改脚本
diff --git a/src/Masa.Blazor/Components/Form/AutoLabelOptions.cs b/src/Masa.Blazor/Components/Form/AutoLabelOptions.cs
index 3f228106a7..af36323f27 100644
--- a/src/Masa.Blazor/Components/Form/AutoLabelOptions.cs
+++ b/src/Masa.Blazor/Components/Form/AutoLabelOptions.cs
@@ -1,5 +1,4 @@
-using System.ComponentModel;
-using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations;
using IComponent = Microsoft.AspNetCore.Components.IComponent;
namespace Masa.Blazor.Components.Form;
@@ -17,7 +16,8 @@ public class AutoLabelOptions : IComponent
/// Supported types are and .
///
[Parameter]
- public Type? AttributeType { get; set; } = typeof(DisplayNameAttribute);
+ [MasaApiParameter(nameof(DisplayAttribute))]
+ public Type? AttributeType { get; set; } = typeof(DisplayAttribute);
private bool _init;
diff --git a/src/Masa.Blazor/Components/Form/MForm.razor b/src/Masa.Blazor/Components/Form/MForm.razor
index 61d1c1d2fb..b407e88a61 100644
--- a/src/Masa.Blazor/Components/Form/MForm.razor
+++ b/src/Masa.Blazor/Components/Form/MForm.razor
@@ -10,7 +10,7 @@
@attributes="@Attributes">
@ChildContent?.Invoke(FormContext!)
- @if (AutoLabel)
+ @if (ComputedAutoLabel)
{
}
diff --git a/src/Masa.Blazor/Components/Form/MForm.razor.cs b/src/Masa.Blazor/Components/Form/MForm.razor.cs
index 501d5b2fa2..cc5f316fda 100644
--- a/src/Masa.Blazor/Components/Form/MForm.razor.cs
+++ b/src/Masa.Blazor/Components/Form/MForm.razor.cs
@@ -1,13 +1,22 @@
using System.Collections.Concurrent;
-using System.ComponentModel;
+using System.ComponentModel.DataAnnotations;
using System.Reflection;
using Masa.Blazor.Components.Form;
using Masa.Blazor.Components.Input;
+using ValidationResult = Masa.Blazor.Components.Form.ValidationResult;
namespace Masa.Blazor;
public partial class MForm : MasaComponentBase
{
+ ///
+ /// Auto generate label for the form fields.
+ /// The default logic is to use the attribute.
+ ///
+ [Parameter]
+ [MasaApiParameter(ReleasedOn = "v1.7.0")]
+ public bool AutoLabel { get; set; }
+
[Parameter] public RenderFragment? ChildContent { get; set; }
[Parameter] public EventCallback OnSubmit { get; set; }
@@ -33,10 +42,8 @@ public partial class MForm : MasaComponentBase
[Parameter] public EventCallback OnInvalidSubmit { get; set; }
[Parameter]
- [MasaApiParameter(true, ReleasedOn = "v1.7.0")]
- public bool AutoLabel { get; set; } = true;
-
- [Parameter] public ValidateOn ValidateOn { get; set; } = ValidateOn.Input;
+ [MasaApiParameter(ReleasedOn = "v1.7.0")]
+ public ValidateOn ValidateOn { get; set; } = ValidateOn.Input;
internal ConcurrentDictionary AutoLabelMap { get; } = new();
@@ -44,6 +51,8 @@ public partial class MForm : MasaComponentBase
private object? _oldModel;
+ private bool ComputedAutoLabel => AutoLabel || EnableI18n;
+
public EditContext? EditContext { get; protected set; }
public FormContext? FormContext { get; private set; }
@@ -56,7 +65,7 @@ public partial class MForm : MasaComponentBase
/// The type of property attribute used to generate the label,
/// the default value is same as .
///
- internal Type? LabelAttributeType { get; set; } = typeof(DisplayNameAttribute);
+ internal Type? LabelAttributeType { get; set; } = typeof(DisplayAttribute);
protected override void OnParametersSet()
{