[UPDATE – Version 1.0 released]
Similar to those "utilicous" moments are the “I got to write a jQuery plugin that does this” moments..
Had one of those a while ago, and the results were the jQuery Print Element Plugin.
For those of you that are not familiar with jQuery, I mentioned it previously in an early post.
So what does this plug-in do?
Well, as per the title, it sends a jQuery selected element to the printer.
So what’s special about it?
Well, I saw a few existing plug-ins around (Kudos again to PrintArea and this fellow for the inspiration), but they lacked the functionality I needed.
And of course, I really wanted to write my first jQuery plug-in :-)
The usage is rather strait forward:
$("selector").printElement();Which will caused the selected jQuery objects html to be sent to the printer.
There are two main modes you can use:
There are two main modes you can use:
Print from :
- Iframe (default, Pro: Hidden)
- Popup (Pro: shows the user a preview of what’ll be printed)
For more info, and more options, have a look at the Wiki, or at the official plug-in page at jQuery.
Would love to hear any feedback, either here or at the issues section..
Cheers,
Erik

Hi Erik,
ReplyDeleteGood plugin, but found what seems to be an issue. I have a table which contains a form used for membership creation. The entire table and form show up as they should, but the values entered into the form do not. I have a javascript solution, but was looking for a jq plugin to simplify. Following is the javascript which copies not only the table and form, but also any data entered into the input tags (with the exception of select boxes) :-(.
var node = document.getElementById(divName).cloneNode(true);
node.id = "printDiv";
var winId;
winId = window.open("printwindow.jsp","printWin","width=650,height=570,menubar=1,toolbar=0,scrollbars=1,resizable=0,location=0");
winId.document.write('<html>');
winId.document.write('<head>');
winId.document.write('<link type="text/css" href="../css/coolstyle.css" rel="StyleSheet" />');
winId.document.write('</head>');
winId.document.write('<body>');
winId.document.write('</body>');
winId.document.write('</html>');
winId.document.body.appendChild(node);
winId.document.close();
winId.print();
winId.focus();
Thank you (Anonymous)..
ReplyDeleteI've added this problem to the issues section (see link above), and I'll definitely add a solution similar to yours soon..
Erik
Erik, a small update. I changed the first line of function _printElement.
ReplyDeleteFrom: var $elementToPrint = $(element);
To: var $elementToPrint = $(element).clone(true);
Thinking that a deep cloning would produce the values in the output. This did not work :-( However I then wanted to see if the values were even making it into the plugin, so I added
alert($elementToPrint.find("#firstName").val());
As you can guess, the first name selector is the ld field on my membership form. The alert did validate that the value is coming in however it's not showing up in the output. To determine this I added the following to the onload js.
From: focus();print();
To: focus();alert("new value:"+document.getElementById("firstName").value);print();
I believe it might be in the push to the html array due to the fact that onload the value is blank.
Just thought I would share what I found.
John, I've added this to the issue section (see http://github.com/erikzaadi/jQueryPlugins/issues/#issue/1), thanks for the info.
ReplyDeleteI'll update both the issue and this thread of any progress..
Hi Again, I've tried to add a comment on github, but am unable to add. Do I have to join github to post a comment? I'm pasting a solution below. I'm sure there is a more elegant solution, but I don't have a lot of time to finish this particular project. There is still another issue which needs attention. Although the below solution now copies all input entered into form elements, the selected values of selectboxes is not carrying over.
ReplyDeleteHere is a possible solution:
function _printElement(element, opts) {
// Modified
var $elementToPrint = $(element).clone(true);
//Create markup to be printed
var html = _getMarkup($elementToPrint, opts);
var popupOrIframe = null;
var documentToWriteTo = null;
if (opts.printMode.toLowerCase() == 'popup') {
popupOrIframe = window.open('', 'printElementWindow', 'width=650,height=440,scrollbars=yes');
documentToWriteTo = popupOrIframe.document;
}
else {
var printElementID = "printElement_" + (Math.random() * 99999).toString();
popupOrIframe = $('< iframe />').attr({ style: opts.iframeElementOptions.styleToAdd,
id: printElementID,
className: opts.iframeElementOptions.classNameToAdd
}).appendTo('body')[0].contentWindow;
documentToWriteTo = popupOrIframe.document;
}
// Modified
window.focus();
documentToWriteTo.open();
documentToWriteTo.write(html);
documentToWriteTo.body.appendChild($elementToPrint[0]);
documentToWriteTo.close();
popupOrIframe.focus();
};
function _getMarkup(element, opts) {
var $elementToPrint = $(element);
var html = new Array();
html.push('< html>< head>< title>' + opts.pageTitle + '< /title>');
if (opts.overrideElementCSS && opts.overrideElementCSS.length > 0) {
for (var x = 0; x < opts.overrideElementCSS.length; x++) {
html.push('< link type="text/css" rel="stylesheet" href="' + opts.overrideElementCSS[x] + '" >');
}
}
else {
$(document).find("link ")
.filter(function() {
return $(this).attr("rel").toLowerCase() == "stylesheet";
})
.each(function() {
html.push('< link type="text/css" rel="stylesheet" href="' + $(this).attr("href") + '" >');
});
}
html.push('< /head>< body onload="printPage();" style="' + opts.printBodyOptions.styleToAdd + '" class="' + opts.printBodyOptions.classNameToAdd + '">');
// Modified
html.push('< div id="elementWrapper" class="' + $elementToPrint.attr("class") + '">< /div>');
html.push('< script type="text/javascript">function printPage() { focus();print();' + (opts.leaveOpen ? '' : 'close();') + '}< /script>< /body>< /html>');
return html.join('');
};
Ok. Here is the solution to getting selectbox values in the print output.
ReplyDeletevar $elementToPrint = $(element).clone(true);
var selvals = [];
$(element).find("select").each(function() {
selvals.push($(this).val());
});
$elementToPrint.find("select").each(function() {
$(this).val(selvals.shift());
});
It appears that IE8 has an issue with appendChild, at least the way I used it above. The following is my changes.
ReplyDeletewindow.focus();
documentToWriteTo.open();
documentToWriteTo.write(html);
if($.browser.msie) {
documentToWriteTo.write($elementToPrint.html());
} else {
documentToWriteTo.body.appendChild($elementToPrint[0]);
}
documentToWriteTo.close();
popupOrIframe.focus();
I'm getting an error:
ReplyDeletethis.firstChild is null
I do have a bunch of hidden divs on the page, that's the only thing I can think of that might be causing it
Hey byronbulb, what version of jQuery.printElement are you using? And what browser?
ReplyDeleteThanks
Erik
Hi Erik,
ReplyDeleteIs there any other jQuery files need to be included in the page for the printElement to work? I downloaded version 1 and am using jQuery 3.2. I can get the object, but when I call:
$('#calendar').printElement({});
I get "Object doesn't support this property or method" error....
Any ideas?
Thank you,
Annie
Hey Annie,
ReplyDeleteThat should work fine, what jQuery Printelement JS file did you download?
Erik
Hi Erik,
ReplyDeleteIt's the jquery.printElement.min.js, and it's the version 1.0.
Oh, and sorry, my bad, the jQuery i'm using is version 1.3.2.
One other thing to mention is that the #calendar is a div element, and it was converted to a jQuery fullcalendar object before I call the printElement.
Do you think that makes any difference?
Thank you,
Annie
Hi again Annie
ReplyDeleteWell, it might, I'm not familiar with the fullcalendar plugin..
Do you mind continuing this thread on my new blog?
http://erikzaadi.com/blog/2009/10/09/Update-JQueryPrintElementPluginVersion10Released.xhtml
Erik