mirror of
https://gitee.com/LongbowEnterprise/BootstrapBlazor.git
synced 2024-11-30 02:58:37 +08:00
!2788 feat(#I57PKH): markdown support validate
* doc: 更新示例 * refactor: 重构代码 * feat: Markdown 增加 SetValue 方法 * doc: 增加 Markdown 客户端验证示例 * style: 增加 Validate 样式 * chore: bump version 6.1.6 * feat: Markdown 组件支持 Validate
This commit is contained in:
parent
71c55f481d
commit
469d7afd68
@ -1359,6 +1359,9 @@
|
||||
"BrowserButtonText2": "Insert a picture",
|
||||
"BrowserButtonText3": "The cursor moves to the end",
|
||||
"BrowserText": "coconut palm",
|
||||
"ValidateTitle": "Validate",
|
||||
"ValidateIntro": "Check data validity and prompt automatically based on custom validation rules",
|
||||
"SubmitText": "Save",
|
||||
"P7": "Set the <code>markdown</code> editor to browse-only mode, <code>IsViewer='true'</code>",
|
||||
"Att1": "Control height",
|
||||
"Att2": "The minimum height of the control",
|
||||
|
@ -1361,6 +1361,9 @@
|
||||
"BrowserButtonText3": "光标移动到最后",
|
||||
"BrowserText": "椰子树",
|
||||
"P7": "设置<code>Markdown</code> 编辑器为纯浏览模式,<code>IsViewer='true'</code>",
|
||||
"ValidateTitle": "客户端验证",
|
||||
"ValidateIntro": "根据自定义验证规则进行数据有效性检查并自动提示",
|
||||
"SubmitText": "提交",
|
||||
"MarkdownString": "测试",
|
||||
"Att1": "控件高度",
|
||||
"Att2": "控件最小高度",
|
||||
|
@ -39,7 +39,7 @@
|
||||
<DemoBlock Title="@Localizer["Block1Title"]" Introduction="@Localizer["Block1Intro"]" Name="Normal">
|
||||
<p>@((MarkupString)Localizer["P5"].Value)</p>
|
||||
<div style="width: 100%; height: 300px;">
|
||||
<Markdown Language="@Language" Value="@MarkdownString" OnValueChanged="OnValueChanged" Html="@HtmlString" OnHtmlChanged="OnHtmlChanged" />
|
||||
<Markdown Language="@Language" @bind-Value="@MarkdownString" @bind-Html="@HtmlString" />
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<textarea class="form-control" rows="6" disabled="disabled">
|
||||
@ -55,7 +55,7 @@
|
||||
|
||||
<DemoBlock Title="@Localizer["Block2Title"]" Introduction="@Localizer["Block2Intro"]" Name="Async">
|
||||
<Button Text="@Localizer["ButtonText"]" IsAsync="true" OnClick="GetAsyncString" Icon="fa fa-fa" class="mb-3" />
|
||||
<Markdown Value="@AsyncValue"></Markdown>
|
||||
<Markdown Value="@AsyncValue" @ref="MarkdownSetValue"></Markdown>
|
||||
</DemoBlock>
|
||||
|
||||
<DemoBlock Title="@Localizer["Block3Title"]" Introduction="@Localizer["Block3Intro"]" Name="CommonProperty">
|
||||
@ -85,4 +85,17 @@
|
||||
</div>
|
||||
</DemoBlock>
|
||||
|
||||
<DemoBlock Title="@Localizer["ValidateTitle"]" Introduction="@Localizer["ValidateIntro"]" Name="Validate">
|
||||
<ValidateForm Model="@Model">
|
||||
<div class="row g-3 form-inline">
|
||||
<div class="col-12">
|
||||
<Markdown @bind-Value="Model.Name"></Markdown>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<Button ButtonType="ButtonType.Submit" Icon="fa fa-fw fa-save" Text="@Localizer["SubmitText"]" />
|
||||
</div>
|
||||
</div>
|
||||
</ValidateForm>
|
||||
</DemoBlock>
|
||||
|
||||
<AttributeTable Items="GetAttributes()"></AttributeTable>
|
||||
|
@ -33,12 +33,20 @@ console.log('test');
|
||||
[NotNull]
|
||||
private Markdown? Markdown { get; set; }
|
||||
|
||||
[NotNull]
|
||||
private Markdown? MarkdownSetValue { get; set; }
|
||||
|
||||
[NotNull]
|
||||
private Foo? Model { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// OnInitializedAsync 方法
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Model = new() { Name = "Name", Education = EnumEducation.Primary, DateTime = DateTime.Now };
|
||||
|
||||
Language = CultureInfo.CurrentUICulture.Name;
|
||||
MarkdownString = $"### {Localizer["MarkdownString"]}";
|
||||
Version = await VersionManager.GetVersionAsync("bootstrapblazor.markdown");
|
||||
@ -48,20 +56,7 @@ console.log('test');
|
||||
{
|
||||
await Task.Delay(600);
|
||||
AsyncValue = $"### {DateTime.Now}";
|
||||
}
|
||||
|
||||
private Task OnValueChanged(string value)
|
||||
{
|
||||
MarkdownString = value;
|
||||
StateHasChanged();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task OnHtmlChanged(string value)
|
||||
{
|
||||
HtmlString = value;
|
||||
StateHasChanged();
|
||||
return Task.CompletedTask;
|
||||
await MarkdownSetValue.SetValue(AsyncValue);
|
||||
}
|
||||
|
||||
private IEnumerable<AttributeItem> GetAttributes() => new AttributeItem[]
|
||||
|
@ -3,7 +3,7 @@
|
||||
<Import Project="..\..\..\bundleconfig.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<Version>6.1.5</Version>
|
||||
<Version>6.1.6</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
@ -11,3 +11,11 @@
|
||||
border-radius: unset;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.is-invalid > .toastui-editor-defaultUI {
|
||||
border: 1px solid var(--bs-danger);
|
||||
}
|
||||
|
||||
.is-valid > .toastui-editor-defaultUI {
|
||||
border: 1px solid var(--bs-success);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
@namespace BootstrapBlazor.Components
|
||||
@inherits BootstrapComponentBase
|
||||
@inherits ValidateBase<string>
|
||||
|
||||
<div @attributes="@AdditionalAttributes" @ref="MarkdownElement" />
|
||||
<div @attributes="@AdditionalAttributes" id="@Id" class="@GetClassString()" @ref="MarkdownElement" />
|
||||
|
@ -54,30 +54,6 @@ public partial class Markdown : IAsyncDisposable
|
||||
[Parameter]
|
||||
public string? Placeholder { get; set; }
|
||||
|
||||
private string? _value;
|
||||
/// <summary>
|
||||
/// 获得/设置 组件值
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string? Value
|
||||
{
|
||||
get => _value;
|
||||
set
|
||||
{
|
||||
if (_value != value)
|
||||
{
|
||||
_value = value;
|
||||
IsRender = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 组件值回调
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<string?, Task>? OnValueChanged { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 组件 Html 代码
|
||||
/// </summary>
|
||||
@ -88,7 +64,7 @@ public partial class Markdown : IAsyncDisposable
|
||||
/// 获得/设置 组件 Html 代码回调
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<string?, Task>? OnHtmlChanged { get; set; }
|
||||
public EventCallback<string> HtmlChanged { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取/设置 组件是否为浏览器模式
|
||||
@ -108,13 +84,18 @@ public partial class Markdown : IAsyncDisposable
|
||||
[Parameter]
|
||||
public bool EnableHighlight { get; set; } = false;
|
||||
|
||||
private readonly MarkdownOption _markdownOption = new();
|
||||
|
||||
private bool IsRender { get; set; }
|
||||
private MarkdownOption Option { get; } = new();
|
||||
|
||||
[NotNull]
|
||||
private JSModule<Markdown>? Module { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得 组件样式
|
||||
/// </summary>
|
||||
protected string? GetClassString() => CssBuilder.Default()
|
||||
.AddClass(CssClass).AddClass(ValidCss)
|
||||
.Build();
|
||||
|
||||
/// <summary>
|
||||
/// OnInitialized 方法
|
||||
/// </summary>
|
||||
@ -122,16 +103,16 @@ public partial class Markdown : IAsyncDisposable
|
||||
{
|
||||
base.OnInitialized();
|
||||
|
||||
_markdownOption.PreviewStyle = PreviewStyle.ToDescriptionString();
|
||||
_markdownOption.InitialEditType = InitialEditType.ToDescriptionString();
|
||||
_markdownOption.Language = Language;
|
||||
_markdownOption.Placeholder = Placeholder;
|
||||
_markdownOption.Height = $"{Height}px";
|
||||
_markdownOption.MinHeight = $"{MinHeight}px";
|
||||
_markdownOption.InitialValue = Value ?? "";
|
||||
_markdownOption.Viewer = IsViewer;
|
||||
_markdownOption.Theme = IsDark ? "dark" : "light";
|
||||
_markdownOption.EnableHighlight = EnableHighlight;
|
||||
Option.PreviewStyle = PreviewStyle.ToDescriptionString();
|
||||
Option.InitialEditType = InitialEditType.ToDescriptionString();
|
||||
Option.Language = Language;
|
||||
Option.Placeholder = Placeholder;
|
||||
Option.Height = $"{Height}px";
|
||||
Option.MinHeight = $"{MinHeight}px";
|
||||
Option.InitialValue = Value ?? "";
|
||||
Option.Viewer = IsViewer;
|
||||
Option.Theme = IsDark ? "dark" : "light";
|
||||
Option.EnableHighlight = EnableHighlight;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -145,14 +126,8 @@ public partial class Markdown : IAsyncDisposable
|
||||
|
||||
if (firstRender)
|
||||
{
|
||||
IsRender = false;
|
||||
Module = await JSRuntime.LoadModule<Markdown>("./_content/BootstrapBlazor.Markdown/js/bootstrap.blazor.markdown.min.js", this, false);
|
||||
await Module.InvokeVoidAsync("bb_markdown", MarkdownElement, _markdownOption, nameof(Update));
|
||||
}
|
||||
|
||||
if (IsRender)
|
||||
{
|
||||
await Module.InvokeVoidAsync("bb_markdown", MarkdownElement, Value ?? "", "setMarkdown");
|
||||
await Module.InvokeVoidAsync("bb_markdown", MarkdownElement, Option, nameof(Update));
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,28 +141,35 @@ public partial class Markdown : IAsyncDisposable
|
||||
{
|
||||
if (vals.Length == 2)
|
||||
{
|
||||
var hasChanged = !EqualityComparer<string>.Default.Equals(vals[0], Value);
|
||||
if (hasChanged)
|
||||
{
|
||||
_value = vals[0];
|
||||
if (OnValueChanged != null)
|
||||
{
|
||||
await OnValueChanged(Value);
|
||||
}
|
||||
}
|
||||
CurrentValueAsString = vals[0];
|
||||
|
||||
hasChanged = !EqualityComparer<string>.Default.Equals(vals[1], Html);
|
||||
var hasChanged = !EqualityComparer<string>.Default.Equals(vals[1], Html);
|
||||
if (hasChanged)
|
||||
{
|
||||
Html = vals[1];
|
||||
if (OnHtmlChanged != null)
|
||||
if (HtmlChanged.HasDelegate)
|
||||
{
|
||||
await OnHtmlChanged(Html);
|
||||
await HtmlChanged.InvokeAsync(Html);
|
||||
}
|
||||
}
|
||||
|
||||
if (ValidateForm != null)
|
||||
{
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置 Value 方法
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public new ValueTask SetValue(string value)
|
||||
{
|
||||
CurrentValueAsString = value;
|
||||
return Module.InvokeVoidAsync("bb_markdown", MarkdownElement, Value ?? "", "setMarkdown");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行方法
|
||||
/// </summary>
|
||||
@ -200,7 +182,7 @@ public partial class Markdown : IAsyncDisposable
|
||||
/// Dispose 方法
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual async ValueTask DisposeAsync(bool disposing)
|
||||
protected override async ValueTask DisposeAsyncCore(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
@ -210,13 +192,4 @@ public partial class Markdown : IAsyncDisposable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose 方法
|
||||
/// </summary>
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
await DisposeAsync(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user