-1

I know that questions like this were asked many times in a similar way, but there isn't a solution given i'm satisified with...

The objectiv: I want to have something like a textarea (div contenteditable) in which the use can input some SQL. Some buzzword like "SELECT", "FROM".... should be colored while the user is entering the SQL. But the solution should be fluently, without losing the cursor-position and with accepting new lines. And it should be possible to change the coloring if the correct the wording afterwords.

The solutions i tried:

Way 1: Change color of specific words in textarea

I tried to wrap every word and put a span arround, like the example in the link. The Problem:

  • New lines will be deleted
  • it's not possible to add a space including the text afterwords
  • The cursor is always at the end

Way 2: regular expressions (i don't find the link again)

not to use "$(this).text()" but "$(this).html()", delete all tags (without breaks/new lines) and use a regex to color the words again. The word's are colored and the new lines still exists but the cursor possition is lost :/ So i tried to save the current cursor position and restore it at the end... but it doesn't work... this is my current code:

$("#SQL_editor").on("keyup", function(e){
            if (e.keyCode == 32){
                saveSelection();

                var pureHtml = $(this).html();
                pureHtml = pureHtml.replace(new RegExp('<span class="statement">', 'g'),  '');
                pureHtml = pureHtml.replace(new RegExp('</span>', 'g'),  '');
                pureHtml = pureHtml.replace(new RegExp('SELECT ', 'g'),  '<span class="statement">SELECT </span>');
                pureHtml = pureHtml.replace(new RegExp('FROM ', 'g'),  '<span class="statement">FROM </span>');
                pureHtml = pureHtml.replace(new RegExp('WHERE ', 'g'),  '<span class="statement">WHERE </span>');
                pureHtml = pureHtml.replace(new RegExp('NULL ', 'g'),  '<span class="statement">NULL </span>');
                pureHtml = pureHtml.replace(new RegExp('ON ', 'g'),  '<span class="statement">ON </span>');
                pureHtml = pureHtml.replace(new RegExp('IN ', 'g'),  '<span class="statement">IN </span>');
                pureHtml = pureHtml.replace(new RegExp('LIKE ', 'g'),  '<span class="statement">LIKE </span>');
                pureHtml = pureHtml.replace(new RegExp('NOT ', 'g'),  '<span class="statement">NOT </span>');
                $(this).html(pureHtml);

                restoreSelection();
                //placeCaretAtEnd($("#SQL_editor").get(0));
            }
        });



function saveSelection(){
                console.log("save");
                if(window.getSelection)//non IE Browsers
                {
                    savedRange = window.getSelection().getRangeAt(0);
                }
                else if(document.selection)//IE
                { 
                    savedRange = document.selection.createRange();  
                } 
            }

            function restoreSelection(){
                isInFocus = true;
                document.getElementById("SQL_editor").focus();
                if (savedRange != null) {
                    if (window.getSelection) {//non IE and there is already a selection{

                        var s = window.getSelection();
                        if (s.rangeCount > 0) 
                            s.removeAllRanges();
                        s.addRange(savedRange);
                    } else if (document.createRange)//non IE and no selection
                    {
                        window.getSelection().addRange(savedRange);
                    } else if (document.selection)//IE
                    {
                        savedRange.select();
                    }
                }
            }

Unfortunatelly it doesn't work. Currently the cursor focus is always at the beginning. But it shouldn't be always at the beginning and not always at the end... it should be on this position (in the appropriate row") where the user types the space...

Can anybody help me with this solution or supose a new one, that works better?

Thank's a lot

V

Sivasankar
  • 753
  • 8
  • 22
Der_V
  • 177
  • 1
  • 16
  • Hey, everybody, i don't have the solution for the specific problem, BUT i found a solution that works much better then every own development variant... the [post](https://stackoverflow.com/questions/34091730/get-and-set-cursor-position-with-contenteditable-div) links to codemirror that is better than my suggestions... **Here the SQL-Solution** : [link](http://codemirror.net/2/mode/sql/?mime=text/x-sql) – Der_V Jun 01 '17 at 06:04

1 Answers1

0
function placeCaretAtEnd(el) {
    el.focus();
    if (typeof window.getSelection != "undefined"
            && typeof document.createRange != "undefined") {
        var range = document.createRange();
        range.selectNodeContents(el);
        range.collapse(false);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    } else if (typeof document.body.createTextRange != "undefined") {
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.collapse(false);
        textRange.select();
    }
}

placeCaretAtEnd( document.getElementById("content") );

This question is already asked : contenteditable, set caret at the end of the text (cross-browser)

CristianS9
  • 160
  • 10
  • Hey, your first problem can be solved if you would change your line " var regex = new RegExp(search);" to "var regex = new RegExp(search, 'g');" like my example. The second problem is the same like mine... – Der_V May 25 '17 at 12:15
  • Done, cursor moves to the end now – CristianS9 May 25 '17 at 12:38
  • Yes, but that's not the 100% solution. The cursor should be at that point the user is typing at the moment... At the beginning the cursor is always at the end. But if the user want to correct some written text he is in the middle and the cursor should stay there and not moving to the end at every space... but i don't get it run :/ – Der_V May 26 '17 at 06:04