更新Material多行文本框TagHelper

This commit is contained in:
何镇汐
2018-01-09 23:22:37 +08:00
parent 83229ff782
commit 9ea2cb9960
13 changed files with 481 additions and 23 deletions
@@ -5,6 +5,7 @@
import { Component, Input, ViewChild } from '@angular/core';
import { NgModel } from '@angular/forms';
import { FormControlWrapperBase } from './base/form-control-wrapper-base';
import { MessageConfig } from '../config/message-config';
/**
* Mat多行文本框包装器
@@ -83,7 +84,7 @@ export class TextareaWrapperComponent extends FormControlWrapperBase {
if (this.inputModel.hasError('required'))
return this.requiredMessage;
if (this.inputModel.hasError('minlength'))
return this.minLengthMessage;
return this.minLengthMessage || MessageConfig.minLengthMessage.replace(/\{0\}/, String(this.minLength));
return "";
}
}
@@ -24,11 +24,11 @@
<div style="margin: 100px">
<util-textbox name="a" max-length="8" prefix="$" placeholder="你好啊" model="model.value" required="true" min-length="4" readonly="true"></util-textbox>
<util-textbox prefix="$" placeholder="你好啊" model="model.value" required="true" ></util-textbox>
<util-textarea placeholder="在吗" min-length="10" end-hint="a" model="model.value" ></util-textarea>
</div>
<div style="margin: 100px">
@(x.TextBox().Name( "b" ).Prefix( "$" ).MinLength( 5 ).MaxLength( 8 ).ShowClearButton( false ).ReadOnly( false )
.Placeholder( "你不好" ).Hint( "左边" ).Hint( "右边", true ).Model( "model.value" ).Required())
@x.TextBox().Prefix( "$" ).Placeholder( "你不好" ).Model( "model.value" ).Required().ToTextArea( 5,6 )
</div>
@@ -5,6 +5,6 @@ namespace Util.Ui.Components {
/// <summary>
/// 文本框
/// </summary>
public interface ITextBox : IFormControl, IEmail, IMinLength, IMaxLength, IReadOnly {
public interface ITextBox : IFormControl, IMinLength, IMaxLength, IReadOnly {
}
}
@@ -1,7 +0,0 @@
namespace Util.Ui.Operations.Forms.Validations {
/// <summary>
/// 电子邮件验证
/// </summary>
public interface IEmail {
}
}
@@ -43,5 +43,13 @@
/// 是否显示清除按钮
/// </summary>
public const string ShowClearButton = "show-clear-button";
/// <summary>
/// 最小行数
/// </summary>
public const string MinRows = "min-rows";
/// <summary>
/// 最大行数
/// </summary>
public const string MaxRows = "max-rows";
}
}
@@ -2,7 +2,7 @@
using Util.Ui.Components.Internal;
using Util.Ui.Configs;
using Util.Ui.Material.Configs;
using Util.Ui.Operations.Forms.Validations;
using Util.Ui.Material.Forms.Configs;
namespace Util.Ui.Material.Extensions {
/// <summary>
@@ -41,7 +41,7 @@ namespace Util.Ui.Material.Extensions {
/// <typeparam name="TComponent">组件类型</typeparam>
/// <param name="component">组件实例</param>
/// <param name="message">电子邮件验证错误消息</param>
public static TComponent Email<TComponent>( this TComponent component,string message = null ) where TComponent : IComponent,IEmail {
public static TComponent Email<TComponent>( this TComponent component,string message = null ) where TComponent : ITextBox {
var option = component as IOptionConfig;
option?.Config<Config>( config => {
config.SetAttribute( UiConst.Type, "email" );
@@ -63,5 +63,22 @@ namespace Util.Ui.Material.Extensions {
} );
return component;
}
/// <summary>
/// 转换为多行文本框
/// </summary>
/// <typeparam name="TComponent">组件类型</typeparam>
/// <param name="component">组件实例</param>
/// <param name="minRows">最小行数</param>
/// <param name="maxRows">最大行数</param>
public static TComponent ToTextArea<TComponent>( this TComponent component, int? minRows = null,int? maxRows = null ) where TComponent : ITextBox {
var option = component as IOptionConfig;
option?.Config<TextBoxConfig>( config => {
config.IsTextArea = true;
config.SetAttribute( MaterialConst.MinRows, minRows );
config.SetAttribute( MaterialConst.MaxRows, maxRows );
} );
return component;
}
}
}
@@ -0,0 +1,14 @@
using Util.Ui.Builders;
namespace Util.Ui.Material.Forms.Builders {
/// <summary>
/// Mat多行文本框包装器生成器
/// </summary>
public class TextAreaWrapperBuilder : TagBuilder {
/// <summary>
/// 初始化Mat多行文本框包装器生成器
/// </summary>
public TextAreaWrapperBuilder() : base( "mat-textarea-wrapper" ) {
}
}
}
@@ -18,5 +18,10 @@ namespace Util.Ui.Material.Forms.Configs {
/// <param name="context">TagHelper上下文</param>
public TextBoxConfig( Context context ) : base( context ) {
}
/// <summary>
/// 是否多行文本框
/// </summary>
public bool IsTextArea { get; set; }
}
}
@@ -28,14 +28,14 @@ namespace Util.Ui.Material.Forms.Renders {
protected override ITagBuilder GetTagBuilder() {
var builder = new SelectWrapperBuilder();
base.Config( builder );
Config( builder );
ConfigSelect( builder );
return builder;
}
/// <summary>
/// 配置
/// </summary>
private void Config( SelectWrapperBuilder builder ) {
private void ConfigSelect( SelectWrapperBuilder builder ) {
ConfigUrl( builder );
ConfigDataSource( builder );
ConfigResetOption( builder );
@@ -27,16 +27,36 @@ namespace Util.Ui.Material.Forms.Renders {
/// 获取标签生成器
/// </summary>
protected override ITagBuilder GetTagBuilder() {
var builder = new TextBoxWrapperBuilder();
var builder = CreateBuilder();
base.Config( builder );
Config( builder );
ConfigTextArea( builder );
ConfigTextBox( builder );
return builder;
}
/// <summary>
/// 配置
/// 创建标签生成器
/// </summary>
private void Config( TextBoxWrapperBuilder builder ) {
private TagBuilder CreateBuilder() {
if( _config.IsTextArea )
return new TextAreaWrapperBuilder();
return new TextBoxWrapperBuilder();
}
/// <summary>
/// 配置多行文本框
/// </summary>
private void ConfigTextArea( TagBuilder builder ) {
if( _config.IsTextArea == false )
return;
builder.AddAttribute( "[minRows]", _config.GetValue( MaterialConst.MinRows ) );
builder.AddAttribute( "[maxRows]", _config.GetValue( MaterialConst.MaxRows ) );
}
/// <summary>
/// 配置文本框
/// </summary>
private void ConfigTextBox( TagBuilder builder ) {
ConfigType( builder );
ConfigReadOnly( builder );
ConfigShowClearButton( builder );
@@ -67,7 +87,7 @@ namespace Util.Ui.Material.Forms.Renders {
/// <summary>
/// 配置验证操作
/// </summary>
private void ConfigValidations( TextBoxWrapperBuilder builder ) {
private void ConfigValidations( TagBuilder builder ) {
ConfigEmail( builder );
ConfigMinLength( builder );
ConfigMaxLength( builder );
@@ -83,7 +103,7 @@ namespace Util.Ui.Material.Forms.Renders {
/// <summary>
/// 配置最小长度验证
/// </summary>
private void ConfigMinLength( TextBoxWrapperBuilder builder ) {
private void ConfigMinLength( TagBuilder builder ) {
builder.AddAttribute( "[minLength]", _config.GetValue( UiConst.MinLength ) );
builder.AddAttribute( "minLengthMessage", _config.GetValue( UiConst.MinLengthMessage ) );
}
@@ -91,8 +111,10 @@ namespace Util.Ui.Material.Forms.Renders {
/// <summary>
/// 配置最大长度验证
/// </summary>
private void ConfigMaxLength( TextBoxWrapperBuilder builder ) {
private void ConfigMaxLength( TagBuilder builder ) {
builder.AddAttribute( "[maxLength]", _config.GetValue( UiConst.MaxLength ) );
}
}
}
@@ -0,0 +1,50 @@
using Microsoft.AspNetCore.Razor.TagHelpers;
using Util.Ui.Material.Forms.Configs;
using Util.Ui.Material.Forms.Renders;
using Util.Ui.Renders;
using Util.Ui.TagHelpers;
namespace Util.Ui.Material.Forms.TagHelpers {
/// <summary>
/// 文本框
/// </summary>
[HtmlTargetElement( "util-textarea" )]
public class TextAreaTagHelper : FormControlTagHelperBase {
/// <summary>
/// 是否显示清除按钮
/// </summary>
public bool ShowClearButton { get; set; }
/// <summary>
/// 只读
/// </summary>
public bool Readonly { get; set; }
/// <summary>
/// 最小长度
/// </summary>
public string MinLength { get; set; }
/// <summary>
/// 最小长度错误消息
/// </summary>
public string MinLengthMessage { get; set; }
/// <summary>
/// 最大长度
/// </summary>
public string MaxLength { get; set; }
/// <summary>
/// 最小行数
/// </summary>
public string MinRows { get; set; }
/// <summary>
/// 最大行数
/// </summary>
public string MaxRows { get; set; }
/// <summary>
/// 获取渲染器
/// </summary>
/// <param name="context">上下文</param>
protected override IRender GetRender( Context context ) {
return new TextBoxRender( new TextBoxConfig( context ) { IsTextArea = true } );
}
}
}
@@ -0,0 +1,328 @@
using Microsoft.AspNetCore.Razor.TagHelpers;
using Util.Ui.Configs;
using Util.Ui.Enums;
using Util.Ui.Material.Configs;
using Util.Ui.Material.Enums;
using Util.Ui.Material.Forms.TagHelpers;
using Util.Ui.Tests.XUnitHelpers;
using Xunit;
using Xunit.Abstractions;
using String = Util.Helpers.String;
namespace Util.Ui.Tests.Material.Forms.TagHelpers {
/// <summary>
/// 多行文本框测试
/// </summary>
public class TextAreaTagHelperTest {
/// <summary>
/// 输出工具
/// </summary>
private readonly ITestOutputHelper _output;
/// <summary>
/// 多行文本框
/// </summary>
private readonly TextAreaTagHelper _component;
/// <summary>
/// 测试初始化
/// </summary>
public TextAreaTagHelperTest( ITestOutputHelper output ) {
_output = output;
_component = new TextAreaTagHelper();
Config.IsValidate = false;
}
/// <summary>
/// 获取结果
/// </summary>
private string GetResult( TagHelperAttributeList contextAttributes = null, TagHelperAttributeList outputAttributes = null, TagHelperContent content = null ) {
return Helper.GetResult( _output, _component, contextAttributes, outputAttributes, content );
}
/// <summary>
/// 测试默认输出
/// </summary>
[Fact]
public void TestDefault() {
var result = new String();
result.Append( "<mat-textarea-wrapper></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult() );
}
/// <summary>
/// 测试设置名称
/// </summary>
[Fact]
public void TestName() {
var attributes = new TagHelperAttributeList { { UiConst.Name, "a" } };
var result = new String();
result.Append( "<mat-textarea-wrapper name=\"a\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试禁用
/// </summary>
[Fact]
public void TestDisabled() {
var attributes = new TagHelperAttributeList { { UiConst.Disabled, true } };
var result = new String();
result.Append( "<mat-textarea-wrapper [disabled]=\"true\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试只读
/// </summary>
[Fact]
public void TestReadOnly() {
var attributes = new TagHelperAttributeList { { UiConst.ReadOnly, true } };
var result = new String();
result.Append( "<mat-textarea-wrapper [readonly]=\"true\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试设置占位提示
/// </summary>
[Fact]
public void TestPlaceholder() {
var attributes = new TagHelperAttributeList { { UiConst.Placeholder, "a" } };
var result = new String();
result.Append( "<mat-textarea-wrapper placeholder=\"a\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试设置占位提示浮动位置
/// </summary>
[Fact]
public void TestFloatPlaceholder() {
var attributes = new TagHelperAttributeList { { MaterialConst.FloatPlaceholder, FloatType.Never } };
var result = new String();
result.Append( "<mat-textarea-wrapper floatPlaceholder=\"never\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试设置起始提示
/// </summary>
[Fact]
public void TestStartHint() {
var attributes = new TagHelperAttributeList { { MaterialConst.StartHint, "a" } };
var result = new String();
result.Append( "<mat-textarea-wrapper startHint=\"a\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试设置结束提示
/// </summary>
[Fact]
public void TestEndHint() {
var attributes = new TagHelperAttributeList { { MaterialConst.EndHint, "a" } };
var result = new String();
result.Append( "<mat-textarea-wrapper endHint=\"a\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试设置前缀
/// </summary>
[Fact]
public void TestPrefix() {
var attributes = new TagHelperAttributeList { { UiConst.Prefix, "a" } };
var result = new String();
result.Append( "<mat-textarea-wrapper prefixText=\"a\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试设置后缀文本
/// </summary>
[Fact]
public void TestSuffixText() {
var attributes = new TagHelperAttributeList { { MaterialConst.SuffixText, "a" } };
var result = new String();
result.Append( "<mat-textarea-wrapper suffixText=\"a\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试设置后缀FontAwesome图标
/// </summary>
[Fact]
public void TestSuffixFontAwesomeIcon() {
var attributes = new TagHelperAttributeList { { MaterialConst.SuffixFontAwesomeIcon, FontAwesomeIcon.Apple } };
var result = new String();
result.Append( "<mat-textarea-wrapper suffixFontAwesomeIcon=\"fa-apple\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试设置后缀Material图标
/// </summary>
[Fact]
public void TestSuffixMaterialIcon() {
var attributes = new TagHelperAttributeList { { MaterialConst.SuffixMaterialIcon, MaterialIcon.Android } };
var result = new String();
result.Append( "<mat-textarea-wrapper suffixMaterialIcon=\"android\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试设置后缀图标单击事件
/// </summary>
[Fact]
public void TestOnSuffixIconClick() {
var attributes = new TagHelperAttributeList { { MaterialConst.OnSuffixIconClick, "a" } };
var result = new String();
result.Append( "<mat-textarea-wrapper (onSuffixIconClick)=\"a\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试是否显示清除按钮
/// </summary>
[Fact]
public void TestShowClearButton() {
var attributes = new TagHelperAttributeList { { MaterialConst.ShowClearButton, false } };
var result = new String();
result.Append( "<mat-textarea-wrapper [showClearButton]=\"false\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试模型绑定
/// </summary>
[Fact]
public void TestModel() {
var attributes = new TagHelperAttributeList { { UiConst.Model, "a" } };
var result = new String();
result.Append( "<mat-textarea-wrapper [(model)]=\"a\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试必填项
/// </summary>
[Fact]
public void TestRequired() {
var attributes = new TagHelperAttributeList { { UiConst.Required, true } };
var result = new String();
result.Append( "<mat-textarea-wrapper [required]=\"true\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试必填项错误消息
/// </summary>
[Fact]
public void TestRequiredMessage() {
var attributes = new TagHelperAttributeList { { UiConst.RequiredMessage, "a" } };
var result = new String();
result.Append( "<mat-textarea-wrapper requiredMessage=\"a\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试最小长度
/// </summary>
[Fact]
public void TestMinLength() {
var attributes = new TagHelperAttributeList { { UiConst.MinLength, 3 } };
var result = new String();
result.Append( "<mat-textarea-wrapper [minLength]=\"3\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试最小长度,添加指定错误消息
/// </summary>
[Fact]
public void TestMinLength_Message() {
var attributes = new TagHelperAttributeList { { UiConst.MinLengthMessage, "a" } };
var result = new String();
result.Append( "<mat-textarea-wrapper minLengthMessage=\"a\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试最大长度
/// </summary>
[Fact]
public void TestMaxLength() {
var attributes = new TagHelperAttributeList { { UiConst.MaxLength, 3 } };
var result = new String();
result.Append( "<mat-textarea-wrapper [maxLength]=\"3\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试变更事件
/// </summary>
[Fact]
public void TestOnChange() {
var attributes = new TagHelperAttributeList { { UiConst.OnChange, "a" } };
var result = new String();
result.Append( "<mat-textarea-wrapper (onChange)=\"a\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试获得焦点事件
/// </summary>
[Fact]
public void TestOnFocus() {
var attributes = new TagHelperAttributeList { { UiConst.OnFocus, "a" } };
var result = new String();
result.Append( "<mat-textarea-wrapper (onFocus)=\"a\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试失去焦点事件
/// </summary>
[Fact]
public void TestOnBlur() {
var attributes = new TagHelperAttributeList { { UiConst.OnBlur, "a" } };
var result = new String();
result.Append( "<mat-textarea-wrapper (onBlur)=\"a\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试键盘按下事件
/// </summary>
[Fact]
public void TestOnKeydown() {
var attributes = new TagHelperAttributeList { { UiConst.OnKeydown, "a" } };
var result = new String();
result.Append( "<mat-textarea-wrapper (onKeydown)=\"a\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试最小行数
/// </summary>
[Fact]
public void TestMinRows() {
var attributes = new TagHelperAttributeList { { MaterialConst.MinRows, 3 } };
var result = new String();
result.Append( "<mat-textarea-wrapper [minRows]=\"3\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
/// <summary>
/// 测试最大行数
/// </summary>
[Fact]
public void TestMaxRows() {
var attributes = new TagHelperAttributeList { { MaterialConst.MaxRows, 3 } };
var result = new String();
result.Append( "<mat-textarea-wrapper [maxRows]=\"3\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( attributes ) );
}
}
}
@@ -337,5 +337,25 @@ namespace Util.Ui.Tests.Material.Forms {
result.Append( "<mat-textbox-wrapper [maxLength]=\"3\"></mat-textbox-wrapper>" );
Assert.Equal( result.ToString(), GetResult( _component.MaxLength( 3 ) ) );
}
/// <summary>
/// 测试多行文本框
/// </summary>
[Fact]
public void TestToTextArea_1() {
var result = new String();
result.Append( "<mat-textarea-wrapper [minRows]=\"3\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( _component.ToTextArea( 3) ) );
}
/// <summary>
/// 测试多行文本框
/// </summary>
[Fact]
public void TestToTextArea_2() {
var result = new String();
result.Append( "<mat-textarea-wrapper [maxRows]=\"5\" [minRows]=\"3\"></mat-textarea-wrapper>" );
Assert.Equal( result.ToString(), GetResult( _component.ToTextArea( 3,5 ) ) );
}
}
}