Treehouse

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?

ydkjs-6.png

Recent Features

Incredible Demos

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. [...] Record Text Selections Using MooTools or jQuery AJAX This post demonstrates a useful technique for keeping track of what text users are highlighting and copying on a given Web page. It is helpful because it gives you an indication of what visitors really want from your website. [...]

  28. @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

  29. [...] Record Text Selections Using MooTools or jQuery AJAX This post demonstrates a useful technique for keeping track of what text users are highlighting and copying on a given Web page. It is helpful because it gives you an indication of what visitors really want from your website. [...]

  30. [...] Record Text Selections Using MooTools or jQuery AJAX [...]

  31. John

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

  32. [...] Record Text Selections Using MooTools [...]

  33. [...] Record Text Selections Using MooTools or jQuery AJAX This post demonstrates a useful technique for keeping track of what text users are highlighting and copying on a given Web page. It is helpful because it gives you an indication of what visitors really want from your website. [...]

  34. […] Users will learn how they record text selections by using MooTools or jQuery Ajax and learn maximum how to detect the terms over and over again. MORE INFO […]

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

Use Code Editor