Highlight Certain Number of Characters

Chris Coyier //

I had a unique programming challenge the other day that I thought I'd share here. It's rather specific and probably won't be of huge general use, but hey, it might be interesting.

The idea was to have 160 characters become "selected" when you click on any letter in a block of text:

I didn't think it was possible to "actually" select the text automatically like that, since that seemed to me kind of like an operating-system level function. I really don't know though, correct me if I'm wrong. So instead what I set out to do what "fake" it, by applying a background color behind the appropriate characters. In the context of what we were doing, this worked fine anyway. Then those same characters were moved down into a text box for potential editing and submission.

The hardest part, to me, was thinking of a way to figure out exactly what character in a string of text was clicked on. So again, I kind of cheated. I figured if I wrapped every single character in a <span> I could watch for click events on each of those spans. Just as good. jQuery as usual:

var theText = $("#theText");

var theString = theText.text();

var numCharacters = theString.length;

var newHTML = "";

for (i = 0; i <= numCharacters; i++) {
    
    var newHTML = newHTML + "" + theString[i] + "";

}

theText.html(newHTML);

Now I bound (binded?) click events to each of those new span-wrapped characters. When they are clicked, the "selected" class is removed from all of them and applied to the one that is clicked. Then a for-loop fires off looping 160 times. It moves to the next character and highlights it (by adding a class):

$("span").click(function(){

    $("span").removeClass("selected");

    $(this).addClass("selected");
    
    var nextSpan = $(this);
    
    for (i = 1; i <= 160; i++) {
    
        nextSpan = nextSpan.next();
    
        nextSpan.addClass("selected");
                    
    }

});

Because I also wanted to move this newly-selected text down into a text box (for potential further editing), I run a second loop inside the click function. This second loop loops through each character that is currently selected and appends it to a string being held in a jQuery data chunk. At the end of the loop, that data chunk is applied to the textarea:

$("#result").data("result", "");
        
$(".selected").each(function() {

    var oldResults = $("#result").data("result");
            
    var newResults = oldResults + $(this).text();
    
    $("#result").data("result", newResults);

});

$("#result").val($("#result").data("result"));

Because the goal of this was to ultimately submit the characters to another URL, I made a button which would do that. When that button was clicked, it took the value of the text area, appended it to a URL and sent it away:

$("#sendit").click(function() {

    var toURL = "?=" + $("#result").val();

    window.location = toURL;
    
    return false;

});

So again, rather specific and I'm sure not widely useful, but I had never seen any other functionality like this so perhaps it'll be useful to someone in a similar spot.

 

View Demo   Download Files

 

UPDATE: Just as I hoped, someone jumped in with another (smarter) approach: Matt Wondra has a demo available here. It makes use of a textarea and JavaScript "ranges". The only weakness being textareas inherent dumbness of not being able to grow in height with content.