New York Times-Style Text Selection Widget Using MooTools or jQuery
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. </div>
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
window.addEvent('domready',function(){
(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;
};
//vars
var url = 'https://davidwalsh.name/?s={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 { https://davidwalsh.name/text-selection-ajax }
if(!selectionImage) {
selectionImage = new Element('a',{
href: url,
opacity:0,
id: 'selection-image',
title: 'Click here to learn more about this term',
target: '_blank'
}).inject(document.body,'top');
}
//handle the every-time event
//alert(selection);
selectionImage.set('href',url.replace('{term}',encodeURI(selection))).setStyles({
top: e.page.y - 30, //offsets
left: e.page.x - 13 //offsets
}).tween('opacity',0);
}
});
$(document.body).addEvent('mousedown',function() {
//hider
if(selectionImage) { selectionImage.tween('opacity',1); }
});
})(document.id);
});
During the mouseup event within the selected container (content-area), we determine if any text has been highlighted. If so, we:
- Insert the A element if it has not yet been injected into the body.
- Change the A element's URL to accommodate for the new search term.
- 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 = 'https://davidwalsh.name/?s={term}', selectionImage;
$('#content-area').mouseup(function(e) {
var selection = getSelected();
if(selection && (selection = new String(selection).replace(/^\s+|\s+$/g,''))) {
//ajax here { https://davidwalsh.name/text-selection-ajax }
if(!selectionImage) {
selectionImage = $('<a>').attr({
href: url,
title: 'Click here to learn more about this term',
target: '_blank',
id: 'selection-image'
}).hide();
$(document.body).append(selectionImage);
}
selectionImage.attr('href',url.replace('{term}',encodeURI(selection))).css({
top: e.pageY - 30, //offsets
left: e.pageX - 13 //offsets
}).fadeIn();
}
});
$(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)?





This is totally cool, and I KNOW this would be a great feature to add to a hyperlocal blog that I work for.
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': e.page.y - 30, 'left': e.page.x - 13 'opacity':0, } }).inject(document.body, 'top'); }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.
Very nice thanks!
I am with a PHP web development company http://www.rightwaysolution.com
Very nice article thanks for explaining this. i am bookmarking this and will surely return for more knowledge:)
Pretty sweet, always enjoy your blog.
nice article dev….:)
Is the plugin you’re using on this website?
Yep — it was really easy to implement too!
The mootools demo isn’t working for me (the jqery one does).
@Graeme Coultrip: Updated!
@David Walsh: It was simple opacity mistake.
Cool. I think this could be very useful.
Hi,
How can I change getSelected function to return the start and end position index?
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,
M.Rashidi
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.
How can I use colorbox to open the search results page instead of a new window? I hve tried onclick attribute for $(‘‘) but it doesnt work.
selectionImage = $('<a>').attr({ href="#", onclick="$.colorbox({opacity:'0.55', href:'" + url + ",'});" , title: 'Click here to learn more about this term', id: 'selection-image' }).hide();The mootools demo isn’t working for me, too. It bothers me a lot. Who can help?