Big fixes with arguments and save
The current state was completely messed up with saving and all the different scenarios. This update brings back my main intent of the code and also does a separate merge of the attributes for the use of the FileObj. It also adds Blob support, and I finally written some tests.
This commit is contained in:
parent
5236fd812b
commit
3a31989778
@ -1,4 +1,4 @@
|
||||
// Backbone.Model File Upload v0.3
|
||||
// Backbone.Model File Upload v0.4
|
||||
// by Joe Vu - joe.vu@homeslicesolutions.com
|
||||
// For all details and documentation:
|
||||
// https://github.com/homeslicesolutions/backbone-model-file-upload
|
||||
@ -20,7 +20,7 @@
|
||||
var backboneModelClone = _.clone( Backbone.Model.prototype );
|
||||
|
||||
// Extending out
|
||||
_.extend(Backbone.Model.prototype, {
|
||||
_.extend(Backbone.Model.prototype, {
|
||||
|
||||
// ! Default file attribute - can be overwritten
|
||||
fileAttribute: 'file',
|
||||
@ -31,16 +31,11 @@
|
||||
// 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;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
@ -52,19 +47,24 @@
|
||||
} else {
|
||||
if (!this._validate(attrs, options)) return false;
|
||||
}
|
||||
|
||||
// Merge data temporarily for formdata
|
||||
var mergedAttrs = _.extend({}, attributes, attrs);
|
||||
|
||||
if (attrs && options.wait) {
|
||||
this.attributes = _.extend({}, attributes, attrs);
|
||||
this.attributes = mergedAttrs;
|
||||
}
|
||||
|
||||
// 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 ) {
|
||||
&& mergedAttrs[ this.fileAttribute ]
|
||||
&& mergedAttrs[ this.fileAttribute ] instanceof File
|
||||
|| mergedAttrs[ this.fileAttribute ] instanceof Blob ) {
|
||||
|
||||
// Flatten Attributes reapplying File Object
|
||||
var formAttrs = _.clone( attrs ),
|
||||
fileAttr = attrs[ this.fileAttribute ];
|
||||
var formAttrs = _.clone( mergedAttrs ),
|
||||
fileAttr = mergedAttrs[ this.fileAttribute ];
|
||||
formAttrs = this._flatten( formAttrs );
|
||||
formAttrs[ this.fileAttribute ] = fileAttr;
|
||||
|
||||
@ -75,7 +75,6 @@
|
||||
});
|
||||
|
||||
// Set options for AJAX call
|
||||
options = options || {};
|
||||
options.data = formData;
|
||||
options.processData = false;
|
||||
options.contentType = false;
|
||||
@ -85,11 +84,10 @@
|
||||
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
|
||||
@ -97,7 +95,7 @@
|
||||
|
||||
// Continue to call the existing "save" method
|
||||
return backboneModelClone.save.call(this, attrs, options);
|
||||
|
||||
|
||||
},
|
||||
|
||||
// _ FlattenObject gist by "penguinboy". Thank You!
|
||||
@ -119,7 +117,7 @@
|
||||
return output;
|
||||
|
||||
},
|
||||
|
||||
|
||||
// _ Get the Progress of the uploading file
|
||||
_progressHandler: function( event ) {
|
||||
if (event.lengthComputable) {
|
||||
|
@ -1,29 +1,161 @@
|
||||
!function(){
|
||||
'use strict'
|
||||
|
||||
var File = Backbone.Model.extend({
|
||||
url: 'upload-test.php',
|
||||
fileAttribute: 'fileAttachment'
|
||||
describe('Testing Backbone Model Plugin', function(){
|
||||
|
||||
var File = Backbone.Model.extend({
|
||||
url: 'upload-test.php',
|
||||
fileAttribute: 'fileAttachment'
|
||||
});
|
||||
|
||||
var fileModel;
|
||||
var simulatedFileObj;
|
||||
|
||||
beforeEach(function(){
|
||||
|
||||
simulatedFileObj = new Blob(['<strong>Hello World</strong>'], {type : 'text/html'});
|
||||
|
||||
fileModel = new File({
|
||||
from: 'sample@email.com',
|
||||
subject: 'Hello, friend!',
|
||||
body: 'Dear friend, Just saying hello! Love, Yours truly.',
|
||||
nestedObject: {
|
||||
nest: 'eggs'
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('should detect the file(blob) save successfully', function(done){
|
||||
|
||||
// Arrange
|
||||
fileModel.set({fileAttachment: simulatedFileObj});
|
||||
|
||||
// Listen
|
||||
fileModel.on('sync', function(model){
|
||||
|
||||
// Assert
|
||||
expect(model.get('from')).toBe('sample@email.com');
|
||||
expect(model.get('fileAttachment').data).toBe('data:text/html;base64,PHN0cm9uZz5IZWxsbyBXb3JsZDwvc3Ryb25nPg==');
|
||||
|
||||
done();
|
||||
|
||||
})
|
||||
|
||||
// Act
|
||||
fileModel.save(null);
|
||||
|
||||
});
|
||||
|
||||
it ('should be able to be saved in as an argument of "save" as object', function(done){
|
||||
|
||||
// Listen
|
||||
fileModel.on('sync', function(model){
|
||||
|
||||
// Assert
|
||||
expect(model.get('from')).toBe('sample@email.com');
|
||||
expect(model.get('fileAttachment').data).toBe('data:text/html;base64,PHN0cm9uZz5IZWxsbyBXb3JsZDwvc3Ryb25nPg==');
|
||||
|
||||
done();
|
||||
|
||||
});
|
||||
|
||||
// Act
|
||||
fileModel.save({fileAttachment: simulatedFileObj});
|
||||
|
||||
});
|
||||
|
||||
it ('should be able to be saved in as an argument of "save" as key/value argument', function(done){
|
||||
|
||||
// Listen
|
||||
fileModel.on('sync', function(model){
|
||||
|
||||
// Assert
|
||||
expect(model.get('from')).toBe('sample@email.com');
|
||||
expect(model.get('fileAttachment').data).toBe('data:text/html;base64,PHN0cm9uZz5IZWxsbyBXb3JsZDwvc3Ryb25nPg==');
|
||||
|
||||
done();
|
||||
|
||||
});
|
||||
|
||||
// Act
|
||||
fileModel.save('fileAttachment', simulatedFileObj);
|
||||
|
||||
});
|
||||
|
||||
it ('should be able to have "wait" and "validate" option', function(done){
|
||||
|
||||
// Listen
|
||||
fileModel.on('sync', function(model){
|
||||
|
||||
// Assert
|
||||
expect(model.get('from')).toBe('sample@email.com');
|
||||
expect(model.get('fileAttachment').data).toBe('data:text/html;base64,PHN0cm9uZz5IZWxsbyBXb3JsZDwvc3Ryb25nPg==');
|
||||
|
||||
done();
|
||||
|
||||
});
|
||||
|
||||
// Act
|
||||
fileModel.save({fileAttachment: simulatedFileObj},{wait: true, validate: false});
|
||||
|
||||
});
|
||||
|
||||
it('should still have the option to save normally by setting it and save(null)', function(done){
|
||||
|
||||
// Listen
|
||||
fileModel.on('sync', function(model){
|
||||
|
||||
// Assert
|
||||
expect(model.get('from')).toBe('somethingelse@email.com');
|
||||
//expect(model.get('fileAttachment').data).toBe('data:text/html;base64,PHN0cm9uZz5IZWxsbyBXb3JsZDwvc3Ryb25nPg==');
|
||||
|
||||
done();
|
||||
|
||||
});
|
||||
|
||||
// Act
|
||||
fileModel.set({from: 'somethingelse@email.com'});
|
||||
fileModel.save(null);
|
||||
|
||||
});
|
||||
|
||||
it('should still have the option to save normally by save("from","yes")', function(done){
|
||||
|
||||
// Listen
|
||||
fileModel.on('sync', function(model){
|
||||
|
||||
// Assert
|
||||
expect(model.get('from')).toBe('yes');
|
||||
//expect(model.get('fileAttachment').data).toBe('data:text/html;base64,PHN0cm9uZz5IZWxsbyBXb3JsZDwvc3Ryb25nPg==');
|
||||
|
||||
done();
|
||||
|
||||
});
|
||||
|
||||
// Act
|
||||
fileModel.save('from','yes');
|
||||
|
||||
});
|
||||
|
||||
it('should still have the option to save normally by save({from: "yes"})', function(done){
|
||||
|
||||
// Listen
|
||||
fileModel.on('sync', function(model){
|
||||
|
||||
// Assert
|
||||
expect(model.get('from')).toBe('yes');
|
||||
//expect(model.get('fileAttachment').data).toBe('data:text/html;base64,PHN0cm9uZz5IZWxsbyBXb3JsZDwvc3Ryb25nPg==');
|
||||
|
||||
done();
|
||||
|
||||
});
|
||||
|
||||
// Act
|
||||
fileModel.save({from: "yes"});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
var file = new File({
|
||||
from: 'sample@email.com',
|
||||
subject: 'Hello, friend!',
|
||||
body: 'Dear friend, Just saying hello! Love, Yours truly.',
|
||||
nestedObject: {
|
||||
nest: 'eggs'
|
||||
}
|
||||
});
|
||||
|
||||
$('#fileupload').on('change', function(e){
|
||||
var fileObj = $(this)[0].files[0];
|
||||
console.log(fileObj)
|
||||
file.set('fileAttachment', fileObj);
|
||||
file.save();
|
||||
})
|
||||
|
||||
//file.save();
|
||||
|
||||
|
||||
|
||||
}();
|
@ -11,22 +11,13 @@
|
||||
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../backbone-model-file-upload.js"></script>
|
||||
<!--
|
||||
|
||||
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js"></script>
|
||||
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine-html.js"></script>
|
||||
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/boot.js"></script>
|
||||
-->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
</script>
|
||||
|
||||
<input type="file" id="fileupload" />
|
||||
|
||||
<script type="text/javascript" src="backbone-model-file-upload.spec.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -1,23 +1,48 @@
|
||||
<?php
|
||||
|
||||
// Parse as Form Data
|
||||
$passthrough = $_REQUEST;
|
||||
|
||||
// Parse as JSON API Request
|
||||
foreach (getallheaders() as $name => $value) {
|
||||
if (strpos(strtolower($name), 'content-type') > -1
|
||||
&& strpos(strtolower($value), 'json') > -1) {
|
||||
|
||||
$json = file_get_contents('php://input');
|
||||
$obj = json_decode($json);
|
||||
|
||||
foreach ($obj as $key => $value) {
|
||||
$passthrough[$key] = $value;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$model = array(
|
||||
'from' => $passthrough['from'],
|
||||
'subject' => $passthrough['subject'],
|
||||
'body' => $passthrough['body'],
|
||||
'nestedObject' => array(
|
||||
'nest' => $passthrough["nestedObject_nest"]
|
||||
)
|
||||
);
|
||||
|
||||
$fileName = $_FILES['fileAttachment']['name'];
|
||||
$fileType = $_FILES['fileAttachment']['type'];
|
||||
$fileContent = file_get_contents($_FILES['fileAttachment']['tmp_name']);
|
||||
$dataUrl = 'data:' . $fileType . ';base64,' . base64_encode($fileContent);
|
||||
|
||||
|
||||
$json = json_encode(array(
|
||||
'fileAttachment' => array(
|
||||
if ($_FILES['fileAttachment']['tmp_name'] != "") {
|
||||
$fileContent = file_get_contents($_FILES['fileAttachment']['tmp_name']);
|
||||
$dataUrl = 'data:' . $fileType . ';base64,' . base64_encode($fileContent);
|
||||
|
||||
$model['fileAttachment'] = array(
|
||||
'name' => $fileName,
|
||||
'type' => $fileType,
|
||||
'data' => $dataUrl
|
||||
),
|
||||
'from' => $_REQUEST['from'],
|
||||
'subject' => $_REQUEST['subject'],
|
||||
'body' => $_REQUEST['body'],
|
||||
'nestedObject' => array(
|
||||
'nest' => $_REQUEST["nestedObject.nest"]
|
||||
)
|
||||
));
|
||||
|
||||
echo $json;
|
||||
?>
|
||||
);
|
||||
|
||||
}
|
||||
echo json_encode($model);
|
||||
?>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user