Skip to content

Instantly share code, notes, and snippets.

@SaneMethod
Created March 1, 2013 19:20
Show Gist options
  • Save SaneMethod/5067044 to your computer and use it in GitHub Desktop.
Save SaneMethod/5067044 to your computer and use it in GitHub Desktop.
jQuery transparent submission plugin - uses iFrames to allow for an 'ajax-like' submission of a form to some endpoint, and retrieve the json, html or text response offered by that server to said frame.
/**
* jQuery plugin for transparent submission of a form using an $.ajax-like interface.
* Usage Examples:
* $.transparentSubmit({dataType:'json', form:$('#myForm')})
* $('#myForm').transparentSubmit({dataType:'html'})
* Supports Deferred (.done, .fail, .when, etc.)
*/
(function($){
$.transparentSubmit = function(options){
var defer = $.Deferred(), // Deferred object whose promise we will hook into when adding .done, etc to calls
options = $.extend({
dataType:'json'
}, (options || {})), // coerce options into being an object, extend defaults
name = 'target-'+Math.random().toString(36).substring(7), // assign a psuedo-random name to the frame
hiframe = $('<iframe id="'+name+'" name="'+name+'" src="about:blank" ' +
'style="width:0;height:0;border:0px solid #fff;"></iframe>'), // create invisible iframe - NOT display:none
form = $(options.form), // get form, make sure its a jquery object
cleanup = function(){
hiframe.remove();
delete frames[name];
}; // clean iframe away when we're finished with it
if (!form.length || form[0].tagName !== 'FORM'){ // if we don't have a form to submit, reject (call .fail)
defer.reject("No form element specified to submit.");
return defer.promise();
}
form.attr('target', name).append(hiframe); // set target of form to iframe, and append iframe to the form
// On load event, grab and parse the contents of the iframe
hiframe.on('load', function(){
var res;
form.removeAttr('target');
try{
if (options.dataType.indexOf('json') != -1)
{ // browsers will wrap a json return with <pre></pre>
res = frames[name].document.getElementsByTagName("pre")[0].innerHTML;
}
else
{
res = frames[name].document.getElementsByTagName('body')[0].innerHTML;
}
}catch(e){
// Failed to receive anything in the body of the frame
cleanup();
defer.reject("Failed to receive response in form target "+name+": "+e.message);
return;
}
cleanup();
if (options.dataType.indexOf('json') != -1)
{
try{
res = $.parseJSON(res);
}catch(e){
defer.reject("Failed to parse response into JSON: "+e.message);
return;
}
}
else if (options.dataType.indexOf('html') != -1)
{
res = $.parseHTML(res);
}
defer.resolve(res); // Finished (call .done)
});
form.submit();
return defer.promise();
}
/*
* This allows us the option to call $('#myForm').transparentSubmit - as you can see, its just a slightly different form
* to the plugin, which calls our transparentSubmit function as defined above.
*/
$.fn.transparentSubmit = function(options){
options.form = this;
return $.transparentSubmit(options);
};
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment