Potable Quotables

One of the recurring requests out of the fixed commenting system was the ability to point to a comment and quote from that post. While I haven't had the time to get that functionality together for my own blog, I had been asked by Jacob G. (of recent CSSVault fame) to put together a new design for a series of blogs that he had or wanted to put together [See Fun Money Blog, CPVault, and Filmsy].

One of the things that he requested was to have the comments include a way to spark conversation. In taking the suggestions for my own comments system into account, I wanted to make it easy for users to refer to what others had to say.

Enter some JavaScript and the usual DOM scripting and out comes some quick quotable comments. Hop on over to a post on Fun Money to check it out. Beneath each comment is a set of quote marks. Clicking on the quote marks will copy the comment into the textarea and wrap some blockquote tags around it. While not in the live site, the possibility exists to include a citation in the blockquote automatically as you'll see in the following code.

HTML Code Structure

When I set up Jacob's HTML for the comments, I mimicked what I use on my own site. Mostly because I feel that it works well.

<div class="comment" id="c001611"><a name="c001611"></a>
    	<div class="commentmetadata">
        <span class="commentnumber"><a href="#c001611">56</a></span>
        <span class="poster"><a href="http://www.example.com">Joe Smith</a></span>
        <span class="postdate">May 23, 2005<br/>01:40 PM</span>
      </div>
      <div class="commenttext"><p>This is my comment.</p>
			</div>
</div>

It's likely fairly obvious what each component is made of. First, I wrap the entire comment into a div and assign it an id. I also include an anchor so that I can create a link to this specific comment. Consider it a comment permalink. Next I set up some comment metadata such as who the poster is (and any associated url) and when the comment was posted. Finally, we have the text of the comment itself.

JavaScript

Now that we have a page full of comments, we need some way to wire up the quotable feature. I could have included some HTML with each comment that displayed the image and possibly had an onclick handler. The problem with this is for users who do not have JavaScript. They'd have a useless button. Instead, I use JavaScript to create the buttons to help ensure that only those that can make use of the feature can actually use the feature.

The first step is to add some code to the onload event of the window.

// ========================================
// set up quote buttons
try{
	var els = document.getElementById('comments').getElementsByTagName('DIV');
	for(var i=0,j=els.length;i<j;i++)
	{
		if(els[i].className=='comment')
		{
			var newel = document.createElement('DIV');
			newel.className = 'commentquote';
			newel.innerHTML = '<a href="#" onclick=\'addQuote(this);return false;\'><img src="images/quote.gif"></a>';
			els[i].appendChild(newel);
			j++; // increment to include the new div element I just inserted
		}
	}
}catch(e){/*fail gracefully*/}

What actually happens here may seem self-evident. I get the comments container and loop through all the DIVs in that container. This saves me some time not having to loop through all the elements on the page. If the element is a comment then I create a new DIV, assign it a class name in case I want to style it, add the html for my quote image and add the JavaScript required to load the comment into the textarea.

Now, once we have the quote buttons in place, we need our function to handle the request.

function addQuote(el)
{
	var c = el.parentNode.parentNode; // grabs current comment
	var els = c.getElementsByTagName('DIV');
	for(var i=0,j=els.length;i<j;i++)
	{
		if(els[i].className=='commenttext')
		{
			document.getElementById('text').value = document.getElementById('text').value + '\n<blockquote cite="#'+c.id+'">\n' + els[i].innerHTML + '</blockquote>\n';
		}
	}
}

Whenever I click on the quotemarks, I pass the object into the addQuote function. Since I always know that my comment container is two levels up, I grab that element and assign it to a variable. Then, I loop through all DIV containers contained within my comment to try and locate the actual text of the comment. Once I have the text, it's simply a matter of appending it onto the end of the content already in the textarea and attaching the cite attribute to it.

The user now has a quick way to quote other comments!

Published May 27, 2005 · Updated September 17, 2005
Categorized as JavaScript
Short URL: https://snook.ca/s/369

Conversation

7 Comments · RSS feed
Rob Mientjes said on May 27, 2005

Neat. Just... neat. JavaScript is, in my opinion, meant for either full-blown web apps or small stuff like this, additions that make life easier. Very neat (three times!).

Anne said on May 27, 2005

Cool! I just implemented something similar on my weblog a few days ago. Implementation is a bit different as I have somewhat specific markup and a lot less DIV elements to take the markup from...

Anne said on May 27, 2005

By the way, you should really have used some ALT text. Although the percentage of people who have images turned of is probably negligible, it would be useful for people who use screen readers and such.

vaidas said on May 30, 2005

cool

Mark Wubben said on May 30, 2005

Nice, but you're missing the `cite` attribute, and blockquotes require block level content ;-)

Henrik said on June 16, 2005

Hey!

Looks great, really. But didn't you know that you can use IDs as anchors? No need for the :)

Bookmarked.

//Henke

Henrik said on June 16, 2005

Hey!

Nice! But didn't you know that you can use IDs as anchors? No need for the here :)

Bookmarked.

//Henke

Sorry, comments are closed for this post. If you have any further questions or comments, feel free to send them to me directly.

Want to learn about scaling CSS for large projects?

I'm available for full and half-day workshops on scalable CSS architecture. I can provide on-site training for your team. Interested?
Get in touch.