JSFiddle - React, Tailwind, and code Playground

HTML

<table>
    <tr>
      <td>
<textarea id="myTxt" onmouseup="getRange();" onkeyup="getRange();">
123456789
1234
123456789

</textarea>
</td>

      <td>
        <input type="button" value="&lt;&lt; Set Caret/Selection" onclick="setRange();" />
      </td>

      <td>
        <div>
          Start:
        </div>
        <input type="text" id="inpStart" /><br />
        <div>
          End:
        </div>
        <input type="text" id="inpEnd" />
        <div>
          Text To Insert:
        </div>
        <input type="text" id="insTxt" />
        <br /><br />
        <div>
          Caret position after insertion:
        </div>
        <div>Before:<input type="radio" name="insPos" value="before" checked="on"></div>
        <div>After:<input type="radio" name="insPos" value="after"></div>
        <div>Select Insertion:<input type="radio" name="insPos" value="select"></div>
      </td>
    </tr>
    <tr>
      <td colspan="3">
        <b>Note:</b>
        Select text in textarea using keyboard/mouse, start & end position of selection should show up in fields.<br/>
        Populate start and end fields and click the button to set caret position or select text.<br/>
        Populate start,end, insert and position fields to replace selected text and place caret/selection as selected in radio button options.
        Entering same value in both Start and End fields will set the caret position instead of highlighting a text selection.
      </td>
    </tr>
  </table>

CSS

textarea
{
    width: 300px;
    height: 300px;
}
table
{
    width: 600px;
}

JavaScript

$.fn.extend({
    caretSelection : function(options)
    {
        if(options && !isNaN(options.start) && !isNaN(options.end))
        {
            this.setCaretSelection(options);
        }
        else
        {
            return this.getCaretSelection();
        }
    },
    setCaretSelection : function(options)
    {
        var inp = this[0];
        if(inp.createTextRange)
        {
            var selRange = inp.createTextRange();
            selRange.collapse(true);
            selRange.moveStart('character', options.start);
            selRange.moveEnd('character',options.end - options.start);
            selRange.select();
        }
        else if(inp.setSelectionRange)
        {
            inp.focus();
            inp.setSelectionRange(options.start, options.end);
        }
    },
    getCaretSelection: function()
    {
        var inp = this[0], start = 0, end = 0;
        if(!isNaN(inp.selectionStart))
        {
            start = inp.selectionStart;
            end = inp.selectionEnd;
        }
        else if( inp.createTextRange )
        {
            var inpTxtLen = inp.value.length, jqueryTxtLen = this.val().length;
            var inpRange = inp.createTextRange(), collapsedRange = inp.createTextRange();

            inpRange.moveToBookmark(document.selection.createRange().getBookmark());
            collapsedRange.collapse(false);

            start = inpRange.compareEndPoints('StartToEnd', collapsedRange) > -1 ? jqueryTxtLen : inpRange.moveStart('character', -inpTxtLen);
            end = inpRange.compareEndPoints('EndToEnd', collapsedRange) > -1 ? jqueryTxtLen : inpRange.moveEnd('character', -inpTxtLen);
        }
        return {start: Math.abs(start), end: Math.abs(end)};

    },
    replaceCaretSelection: function(options)
    {
        var pos = this.caretSelection();
        this.val( this.val().substring(0,pos.start) + options.text + this.val().substring(pos.end) );
        if(options.insPos == 'before')
        {
           ...