I have a form that works in Firefox and Chrome, but not Internet Explorer 8. It's got some text inputs and one file input: it's the file input that isn't working.
The problem seems to be that the server isn't getting the file at all. The server throws MultiValueDictKeyError
because my view is trying to look up the element with the file in it, and it's not present in request.FILES
.
I checked the IE developer tools and the input
element is holding the file when the form submits. Something else is going on.
There is one curveball in the form: I'm using a styled input button using help from this thread
My HTML, plus some inline js:
<form action="{{ order.get_absolute_url }}load/" method="post" enctype="multipart/form-data" class="med order" id="order_form" name="order_form">
<div class="card form_wrapper float_left">
<h2 class="section_header">{{ order.order_number }} - Add Homeowners<span class="status_label">{{ order.get_current_status_display }}</span></h2>
<table id="certified_one_off_table" class="residents">
<thead>
<tr>
<th>Owner Name<span class="ho_required_note">*</span></th>
<th>Co-owner Name</th>
<th>Account #<span class="ho_required_note">*</span></th>
<th>Address<span class="ho_required_note">*</span></th>
<th>Address, Continued</th>
<th>City, State Zip<span class="ho_required_note">*</span></th>
<th>Letter file<span class="ho_required_note">*</span></th>
</tr>
</thead>
<tbody>
<tr class="ho_load_row">
<td>
<input type="text" name="ho_owner-1" value="" class="ho_owner ho_load_field ho_required" />
</td>
<td>
<input type="text" name="ho_co_owner-1" value="" class="ho_co_owner ho_load_field" />
</td>
<td>
<input type="text" name="ho_account_id-1" value="" class="ho_account_id ho_load_field ho_required" />
</td>
<td>
<input type="text" name="ho_mailing_address-1" value="" class="ho_mailing_address ho_load_field ho_required" />
</td>
<td>
<input type="text" name="ho_mailing_address_contd-1" value="" class="ho_mailing_address ho_load_field" />
</td>
<td>
<input type="text" name="ho_mailing_csz-1" value="" class="ho_mailing_csz ho_load_field ho_required" />
</td>
<td id="upload_button_cell">
<div id="certified_upload_button" class="new_button" onclick="getFile(this)">Upload</div>
<div style='height: 0px;width: 0px; overflow:hidden;'><input id="id_ho_document-1" name="ho_document-1" type="file" class="ho_file ho_load_field ho_required" /></div>
</td>
<td id="validate_cell">
<img id="id_ho_document_valid-1" src="/public/img/cross.png" alt="Invalid or no document selected" />
</td>
</tr>
<tr>
<td colspan="6">
<a id="certified_add_ho" href="#">Add Another Homeowner →</a>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="6">
<br />
<center><input type="submit" id="certified_one_off_button" class="new_button_disabled" value="Approve Order for these Homeowners" disabled="disabled" /></center>
<br />
</td>
</tr>
</tfoot>
</table>
</div>
</form>
<script type="text/javascript">
function getFile(obj) { $(obj).siblings('div').children('input').click(); }
</script>
Snippet of the view code:
if request.method == 'POST':
order_quantity = 0
for row_number in xrange(1, len(request.POST)):
if 'ho_owner-{0!s}'.format(row_number) not in request.POST:
break
document = request.FILES['ho_document-{0!s}'.format(row_number)]
edit: forgot the js that validates the form and enables the submit button
$(document).ready(function() {
function update_certified_one_off_button() {
var invalid_fields = 0
$('.ho_load_field.ho_required').each(function() {
if ($(this).val() === '') {
invalid_fields += 1;
$(this).css('background-color', '#fff2f2');
} else {
$(this).css('background-color', '#ffffff');
}
});
$('input[name^="ho_document-"]').each(function() {
var ext = $(this).val().split('.').pop().toLowerCase();
if($.inArray(ext, ['pdf']) == -1) {
invalid_fields += 1;
}
});
var submit_button = $('#certified_one_off_button');
if (invalid_fields > 0) {
submit_button.addClass('new_button_disabled');
submit_button.removeClass('new_button');
submit_button.attr('disabled', 'disabled');
} else {
submit_button.addClass('new_button');
submit_button.removeClass('new_button_disabled');
submit_button.removeAttr('disabled');
}
}
function certified_validate(event) {
var old_name_full = $(event.target).attr('id').split('-');
var old_name = old_name_full[0];
var old_num = parseInt(old_name_full[1]);
var icon = $("#id_ho_document_valid-" + String(old_num));
var ext = $(event.target).val().split('.').pop().toLowerCase();
if($.inArray(ext, ['pdf']) == -1) {
icon.attr('src', '/public/img/cross.png');
alert('Only PDF format documents will be accepted.');
} else {
icon.attr('src', '/public/img/tick.png');
}
}
$('#certified_add_ho').click(function(e) {
e.preventDefault();
var last_row = $('.ho_load_row').last();
last_row.after('<tr class="ho_load_row">' + last_row.html() + '</tr>');
var last_row_img = $('.ho_load_row').last().find('img');
var old_name_full = last_row_img.attr('id').split('-');
var old_name = old_name_full[0];
var old_num = parseInt(old_name_full[1]);
last_row_img.attr('id', old_name + '-' + String(old_num + 1));
last_row_img.attr('src', '/public/img/cross.png');
var last_row_inputs = $('.ho_load_row').last().find('input');
last_row_inputs.each(function() {
$(this).val('').find('.default').attr('selected', 'selected');
old_name = $(this).attr('name').split('-')[0];
$(this).attr('name', old_name + '-' + String(old_num + 1));
var old_id = $(this).attr('id');
if (old_id) {
old_id = old_id.split('-')[0];
$(this).attr('id', old_id + '-' + String(old_num + 1));
}
});
$("#id_ho_document-" + String(old_num + 1)).change(certified_validate);
$('.ho_load_field.ho_required').bind('change keyup', update_certified_one_off_button);
update_certified_one_off_button();
});
$('#order_form .ho_load_field').bind('change keyup', update_certified_one_off_button);
$("#id_ho_document-1").change(certified_validate);
});
edit 2: I managed to capture my http request using a 3rd party tool, and it looks like my file never leaves the machine:
POST /order/ndVKUeCRT1/load/ HTTP/1.1
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*
Referer: http://eiger.optimaloutsource.com:8088/order/ndVKUeCRT1/load/
Accept-Language: en-US
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E)
Content-Type: multipart/form-data; boundary=---------------------------7dc1bd1f60702
Accept-Encoding: gzip, deflate
Host: eiger.optimaloutsource.com:8088
Content-Length: 899
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: sessionid=0a37e24c25c4b7716249c50eb52b523a; __utma=133342874.1270580592.1320187097.1340128445.1340141010.4; __utmz=133342874.1340055122.2.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmb=133342874.2.10.1340141010; __utmc=133342874
-----------------------------7dc1bd1f60702
Content-Disposition: form-data; name="ho_owner-1"
phasetwenty
-----------------------------7dc1bd1f60702
Content-Disposition: form-data; name="ho_co_owner-1"
-----------------------------7dc1bd1f60702
Content-Disposition: form-data; name="ho_account_id-1"
account
-----------------------------7dc1bd1f60702
Content-Disposition: form-data; name="ho_mailing_address-1"
address
-----------------------------7dc1bd1f60702
Content-Disposition: form-data; name="ho_mailing_address_contd-1"
-----------------------------7dc1bd1f60702
Content-Disposition: form-data; name="ho_mailing_csz-1"
city, CA 90000
-----------------------------7dc1bd1f60702
Content-Disposition: form-data; name="ho_document-1"; filename=""
Content-Type: application/octet-stream
-----------------------------7dc1bd1f60702--
HTTP/1.1 500 INTERNAL SERVER ERROR
Date: Tue, 19 Jun 2012 21:25:31 GMT
Server: Apache/2.2.14 (Ubuntu)
Vary: Cookie
Connection: close
Content-Type: text/html; charset=utf-8
How can I get IE to submit this form correctly?