Stupid jQuery Trick - HTML Preview

This post is more than 2 years old.

This came up in an earlier conversation today, and I don't think it's something anyone would actually use, but I love how simple it is and - well, it's kinda cool too. And stupid. (Which means it was fun to write.) So what in the heck am I talking about? Imagine you give a textarea field for your client to enter text into. You trust them with HTML, but don't want to bother with a rich text area. It would be nice to give them the ability to see their code while they type. Here's a quickie jQuery solution for this.

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script> $(document).ready(function() { $("#codehere").keyup(function() { $("#preview").html($(this).val()) }) }) </script>

code here:<br/> <textarea id="codehere" cols="50" rows="10"></textarea>

<p/>

preview here: <div id="preview"></div>

Working from the bottom first - notice I've got my form (well, to be technical, it's just one field, not a complete form) and a div set up for my preview. My jQuery code then simply then binds to the form and on every key press, I set the HTML property of the preview div with the text value of the form. You can play with this here or if you just want to see what it looks like, here is a simple screen shot.

Edited at 2:39 PM: Thanks to multiple commenter for pointing out I should be using keyup instead.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Dale Severin posted on 4/28/2010 at 10:02 PM

That is so clever and cool. It is just amazing what simple jQuery statements can accomplish.

Comment 2 by Ryan Jeffords posted on 4/28/2010 at 10:21 PM

It's funny -- I was thinking about this exact concept this morning (while wondering why mangoblog.org was down).

Good game!

Comment 3 by Raymond Camden posted on 4/28/2010 at 10:23 PM

You should have been visiting blogcfc.com instead. It was up. ;) (Although its quite a bit more ugly. :)

Comment 4 by Matt W posted on 4/28/2010 at 10:52 PM

I actually like this idea for BlogCFC. I use the plain textarea for adding blog entries and occasionally put in some html. A pop-up preview could be handy to help me make sure I didn't fat finger something.

Comment 5 by Raymond Camden posted on 4/28/2010 at 10:54 PM

Interesting. As you know, I toyed with the idea of adding a RTE to BlogCFC, but had trouble making it work with the code blocks. I think that would be a problem here too. Then again, I can customize the above to change both a) ignore <more/> and b), change <code> to pre blocks. It won't be an EXACT match, but would be close. (I could get fancy and do an AJAX call to render code blocks.) Of course, you can just click the Preview button too. You do know that feature exists, right? :)

Comment 6 by Matt W posted on 4/28/2010 at 11:00 PM

Yes, and right after I posted my comment I realized I should've mentioned the existing preview which I do use. But the jQuery way would be more faster, more cooler, and a real world use for this blog post. :)

Comment 7 by David Long posted on 4/28/2010 at 11:01 PM

Just one problem with your app. If a use puts leaves the textarea then the last character typed will not be seen... could be something frustrating...

But as you said this was just a quick and really cool code bit.

Comment 8 by William Mengers posted on 4/28/2010 at 11:15 PM

Web based IDE?!

Comment 9 by brookr posted on 4/28/2010 at 11:19 PM

I think if you use the keyup(func) event handler instead, it will show that last character.

Cool demo, thanks!

Comment 10 by Justin Campbell posted on 4/28/2010 at 11:23 PM

You should bind this to .keyup instead. That way $(this).val will include the most recent character.

Comment 11 by Raymond Camden posted on 4/28/2010 at 11:38 PM

For those who suggested keyup - thank you. I hate to say it but I _always_ forget it.

I updated both the demo and the blog post. (Ok, technically, demo is updated, blog post being updated in 30 seconds.)

Comment 12 by Me posted on 4/28/2010 at 11:44 PM

I pasted the code from the comment form into the "Stupid jQuery Trick - HTML Preview" demo textarea. I'm able to modify the form even though it's still being served from coldfusionjedi.com -- so I'm thinking that this poses some security risks. People can bypass XSS checks by submitting a modified/malicious form from your own domain.

Comment 13 by Raymond Camden posted on 4/28/2010 at 11:46 PM

Well normally such a code block would be admin only. But as to my _particular_ demo - I don't see how much of a security risk it would be. My comment form is an 'open' POST. It does have spam protection on it though. If you were to write code to hit it N times I'd block against that too. ;) But on a practical level, anyone writing HTML for content for a web app is going to be a trusted user.

Comment 14 by Stephen Belanger posted on 4/29/2010 at 12:09 AM

This would fail rather fantastically in real world use. For one thing, someone could just enter '</div>' to escape the preview box. If you are calling this on each keyup you'd likely also have issues with dead elements being generated in some browsers. Say you type '<font>' and then start to type some text before closing it, you will generate an empty <font> element before the text like this <font /> that will sitFor there until you finish closing it. Some browsers may also have issues with finding a non-encoded < without a closing > to indicate an element closure.

Comment 15 by Raymond Camden posted on 4/29/2010 at 12:12 AM

You could always block div easily enough, could you not? Also, when I tried <font> ... it worked fine in Chrome. Seriously though - this is mainly just an experiment. Worked well in Chrome and was fun to look at it. I'm not going to be selling it to any clients anytime soon. ;)

Comment 16 by "Cowboy" Ben Alman posted on 4/29/2010 at 12:12 AM
Comment 17 by Raymond Camden posted on 4/29/2010 at 12:14 AM

I'd add script then to the text you want to remove. Again, I'm thinking of clients who just want some simple HTML styled blocks.

Comment 18 by todd sharp posted on 4/29/2010 at 12:27 AM

Cool stuff man - just one thought re: blogcfc -- you technically wouldn't have to change the <code> blocks because <code> is a valid HTML tag. Now your textblocks and includes, etc wouldn't obviously work, but that's a different story.

Comment 19 by Aaron Cox posted on 4/29/2010 at 1:15 AM

There are plenty of things that could go wrong here, I think we all know that so aside from suggestions let's not bother with the whole "real world" thing. I know Ray didn't write this to be someone's silver bullet. These things are always fun to play with.

Ray, another thing you can add is mouse event detection whenever the field is focused. I've used it for textarea counters and the like. This way you can pick up on paste operations. As far as the unclosed tags... pffft, get some interns to write the validation garble :P.

Comment 20 by Raymond Camden posted on 4/29/2010 at 1:19 AM

Aaron, I want to focus on something you said at the end there - as it is something I've thought about for quite some time. Ignore the preview. Just imagine a simple text field.

Is there a simple jQuery way (or whatever, who cares about frameworks now) to examine a string and see if it is valid HTML? One could simply count tags and closing tags. (And frankly, that would be enough for most of the mistakes I make when editing blog posts.) But that wouldn't handle cases where you use 'bad' html, like the <foo> tag. One could then simply regex for unrecognized tags. But that would be hard to maintain with HTML 5 coming out in the next decade or so. (Sorry, old time coder here, bit cranky it's going to take 20 years for some of the more simpler parts of HTML5.)

Anyway, has anyone ever tackled this type of validation before?

Comment 21 by Aaron Cox posted on 4/29/2010 at 1:43 AM

I've done a little bit of that sort of tag checking with a few regexes. They weren't all that simple though, since you need to do some look aheads and all that jazz. Then again I'm not claiming to be a regex wizard either. I'm definitely going to take a shot at scripting that tonight though, I'm intrigued now.

Comment 22 by John Allen posted on 4/29/2010 at 4:22 AM

TOOOO Cute!

Comment 23 by Raymond Camden posted on 4/29/2010 at 4:50 AM

That's me - the cute programmer. ;)

Comment 24 by Luke Scammell posted on 4/30/2010 at 4:20 PM

This is very cool, I like it a lot.

If you wanted to use it in "The Real World™" you'd probably want to look at porting HTML purifier (http://htmlpurifier.org/) to Javascript - that could be fun! :D

Comment 25 by Ofeargall posted on 5/14/2010 at 8:46 PM

Ahhh, Ray, I love stupid, it suits me so well! Actually, this turns out to be something I'm really needing as a part of an upcoming site. The site has a jQuery rotator that displays specials. It's got a headline, short description and a price. I've got the preview area set up to look just like the rotator and 3 fields in the 'form'. I was REALLY trying to figure out a way to NOT have to use a character counter on each line because not all characters are the same width, etc... This solves that problem completely. Love it.
[code]<script type="text/javascript" src="http://ajax.googleapis.com/..." ></script>
<script>
$(document).ready(function() {
$("#headline").keyup(function() {
$(".headline").html($(this).val())
});
$("#description").keyup(function() {
$(".description").html($(this).val())
});
$("#price").keyup(function() {
$(".price").html($(this).val())
});
});
</script>
</head>

<body>
</body>
</html>

<p>Headline:<br/>
<textarea id="headline" cols="20" rows="3"></textarea>
<br/>
<textarea id="description" cols="20" rows="3"></textarea>
<br/>
<textarea id="price" cols="20" rows="3"></textarea>
<p/>

<div id="specials">
<h1 class="headline"></h1>
<p class="description"></p>
<p class="price"></p>
</div>[/code]

Comment 26 by Ofeargall posted on 5/14/2010 at 8:52 PM

Ouch. Major posting faux pas. Sorry for incorrect code sampling.