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