Skip to content

Instantly share code, notes, and snippets.

@moski
Created October 13, 2011 16:10
Show Gist options
  • Save moski/1284652 to your computer and use it in GitHub Desktop.
Save moski/1284652 to your computer and use it in GitHub Desktop.
Getting backbone-rails to play nicely with iframe upload
(function () {
Backbone.syncWithoutUpload = Backbone.sync
Backbone.syncWithUpload = function(method, model, options) {
var methodMap = {
'create': 'POST',
'update': 'PUT',
'delete': 'DELETE',
'read' : 'GET'
};
var type = methodMap[method];
// Create iframe
var iframe_id = 'file_upload_iframe_' + Date.now()
, iframe = jQuery('<iframe id="' + iframe_id + '" name="' + iframe_id + '" ></iframe>').hide();
// Create an hidden form
var authToken = jQuery('meta[name=csrf-token]').attr('content')
, authParam = jQuery('meta[name=csrf-param]').attr('content');
// Find the form element based on the paramRoot.
var form = $("#new-" + model.paramRoot);
// Update the scope for all inputs.
var inputs = form.find("input");
_.each(inputs, function(el) {
if ($(el).attr("name") != undefined){
$(el).attr({
'name': model.paramRoot + "[" + $(el).attr('name') + "]"
})
}
});
form.attr({
'target':iframe_id,
'action':model.url(),
'method': type
});
if (form.has('input[name="'+ authParam +'"]').length == 0) {
form.append('<input type="hidden" name="'+ authParam +'" value="'+ authToken +'" />');
}
form.append('<input type="hidden" name="is_iframe" value="true" />');
jQuery(document.body).prepend(iframe);
function callback() {
// contentDocument doesn't work in IE (7)
var iframe_body = (iframe[0].contentDocument || iframe[0].contentWindow.document).body;
var response = JSON.parse(iframe_body.innerHTML);
// TODO: Migrate to api v2. Make this check redundant
response = response.objects ? response.objects : response;
if (iframe_body.className !== "error") {
var success = options.success
if (success) options.success(response)
} else {
var error = options.error
if (error) options.error(response)
}
iframe.remove();
form.remove();
}
// Setup the iframe callback
// for IE (7)
iframe[0].onreadystatechange = function() {
if (this.readyState === 'complete') {
callback()
}
};
// non-IE
iframe[0].onload = callback;
form[0].submit();
}
Backbone.sync = function(method, model, options) {
if ( options && options.iframe ){
Backbone.syncWithUpload(method, model, options)
} else {
Backbone.syncWithoutUpload(method, model, options)
}
};
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment