Scroll to bottom of text in RichTextEditor

I have a serverside Blazor app, and am using the RichTextEditor control. My app is .net 7 blazor app

I am trying to scroll to the bottom of the text in the editor programatically, but it errors when I use the code I found which says it should work.

In my _Host.cshtml file I have the following:

<script>

    ScrollToBottom = function (id) {

        var el = document.getElementById(id);

        if (el) {

            // To find last direct childnode

            var editEleLastNode = el.querySelector('.e-richtexteditor .e-content').lastChild;


            // Find the all text node from editor element

            var textNodes = getTextNodesUnder(el, editEleLastNode);


            // Last textnode, where we going to set a cursor

            var lastTextNode = textNodes[textNodes.length - 1];

            var selectioncursor = new ej.richtexteditor.NodeSelection();

            var range = document.createRange();

            // to set the range

            range.setStart(lastTextNode, 1);

            // to set the cursor

            selectioncursor.setRange(document, range);

        }

        return true;

    }


    // Find the all text node from given node

    function getTextNodesUnder(document, node) {

        var nodes = [];

        for (node = node.firstChild; node; node = node.nextSibling) {

            if (node.nodeType === 3) {

                nodes.push(node);

            }

            else {

                nodes = nodes.concat(getTextNodesUnder(document, node));

            }

        }

        return nodes;

    }

</script>


I am calling it in my razor page with:

    private async Task Scroller()

    {

       await jsRuntime.InvokeAsync<bool>("ScrollToBottom", "MainWindow");

    }


When I call the Scroller() function in my C# code I get the error:

Microsoft.JSInterop.JSException: 'ej is not defined

ReferenceError: ej is not defined

    at ScrollToBottom (https://localhost:44370/:77:35)

    at https://localhost:44370/_framework/blazor.server.js:1:3506

    at new Promise (<anonymous>)


Any ideas please?


5 Replies

VY Vinothkumar Yuvaraj Syncfusion Team October 16, 2023 01:33 PM UTC

Hi Mark Hodgkinson,


We have validated your reported query. You can use the following method to scroll down to the last element in the Rich Text Editor. Then, use the following methods to get the nodeSelection from the Rich Text Editor instance. Please refer to the attached sample and code below for further clarification.


Index.razor

```

<button @onclick="@Scroller">Click</button>

<div class="control-section" id="MainWindow">

    <SfRichTextEditor ID="richTextEditor">

    </SfRichTextEditor>

</div>

 

@code {

    private async Task Scroller()

    {

await JSRuntime.InvokeAsync<bool>("ScrollToBottom", "MainWindow");

    }

}

```


_Layout.cshtml

    <script>

ScrollToBottom = function (id) {

  var el = document.getElementById(id);

  if (el) {

                // To find last direct childnode

                var editEleLastNode = el.querySelector('.e-richtexteditor .e-content').lastChild;

                // Find the all text node from editor element

                var textNodes = getTextNodesUnder(el, editEleLastNode);

// Last textnode, where we going to set a cursor

                var lastTextNode = textNodes[textNodes.length - 1];

                var selectioncursor = sfBlazor.instances.richTextEditor.formatter.editorManager.nodeSelection;

                var range = document.createRange();

                // to set the range

                range.setStart(lastTextNode, 1);

                // to set the cursor

selectioncursor.setRange(document, range);

                lastTextNode.parentElement.scrollIntoView({ behavior: 'smooth', block: 'end' })

    }

  return true;

}

// Find the all text node from given node

function getTextNodesUnder(document, node) {

   var nodes = [];

     for (node = node.firstChild; node; node = node.nextSibling) {

                if (node.nodeType === 3) {

                    nodes.push(node);

                }

                else {

                    nodes = nodes.concat(getTextNodesUnder(document, node));

                }

    }

  return nodes;

}

</script>


Please get back to us if you have any further questions or concerns.


Regards,

Vinothkumar


Attachment: BlazorApp1_f4828a9e_d43bcbcd.zip


MH Mark Hodgkinson October 17, 2023 08:16 AM UTC

Thank you for the reply.  Would this solution work for a web assembly Blazor app also?


If not, what would the changes need to be to the solution you provided?

Thank you!



VJ Vinitha Jeyakumar Syncfusion Team October 18, 2023 05:37 AM UTC

Hi Mark Hodgkinson,

The solution works for the web assembly project too. Please let us know if you faced any issues.

Regards,
Vinitha


MH Mark Hodgkinson October 18, 2023 08:17 AM UTC

I face an issue! - it is the same issue whether it is server side or web assembly


I get an exception raised when executing the command:

await jsRuntime.InvokeAsync<bool>("ScrollToBottom", "MainWindow");


The error is:

'Cannot read properties of undefined (reading 'formatter')TypeError: Cannot read properties of undefined (reading 'formatter') at ScrollToBottom (https://localhost:7281/:53:73) at https://localhost:7281/_framework/blazor.webassembly.js:1:3337 at new Promise (<anonymous>) at Object.beginInvokeJSFromDotNet (https://localhost:7281/_framework/blazor.webassembly.js:1:3311) at Object.Gt [as invokeJSFromDotNet] (https://localhost:7281/_framework/blazor.webassembly.js:1:62569) at Object.Ii (https://localhost:7281/_framework/dotnet.7.0.11.1pg2jmtebi.js:5:71974) at _mono_wasm_invoke_js_blazor (https://localhost:7281/_framework/dotnet.7.0.11.1pg2jmtebi.js:14:103886) at wasm://wasm/00993932:wasm-function[313]:0x1d6b8 at wasm://wasm/00993932:wasm-function[283]:0x1cae6 at wasm://wasm/00993932:wasm-function[221]:0xe1d6'



VY Vinothkumar Yuvaraj Syncfusion Team October 19, 2023 09:15 AM UTC

Hi Mark Hodgkinson,


We have validated the query, and we suspect that the ‘Cannot read properties of undefined (reading 'formatter')’ error occurred because 'sfBlazor.instances.richTextEditor' got null. To solve your issue, could you please ensure that you have entered the Rich Text Editor ID next to sfBlazor.instances to get the Rich Text Editor instance (sfBlazor.instances.richTextEditor). Please see the following code for your reference.


   <SfRichTextEditor ID="richTextEditor">

   </SfRichTextEditor>

 

   var selectioncursor = sfBlazor.instances.richTextEditor.formatter.editorManager.nodeSelection;


Loader.
Up arrow icon