feat(module: form): add complex form control (#349)

Co-authored-by: James Yeung <shunjiey@hotmail.com>
This commit is contained in:
笨木头 2020-07-13 12:26:09 +08:00 committed by GitHub
parent dcbb3d8fbd
commit 0da743fab2
5 changed files with 123 additions and 4 deletions

View File

@ -33,6 +33,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.DataAnnotations.Validation" Version="3.2.0-rc1.20223.4" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="3.1.0" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.0.0">
<PrivateAssets>all</PrivateAssets>

View File

@ -11,7 +11,7 @@
EditContext="_editContext"
OnValidSubmit="OnFinish"
OnInvalidSubmit="OnFinishFailed">
<DataAnnotationsValidator />
<ObjectGraphDataAnnotationsValidator />
<CascadingValue Value="this" Name="Form" TValue="IForm">
@if (!string.IsNullOrEmpty(Size))
{

View File

@ -11,11 +11,19 @@ namespace AntDesign
{
public partial class FormItem : AntDomComponentBase, IFormItem
{
private static readonly Dictionary<string, object> _noneColAttributes = new Dictionary<string, object>();
private readonly string _prefixCls = "ant-form-item";
[CascadingParameter(Name = "Form")]
private IForm Form { get; set; }
[CascadingParameter(Name = "FormItem")]
private IFormItem ParentFormItem { get; set; }
[CascadingParameter]
private EditContext CurrentEditContext { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
@ -28,6 +36,9 @@ namespace AntDesign
[Parameter]
public ColLayoutParam WrapperCol { get; set; }
[Parameter]
public bool NoStyle { get; set; } = false;
private EditContext EditContext => Form?.EditContext;
private bool _isValid = true;
@ -38,9 +49,6 @@ namespace AntDesign
private RenderFragment _formValidationMessages;
[CascadingParameter]
private EditContext CurrentEditContext { get; set; }
protected override void OnInitialized()
{
base.OnInitialized();
@ -70,6 +78,11 @@ namespace AntDesign
private Dictionary<string, object> GetLabelColAttributes()
{
if (NoStyle || ParentFormItem != null)
{
return _noneColAttributes;
}
ColLayoutParam labelColParameter;
if (LabelCol != null)
@ -90,6 +103,11 @@ namespace AntDesign
private Dictionary<string, object> GetWrapperColAttributes()
{
if (NoStyle || ParentFormItem != null)
{
return _noneColAttributes;
}
ColLayoutParam wrapperColParameter;
if (WrapperCol != null)

View File

@ -0,0 +1,76 @@
@using System.ComponentModel.DataAnnotations;
@using System.Text.Json;
<Form Model="@model"
LabelCol="new ColLayoutParam { Span = 8 }"
WrapperCol="new ColLayoutParam { Span = 16 }"
OnFinish="OnFinish"
OnFinishFailed="OnFinishFailed">
<FormItem Label="Username">
<Input @bind-Value="context.Username" Style="width: 160px" Placeholder="Please input" />
<Tooltip Title=@("Useful information")>
<a href="#API" Style="margin: 0 8px" }>
Need Help?
</a>
</Tooltip>
</FormItem>
<FormItem label="Address">
<InputGroup Compact>
<FormItem NoStyle>
<Input @bind-Value="context.Address.Province" Placeholder="Select is not yet" />
</FormItem>
<FormItem NoStyle>
<Input @bind-Value="context.Address.Street" Style="width: 50%" Placeholder="Input street" />
</FormItem>
</InputGroup>
</FormItem>
<FormItem Label="BirthDate" style="margin-bottom: 0">
<FormItem Style="display: inline-block; width: calc(50% - 10px)">
<Input @bind-Value="context.Year" Placeholder="Input birth year" />
</FormItem>
<FormItem Style="display: inline-block; width: calc(50% - 10px); margin: 0 8px">
<Input @bind-Value="context.Month" Placeholder="Input birth month" />
</FormItem>
</FormItem>
<FormItem WrapperCol="new ColLayoutParam{ Offset = 8, Span = 16 }">
<Button HtmlType="submit">
Submit
</Button>
</FormItem>
</Form>
@code
{
public class Address
{
[Required]
public string Province { get; set; }
[Required]
public string Street { get; set; }
}
public class Model
{
[Required]
public string Username { get; set; }
[ValidateComplexType]
public Address Address { get; set; } = new Address();
[Required]
public string Year { get; set; }
[Required]
public string Month { get; set; }
}
private Model model = new Model();
private void OnFinish(EditContext editContext)
{
Console.WriteLine($"Success:{JsonSerializer.Serialize(model)}");
}
private void OnFinishFailed(EditContext editContext)
{
Console.WriteLine($"Failed:{JsonSerializer.Serialize(model)}");
}
}

View File

@ -0,0 +1,24 @@
---
order: 6
title:
zh-CN: 复杂一点的控件
en-US: complex form control
---
## zh-CN
这里演示 `FormItem` 内有多个元素的使用方式。
这里展示了三种典型场景:
- `Username`:输入框后面有描述文案或其他组件,在 `FormItem` 内只有使用了@bind-Value的组件才会绑定到FormItem其他组件可任意添加。
- `Address`:有两个控件,在 `FormItem` 内使用两个 `<FormItem NoStyle />` 分别绑定对应控件一个FormItem下只能出现一个使用了@bing-Value的控件对FormItem使用NoStyle则FormItem的Grid布局会被忽略就算主动使用了LabelCol或WrapperCol也不会产生效果。
这个场景还展示了复杂类型的表单验证Address是一个包含了两个属性的类结构通过附加ValidateComplexType表单可以对其所有属性进行验证。详情可参考Blazor文档[嵌套模型、集合类型和复杂类型](https://docs.microsoft.com/zh-cn/aspnet/core/blazor/forms-validation)
- `BirthDate`:有两个内联控件,错误信息展示各自控件下,使用两个 `<FormItem />` 分别绑定对应控件,并修改 `style` 使其内联布局。
更复杂的封装复用方式可以参考下面的 `自定义表单控件` 演示TODO
## en-US
Help Wanted