O'Reilly

Record Text Selections Using MooTools or jQuery AJAX

By on  

One technique I'm seeing more and more these days (CNNSI.com, for example) is AJAX recording of selected text. It makes sense -- if you detect users selecting the terms over and over again, you can probably assume your visitors are searching that term on Google, Yahoo, etc. I've duplicated this functionality using my favorite JavaScript library, MooTools, and another JavaScript library, jQuery.

The MooTools JavaScript

window.addEvent('domready',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;
	};
	//event to listen
	var selectRequest = new Request({
		url: 'ajax-selection-copy.php',
		method: 'post'
	});
	$('content-area').addEvent('mouseup',function(e) {
		var selection = getSelection();
		if(selection && (selection = new String(selection).replace(/^\s+|\s+$/g,''))) {
			selectRequest.send('selection=' + encodeURI(selection));
		}
	});
});

The first step is attempting to grab the selected text during the mouseup within our designated container. If we find a text selection we fire an AJAX request to a PHP script which will save the text selection.

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() {
	$('#content-area').mouseup(function() {
		var selection = getSelected();
		if(selection && (selection = new String(selection).replace(/^\s+|\s+$/g,''))) {
			$.ajax({
				type: 'post',
				url: 'ajax-selection-copy.php',
				data: 'selection=' + encodeURI(selection)
			});
		}
	});
});

The MooTools code translated to jQuery.

The PHP

if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' && $selection = trim($_POST['selection'])) {
	mysql_query('INSERT INTO text_selections (selection,date_selected) VALUES(\''.mysql_escape_string(stripslashes($selection)).'\',NOW())');
}

The above PHP code is very primitive. Depending on the setup of your system (PHP Framework, security settings, etc.) you will want to implement additional measures to prevent attacks on this script.

Recording text selections is a great way to discover what topics and/or terms your audience is interested in. You may also want to provide more information on these terms within posts.

What are your thoughts on this? Do you think this is too much like Spyjax? Perfectly OK?

Track.js Error Reporting

Upcoming Events

Recent Features

  • Regular Expressions for the Rest of Us

    Sooner or later you’ll run across a regular expression. With their cryptic syntax, confusing documentation and massive learning curve, most developers settle for copying and pasting them from StackOverflow and hoping they work. But what if you could decode regular expressions and harness their power? In...

  • CSS Filters

    CSS filter support recently landed within WebKit nightlies. CSS filters provide a method for modifying the rendering of a basic DOM element, image, or video. CSS filters allow for blurring, warping, and modifying the color intensity of elements. Let's have...

Incredible Demos

  • Control Element Outline Position with outline-offset

    I was recently working on a project which featured tables that were keyboard navigable so obviously using cell outlining via traditional tabIndex=0 and element outlines was a big part of allowing the user navigate quickly and intelligently. Unfortunately I ran into a Firefox 3.6 bug...

  • Background Animations Using MooTools

    One of the sweet effects made easy by JavaScript frameworks like MooTools and jQuery is animation. I ran across this great jQuery tutorial that walks you through animating a background image of a page. Here's a quick MooTools code snippet that...

Discussion

  1. It’s been some time I haven’t seen something interesting (for my own taste and interests) at here. This can be added in the good category of spyjax techniques :)
    Nice one David!

  2. Delicious! text selection for the masses. Perhaps I’ll try to find some useful applications for it…

  3. Hunter

    You bring up a good topic on PHP security. I am just getting into PHP and am reading up on writing secure PHP w/MySQL. I read the site below which seems to have some good advice, but I was curious if you had any references you could recommend.

    Also, I enjoy this blog as I am just starting out with jQuery.

  4. @Hunter
    Addison Wesley – Securing PHP Web Applications (2008)
    You can buy it on amazon or download it as a warez ebook copy.

  5. Cool stuff. This technique could mimic the nytimes’ website text selection search feature

  6. Hunter

    Thanks Alex! I have to make this comment longer, so I am doing that here.

  7. Alex, I don’t know who you are but thanks for using http://www.geekherocomic.com as a link there :-) Salva.

  8. Another very useful function, that’s worth sharing!
    THX!

  9. Jack Watson-Hamblin

    Hey, I wouldn’t mind turning this into a jQuery plugin, mind if I do, I”ll link back to you if I post it up on the plugins.jquery.com site.

  10. Adrien

    Well, it might be interresting for the coding part.
    But if you have a visitor like, you’ll have about a hundred INSERT per page. I select text all the time while I’m reading it. sorry. :/

  11. @Hunter && @Salva

    You are both welcome guys, and Salva – your webcomic is GREAT!

  12. Awesome script! Thanks David!

  13. Wow this very cool script :D BTW let’s me know … why on Safari browser it’s doesn’t work :(

  14. I like the way you did in the php security.. Honestly, I haven’t encounter that code. but It’s very useful. thanks

  15. Hey David – I just found your site a couple months ago and have been reading it frequently ever since. I just wanted to comment on your use of mysql_escape_string() there: that function is deprecated in 5.3 and removed in php 6 along with a big note saying that relying on it is highly discouraged.

    The proper one to use is mysql_real_escape_string() or my favorite, binding variables with the PDO interface.

    Thanks for making such a good site!

  16. @Aleks: Thank you sir!

  17. Wow you certainly have a great site here and also nice script.

  18. Great post! Thanks you gave me a great idea for a UI I must do… grazie!

  19. The only problem I can see with this, is that I select text when I am reading. It is a bad habit of mine… so pretty much any article I would read would have multiple selections.

  20. KG

    Hi

    Need help, i want write a code that does what you have done on this page, when i select a text i get a image that says “Click here to learn more about this term” can you please guide me with a code sample

  21. alex

    hey david this is a great script i have been looking for a way to store selected text you see im building an in-place editor with jquery
    so after implementing your script to my project i noticed some strange behaviour
    when there is more one same words only the first is getting stored

    http://hostmyfiles.gr/newsletter/ajax-selection-copy.php.htm

    e.g. try selecting the last “you”

    is there a workaround ?
    am i doing something wrong ?

    thanks in advance
    alex

  22. Hey I finally found your script after looking around forever or finding the right keywords to search for. Besides saving the text into a database, is there also some way to save the highlighted text also because I am building a project with a critique system that saves the highlighted words or selection. So that when the critique is pulled up it will show the previously highlighted words and their comments.

    If you happen to know of something or what keywords i can try to find this then let me know.

    Thanks.

  23. rekvizit

    Thanks a lot! But I’d rather fire the request on Ctrl+C keydown.

  24. Thomas

    Cool code, thanks a lot

  25. Tim Down

    That’s not a great function for getting the selected text:

    window.getSelection() and document.getSelection() return a Selection object, not a string
    document.getSelection() is redundant unless you need to support Safari 2 or lower
    – Selection text can legitimately be empty, in which case the IE branch will needlessly return false rather than an empty string.

    Here’s a better implementation:

    function getSelectedText() {
        var selectedText = "", sel;
        if (window.getSelection) {
            selectedText = "" + window.getSelection();
        } else if ( (sel = document.selection) && sel.type == "Text") {
            selectedText = sel.createRange().text;
        }
        return selectedText;
    }
  26. Tim Down

    That’s not a great function for getting the selected text. window.getSelection() and document.getSelection() return a Selection object, not a string. document.getSelection() is redundant unless you need to support Safari 2 and lower. Selection text can legitimately be empty, in which case the IE branch will needlessly return false rather than an empty string.

    Here’s a better implementation:

    function getSelectedText() {
      var selectedText = "", sel;
      if (window.getSelection) {
        selectedText = "" + window.getSelection();
      } else if ( (sel = document.selection) && sel.type == "Text") {
        selectedText = sel.createRange().text;
      }
      return selectedText;
    }
    
  27. @David, How can we save the selection in database so that we can highlight the same selection on next user visit?
    Hope you got my question…

    Thanks,
    Arvind

  28. John

    There is no point in doing “new String”. Just use the string that you’re passing to the String constructor, that’s it.

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

Recently on David Walsh Blog

  • Intercept HTTP Requests with Node.js nock

    Unit testing external APIs is difficult no matter what language you do it in.  Hell, working with any external API is scary, if only because you have zero control of networking issues, API changes, and a host of other issues.  But if you do create a service...

  • Introducing Frontend Masters (with Giveaway)

    Hey DWB readers, I'm super happy to sponsor this blog. I've been a long-time reader and fan, since back when David wrote about JavaScript and MooTools back in 2007. ;-) We are in one of the fastest changing, evolving, most lively communities on earth: JavaScript and front-end web...

  • Get Node.js Command Line Arguments with yargs

    Using command line arguments within Node.js apps is par for the course, especially when you're like me and you use JavaScript to code tasks (instead of bash scripts).  Node.js provides process.argv but that doesn't provide a key: value object like you'd expect: Bleh.  If you want to work with a...

  • OâReilly Velocity Conference â New York

    My favorite front-end conference has always been O'Reilly's Velocity Conference because the conference series has focused on one of the most undervalued parts of client side coding:  speed.  So often we're so excited that our JavaScript works that we forget that speed, efficiency, and performance are just as important. The next Velocity...

  • Free Download: Font Bundle Featuring 17 Incredible Typefaces

    The only thing we love more than a good font, is a good free font. So we’ve combed the Web for some of our favorite free fonts, and gathered them here in a single download. You’ll find a variety of useful typefaces, from highly geometric designs...