jQuery plugin to print HTML forms

Recently for a project, a client wanted to be able to print pages from a web application that were just forms. This was never intended when the application was originally built, so there were no separate view screens of data. Naively I thought this would be easy – knock up a print style sheet and bob’s your uncle… if only.

There are a couple of problems that just aren’t really fixable using a pure CSS solution, firstly <select> menus look pretty horrible no matter what you to them and <textarea> fields look fairly bad, but even worse than their aesthetic merits (or lack of rather) is the fact that the overflowing content i.e. the content that you need to scroll to see, will not be printed.

In the end for the application I ended up adding views, but it got me thinking and so I’ve written a quick jQuery plugin to print forms. It works by looking for any <select> menus or <textarea> fields and replacing them with <div> tags styled to look like form elements. When you click on one of the <div>s to edit it, it reverts to the original form element and when it looses the focus (using the jQuery blur() method) the field is swapped back and replaced by the <div>.

When you come to print the form because all of the <select> menus and <textarea> fields have been replaced by <div>s you can style them as you want using a print style sheet and get a nice looking form with no missing content.

Have a look at the working example and view source to see how to use it.

download printform plugin example

You will want to edit / write CSS for both screen and print appropriate to your situation.
Tested on IE6, IE7, Firefox 2.0.


/*
 * printform 1.0
 * By John Elliott (http://www.flipflops.org)
 * Copyright (c) 2008 John Elliott
 * Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php
*/
   
/**
 * convert textareas and select tags to divs so that you HTML forms can be printed.
 *
 *
 *
 * @name printform
 * @type jQuery
 * @author John Elliott (http://www.flipflops.org)
 * @desc 
 * 
 * @example $('#tester').printform();
 * @desc call the plugin on #tester - any select or textareas will be replaced
 *
 * @param settings - not used, but included for future proofing! (I'm sure there will be options sometime...)
 *
*/

jQuery.fn.printform = function(settings){
	return this.each(function(){
		new jQuery.printform(this, settings);
	});
}



jQuery.printform = function(obj, settings) {
  
  	/*
  	* within a parent object - replace the textareas and select menus
  	*/
  
  
 	init(obj, 'textarea');
	init(obj, 'select');	
	
		
	function init(obj, fieldType) {
	
	/*
	* loop through each instance of an element within the parent 
	*/
		
		obj = jQuery(obj).attr('id');
			
		jQuery('#' + obj + ' ' + fieldType).each( function() {
					
			var id = jQuery(this).attr('id');
			
			field_replacer(id, fieldType);
		});
	}		
	
	
	function field_replacer(id, fieldType) {
	
	/*
	* function to replace the elements with divs
	*/
	
			str = jQuery('#' + id).val();
			str = str.replace(/\n/g, '
'); if ( jQuery('#replace-' + id).length > 0 ) { // if a replacement div already exists for this element, then just show it. // update the content of the replacer with the edited content jQuery('#replace-' + id).html(str).show(); } else { // otherwise create a new replacement div for the element jQuery('#' + id).after('
' + str + '
'); } jQuery('#' + id).hide(); // hide the element that has just been replaced field_watcher(id, fieldType); // add event listeners } function field_watcher(id, fieldType) { /* * add listeners to the elements * onclick - show the original element and hide the replacer * onblur - call the field_replacer to update the page */ jQuery('#replace-' + id).click(function() { jQuery('#' + id).show().focus(); jQuery('#replace-' + id).hide(); jQuery('#' + id).blur(function() { field_replacer(id, fieldType); }); }); } };

Thanks to to Mike Alsup for his great (if rather daunting) guide to writing plugins on Learning jQuery.