Growing TextArea in Blazor

11,368

As long as you know how many lines are in your text, you can just use the "rows" attribute on the TextView, like this

<textarea rows="@Rows"
          @bind-value="MyText"
          @bind-value:event="oninput" />

And in your code, you can determine the value for Rows

Note, I use Math.Max(Rows,2) to keep a minimum of two rows.

private void CalculateSize(string value)
{
  Rows = Math.Max(value.Split('\n').Length, value.Split('\r').Length);
  Rows = Math.Max(Rows, 2);
}

I call CalculateSize from code that handles changes to "MyText" - either a custom setter like this or A.N.Other method

string _myText;
protected string MyText
{
  get => _myText;
  set
  {
    _myText = value; 
    CalculateSize(value);
  }
}

The maximum height can easily be set either through CSS for a design approach or by adding another constraint to the CalculateSize method.

private void CalculateSize(string value)
{
  Rows = Math.Max(value.Split('\n').Length, value.Split('\r').Length);
  Rows = Math.Max(Rows, MIN_ROWS);
  Rows = Math.Min(Rows, MAX_ROWS);
}

Option 2

If you want simplicity and don't mind a bit of inline JS (if you do, then it's time to crack open the JSInterop....)

<textarea 
      rows="2" 
      placeholder="Sample text."
      style="resize:both;"
      oninput="this.style.height = 'auto'; this.style.height = (this.scrollHeight) + 'px';">
</textarea>

Option 3

If you did want to use JSInterop, you could do something like this or place your code in a JS file and include it in the page.

<textarea id="MyTextArea"
      rows="2" 
      placeholder="Sample text."
      @oninput="Resize"></textarea>

<label>This area is @(MyHeight)px</label>
@code
{
[Inject] IJSRuntime JSRuntime { get; set; }
double MyHeight=0;
async Task Resize()
{
    var result = await JSRuntime.InvokeAsync<object>("eval",@"(function() {
            MyTextArea.style.height='auto';
            MyTextArea.style.height=(MyTextArea.scrollHeight)+'px';
            return MyTextArea.scrollHeight;
        })()");
    Double.TryParse(result.ToString(), out MyHeight);
}
}
Share:
11,368

Related videos on Youtube

FusionBreak
Author by

FusionBreak

Updated on June 04, 2022

Comments

  • FusionBreak
    FusionBreak almost 2 years

    I need a text area that grows as the number of lines increases. As soon as lines are deleted, the TextArea should shrink again. In the best case with a maximum height.

    How it works with Javascript I could already read here: textarea-to-resize-based-on-content-length

    But in Blazor I have unfortunately, as far as I know, no "scrollHeight" available for the TextArea.

    (My problem relates to the Blazor framework, which allows browser frontend development using C# (+HTML/CSS) and not a desktop UI like WPF/WinForms.)

  • FusionBreak
    FusionBreak over 4 years
    I have also tried a solution similar to the one you described here. I also counted line breaks and created the rows from them. The problem is when writing a line that is longer than the TextArea without having a line break. See here: gifyu.com/image/kKPL
  • FusionBreak
    FusionBreak over 4 years
    I was really hoping it would work without JS already. Maybe in the future. Many thanks for the help! Option 2 is my choice.
  • tocqueville
    tocqueville over 4 years
    Option 2 only works oninput, when the textarea loads with its initial value it will always have 2 rows. I haven't found a way to fix that.
  • Thorgeir
    Thorgeir over 4 years
    @tocqueville change the rows attribute to 1 to on the textarea to fix the inital two lines
  • Vencovsky
    Vencovsky almost 4 years
    I wasn't looking for this answer but I loved how you used eval just to call some javascript, this is so good. Thanks!
  • Christopher Edwards
    Christopher Edwards about 3 years
    Why do you count both \r and \n? Does the newline character differ between different browsers or something?
  • Mister Magoo
    Mister Magoo about 3 years
    @ChristopherEdwards You never know where the text came from and what it contains - could have \n or \r or both, hopefully it is consistent though or it all goes to pot.
  • Bennyboy1973
    Bennyboy1973 almost 3 years
    a bit late, but another +1 for "eval"