views:

61

answers:

2

With jQuery, I'm interested in creating the following interaction model.

  1. When a user types in the page, anytime jQuery notices three !, "!!!" typed in a row, to be able to do something about it.

  2. After noticing three !, "!!!", wrap the previous sentence (finding the last period from the location the user is currently typing and wrapping a <span class=Important>

How can I do this?

A: 

As much as I am loathe to say that jQuery isn't good for something - perhaps this kind of logic is better handled on the server. Unless they are typing in an HTML editor where the newly inserted span tags are invisible to the user, it may be a little disconcerting to be typing in a textarea/textbox and suddenly see a bunch of HTML inserted into my comment.

BradBrening
Interesting, but ya, it is in an HTML editor. Any ideas?
WozPoz
+6  A: 

This should work. I've set it up as a live event handler (so that it works for elements dynamically added to the page), but you could use the exact same function as a normal keyup handler on any textarea or input element as well.

It checks to see whether the element's current value ends with !!! and if so performs the replacement, both using simple regular expressions.

$("input,textarea").live("keyup", function() {
    var $this = $(this);
    var value = $this.val();

    if (/!!!$/.test(value)) {
        $this.val(value.replace(/(\.?)([^.]+?\.?\s*)!!!$/, '$1<span class="important">$2</span>'));
    }
});
Ben Blank
Great answer. I was about to post something similar.
FK82
Very cool idea! It doesn't seem to be working just yet thought, something wrong in the IF
WozPoz
Also, will this grab just the most recent sentence based on the period?
WozPoz
Here's a public link of JSBIN: http://jsbin.com/abira3/edit
WozPoz
Looks like it's the $this.val(value.replace which is breaking
WozPoz
That code was requiring a period to be in front, which won't work for the first sentence. I made it optional.http://jsbin.com/abira3/3/edit
Patrick
@Patrick — Good catch! I only tested it with two sentences; I'll update my answer.
Ben Blank
Very cool! I'm curious, would this approach work for modern editors that use iframes like: <body contenteditable="true"> ? or is it required to have an INPUT for the val() line?
WozPoz
@WozPoz — I haven't tried it with `contenteditable`, but as long as `keyup` events are fired (and I'm pretty sure they are), it should work just fine.
Ben Blank
@Ben. That's great. I tried it out of curiosity and I doesn't strangely enough. The only difference should be using .html() instead of .val()
WozPoz
@Ben, if you remove the "contenteditable="true"" in the body tag it works otherwise it doesn't. Horribly strange
WozPoz
@Ben, I believe the reason contenteditable isn't working is bec: #1, Val() needs to be html(). Also, when the text isn't in a textarea, the browser adds HTML tags, so what was helloben!!! is now ...helloben!!!</p>, is there a way to update the regext to support this? If you'd prefer I open a new question, please let me know - thxs!
WozPoz
@WozPoz — I've played around with it a bit and there's no simple way to do it. (Regexes don't work well with nested structures like raw HTML.) I think you could get it working using the browser's text selection capabilities, but it would be a great deal more complicated.
Ben Blank