forked from homeslicesolutions-zz/backbone-model-file-upload
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbackbone-model-file-upload.js
137 lines (114 loc) · 4.13 KB
/
backbone-model-file-upload.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Backbone.Model File Upload v0.3
// by Joe Vu - [email protected]
// For all details and documentation:
// https://github.com/homeslicesolutions/backbone-model-file-upload
// Contributors:
// lutherism - Alex Jansen - alex.openrobot.net
// bildja - Dima Bildin - github.com/bildja
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['underscore', 'backbone'], factory);
} else {
// Browser globals
factory(_, Backbone);
}
}(this, function(_, Backbone){
// Clone the original Backbone.Model.prototype
var backboneModelClone = _.clone( Backbone.Model.prototype );
// Extending out
var FileModel = Backbone.Model.extend({
// ! Default file attribute - can be overwritten
fileAttribute: 'file',
// @ Save - overwritten
save: function(key, val, options) {
// Variables
var attrs, attributes = this.attributes;
// Signature parsing - similar to original Backbone.Model.save
// Handle (key, value, options), ({key: value}, options), and (options) -style arguments.
if (typeof key === 'object') {
if (typeof val === void 0) {
attrs = attributes;
options = key;
} else {
attrs = key;
options = val;
}
} else {
(attrs = {})[key] = val;
}
// Validate & wait options - taken directly from original Backbone.Model.save
options = _.extend({validate: true}, options);
if (attrs && !options.wait) {
if (!this.set(attrs, options)) return false;
} else {
if (!this._validate(attrs, options)) return false;
}
if (attrs && options.wait) {
this.attributes = _.extend({}, attributes, attrs);
}
// Check for "formData" flag and check for if file exist.
if ( options.formData === true
|| options.formData !== false
&& attrs[ this.fileAttribute ]
&& attrs[ this.fileAttribute ] instanceof File ) {
// Flatten Attributes reapplying File Object
var formAttrs = _.clone( attrs ),
fileAttr = attrs[ this.fileAttribute ];
formAttrs = this._flatten( formAttrs );
formAttrs[ this.fileAttribute ] = fileAttr;
// Converting Attributes to Form Data
var formData = new FormData();
_.each( formAttrs, function( value, key ){
formData.append( key, value );
});
// Set options for AJAX call
options = options || {};
options.data = formData;
options.processData = false;
options.contentType = false;
// Apply custom XHR for processing status & listen to "progress"
var that = this;
options.xhr = function() {
var xhr = $.ajaxSettings.xhr();
xhr.upload.addEventListener('progress', function(){
that._progressHandler.apply(that, arguments);
}, false);
return xhr;
}
}
// Resume back to original state
if (attrs && options.wait) this.attributes = attributes;
// Continue to call the existing "save" method
return backboneModelClone.save.call(this, attrs, options);
},
// _ FlattenObject gist by "penguinboy". Thank You!
// https://gist.github.com/penguinboy/762197
_flatten: function( obj ) {
var output = {};
for (var i in obj) {
if (!obj.hasOwnProperty(i)) continue;
if (typeof obj[i] == 'object') {
var flatObject = this._flatten(obj[i]);
for (var x in flatObject) {
if (!flatObject.hasOwnProperty(x)) continue;
output[i + '.' + x] = flatObject[x];
}
} else {
output[i] = obj[i];
}
}
return output;
},
// _ Get the Progress of the uploading file
_progressHandler: function( event ) {
if (event.lengthComputable) {
var percentComplete = event.loaded / event.total;
this.trigger( 'progress', percentComplete );
}
}
});
//Exports
Backbone.FileModel = FileModel;
return FileModel;
}));