jquery.print.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /* @license
  2. * jQuery.print, version 1.3.2
  3. * (c) Sathvik Ponangi, Doers' Guild
  4. * Licence: CC-By (http://creativecommons.org/licenses/by/3.0/)
  5. *--------------------------------------------------------------------------*/
  6. (function ($) {
  7. "use strict";
  8. // A nice closure for our definitions
  9. function getjQueryObject(string) {
  10. // Make string a vaild jQuery thing
  11. var jqObj = $("");
  12. try {
  13. jqObj = $(string)
  14. .clone();
  15. } catch (e) {
  16. jqObj = $("<span />")
  17. .html(string);
  18. }
  19. return jqObj;
  20. }
  21. function printFrame(frameWindow) {
  22. // Print the selected window/iframe
  23. var def = $.Deferred();
  24. try {
  25. setTimeout(function () {
  26. // Fix for IE : Allow it to render the iframe
  27. frameWindow.focus();
  28. try {
  29. // Fix for IE11 - printng the whole page instead of the iframe content
  30. if (!frameWindow.document.execCommand('print', false, null)) {
  31. // document.execCommand returns false if it failed -http://stackoverflow.com/a/21336448/937891
  32. frameWindow.print();
  33. }
  34. } catch (e) {
  35. frameWindow.print();
  36. }
  37. frameWindow.close();
  38. def.resolve();
  39. }, 250);
  40. } catch (err) {
  41. def.reject(err);
  42. }
  43. return def;
  44. }
  45. function printContentInNewWindow(content) {
  46. // Open a new window and print selected content
  47. var w = window.open();
  48. w.document.write(content);
  49. w.document.close();
  50. return printFrame(w);
  51. }
  52. function isNode(o) {
  53. /* http://stackoverflow.com/a/384380/937891 */
  54. return !!(typeof Node === "object" ? o instanceof Node : o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName === "string");
  55. }
  56. $.print = $.fn.print = function () {
  57. // Print a given set of elements
  58. var options, $this, self = this;
  59. console.log("Printing", this, arguments);
  60. if (self instanceof $) {
  61. // Get the node if it is a jQuery object
  62. self = self.get(0);
  63. }
  64. if (isNode(self)) {
  65. // If `this` is a HTML element, i.e. for
  66. // $(selector).print()
  67. $this = $(self);
  68. if (arguments.length > 0) {
  69. options = arguments[0];
  70. }
  71. } else {
  72. if (arguments.length > 0) {
  73. // $.print(selector,options)
  74. $this = $(arguments[0]);
  75. if (isNode($this[0])) {
  76. if (arguments.length > 1) {
  77. options = arguments[1];
  78. }
  79. } else {
  80. // $.print(options)
  81. options = arguments[0];
  82. $this = $("html");
  83. }
  84. } else {
  85. // $.print()
  86. $this = $("html");
  87. }
  88. }
  89. // Default options
  90. var defaults = {
  91. globalStyles: true,
  92. mediaPrint: false,
  93. stylesheet: null,
  94. noPrintSelector: ".no-print",
  95. iframe: true,
  96. append: null,
  97. prepend: null,
  98. manuallyCopyFormValues: true,
  99. deferred: $.Deferred()
  100. };
  101. // Merge with user-options
  102. options = $.extend({}, defaults, (options || {}));
  103. var $styles = $("");
  104. if (options.globalStyles) {
  105. // Apply the stlyes from the current sheet to the printed page
  106. // $styles = $("style, link, meta, title");
  107. $styles = $("style, link, meta");
  108. } else if (options.mediaPrint) {
  109. // Apply the media-print stylesheet
  110. $styles = $("link[media=print]");
  111. }
  112. if (options.stylesheet) {
  113. // Add a custom stylesheet if given
  114. $styles = $.merge($styles, $('<link rel="stylesheet" href="' + options.stylesheet + '">'));
  115. }
  116. // Create a copy of the element to print
  117. var copy = $this.clone();
  118. // Wrap it in a span to get the HTML markup string
  119. copy = $("<span/>")
  120. .append(copy);
  121. // Remove unwanted elements
  122. copy.find(options.noPrintSelector)
  123. .remove();
  124. // Add in the styles
  125. copy.append($styles.clone());
  126. // Appedned content
  127. copy.append(getjQueryObject(options.append));
  128. // Prepended content
  129. copy.prepend(getjQueryObject(options.prepend));
  130. if (options.manuallyCopyFormValues) {
  131. // Manually copy form values into the HTML for printing user-modified input fields
  132. // http://stackoverflow.com/a/26707753
  133. copy.find("input")
  134. .each(function () {
  135. var $field = $(this);
  136. if ($field.is("[type='radio']") || $field.is("[type='checkbox']")) {
  137. if ($field.prop("checked")) {
  138. $field.attr("checked", "checked");
  139. }
  140. } else {
  141. $field.attr("value", $field.val());
  142. }
  143. });
  144. copy.find("select").each(function () {
  145. var $field = $(this);
  146. $field.find(":selected").attr("selected", "selected");
  147. });
  148. copy.find("textarea").each(function () {
  149. // Fix for https://github.com/DoersGuild/jQuery.print/issues/18#issuecomment-96451589
  150. var $field = $(this);
  151. $field.text($field.val());
  152. });
  153. }
  154. // Get the HTML markup string
  155. var content = copy.html();
  156. // Notify with generated markup & cloned elements - useful for logging, etc
  157. try {
  158. options.deferred.notify('generated_markup', content, copy);
  159. } catch (err) {
  160. console.warn('Error notifying deferred', err);
  161. }
  162. // Destroy the copy
  163. copy.remove();
  164. if (options.iframe) {
  165. // Use an iframe for printing
  166. try {
  167. var $iframe = $(options.iframe + "");
  168. var iframeCount = $iframe.length;
  169. if (iframeCount === 0) {
  170. // Create a new iFrame if none is given
  171. $iframe = $('<iframe height="0" width="0" border="0" wmode="Opaque"/>')
  172. .prependTo('body')
  173. .css({
  174. "position": "absolute",
  175. "top": -999,
  176. "left": -999
  177. });
  178. }
  179. var w, wdoc;
  180. w = $iframe.get(0);
  181. w = w.contentWindow || w.contentDocument || w;
  182. wdoc = w.document || w.contentDocument || w;
  183. wdoc.open();
  184. wdoc.write(content);
  185. wdoc.close();
  186. printFrame(w)
  187. .done(function () {
  188. // Success
  189. setTimeout(function () {
  190. // Wait for IE
  191. if (iframeCount === 0) {
  192. // Destroy the iframe if created here
  193. $iframe.remove();
  194. }
  195. }, 100);
  196. })
  197. .fail(function (err) {
  198. // Use the pop-up method if iframe fails for some reason
  199. console.error("Failed to print from iframe", err);
  200. printContentInNewWindow(content);
  201. })
  202. .always(function () {
  203. try {
  204. options.deferred.resolve();
  205. } catch (err) {
  206. console.warn('Error notifying deferred', err);
  207. }
  208. });
  209. } catch (e) {
  210. // Use the pop-up method if iframe fails for some reason
  211. console.error("Failed to print from iframe", e.stack, e.message);
  212. printContentInNewWindow(content)
  213. .always(function () {
  214. try {
  215. options.deferred.resolve();
  216. } catch (err) {
  217. console.warn('Error notifying deferred', err);
  218. }
  219. });
  220. }
  221. } else {
  222. // Use a new window for printing
  223. printContentInNewWindow(content)
  224. .always(function () {
  225. try {
  226. options.deferred.resolve();
  227. } catch (err) {
  228. console.warn('Error notifying deferred', err);
  229. }
  230. });
  231. }
  232. return this;
  233. };
  234. })(jQuery);