feat: Implement a real-time character counter and limit validation for the rich text editor, including timer management.
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
|
||||
@namespace SZUAbsolventenverein.Module.HallOfFame
|
||||
@implements IDisposable
|
||||
@inherits ModuleBase
|
||||
@inject IHallOfFameService HallOfFameService
|
||||
@inject NavigationManager NavigationManager
|
||||
@@ -42,6 +43,11 @@
|
||||
{
|
||||
<RichTextEditor Content="@_description" @ref="@_richTextEditorRef"
|
||||
Placeholder="Beschreibe deinen Werdegang..."></RichTextEditor>
|
||||
<div class="text-muted small mt-1">
|
||||
Aktuell: <strong
|
||||
class="@(_currentCharCount > _charLimit ? "text-danger" : "text-success")">@_currentCharCount</strong>
|
||||
von maximal @_charLimit Zeichen.
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -157,9 +163,32 @@ new Stylesheet("_content/SZUAbsolventenverein.Module.HallOfFame/Module.css")
|
||||
private string _modifiedby;
|
||||
private DateTime _modifiedon;
|
||||
private int _charLimit = 500;
|
||||
private int _currentCharCount = 0;
|
||||
private System.Timers.Timer _timer;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
_timer = new System.Timers.Timer(1000); // 1 sekunde
|
||||
_timer.Elapsed += async (s, e) =>
|
||||
{
|
||||
if (_richTextEditorRef != null && _descriptionLoaded)
|
||||
{
|
||||
try
|
||||
{
|
||||
var html = await _richTextEditorRef.GetHtml();
|
||||
var plainText = System.Text.RegularExpressions.Regex.Replace(html ?? "", "<.*?>", String.Empty);
|
||||
plainText = System.Net.WebUtility.HtmlDecode(plainText);
|
||||
if (_currentCharCount != plainText.Length)
|
||||
{
|
||||
_currentCharCount = plainText.Length;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
catch { } // Ignore interop errors during disposal
|
||||
}
|
||||
};
|
||||
_timer.Start();
|
||||
|
||||
try
|
||||
{
|
||||
// Load character limit setting
|
||||
@@ -263,6 +292,7 @@ new Stylesheet("_content/SZUAbsolventenverein.Module.HallOfFame/Module.css")
|
||||
{
|
||||
try
|
||||
{
|
||||
ClearModuleMessage();
|
||||
validated = true;
|
||||
// Get the HTML content from the rich text editor
|
||||
if (_richTextEditorRef != null)
|
||||
@@ -273,6 +303,16 @@ new Stylesheet("_content/SZUAbsolventenverein.Module.HallOfFame/Module.css")
|
||||
var interop = new Oqtane.UI.Interop(JSRuntime);
|
||||
if (await interop.FormValid(form))
|
||||
{
|
||||
// Custom character limit validation for rich text
|
||||
var plainText = System.Text.RegularExpressions.Regex.Replace(_description ?? "", "<.*?>", String.Empty);
|
||||
plainText = System.Net.WebUtility.HtmlDecode(plainText);
|
||||
if (plainText.Length > _charLimit)
|
||||
{
|
||||
AddModuleMessage($"Fehler: Die Beschreibung ist zu lang (Aktuell {plainText.Length}, Maximal {_charLimit} Zeichen).",
|
||||
MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
_status = status;
|
||||
|
||||
if (PageState.Action == "Add")
|
||||
@@ -333,4 +373,10 @@ new Stylesheet("_content/SZUAbsolventenverein.Module.HallOfFame/Module.css")
|
||||
AddModuleMessage("Fehler beim Löschen des Eintrags.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_timer?.Stop();
|
||||
_timer?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user