New York Times-Style Text Selection Widget Using MooTools or jQuery

By  on  

NY Times Widget

Aaron Newton made a great request to me last week: why not make my MooTools Documentation Bookmarklet function more like the New York Time's text selection widget. NYT's text selection widget listens for text selection and presents the user with a "search" icon they may click on to learn more about that term. I've tried to answer that challenge -- not in bookmarklet form but in website widget form.

The Sample HTML

<div id="content-area">
	.htaccess AJAX Apache / Server APIs Blog Bookmarking / Social Books Browsers CSS / Design Google Guest Blogger Hosting / Domain JavaScript jQuery
	link() Microsoft MooTools MySQL Optimization PHP Poll rand() Security Shell Theory / Ideas Usability / Accessibility XML / XHTML
	This blog is targeted toward all levels of web designers and developers. All web topics are discussed, including CSS, JavaScript (MooTools and jQuery), PHP, and more.

The above code is next to meaningless per the widget -- I simply want to illustrate the area I'd like it to work in has an ID of content-area.

The MooTools JavaScript

	(function($) {
		//gets the selected text
		var getSelection = function() {
			return $try(
				function() { return window.getSelection(); },
				function() { return document.getSelection(); },
				function() { 
			        var selection = document.selection && document.selection.createRange();
					if(selection.text) { return selection.text; }
					return false;
			) || false;
		var url = '{term}', selectionImage;
		//event to listen
		$('content-area').addEvent('mouseup',function(e) {
			var selection = getSelection();
			if(selection && (selection = new String(selection).replace(/^\s+|\s+$/g,''))) {
				//ajax here { }
				if(!selectionImage) {
					selectionImage = new Element('a',{
						href: url,
						id: 'selection-image',
						title: 'Click here to learn more about this term',
						target: '_blank'
				//handle the every-time event
					top: - 30,	//offsets
					left: - 13 //offsets
		$(document.body).addEvent('mousedown',function() {
			if(selectionImage) { selectionImage.tween('opacity',1); }

During the mouseup event within the selected container (content-area), we determine if any text has been highlighted. If so, we:

  1. Insert the A element if it has not yet been injected into the body.
  2. Change the A element's URL to accommodate for the new search term.
  3. Position the element to at an offset position above where the mouse goes up.

During every mousedown event we hide the A element.

The jQuery JavaScript

/* attempt to find a text selection */
function getSelected() {
	if(window.getSelection) { return window.getSelection(); }
	else if(document.getSelection) { return document.getSelection(); }
	else {
		var selection = document.selection && document.selection.createRange();
		if(selection.text) { return selection.text; }
		return false;
	return false;
/* create sniffer */
$(document).ready(function() {
	var url = '{term}', selectionImage;
	$('#content-area').mouseup(function(e) {
		var selection = getSelected();
		if(selection && (selection = new String(selection).replace(/^\s+|\s+$/g,''))) {
			//ajax here { }
			if(!selectionImage) {
				selectionImage = $('<a>').attr({
					href: url, 
					title: 'Click here to learn more about this term',
					target: '_blank',
					id: 'selection-image'
				top: e.pageY - 30,	//offsets
				left: e.pageX - 13 //offsets
	$(document.body).mousedown(function() {
		if(selectionImage) { selectionImage.fadeOut(); }

Follows the same principal as above.

Ideas & Enhancements

  • Depending on your philosophy, you may want to implement a minimum character check as well:

    if(selection && (selection = new String(selection).replace(/^\s+|\s+$/g,'')) && selection.length > 4) { //5 char min
  • You may want to also fidget with adding/modifying text selection with keyboard keys as well. I've chosen to pass on that.
  • Saving the selection content via AJAX for analytical reasons may not be a bad idea either.

Have any other ideas for improvement? Would you have any use for this on your website(s)?

Recent Features

  • By
    Being a Dev Dad

    I get asked loads of questions every day but I'm always surprised that they're rarely questions about code or even tech -- many of the questions I get are more about non-dev stuff like what my office is like, what software I use, and oftentimes...

  • By
    Create Namespaced Classes with MooTools

    MooTools has always gotten a bit of grief for not inherently using and standardizing namespaced-based JavaScript classes like the Dojo Toolkit does.  Many developers create their classes as globals which is generally frowned up.  I mostly disagree with that stance, but each to their own.  In any event...

Incredible Demos

  • By
    PHP / MooTools 1.2 Accordion Helper

    The MooTools Accordion plugin seems to be the plugin that people seem to have the most problems with. It's an awesome plugin, so I can see why so many people want to use it, but I think that may be part of the problem.

  • By
    Using Dotter for Form Submissions

    One of the plugins I'm most proud of is Dotter. Dotter allows you to create the typical "Loading..." text without using animated images. I'm often asked what a sample usage of Dotter would be; form submission create the perfect situation. The following...


  1. This is totally cool, and I KNOW this would be a great feature to add to a hyperlocal blog that I work for.

  2. Nice use! Could be a little neater on the MooTools side though…

    if(!selectionImage) { 
    	selectionImage = new Element('a', { 
    		'href': url.substitute({
    			'term': encodeURI(selection)
    		'id': 'selection-image', 
    		'title': 'Click here to learn more about this term', 
    		'target': '_blank', 
    		'fade': {
    			'duration': 50
    		'styles': { 
    			'top': - 30,
    			'left': - 13
    	}).inject(document.body, 'top'); 
  3. Rich

    Nice man. very cool and you got the jquery version which makes it so much better for me. I might have to try this on a project. thanks again for all the work you put into your blog. Its much appreciated.

  4. Mr.X.

    Very nice thanks!

  5. I am with a PHP web development company
    Very nice article thanks for explaining this. i am bookmarking this and will surely return for more knowledge:)

  6. Pretty sweet, always enjoy your blog.

  7. nice article dev….:)

  8. Is the plugin you’re using on this website?

  9. Yep — it was really easy to implement too!

  10. The mootools demo isn’t working for me (the jqery one does).

  11. @Graeme Coultrip: Updated!

  12. @David Walsh: It was simple opacity mistake.

  13. Cool. I think this could be very useful.

  14. Willian


    How can I change getSelected function to return the start and end position index?

  15. hi devid.

    i am following Your blog for Years.

    first of all , i appreciate you for your knowledge sharing ;)

    i am using Joomla 1.5 in my New Project and as you may know, Joomla Is using Mootools 1.11 in its core.

    So by know , i want to use this Useful plug-in and it does not work with this mootools version.

    how do you see this problem? any solution?

    i had updated the Joomla Mootools version, but some other part of the website drops :D

    best Regards,


  16. That’s really wow I say because this would be a source of getting inspiration and that is all what is required to start the things, thank you.

  17. The mootools demo isn’t working for me, too. It bothers me a lot. Who can help?

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!