Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove last x characters before carret position

Short version:

I have a contenteditable div. I want to remove the last x chars before carret postion.

Long version:

If someone types a [ in the contenteditable div there should appear an autosuggest list, filled by an ajax call. This is allready working. I can also insert the selected suggestion at carret position and add a ]. But the chars, already typed by the user, should be deleted before appending the suggestion. The bracket [ is not only the "trigger-char" but also a markdown-like format element.

Example:

Text in the div ("|" stands for carret): Lorem ipsum| sit lorem ipsum dolor

User now types [do to start auto suggestion: Lorem ipsum [do| sit lorem ipsum dolor

dolor is suggested and inserted after carret: Lorem ipsum [do|dolor sit lorem ipsum dolor

Problem: the allready typed chars do should be removed before inserting the suggestion

Desired behaviour: Lorem ipsum [dolor] sit lorem ipsum dolor

Attempted Solutions:

Insert text at cursor in a content editable div - working but i can't remove the last chars https://developer.mozilla.org/en-US/docs/Web/API/Selection - tried to get some ideas from MDN, but no idea how to change the selection's textNode's content

Code:

Extract the string between last "[" and carret to search for suggestions in DB:

var sel = window.getSelection();
var cords = getCaretCoords();
var searchQuery = extractSearchQuery(sel.anchorNode.data, sel.anchorOffset, "[");

function extractSearchQuery(searchString, caretPos, triggerString) {
    //cut everything after carret
    searchString = searchString.slice(searchString.lastIndexOf(triggerString) + 1, caretPos);
    return searchString;
}

Insert the suggestion after carret:

function insertTextAtCursor(text) {
    var sel, range, html;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = sel.getRangeAt(0);
            range.deleteContents();
            var newTextNode = document.createTextNode(text);
            range.insertNode(newTextNode);
        }
    } else if (document.selection && document.selection.createRange) {
        document.selection.createRange().text = text;
    }
}
like image 704
superjojo140 Avatar asked Dec 19 '17 12:12

superjojo140


People also ask

How do I remove the last 3 characters from a string?

To remove the last three characters from the string you can use string. Substring(Int32, Int32) and give it the starting index 0 and end index three less than the string length. It will get the substring before last three characters.

How do I remove a first and last character from a string in typescript?

To remove the first and last characters from a string, call the slice() method, passing it 1 and -1 as parameters, e.g. str. slice(1, -1) . The slice method returns a new string containing the extracted section from the original string.


1 Answers

With the following assumptions and definitions:

  • You know the location of the "[" as this triggers the auto-suggest to start working after all. Let's call this indexbracket
  • You know what text has been typed after the bracket as you used that for the auto-suggestion. Let's call this lookupstring

Then you should replace the content of your div by:

divtext = divtext.substring(0, indexbracket) + divtext.substring(indexbracket + lookupstring.length + 1);

Example: (in which I used different methods to find indexbracket etc. than you probably used)

var divtext = "Lorum ipsum [doAUTOSUGGESTEDTEXT sit";
var indexbracket = divtext.indexOf('[');
var lookupstring = "do";
divtext = divtext.substring(0, indexbracket) + divtext.substring(indexbracket+lookupstring.length+1);
console.log(divtext);

Update after edit of post Given your need for the position of the caret, you could opt to "manually" reset the location of the caret after replacing the text, see this excellent answer here: https://stackoverflow.com/a/512542/3000771

like image 137
rolfv1 Avatar answered Oct 22 '22 00:10

rolfv1