javascriptangularangularjsangularjs-directive

How to insert text at current cursor position in Summernote editor in Angular 12


Description:

I have a Summernote editor (https://www.npmjs.com/package/ngx-summernote) in my Angular 12 project, and I also have a button outside the editor. When the user clicks on this button, I want to insert the text "Heeello" at the current cursor position in the editor.

I've tried accessing the editor object through the ngx-summernote directive, but I keep getting errors like "Cannot read properties of undefined". I've also looked at the Summernote API documentation, but I'm not sure how to use it in my Angular project.

<div [ngxSummernote]="config"></div>

Component.ts

import { NgxSummernoteDirective } from 'ngx-summernote';

@ViewChild(NgxSummernoteDirective)  ngxSummernote: NgxSummernoteDirective;

 config = {
    placeholder: '',
    tabsize: 2,
    height: '200px',
    uploadImagePath: '/api/upload',
    toolbar: [
        ['misc', ['codeview', 'undo', 'redo']],
        ['style', ['bold', 'italic', 'underline', 'clear']],
        ['font', ['bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript', 'clear']],
        ['fontsize', ['fontname', 'fontsize', 'color']],
        ['para', ['style', 'ul', 'ol', 'paragraph', 'height']],
        ['insert', ['table', 'picture', 'link', 'video', 'hr']]
    ],
    fontNames: ['Helvetica', 'Arial', 'Arial Black', 'Comic Sans MS', 'Courier New', 'Roboto', 'Times']
  }
  ...
}

addText(){
  console.log(this.ngxSummernote);
    console.log(this.ngxSummernote['_editor'][0] )

    this.ngxSummernote['_editor'].insertText('as');
    const currentPosition = this.ngxSummernote['_editor'].sumo.getSelection().index;
    console.log(currentPosition)
    // const currentCursorPosition = ($(this.mySummernote.nativeElement) as any).summernote('code').length;

    // const textToInsert = 'Hello';
}

None of the above is working. Here's the StackBlitz link to my code: https://stackblitz.com/edit/angular-summernote-demo-duemtn?file=src%2Fapp%2Fapp.component.html,src%2Fapp%2Fapp.component.ts

Can someone help me figure out how to insert text at the current cursor position in the Summernote editor in Angular 12?


Solution

  • I have got something which is working but it wont be the one of the best solution. To insert text at the current cursor position in a Summernote editor in Angular 12, you can use the following approach:

    Get the current selection and range:

    const editableDiv = document.querySelector('.note-editable'); 
    // please check as per the stackblitz demo I saw this as the classname for the editable content area
    const sel = window.getSelection();
    const range = sel.getRangeAt(0);
    const startPos = range.startOffset;
    

    Insert the HTML at the current cursor position:

    range.deleteContents();
    const newElem = document.createElement('span');
    newElem.innerHTML = htmlToInsert;
    range.insertNode(newElem);
    
    

    Set the cursor position to the end of the inserted HTML:

    range.setStartAfter(newElem);
    range.collapse(true);
    sel.removeAllRanges();
    sel.addRange(range);
    editableDiv.focus();
    

    This code sets the cursor position to the end of the inserted HTML.

    Update the editor content and set the cursor position:

    const updatedHtml = editableDiv.innerHTML;
    const cursorPosition = startPos + htmlToInsert.length;
    const newRange = document.createRange();
    newRange.setStart(editableDiv.childNodes[0], cursorPosition);
    newRange.setEnd(editableDiv.childNodes[0], cursorPosition);
    sel.removeAllRanges();
    sel.addRange(newRange);
    editableDiv.focus();
    

    This code updates the editor content, sets the cursor position to the end of the inserted text, and focuses on the editor.

    Note that this approach uses the document object to manipulate the DOM, which is not recommended in Angular applications. Instead, you should use Angular's view encapsulation and directives to manipulate the editor content but as I can there are no methods available in the current directive to insert the content at current index.