Mina Gabriel
Mina Gabriel

Reputation: 25180

Wrap certain word with <span> using jquery

I have the following div:

<div id="query" style="width:500px; height:200px;border:1px solid black"
 spellcheck="false" contenteditable="true"></div>​

where Clients can write their SQL queries. What I was trying to do is wrap words the client enters right after hitting Space with a span and give this span a certain class according to the word typed:

example

If the client types select i need to wrap this select word like this in the div:

<span class='select'> SELECT </span> <span> emp_name </span>

CSS

.select{color:blue ;text-transform:uppercase;}

It is something very similar to what jsFiddle does. How can i achieve this?

Here is what i have tried so far : jsFiddle

$(function(){
    $('div').focus() ;
    $('div').keyup(function(e){
        //console.log(e.keyCode) ;
        if(e.keyCode == 32){
            var txt = $('div').text() ;
            var x = 'SELECT' ;
            $('div:contains("'+x+'")').wrap("<span style='color:blue ;
      text-transform:uppercase;'>") ;
            if(txt == 'SELECT'){
                console.log('found') ; // why This Doesn't do any thing  ?
            }

        }
    });

});

Upvotes: 7

Views: 1055

Answers (2)

Oleg
Oleg

Reputation: 25018

Starting with a contenteditable element we can replace the markup as we need by operating directly on its innerHtml:

$('#query-container').on('keyup', function(e){
  var $this = $(this);
  //(?!\<\/b\>) negative lookahead is used so that anything already wrapped
  //into a markup tag would not get wrapped again
  $this.html($this.html().replace(/(SELECT|UPDATE|DELETE)(?!\<\/b\>)/gi, '<b>$1</b>'));
  setEndOfContenteditable(this);
});

IMO this is a more readable option. Add the rangeselect method from the previous answer and we have a working fiddle

Upvotes: 0

Selvakumar Arumugam
Selvakumar Arumugam

Reputation: 79860

I did a proof of concept with some modifications from what you originally had. See below,

DEMO: http://jsfiddle.net/cgy69/

$(function() {
    $('div').focus();
    var x = ['SELECT', 'WHERE', 'FROM'];
    $('div').keyup(function(e) {
        //console.log(e.keyCode) ;
        if (e.keyCode == 32) {

            //using .text() remove prev span inserts
            var text = $.trim($(this).text()).split(' ');            
            $.each(text, function(i, v) {
                $.each(x, function(j, xv) {
                    if (v.toUpperCase() === xv) {
                        text[i] = '<span style="color: blue; text-transform: uppercase;">' + v + '</span>';    
                    }                                        
                });
            });

            $(this).html(text.join(' ') + '&nbsp;');

            setEndOfContenteditable(this);
        }
    });

    function setEndOfContenteditable(contentEditableElement) {
        var range, selection;
        if (document.createRange) //Firefox, Chrome, Opera, Safari, IE 9+
        {
            range = document.createRange(); //Create a range (a range is a like the selection but invisible)
            range.selectNodeContents(contentEditableElement); //Select the entire contents of the element with the range
            range.collapse(false); //collapse the range to the end point. false means collapse to end rather than the start
            selection = window.getSelection(); //get the selection object (allows you to change selection)
            selection.removeAllRanges(); //remove any selections already made
            selection.addRange(range); //make the range you have just created the visible selection
        }
        else if (document.selection) //IE 8 and lower
        {
            range = document.body.createTextRange(); //Create a range (a range is a like the selection but invisible)
            range.moveToElementText(contentEditableElement); //Select the entire contents of the element with the range
            range.collapse(false); //collapse the range to the end point. false means collapse to end rather than the start
            range.select(); //Select the range (make it the visible selection
        }
    }
});

You going to extend this further to handle

  1. Backspace
  2. HTML contents from previous inserts
  3. Cursor position Partially done, editing in the middle would still mess up the caret.

and more..

Upvotes: 3

Related Questions