Commit d9d031bb502aff9e76d319f1b366ce214d6a0bbc
Exists in
master
and in
2 other branches
Merge branch 'refactoring' of https://github.com/amadeusproject/amadeuslms into refactoring
Showing
4 changed files
with
349 additions
and
34 deletions
Show diff stats
@@ -0,0 +1,304 @@ | @@ -0,0 +1,304 @@ | ||
1 | +/* | ||
2 | + * printThis v1.10.0 | ||
3 | + * @desc Printing plug-in for jQuery | ||
4 | + * @author Jason Day | ||
5 | + * | ||
6 | + * Resources (based on) : | ||
7 | + * jPrintArea: http://plugins.jquery.com/project/jPrintArea | ||
8 | + * jqPrint: https://github.com/permanenttourist/jquery.jqprint | ||
9 | + * Ben Nadal: http://www.bennadel.com/blog/1591-Ask-Ben-Print-Part-Of-A-Web-Page-With-jQuery.htm | ||
10 | + * | ||
11 | + * Licensed under the MIT licence: | ||
12 | + * http://www.opensource.org/licenses/mit-license.php | ||
13 | + * | ||
14 | + * (c) Jason Day 2015 | ||
15 | + * | ||
16 | + * Usage: | ||
17 | + * | ||
18 | + * $("#mySelector").printThis({ | ||
19 | + * debug: false, // show the iframe for debugging | ||
20 | + * importCSS: true, // import page CSS | ||
21 | + * importStyle: false, // import style tags | ||
22 | + * printContainer: true, // grab outer container as well as the contents of the selector | ||
23 | + * loadCSS: "path/to/my.css", // path to additional css file - us an array [] for multiple | ||
24 | + * pageTitle: "", // add title to print page | ||
25 | + * removeInline: false, // remove all inline styles from print elements | ||
26 | + * printDelay: 333, // variable print delay | ||
27 | + * header: null, // prefix to html | ||
28 | + * footer: null, // postfix to html | ||
29 | + * base: false, // preserve the BASE tag, or accept a string for the URL | ||
30 | + * formValues: true, // preserve input/form values | ||
31 | + * canvas: false, // copy canvas elements (experimental) | ||
32 | + * doctypeString: '...', // enter a different doctype for older markup | ||
33 | + * removeScripts: false // remove script tags from print content | ||
34 | + * }); | ||
35 | + * | ||
36 | + * Notes: | ||
37 | + * - the loadCSS will load additional css (with or without @media print) into the iframe, adjusting layout | ||
38 | + */ | ||
39 | +; | ||
40 | +(function($) { | ||
41 | + | ||
42 | + function appendContent($el, content) { | ||
43 | + if (!content) return; | ||
44 | + | ||
45 | + // Simple test for a jQuery element | ||
46 | + $el.append(content.jquery ? content.clone() : content); | ||
47 | + } | ||
48 | + | ||
49 | + function appendBody($body, $element, opt) { | ||
50 | + // Clone for safety and convenience | ||
51 | + var $content = $element.clone(); | ||
52 | + | ||
53 | + if (opt.removeScripts) { | ||
54 | + $content.find('script').remove(); | ||
55 | + } | ||
56 | + | ||
57 | + if (opt.printContainer) { | ||
58 | + // grab $.selector as container | ||
59 | + $body.append($("<div/>").html($content).html()); | ||
60 | + } else { | ||
61 | + // otherwise just print interior elements of container | ||
62 | + $content.each(function() { | ||
63 | + $body.append($(this).html()); | ||
64 | + }); | ||
65 | + } | ||
66 | + } | ||
67 | + | ||
68 | + var opt; | ||
69 | + $.fn.printThis = function(options) { | ||
70 | + opt = $.extend({}, $.fn.printThis.defaults, options); | ||
71 | + var $element = this instanceof jQuery ? this : $(this); | ||
72 | + | ||
73 | + var strFrameName = "printThis-" + (new Date()).getTime(); | ||
74 | + | ||
75 | + if (window.location.hostname !== document.domain && navigator.userAgent.match(/msie/i)) { | ||
76 | + // Ugly IE hacks due to IE not inheriting document.domain from parent | ||
77 | + // checks if document.domain is set by comparing the host name against document.domain | ||
78 | + var iframeSrc = "javascript:document.write(\"<head><script>document.domain=\\\"" + document.domain + "\\\";</s" + "cript></head><body></body>\")"; | ||
79 | + var printI = document.createElement('iframe'); | ||
80 | + printI.name = "printIframe"; | ||
81 | + printI.id = strFrameName; | ||
82 | + printI.className = "MSIE"; | ||
83 | + document.body.appendChild(printI); | ||
84 | + printI.src = iframeSrc; | ||
85 | + | ||
86 | + } else { | ||
87 | + // other browsers inherit document.domain, and IE works if document.domain is not explicitly set | ||
88 | + var $frame = $("<iframe id='" + strFrameName + "' name='printIframe' />"); | ||
89 | + $frame.appendTo("body"); | ||
90 | + } | ||
91 | + | ||
92 | + var $iframe = $("#" + strFrameName); | ||
93 | + | ||
94 | + // show frame if in debug mode | ||
95 | + if (!opt.debug) $iframe.css({ | ||
96 | + position: "absolute", | ||
97 | + width: "0px", | ||
98 | + height: "0px", | ||
99 | + left: "-600px", | ||
100 | + top: "-600px" | ||
101 | + }); | ||
102 | + | ||
103 | + // $iframe.ready() and $iframe.load were inconsistent between browsers | ||
104 | + setTimeout(function() { | ||
105 | + | ||
106 | + // Add doctype to fix the style difference between printing and render | ||
107 | + function setDocType($iframe, doctype){ | ||
108 | + var win, doc; | ||
109 | + win = $iframe.get(0); | ||
110 | + win = win.contentWindow || win.contentDocument || win; | ||
111 | + doc = win.document || win.contentDocument || win; | ||
112 | + doc.open(); | ||
113 | + doc.write(doctype); | ||
114 | + doc.close(); | ||
115 | + } | ||
116 | + | ||
117 | + if (opt.doctypeString){ | ||
118 | + setDocType($iframe, opt.doctypeString); | ||
119 | + } | ||
120 | + | ||
121 | + var $doc = $iframe.contents(), | ||
122 | + $head = $doc.find("head"), | ||
123 | + $body = $doc.find("body"), | ||
124 | + $base = $('base'), | ||
125 | + baseURL; | ||
126 | + | ||
127 | + // add base tag to ensure elements use the parent domain | ||
128 | + if (opt.base === true && $base.length > 0) { | ||
129 | + // take the base tag from the original page | ||
130 | + baseURL = $base.attr('href'); | ||
131 | + } else if (typeof opt.base === 'string') { | ||
132 | + // An exact base string is provided | ||
133 | + baseURL = opt.base; | ||
134 | + } else { | ||
135 | + // Use the page URL as the base | ||
136 | + baseURL = document.location.protocol + '//' + document.location.host; | ||
137 | + } | ||
138 | + | ||
139 | + $head.append('<base href="' + baseURL + '">'); | ||
140 | + | ||
141 | + // import page stylesheets | ||
142 | + if (opt.importCSS) $("link[rel=stylesheet]").each(function() { | ||
143 | + var href = $(this).attr("href"); | ||
144 | + if (href) { | ||
145 | + var media = $(this).attr("media") || "all"; | ||
146 | + $head.append("<link type='text/css' rel='stylesheet' href='" + href + "' media='" + media + "'>"); | ||
147 | + } | ||
148 | + }); | ||
149 | + | ||
150 | + // import style tags | ||
151 | + if (opt.importStyle) $("style").each(function() { | ||
152 | + $(this).clone().appendTo($head); | ||
153 | + }); | ||
154 | + | ||
155 | + // add title of the page | ||
156 | + if (opt.pageTitle) $head.append("<title>" + opt.pageTitle + "</title>"); | ||
157 | + | ||
158 | + // import additional stylesheet(s) | ||
159 | + if (opt.loadCSS) { | ||
160 | + if ($.isArray(opt.loadCSS)) { | ||
161 | + jQuery.each(opt.loadCSS, function(index, value) { | ||
162 | + $head.append("<link type='text/css' rel='stylesheet' href='" + this + "'>"); | ||
163 | + }); | ||
164 | + } else { | ||
165 | + $head.append("<link type='text/css' rel='stylesheet' href='" + opt.loadCSS + "'>"); | ||
166 | + } | ||
167 | + } | ||
168 | + | ||
169 | + // print header | ||
170 | + appendContent($body, opt.header); | ||
171 | + | ||
172 | + if (opt.canvas) { | ||
173 | + // add canvas data-ids for easy access after cloning. | ||
174 | + var canvasId = 0; | ||
175 | + $element.find('canvas').each(function(){ | ||
176 | + $(this).attr('data-printthis', canvasId++); | ||
177 | + }); | ||
178 | + } | ||
179 | + | ||
180 | + appendBody($body, $element, opt); | ||
181 | + | ||
182 | + if (opt.canvas) { | ||
183 | + // Re-draw new canvases by referencing the originals | ||
184 | + $body.find('canvas').each(function(){ | ||
185 | + var cid = $(this).data('printthis'), | ||
186 | + $src = $('[data-printthis="' + cid + '"]'); | ||
187 | + | ||
188 | + this.getContext('2d').drawImage($src[0], 0, 0); | ||
189 | + | ||
190 | + // Remove the markup from the original | ||
191 | + $src.removeData('printthis'); | ||
192 | + }); | ||
193 | + } | ||
194 | + | ||
195 | + // capture form/field values | ||
196 | + if (opt.formValues) { | ||
197 | + // loop through inputs | ||
198 | + var $input = $element.find('input'); | ||
199 | + if ($input.length) { | ||
200 | + $input.each(function() { | ||
201 | + var $this = $(this), | ||
202 | + $name = $(this).attr('name'), | ||
203 | + $checker = $this.is(':checkbox') || $this.is(':radio'), | ||
204 | + $iframeInput = $doc.find('input[name="' + $name + '"]'), | ||
205 | + $value = $this.val(); | ||
206 | + | ||
207 | + // order matters here | ||
208 | + if (!$checker) { | ||
209 | + $iframeInput.val($value); | ||
210 | + } else if ($this.is(':checked')) { | ||
211 | + if ($this.is(':checkbox')) { | ||
212 | + $iframeInput.attr('checked', 'checked'); | ||
213 | + } else if ($this.is(':radio')) { | ||
214 | + $doc.find('input[name="' + $name + '"][value="' + $value + '"]').attr('checked', 'checked'); | ||
215 | + } | ||
216 | + } | ||
217 | + | ||
218 | + }); | ||
219 | + } | ||
220 | + | ||
221 | + // loop through selects | ||
222 | + var $select = $element.find('select'); | ||
223 | + if ($select.length) { | ||
224 | + $select.each(function() { | ||
225 | + var $this = $(this), | ||
226 | + $name = $(this).attr('name'), | ||
227 | + $value = $this.val(); | ||
228 | + $doc.find('select[name="' + $name + '"]').val($value); | ||
229 | + }); | ||
230 | + } | ||
231 | + | ||
232 | + // loop through textareas | ||
233 | + var $textarea = $element.find('textarea'); | ||
234 | + if ($textarea.length) { | ||
235 | + $textarea.each(function() { | ||
236 | + var $this = $(this), | ||
237 | + $name = $(this).attr('name'), | ||
238 | + $value = $this.val(); | ||
239 | + $doc.find('textarea[name="' + $name + '"]').val($value); | ||
240 | + }); | ||
241 | + } | ||
242 | + } // end capture form/field values | ||
243 | + | ||
244 | + // remove inline styles | ||
245 | + if (opt.removeInline) { | ||
246 | + // $.removeAttr available jQuery 1.7+ | ||
247 | + if ($.isFunction($.removeAttr)) { | ||
248 | + $doc.find("body *").removeAttr("style"); | ||
249 | + } else { | ||
250 | + $doc.find("body *").attr("style", ""); | ||
251 | + } | ||
252 | + } | ||
253 | + | ||
254 | + // print "footer" | ||
255 | + appendContent($body, opt.footer); | ||
256 | + | ||
257 | + setTimeout(function() { | ||
258 | + if ($iframe.hasClass("MSIE")) { | ||
259 | + // check if the iframe was created with the ugly hack | ||
260 | + // and perform another ugly hack out of neccessity | ||
261 | + window.frames["printIframe"].focus(); | ||
262 | + $head.append("<script> window.print(); </s" + "cript>"); | ||
263 | + } else { | ||
264 | + // proper method | ||
265 | + if (document.queryCommandSupported("print")) { | ||
266 | + $iframe[0].contentWindow.document.execCommand("print", false, null); | ||
267 | + } else { | ||
268 | + $iframe[0].contentWindow.focus(); | ||
269 | + $iframe[0].contentWindow.print(); | ||
270 | + } | ||
271 | + } | ||
272 | + | ||
273 | + // remove iframe after print | ||
274 | + if (!opt.debug) { | ||
275 | + setTimeout(function() { | ||
276 | + $iframe.remove(); | ||
277 | + }, 1000); | ||
278 | + } | ||
279 | + | ||
280 | + }, opt.printDelay); | ||
281 | + | ||
282 | + }, 333); | ||
283 | + | ||
284 | + }; | ||
285 | + | ||
286 | + // defaults | ||
287 | + $.fn.printThis.defaults = { | ||
288 | + debug: false, // show the iframe for debugging | ||
289 | + importCSS: true, // import parent page css | ||
290 | + importStyle: false, // import style tags | ||
291 | + printContainer: true, // print outer container/$.selector | ||
292 | + loadCSS: "", // load an additional css file - load multiple stylesheets with an array [] | ||
293 | + pageTitle: "", // add title to print page | ||
294 | + removeInline: false, // remove all inline styles | ||
295 | + printDelay: 333, // variable print delay | ||
296 | + header: null, // prefix to html | ||
297 | + footer: null, // postfix to html | ||
298 | + formValues: true, // preserve input/form values | ||
299 | + canvas: false, // copy canvas content (experimental) | ||
300 | + base: false, // preserve the BASE tag, or accept a string for the URL | ||
301 | + doctypeString: '<!DOCTYPE html>', // html doctype | ||
302 | + removeScripts: false // remove script tags before appending | ||
303 | + }; | ||
304 | +})(jQuery); |
amadeus/templates/base.html
@@ -34,6 +34,8 @@ | @@ -34,6 +34,8 @@ | ||
34 | <script src="{% static 'js/crop.js' %}"></script> <!-- Js for cropper--> | 34 | <script src="{% static 'js/crop.js' %}"></script> <!-- Js for cropper--> |
35 | <link href="{% static 'css/cropper.min.css' %}" rel="stylesheet"> <!-- CSS for cropper--> | 35 | <link href="{% static 'css/cropper.min.css' %}" rel="stylesheet"> <!-- CSS for cropper--> |
36 | 36 | ||
37 | + <script type="text/javascript" src="{% static 'js/printThis.js' %}"></script> <!-- Print this plugin js--> | ||
38 | + | ||
37 | 39 | ||
38 | <script type="text/javascript" src="{% static 'bootstrap-3.3.7/js/bootstrap.min.js' %}"></script> | 40 | <script type="text/javascript" src="{% static 'bootstrap-3.3.7/js/bootstrap.min.js' %}"></script> |
39 | <!--<script type="text/javascript" src="{% static 'js/bootstrap-acessibility2.min.js' %}"></script>--> | 41 | <!--<script type="text/javascript" src="{% static 'js/bootstrap-acessibility2.min.js' %}"></script>--> |
news/templates/news/view.html
@@ -25,11 +25,11 @@ | @@ -25,11 +25,11 @@ | ||
25 | </script> | 25 | </script> |
26 | {% endfor %} | 26 | {% endfor %} |
27 | {% endif %} | 27 | {% endif %} |
28 | -<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 "> | ||
29 | - <div class="col-lg-12 row-fluid panel panel-default"> | ||
30 | - <div class="panel-body"> | 28 | + |
29 | + <div class="row-fluid panel panel-default" > | ||
30 | + <div class="panel-body" id="printArea"> | ||
31 | <div class="col-md-12" style="display:inline-block"> | 31 | <div class="col-md-12" style="display:inline-block"> |
32 | - <h2><b>{{new.title}}</b></h2> | 32 | + <h2><b>{{new.title}}</b></h2> <button style="text-transform:none; text-decoration: underline;" type="button" class="pull-right btn btn-default btn-sm" id="printButton" name="button">{% trans "Print News" %} <i class="fa fa-print" aria-hidden="true"></i></button><br> |
33 | <p>{{new.creator}}, em {{new.create_date}}</p> | 33 | <p>{{new.creator}}, em {{new.create_date}}</p> |
34 | </div> | 34 | </div> |
35 | <div class="col-md-12"> | 35 | <div class="col-md-12"> |
@@ -43,6 +43,12 @@ | @@ -43,6 +43,12 @@ | ||
43 | 43 | ||
44 | </div> | 44 | </div> |
45 | 45 | ||
46 | + <script type="text/javascript" src="{% static 'js/printThis.js' %}"></script> | ||
47 | + <script type="text/javascript"> | ||
48 | + $('#printButton').click(function(){ | ||
49 | + $("#printArea").printThis({removeInline:true,importStyle: true, }); | ||
50 | + }); | ||
51 | + | ||
52 | + </script> | ||
46 | 53 | ||
47 | -</div> | ||
48 | {% endblock %} | 54 | {% endblock %} |
users/forms.py
@@ -81,18 +81,19 @@ class RegisterUserForm(Validation): | @@ -81,18 +81,19 @@ class RegisterUserForm(Validation): | ||
81 | 81 | ||
82 | if self.instance.image : | 82 | if self.instance.image : |
83 | image = Image.open(self.instance.image) | 83 | image = Image.open(self.instance.image) |
84 | - cropped_image = image.crop((x, y, w+x, h+y)) | ||
85 | - resized_image = cropped_image.resize((200, 200), Image.ANTIALIAS) | 84 | + if not x is None: |
85 | + cropped_image = image.crop((x, y, w+x, h+y)) | ||
86 | + resized_image = cropped_image.resize((200, 200), Image.ANTIALIAS) | ||
86 | 87 | ||
87 | - folder_path = join(settings.MEDIA_ROOT, 'users') | ||
88 | - #check if the folder already exists | ||
89 | - if not os.path.isdir(folder_path): | ||
90 | - os.makedirs(folder_path) | 88 | + folder_path = join(settings.MEDIA_ROOT, 'users') |
89 | + #check if the folder already exists | ||
90 | + if not os.path.isdir(folder_path): | ||
91 | + os.makedirs(folder_path) | ||
91 | 92 | ||
92 | - if ("users" not in self.instance.image.path): | ||
93 | - self.deletepath = self.instance.image.path | 93 | + if ("users" not in self.instance.image.path): |
94 | + self.deletepath = self.instance.image.path | ||
94 | 95 | ||
95 | - resized_image.save(self.instance.image.path) | 96 | + resized_image.save(self.instance.image.path) |
96 | 97 | ||
97 | self.instance.set_password(self.cleaned_data['new_password']) | 98 | self.instance.set_password(self.cleaned_data['new_password']) |
98 | 99 | ||
@@ -128,21 +129,22 @@ class ProfileForm(Validation): | @@ -128,21 +129,22 @@ class ProfileForm(Validation): | ||
128 | y = self.cleaned_data.get('y') | 129 | y = self.cleaned_data.get('y') |
129 | w = self.cleaned_data.get('width') | 130 | w = self.cleaned_data.get('width') |
130 | h = self.cleaned_data.get('height') | 131 | h = self.cleaned_data.get('height') |
131 | - | 132 | + |
132 | if self.instance.image: | 133 | if self.instance.image: |
133 | image = Image.open(self.instance.image) | 134 | image = Image.open(self.instance.image) |
134 | - cropped_image = image.crop((x, y, w+x, h+y)) | ||
135 | - resized_image = cropped_image.resize((200, 200), Image.ANTIALIAS) | 135 | + if not x is None: |
136 | + cropped_image = image.crop((x, y, w+x, h+y)) | ||
137 | + resized_image = cropped_image.resize((200, 200), Image.ANTIALIAS) | ||
136 | 138 | ||
137 | - folder_path = join(settings.MEDIA_ROOT, 'users') | ||
138 | - #check if the folder already exists | ||
139 | - if not os.path.isdir(folder_path): | ||
140 | - os.makedirs(folder_path) | 139 | + folder_path = join(settings.MEDIA_ROOT, 'users') |
140 | + #check if the folder already exists | ||
141 | + if not os.path.isdir(folder_path): | ||
142 | + os.makedirs(folder_path) | ||
141 | 143 | ||
142 | - if ("users" not in self.instance.image.path): | ||
143 | - self.deletepath = self.instance.image.path | 144 | + if ("users" not in self.instance.image.path): |
145 | + self.deletepath = self.instance.image.path | ||
144 | 146 | ||
145 | - resized_image.save(self.instance.image.path) | 147 | + resized_image.save(self.instance.image.path) |
146 | 148 | ||
147 | self.instance.save() | 149 | self.instance.save() |
148 | if (self.deletepath): | 150 | if (self.deletepath): |
@@ -181,7 +183,7 @@ class UserForm(Validation): | @@ -181,7 +183,7 @@ class UserForm(Validation): | ||
181 | 183 | ||
182 | def save(self, commit=True): | 184 | def save(self, commit=True): |
183 | super(UserForm, self).save(commit=False) | 185 | super(UserForm, self).save(commit=False) |
184 | - self.deletepath = "" | 186 | + self.deletepath = "" |
185 | 187 | ||
186 | x = self.cleaned_data.get('x') | 188 | x = self.cleaned_data.get('x') |
187 | y = self.cleaned_data.get('y') | 189 | y = self.cleaned_data.get('y') |
@@ -190,18 +192,19 @@ class UserForm(Validation): | @@ -190,18 +192,19 @@ class UserForm(Validation): | ||
190 | 192 | ||
191 | if self.instance.image : | 193 | if self.instance.image : |
192 | image = Image.open(self.instance.image) | 194 | image = Image.open(self.instance.image) |
193 | - cropped_image = image.crop((x, y, w+x, h+y)) | ||
194 | - resized_image = cropped_image.resize((200, 200), Image.ANTIALIAS) | 195 | + if not x is None: |
196 | + cropped_image = image.crop((x, y, w+x, h+y)) | ||
197 | + resized_image = cropped_image.resize((200, 200), Image.ANTIALIAS) | ||
195 | 198 | ||
196 | - folder_path = join(settings.MEDIA_ROOT, 'users') | ||
197 | - #check if the folder already exists | ||
198 | - if not os.path.isdir(folder_path): | ||
199 | - os.makedirs(folder_path) | 199 | + folder_path = join(settings.MEDIA_ROOT, 'users') |
200 | + #check if the folder already exists | ||
201 | + if not os.path.isdir(folder_path): | ||
202 | + os.makedirs(folder_path) | ||
200 | 203 | ||
201 | - if ("users" not in self.instance.image.path): | ||
202 | - self.deletepath = self.instance.image.path | 204 | + if ("users" not in self.instance.image.path): |
205 | + self.deletepath = self.instance.image.path | ||
203 | 206 | ||
204 | - resized_image.save(self.instance.image.path) | 207 | + resized_image.save(self.instance.image.path) |
205 | 208 | ||
206 | 209 | ||
207 | if not self.is_edit or self.cleaned_data['new_password'] != '': | 210 | if not self.is_edit or self.cleaned_data['new_password'] != '': |