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.
code here:<br/>
<textarea id="codehere" cols="50" rows="10"></textarea> <p/> preview here:
<div id="preview"></div>
<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>
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.
Archived Comments
That is so clever and cool. It is just amazing what simple jQuery statements can accomplish.
It's funny -- I was thinking about this exact concept this morning (while wondering why mangoblog.org was down).
Good game!
You should have been visiting blogcfc.com instead. It was up. ;) (Although its quite a bit more ugly. :)
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.
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? :)
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. :)
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.
Web based IDE?!
I think if you use the keyup(func) event handler instead, it will show that last character.
Cool demo, thanks!
You should bind this to .keyup instead. That way $(this).val will include the most recent character.
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.)
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.
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.
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.
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. ;)
Hmmn.... http://benalman.com/grab/f2...
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.
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.
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.
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?
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.
TOOOO Cute!
That's me - the cute programmer. ;)
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
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]
Ouch. Major posting faux pas. Sorry for incorrect code sampling.