0

I have component with a textarea inside where user can set the rows via parameter. Now i want to make this textarea to grow as user types. The entered parameter becomes minimum number of rows.

What i have now:

Component.razor

<textarea rows="@Rows"
              value="@Value"
              @oninput=@ChangeValueAsync />

Component.razor.cs

private int MinRows { get; set; } = 1;

[Parameter]
public int Rows{ get; set; }

[Parameter]
public string Value { get; set; } = string.Empty;

[Parameter]
public EventCallback<string> ValueChanged { get; set; }

private async Task ChangeValueAsync(ChangeEventArgs args)
{
    Rows= Math.Max(MinRows, Math.Max(Value.Split('\n').Length, Value.Split('\r').Length)+1);
    await ValueChanged.InvokeAsync(args?.Value?.ToString());
}

protected override void OnParametersSet()
{
    MinRows = Math.Abs(Math.Max(1,Rows));
    base.OnParametersSet();
}

In debugger i can read the Rows number is calculated correctly, but textarea doesn't resize. Can anyone explain it to me why is the textarea still the same?

Oh.. The important thing is not to use JavaScript.

  • Does this answer your question? [Growing TextArea in Blazor](https://stackoverflow.com/questions/58169328/growing-textarea-in-blazor) – Dmitry Pavlov Feb 21 '23 at 17:20

1 Answers1

-1

Thank you for the quick answers. Below did the trick

HTML

<textarea value="@Value"
          style="overflow-x: hidden; overflow-y: scroll;"
          @oninput=@ChangeValueAsync
          @attributes="@InputAttributes" />

Code

private int MinRows { get; set; } = 1;

[Parameter]
public int Rows
{
    get
    {
        return _numRows;
    }
    set
    {
        if (value >= MinRows) _numRows= value;
        else _numRows = MinRows;
    }
}

private int _numRows = 1;

[Parameter]
public string Value { get; set; } = string.Empty;

[Parameter]
public EventCallback<string> ValueChanged { get; set; }

private async Task ChangeValueAsync(ChangeEventArgs args)
{
    int oldRows = Rows;
    await ValueChanged.InvokeAsync(args?.Value?.ToString());

    int newRows = GetNumberOfLines(args.Value.ToString());

    if (newRows == MinRows)
    {
        Rows = MinRows;
        ChangeAttribute("rows", Rows);
        StateHasChanged();
    }
    else
    {
        Rows = Math.Max(MinRows, newRows);
        if (oldRows < Rows)
        {
            ChangeAttribute("rows", Rows);
            StateHasChanged();
        }
    }
}

private int GetNumberOfLines(string s)
{
    int result = Math.Max(s.Split("\r\n").Length, 1);
    result = Math.Max(s.Split("\r").Length, result);
    result = Math.Max(s.Split("\n").Length, result);
    return result;
}

private void AddAttribute(string key, object value)
{
    if (!InputAttributes.ContainsKey(key))
        InputAttributes.Add(key, value);
}

private void ChangeAttribute(string key, object value)
{
    if (InputAttributes.ContainsKey(key)) InputAttributes.Remove(key);
        InputAttributes.Add(key, value);
}

protected override void OnInitialized()
{
    base.OnInitialized(); //InputAttributes gets initialized here
    MinRows = Rows;
    AddAttribute("rows", MinRows);
}