Problem: I wanna add the ability to make a preview of user comments in my weblog, but I can't because the system that I'm using or because I don't want that the user has to make a complete POST request to see it.
Solution: use JavaScript and DOM.
As easy as it appears is the solution to this problem. Now that it's finished, it calls powerfully my attention that nobody has do this before.
Let's start from the beggining: how this idea come up my mind? Well, thing is that, right now, I'm using Blogger as my weblogging tool, inkelog. Blogger, as some of you know, doesn't come with a comment system, so I've to search for an fast and efficient solution. While I was searching I found 2 sites which offers this service: Enetation y HaloScan. I've already blog about them. Summary: neither HaloScan nor Enetation adds the ability to make a preview of comments and is something I want for my weblog. That's why I'm writing this lines.
First thing I do was to copy the design that I want for my comments and paste it at the end of the comments list, just like you'll see it if it was a real comment. To those elements I've added the id attribute of HTML so I'll be able to reference them with JavaScript. Now my template looks like this at the end of the comments:
<div id="Preview" class="comment">
<div id="PreviewBody" class="body">comentario</div>
<span class="permalink"><a href="#" id="PreviewLink">permalink</a></span>
<span class="name">
<a href="mailto:inkel-blog@f14web.com.ar" id="PreviewName">nombre</a>
</span>
<span class="website">
<a href="http://f14web.com.ar/inkel/blog/" id="PreviewSite">url</a>
</span>
<span class="date" id="PreviewDate">date</span>
<span class="time" id="PreviewTime">time</span>
</div>
I've also added this button:
<input type="button" name="preview" value="preview"
onclick="return doPreview(this.form)" />
And also I've added this style so the preview isn't visible at first:
#Preview {
visibility: hidden;
display: none;
}
which hides the preview until the u>Now the fun part: programming of the function doPreview, which take the form values and shows them at the preview. Here's the code, correctly commented:
function doPreview(form)
{
/* Get a reference to the preview DIV and show it */
var ps = document.getElementById("Preview").style;
ps.display = "block";
ps.visibility = "visible";
/* Get the reference of the other sections
* where we'll show user data */
var previewBody = document.getElementById("PreviewBody");
var previewName = document.getElementById("PreviewName");
var previewSite = document.getElementById("PreviewSite");
var previewDate = document.getElementById("PreviewDate");
var previewTime = document.getElementById("PreviewTime");
/* Parse comment text to obtain the correct
* DOM representation */
var comment = parseText(form.elements['comments'].value);
/* Reemplazar el contenido anterior por el nuevo */
previewBody.replaceChild(comment, previewBody.lastChild);
/* Show user name with a link to his
* email address */
previewName.href = 'mailto:' + form.elements['email'].value;
var nombre = document.createTextNode(form.elements['name'].value);
previewName.replaceChild(nombre, previewName.lastChild);
/* Show a link to user's site */
previewSite.href = form.elements['webpage'].value;
var url = document.createTextNode(previewSite.href);
previewSite.replaceChild(url, previewSite.lastChild);
/* Create a Date object with the actual date */
var today = new Date();
/* Number formatting */
function fmt(v) { return (v < 10) ? '0' + v : v; }
/* Build a string with date and time */
var date = today.getFullYear() +
'/' + fmt(today.getMonth()) +
'/' + fmt(today.getDate());
var time = fmt(today.getHours()) +
':' + fmt(today.getMinutes()) +
':' + fmt(today.getSeconds());
/* Show date and time at the preview */
var fecha = document.createTextNode(date);
previewDate.replaceChild(fecha, previewDate.lastChild);
var hora = document.createTextNode(time);
previewTime.replaceChild(hora, previewTime.lastChild);
/* Return false so the form isn't submitted */
return false;
}
The function parseText will be more in-depth analyzed in a future article. In fact, I've to take a look to this function looking for bugs, but here's the source code. Enjoy it and send me enhacements!
function parseText(text)
{
try {
if(text.indexOf('<') == -1) {
return document.createTextNode(text);
}
var node = document.createElement("div");
var st = text.split('<');
for(var i = 0, j = st.length; i < j; i++) {
if(st[i]) {
var et = st[i].split('>');
var ea = et[0].split(' ');
var elem = document.createElement(ea[0]);
for(var ii = 1, jj = ea.length; ii < jj; ii++) {
if(ea[ii]) {
var av = ea[ii].split('=');
var valu = av[1].substring(1, av[1].length - 1);
elem.setAttribute(av[0], value);
}
}
elem.appendChild(document.createTextNode(et[1]));
node.appendChild(elem);
}
}
return node;
} catch(e) {
alert("Incorrect markup in comment");
return document.createTextNode(text);
}
}
This ends this article, and we'll be able to enjoy the posibility of make a comment preview in our weblog. See you next time!