You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
3.6 KiB
117 lines
3.6 KiB
// Backbone.Model File Upload v0.1 |
|
// by Joe Vu - joe.vu@homeslicesolutions.com |
|
// For all details and documentation: |
|
// https://github.com/homeslicesolutions/backbone-model-file-upload |
|
|
|
!function(_, Backbone){ |
|
|
|
// Clone the original Backbone.Model.prototype |
|
var backboneModelClone = _.clone( Backbone.Model.prototype ); |
|
|
|
// Extending out |
|
_.extend(Backbone.Model.prototype, { |
|
|
|
// ! Default file attribute - can be overwritten |
|
fileAttribute: 'file', |
|
|
|
// @ Save - overwritten |
|
save: function(key, val, options) { |
|
|
|
// Variables |
|
var attrs, attributes = this.attributes; |
|
|
|
// Signature parsing - taken directly from original Backbone.Model.save |
|
// and it states: 'Handle both "key", value and {key: value} -style arguments.' |
|
if (key == null || typeof key === 'object') { |
|
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 |
|
&& this.attributes[ this.fileAttribute ] |
|
&& this.attributes[ this.fileAttribute ] instanceof File ) { |
|
|
|
// Flatten Attributes reapplying File Object |
|
var formAttrs = _.clone( this.attributes ), |
|
fileAttr = this.attributes[ 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 ); |
|
} |
|
} |
|
|
|
}); |
|
|
|
}(_, Backbone);
|
|
|