I didn't find the solution I was after, however I approached it a different way. Instead of taking an existing form and removing elements, I built a new form and cloned the elements I needed and submitted it. If anyone can demonstrate a cleaner way to do this I'd be glad to see it.
Cheers RobL $('form input[type="file"]').livequery(function(){ $(this).change(function() { input = $(this); form = input.parent().parent('form'); image = form.find('img'); // recreate form with the only input we care about new_form = cloneForm(form).append(input.clone()); $('body').append(new_form); new_form.ajaxSubmit({ beforeSerialize: function (f,o) { o.data = input.serialize(); }, beforeSubmit: function(a,f,o) { o.dataType = 'json'; }, complete: function(XMLHttpRequest, textStatus) { input.attr('value',''); image.attr('src', XMLHttpRequest.responseText); new_form.hide(); new_form.remove(); }, }); }); }); function cloneForm(form) { // reconstruct the important parts of the form new_form = $('<form>'); new_form.attr('action',form.attr('action') + '/upload'); new_form.attr('method',form.attr('method')); new_form.attr('enctype',form.attr('enctype')); new_form.append(form.find('input[name="_method"]').clone()); new_form.append(form.find('input[name="authenticity_token"]').clone ()); new_form.append('<input type="hidden" name="format" value="js" / >'); return new_form; }