Text Area Component

Text area inputs are better at handling large blocks of text, but you might want to put a limit on just how much text the users can enter. It’s probably a good idea to also let the user know what the limit is and how close they are coming to that limit. To achieve this I’ve added a number-of-characters-remaining counter to the InputTextAreaBCA component. 

To use the feature all the developer has to do is enter the character limit in the MaximumLength property. If the developer does not specify the MaximumLength then it defaults to 8000 characters. I chose 8000 since that is the maximum for MS SQL Server VARCHAR(n). Any integer value could be used instead of 8000 up to the signed 32 bit integer maximum value of 2,147,483,647 which seems to be 1 more than what MS SQL Server VARCHAR(max) type can handle.

The number-of-characters-remaining feature is an HTML <small> element so that it appears smaller than the other text in the component. There is also a property named ClassRemaining so the developer can style the number-of-characters-remaining feature however they like.

The InputTextAreaBCA component markup and code.

@inherits InputTextBaseBCA

<div class="@ClassDiv">
    @if (!string.IsNullOrWhiteSpace(Label))
    {
        <label class="@ClassLabel"
           for="@Id">
            @Label
        </label>
    }

    <textarea class="form-control @ClassInput"
              placeholder="@Placeholder"
              id="@Id"
              title="@Title"
              @oninput="HandleOnInput"
              maxlength=@MaximumLength>
              @Value
    </textarea>

    <small class=@ClassRemaining>@CharactersRemaining characters remaining.</small>

    @foreach (var message in ValidationMessages)
    {
        <h6 class="@ClassValidationMessage"
        style="margin-top:3px;">
            @message
        </h6>
    }
</div>

@code{
    [Parameter]
    public int MaximumLength { get; set; } = 8000;

    public string ClassRemaining { get; set; }

    public int CharactersRemaining { get; set; }

    protected override void OnInitialized()
    {
        CalculateCharactersRemaining();

        base.OnInitialized();
    }

    private async Task HandleOnInput(ChangeEventArgs args)
    {
        string data = args?.Value?.ToString() ?? string.Empty;

        Value = data;

        CalculateCharactersRemaining();

        await ValueChanged.InvokeAsync(data);
    }

    private void CalculateCharactersRemaining()
    {
        if (Value != null)
        {
            CharactersRemaining = MaximumLength - Value.Length;
        }
    }
}

For the InputTexBasetBCA that the InputTextAreaBCA inherits from see this previous post:  https://blazorcomponentauthority.com/?p=43

This is an example of how to use the component.

<EditForm @ref=CarOne.EditForm Model="CarOne">
    <DataAnnotationsValidator />
    <ValidationSummary />
    <div class="row mt-3">
        <InputTextAreaBCA Label="COMMENTS"
                      @bind-Value=CarOne.Comments
                      OnChanged="HandleCarCommentsChaged"
                      For="Comments"
                      ClassDiv="col-9" />       
        <ButtonBusyBCA Label="SAVE"
                       OnClick=@((e) => HandleSave(e, CarOne))
                       ClassDiv="col-md-auto mt-4" />

    </div>
    <div class="row mt-3">
        <div class="col-12">
            @CarCommentChangedMessage
        </div>
    </div>
</EditForm>

@code {
    public Car CarOne { get; set; } = new Car(10, string.Empty, "A5", "2022");    

    private int ProcessTime { get; set; } = 2000;
    private string CarCommentChangedMessage { get; set; } = string.Empty;

    protected override void OnInitialized()
    { 
        CarOne.VIN = "12345";

        base.OnInitialized();
    }

    private async Task<EventCallback> HandleSave(EventArgs e, Car car)
    {
        var isValid = car.EditForm?.EditContext?.Validate();
        if (isValid == null || isValid == false)
        {
            return EventCallback.Empty;
        }

        await Task.Delay(ProcessTime);

        car?.EditForm?.EditContext?.MarkAsUnmodified();
        car?.EditForm?.EditContext?.Validate();
        StateHasChanged();
        return EventCallback.Empty;
    }

    protected void HandleCarCommentsChaged(string comments)
    {
        CarCommentChangedMessage = $"Comments were changed to {comments}";
    }
}

Site Footer

Sliding Sidebar