Skip to content

Commit 4ad6a27

Browse files
committed
Size validator, events.
1 parent aa122e8 commit 4ad6a27

File tree

4 files changed

+399
-127
lines changed

4 files changed

+399
-127
lines changed

dist/js/dropify.js

Lines changed: 194 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ function Dropify(element, options) {
3131
var defaults = {
3232
defaultFile: '',
3333
maxFileSize: 0,
34+
minWidth: 0,
35+
maxWidth: 0,
36+
minHeight: 0,
37+
maxHeight: 0,
38+
allowedFormats: ['portrait', 'square', 'landscape'],
3439
messages: {
3540
'default': 'Drag and drop a file here or click',
3641
'replace': 'Drag and drop or click to replace',
@@ -47,23 +52,31 @@ function Dropify(element, options) {
4752
}
4853
};
4954

50-
this.element = element;
51-
this.input = $(this.element);
52-
this.wrapper = null;
53-
this.preview = null;
54-
this.filenameWrapper = null;
55-
this.settings = $.extend(true, defaults, options, this.input.data());
56-
this.imgFileFormats = ['png', 'jpg', 'jpeg', 'gif', 'bmp'];
57-
this.file = null;
58-
this.filename = null;
59-
this.isDisabled = false;
55+
this.element = element;
56+
this.input = $(this.element);
57+
this.wrapper = null;
58+
this.preview = null;
59+
this.filenameWrapper = null;
60+
this.settings = $.extend(true, defaults, options, this.input.data());
61+
this.imgFileExtensions = ['png', 'jpg', 'jpeg', 'gif', 'bmp'];
62+
this.errorsEvent = $.Event('dropify.errors');
63+
this.isDisabled = false;
64+
this.file = {
65+
object: null,
66+
name: null,
67+
size: null,
68+
width: null,
69+
height: null,
70+
type: null
71+
};
6072

6173
this.onChange = this.onChange.bind(this);
6274
this.clearElement = this.clearElement.bind(this);
75+
this.onFileReady = this.onFileReady.bind(this);
6376

6477
this.translate();
6578
this.createElements();
66-
this.setSize();
79+
this.setContainerSize();
6780

6881
this.input.on('change', this.onChange);
6982
}
@@ -74,8 +87,7 @@ function Dropify(element, options) {
7487
Dropify.prototype.onChange = function()
7588
{
7689
this.resetPreview();
77-
this.setFilename(this.input.val());
78-
this.readUrl(this.element);
90+
this.readFile(this.element);
7991
};
8092

8193
/**
@@ -113,36 +125,99 @@ Dropify.prototype.createElements = function()
113125
var defaultFile = this.settings.defaultFile || '';
114126

115127
if (defaultFile.trim() != '') {
116-
this.setFilename(defaultFile);
128+
this.file.name = this.cleanFilename(defaultFile);
117129
this.setPreview(defaultFile);
118130
}
119131
};
120132

121133
/**
122-
* Read the file url using FileReader
134+
* Read the file using FileReader
123135
*
124136
* @param {Object} input
125137
*/
126-
Dropify.prototype.readUrl = function(input)
138+
Dropify.prototype.readFile = function(input)
127139
{
128140
if (input.files && input.files[0]) {
129-
var reader = new FileReader();
130-
this.file = input.files[0];
141+
var reader = new FileReader();
142+
var image = new Image();
143+
var file = input.files[0];
144+
var srcBase64 = null;
145+
var _this = this;
146+
var eventFileReady = $.Event("dropify.fileReady");
147+
148+
this.setFileInformations(file);
149+
reader.readAsDataURL(file);
150+
151+
this.errorsEvent.errors = [];
152+
153+
this.checkFileSize();
154+
155+
reader.onload = function(_file) {
156+
srcBase64 = _file.target.result;
157+
if (this.isImage()) {
158+
image.src = _file.target.result;
159+
image.onload = function() {
160+
_this.setFileDimensions(this.width, this.height);
161+
_this.validateImage();
162+
_this.input.trigger(eventFileReady, [srcBase64]);
163+
};
164+
} else {
165+
this.input.trigger(eventFileReady, [srcBase64]);
166+
}
167+
}.bind(this);
168+
169+
this.input.on('dropify.fileReady', this.onFileReady);
170+
}
171+
};
131172

132-
if (this.checkFileSize()) {
133-
reader.onload = function(e) {
134-
this.setPreview(e.target.result, this.file.name);
135-
}.bind(this);
173+
/**
174+
* On file ready to show
175+
*
176+
* @param {Event} event
177+
* @param {String} src
178+
*/
179+
Dropify.prototype.onFileReady = function(event, src)
180+
{
181+
this.input.off('dropify.fileReady', this.onFileReady);
136182

137-
reader.readAsDataURL(this.file);
138-
} else {
139-
this.wrapper.addClass('has-error');
140-
this.resetPreview();
141-
this.clearElement();
142-
}
183+
if (this.errorsEvent.errors.length === 0) {
184+
this.setPreview(src, this.file.name);
185+
} else {
186+
this.input.trigger(this.errorsEvent, [this]);
187+
for (var i = this.errorsEvent.errors.length - 1; i >= 0; i--) {
188+
console.log(this.errorsEvent.errors[i].namespace);
189+
};
190+
// this.wrapper.addClass('has-error');
191+
this.resetPreview();
192+
this.clearElement();
143193
}
144194
};
145195

196+
/**
197+
* Set file informations
198+
* @param {File} file
199+
*/
200+
Dropify.prototype.setFileInformations = function(file)
201+
{
202+
this.file.object = file;
203+
this.file.name = file.name;
204+
this.file.size = file.size;
205+
this.file.type = file.type;
206+
this.file.width = null;
207+
this.file.height = null;
208+
};
209+
210+
/**
211+
* Set file dimensions
212+
* @param {Int} width
213+
* @param {Int} height
214+
*/
215+
Dropify.prototype.setFileDimensions = function(width, height)
216+
{
217+
this.file.width = width;
218+
this.file.height = height;
219+
};
220+
146221
/**
147222
* Set the preview and animate it
148223
*
@@ -151,6 +226,7 @@ Dropify.prototype.readUrl = function(input)
151226
Dropify.prototype.setPreview = function(src)
152227
{
153228
this.wrapper.removeClass('has-error').addClass('has-preview');
229+
this.filenameWrapper.children('.dropify-filename-inner').html(this.file.name);
154230
var render = this.preview.children('.dropify-render');
155231

156232
if (this.isImage() === true) {
@@ -159,7 +235,6 @@ Dropify.prototype.setPreview = function(src)
159235
$('<i />').attr('class', 'dropify-font-file').appendTo(render);
160236
$('<span class="dropify-extension" />').html(this.getFileType()).appendTo(render);
161237
}
162-
163238
this.preview.fadeIn();
164239
};
165240

@@ -177,13 +252,13 @@ Dropify.prototype.resetPreview = function()
177252
};
178253

179254
/**
180-
* Get the filename
255+
* Clean the src and get the filename
181256
*
182-
* @param {String} src with path
257+
* @param {String} src
183258
*
184-
* @return {String} clean filename
259+
* @return {String} filename
185260
*/
186-
Dropify.prototype.getFilename = function(src)
261+
Dropify.prototype.cleanFilename = function(src)
187262
{
188263
var filename = src.split('\\').pop();
189264
if (filename == src) {
@@ -193,40 +268,46 @@ Dropify.prototype.getFilename = function(src)
193268
return src != "" ? filename : '';
194269
};
195270

196-
/**
197-
* Set the filename in the object and in the dom
198-
*
199-
* @param {String} filename
200-
*/
201-
Dropify.prototype.setFilename = function(filename)
202-
{
203-
var filename = this.getFilename(filename);
204-
this.filename = filename;
205-
this.filenameWrapper.children('.dropify-filename-inner').html(filename);
206-
};
207-
208271
/**
209272
* Clear the element, events are available
210273
*/
211274
Dropify.prototype.clearElement = function()
212275
{
213-
var eventBefore = $.Event("dropify.beforeClear");
214-
this.input.trigger(eventBefore, [this]);
276+
if (this.errorsEvent.errors.length === 0) {
277+
var eventBefore = $.Event("dropify.beforeClear");
278+
this.input.trigger(eventBefore, [this]);
279+
280+
if (eventBefore.result !== false) {
281+
this.resetFile();
282+
this.input.val('');
283+
this.resetPreview();
215284

216-
if (eventBefore.result !== false) {
217-
this.file = null;
285+
this.input.trigger($.Event("dropify.afterClear"), [this]);
286+
}
287+
} else {
288+
this.resetFile();
218289
this.input.val('');
219290
this.resetPreview();
220-
221-
var eventAfter = $.Event("dropify.afterClear");
222-
this.input.trigger(eventAfter, [this]);
223291
}
224292
};
225293

226294
/**
227-
* Set the wrapper height
295+
* Reset file informations
228296
*/
229-
Dropify.prototype.setSize = function()
297+
Dropify.prototype.resetFile = function()
298+
{
299+
this.file.object = null;
300+
this.file.name = null;
301+
this.file.size = null;
302+
this.file.type = null;
303+
this.file.width = null;
304+
this.file.height = null;
305+
};
306+
307+
/**
308+
* Set the container height
309+
*/
310+
Dropify.prototype.setContainerSize = function()
230311
{
231312
if (this.settings.height) {
232313
this.wrapper.height(this.settings.height);
@@ -251,7 +332,7 @@ Dropify.prototype.isTouchDevice = function()
251332
*/
252333
Dropify.prototype.getFileType = function()
253334
{
254-
return this.filename.split('.').pop().toLowerCase();
335+
return this.file.name.split('.').pop().toLowerCase();
255336
};
256337

257338
/**
@@ -261,7 +342,7 @@ Dropify.prototype.getFileType = function()
261342
*/
262343
Dropify.prototype.isImage = function()
263344
{
264-
if (this.imgFileFormats.indexOf(this.getFileType()) != "-1") {
345+
if (this.imgFileExtensions.indexOf(this.getFileType()) != "-1") {
265346
return true;
266347
}
267348

@@ -282,16 +363,12 @@ Dropify.prototype.translate = function()
282363

283364
/**
284365
* Check the limit filesize.
285-
*
286-
* @return {Boolean}
287366
*/
288367
Dropify.prototype.checkFileSize = function()
289368
{
290-
if (this.maxFileSizeToByte() === 0 || this.file.size <= this.maxFileSizeToByte()) {
291-
return true;
369+
if (this.maxFileSizeToByte() !== 0 && this.file.size > this.maxFileSizeToByte()) {
370+
this.pushError("fileSize");
292371
}
293-
294-
return false;
295372
};
296373

297374
/**
@@ -321,6 +398,61 @@ Dropify.prototype.maxFileSizeToByte = function()
321398
return value;
322399
};
323400

401+
/**
402+
* Validate image dimensions and format
403+
*/
404+
Dropify.prototype.validateImage = function()
405+
{
406+
if (this.settings.minWidth !== 0 && this.settings.minWidth >= this.file.width) {
407+
this.pushError("minWidth");
408+
}
409+
410+
if (this.settings.maxWidth !== 0 && this.settings.maxWidth <= this.file.width) {
411+
this.pushError("maxWidth");
412+
}
413+
414+
if (this.settings.minHeight !== 0 && this.settings.minHeight >= this.file.height) {
415+
this.pushError("minHeight");
416+
}
417+
418+
if (this.settings.maxHeight !== 0 && this.settings.maxHeight <= this.file.height) {
419+
this.pushError("maxHeight");
420+
}
421+
422+
if (this.settings.allowedFormats.indexOf(this.getImageFormat()) == "-1") {
423+
this.pushError("imageFormat");
424+
}
425+
};
426+
427+
/**
428+
* Get image format.
429+
* @return {String}
430+
*/
431+
Dropify.prototype.getImageFormat = function()
432+
{
433+
if (this.file.width == this.file.height) {
434+
return "square";
435+
}
436+
437+
if (this.file.width < this.file.height) {
438+
return "portrait";
439+
}
440+
441+
if (this.file.width > this.file.height) {
442+
return "landscape";
443+
}
444+
};
445+
446+
/**
447+
* Push error
448+
* @param {String} errorKey
449+
*/
450+
Dropify.prototype.pushError = function(errorKey) {
451+
var e = $.Event("dropify.error." + errorKey);
452+
this.errorsEvent.errors.push(e);
453+
this.input.trigger(e, [this]);
454+
};
455+
324456
$.fn[pluginName] = function(options) {
325457
this.each(function() {
326458
if (!$.data(this, "plugin_" + pluginName)) {

0 commit comments

Comments
 (0)