Skip to content

Commit cba4758

Browse files
committed
Fix -- Add missing submit value to form
Some forms like Django's admin have multiple submit buttons. The value of those buttons is transmitted on click events. We add them as a hidden field to submit the same value, even thogh the original event is not executed.
1 parent 4240cec commit cba4758

File tree

6 files changed

+66
-20
lines changed

6 files changed

+66
-20
lines changed

s3file/static/s3file/js/s3file.js

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616
form.appendChild(input)
1717
}
1818

19-
function waitForAllFiles(form) {
19+
function waitForAllFiles (form) {
2020
if (window.uploading !== 0) {
2121
setTimeout(() => {
2222
waitForAllFiles(form)
2323
}, 100)
2424
} else {
25-
HTMLFormElement.prototype.submit.call(form)
25+
window.HTMLFormElement.prototype.submit.call(form)
2626
}
2727
}
2828

@@ -77,7 +77,29 @@
7777
fileInput.setCustomValidity(err)
7878
fileInput.reportValidity()
7979
})
80+
}
81+
82+
function clickSubmit (e) {
83+
e.preventDefault()
84+
let submitButton = e.target
85+
let form = submitButton.closest('form')
86+
const submitInput = document.createElement('input')
87+
submitInput.type = 'hidden'
88+
submitInput.value = true
89+
submitInput.name = submitButton.name
90+
form.appendChild(submitInput)
91+
uploadS3Inputs(form)
92+
}
8093

94+
function uploadS3Inputs (form) {
95+
window.uploading = 0
96+
const inputs = form.querySelectorAll('.s3file')
97+
Array.from(inputs).forEach(input => {
98+
window.uploading += 1
99+
uploadFiles(form, input, input.name)
100+
}
101+
)
102+
waitForAllFiles(form)
81103
}
82104

83105
document.addEventListener('DOMContentLoaded', () => {
@@ -88,16 +110,13 @@
88110
forms.forEach(form => {
89111
form.onsubmit = (e) => {
90112
e.preventDefault()
91-
window.uploading = 0
92-
const inputs = document.querySelectorAll('.s3file')
93-
Array.from(inputs).forEach(input => {
94-
window.uploading += 1
95-
uploadFiles(form, input, input.name)
96-
}
97-
)
98-
waitForAllFiles(form)
113+
uploadS3Inputs(e.target)
114+
}
115+
let submitButtons = form.querySelectorAll('input[type=submit], button[type=submit]')
116+
Array.from(submitButtons).forEach(submitButton => {
117+
submitButton.onclick = clickSubmit
99118
}
119+
)
100120
})
101121
})
102-
103122
})()

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
setup(
55
name='django-s3file',
6-
version='3.0.2',
6+
version='3.0.3',
77
description='A lightweight file uploader input for Django and Amazon S3',
88
author='codingjoe',
99
url='https://github.com/codingjoe/django-s3file',

tests/test_forms.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
from contextlib import contextmanager
23

34
import pytest
@@ -51,7 +52,7 @@ def test_value_from_datadict(self, client, upload_file):
5152
's3file': 'file'
5253
})
5354

54-
assert response.status_code == 302
55+
assert response.status_code == 201
5556

5657
def test_value_from_datadict_initial_data(self, filemodel):
5758
form = UploadForm(instance=filemodel)
@@ -136,5 +137,24 @@ def test_file_insert(self, request, driver, live_server, upload_file, freeze):
136137
error = driver.find_element_by_xpath('//body[@JSError]')
137138
pytest.fail(error.get_attribute('JSError'))
138139

140+
def test_file_insert_submit_value(self, driver, live_server, upload_file, freeze):
141+
driver.get(live_server + self.url)
142+
file_input = driver.find_element_by_xpath('//input[@type=\'file\']')
143+
file_input.send_keys(upload_file)
144+
assert file_input.get_attribute('name') == 'file'
145+
save_button = driver.find_element_by_xpath('//input[@name=\'save\']')
146+
with wait_for_page_load(driver, timeout=10):
147+
save_button.click()
148+
assert 'save' in driver.page_source
149+
150+
driver.get(live_server + self.url)
151+
file_input = driver.find_element_by_xpath('//input[@type=\'file\']')
152+
file_input.send_keys(upload_file)
153+
assert file_input.get_attribute('name') == 'file'
154+
save_button = driver.find_element_by_xpath('//button[@name=\'save_continue\']')
155+
with wait_for_page_load(driver, timeout=10):
156+
save_button.click()
157+
assert 'save_continue' in driver.page_source
158+
139159
def test_media(self):
140160
assert ClearableFileInput().media._js == ['s3file/js/s3file.js']

tests/testapp/templates/form.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
<form method="post">
1414
{% csrf_token %}
1515
{{ form }}
16-
<input type="submit" name="submit" value="Submit Form"/>
16+
<input type="submit" name="save" value="Save"/>
17+
<button type="submit" name="save_continue">Save &amp; continue</button>
1718
</form>
1819
{{ form.media.js }}
1920
</body>

tests/testapp/urls.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,5 @@
77
url(r'^s3/$',
88
views.S3MockView.as_view(), name='s3mock'),
99
url(r'^upload/$',
10-
FormView.as_view(
11-
form_class=forms.UploadForm,
12-
template_name='form.html',
13-
success_url='/upload/'
14-
), name='upload'),
10+
views.ExampleFormView.as_view(), name='upload'),
1511
]

tests/testapp/views.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
from django.core.files.storage import default_storage
2-
from django.http import response
2+
from django.http import JsonResponse, response
33
from django.views import generic
44

5+
from tests.testapp import forms
6+
57

68
class S3MockView(generic.View):
79

@@ -19,3 +21,11 @@ def post(self, request):
1921
'<ETag>"1e2580c388265551922a1f73ae5954a3"</ETag>'
2022
'</PostResponse>' % key,
2123
status=201)
24+
25+
26+
class ExampleFormView(generic.FormView):
27+
form_class = forms.UploadForm
28+
template_name = 'form.html'
29+
30+
def form_valid(self, form):
31+
return JsonResponse(self.request.POST, status=201)

0 commit comments

Comments
 (0)