diff options
| author | mo khan <mo@mokhan.ca> | 2014-06-17 23:01:01 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2014-06-17 23:01:01 -0600 |
| commit | 4937ef0fbb2c1815779380159bb8c1280439672a (patch) | |
| tree | bad5118b2be60d8d9241128ebc34fd3a18253375 | |
| parent | 5b70fec2a6ca90f7733bcaaf441578e39a89485e (diff) | |
upload files using backbone and file api.
6 files changed, 140 insertions, 12 deletions
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 88f7f241..3085f831 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -28,4 +28,5 @@ //= require backbone_rails_sync //= require backbone_datalink //= require backbone/cake +//= require backbone-model-file-upload //= require_tree . diff --git a/app/assets/javascripts/backbone/models/photo.js.coffee b/app/assets/javascripts/backbone/models/photo.js.coffee index 5b52d3a2..6bf962c5 100644 --- a/app/assets/javascripts/backbone/models/photo.js.coffee +++ b/app/assets/javascripts/backbone/models/photo.js.coffee @@ -1,5 +1,6 @@ class Cake.Models.Photo extends Backbone.Model paramRoot: 'photo' + fileAttribute: 'image' defaults: thumb_url: null @@ -8,7 +9,6 @@ class Cake.Models.Photo extends Backbone.Model class Cake.Collections.PhotosCollection extends Backbone.Collection model: Cake.Models.Photo - url: '/api/v1/cakes/1/photos' initialize: (options) -> @url="/api/v1/cakes/#{options.cake_id}/photos" diff --git a/app/assets/javascripts/backbone/templates/photos/new.jst.ejs b/app/assets/javascripts/backbone/templates/photos/new.jst.ejs index 2f66004e..d09366aa 100644 --- a/app/assets/javascripts/backbone/templates/photos/new.jst.ejs +++ b/app/assets/javascripts/backbone/templates/photos/new.jst.ejs @@ -3,9 +3,9 @@ <form id="new-photo" name="photo" class="form-horizontal"> <fieldset> <div class="control-group"> - <label class="control-label" for="photo_image">Photo</label> + <label class="control-label" for="photo_attachment">Photo</label> <div class="controls"> - <input class="input-xxlarge" id="photo_image" name="image" type="file"> + <input class="input-xxlarge" id="photo_attachment" name="attachment" type="file"> </div> </div> <div class="form-actions"> diff --git a/app/assets/javascripts/backbone/views/photos/new_view.js.coffee b/app/assets/javascripts/backbone/views/photos/new_view.js.coffee index 5ec33817..a64c6c37 100644 --- a/app/assets/javascripts/backbone/views/photos/new_view.js.coffee +++ b/app/assets/javascripts/backbone/views/photos/new_view.js.coffee @@ -20,14 +20,24 @@ class Cake.Views.Photos.NewView extends Backbone.View @model.unset("errors") - @collection.create(@model.toJSON(), - success: (photo) => - @model = photo - window.location.hash = "/#{@model.id}" - - error: (photo, jqXHR) => - @model.set({errors: $.parseJSON(jqXHR.responseText)}) - ) + fileObject = @$(':input[type="file"]')[0].files[0] + photo = new Cake.Models.Photo(cake_id: 100) + photo.url = => @collection.url + photo.set('image', fileObject) + photo.on('progress', console.log) + photo.save() + + #@model.set('image', fileObject) + #@model.save() + #@model.on('progress', console.log) + #@collection.create(@model.toJSON(), + #success: (photo) => + #@model = photo + #window.location.hash = "/#{@model.id}" + + #error: (photo, jqXHR) => + #@model.set({errors: $.parseJSON(jqXHR.responseText)}) + #) render: -> $(@el).html(@template(@model.toJSON() )) diff --git a/app/controllers/api/v1/photos_controller.rb b/app/controllers/api/v1/photos_controller.rb index cf8a847b..6a9d12a2 100644 --- a/app/controllers/api/v1/photos_controller.rb +++ b/app/controllers/api/v1/photos_controller.rb @@ -5,7 +5,7 @@ module Api def create cake_id = params[:cake_id] - UploadPhoto.new.run(cake_id, photo_params) + UploadPhoto.new.run(cake_id, params) @photo = Creation.find(cake_id).photos.last respond_with(@photo) end diff --git a/vendor/assets/javascripts/backbone-model-file-upload.js b/vendor/assets/javascripts/backbone-model-file-upload.js new file mode 100644 index 00000000..6c9d4aae --- /dev/null +++ b/vendor/assets/javascripts/backbone-model-file-upload.js @@ -0,0 +1,117 @@ +// 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); |
