Skip to content

Fix #309 -- handle submit buttons form* attributes #310

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 36 additions & 32 deletions s3file/static/s3file/js/s3file.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

(function () {
function parseURL (text) {
var xml = new window.DOMParser().parseFromString(text, 'text/xml')
var tag = xml.getElementsByTagName('Key')[0]
const xml = new window.DOMParser().parseFromString(text, 'text/xml')
const tag = xml.getElementsByTagName('Key')[0]
return decodeURI(tag.childNodes[0].nodeValue)
}

Expand All @@ -20,7 +20,7 @@
function request (method, url, data, fileInput, file, form) {
file.loaded = 0
return new Promise(function (resolve, reject) {
var xhr = new window.XMLHttpRequest()
const xhr = new window.XMLHttpRequest()

xhr.onload = function () {
if (xhr.status === 201) {
Expand All @@ -31,11 +31,11 @@
}

xhr.upload.onprogress = function (e) {
var diff = e.loaded - file.loaded
const diff = e.loaded - file.loaded
form.loaded += diff
fileInput.loaded += diff
file.loaded = e.loaded
var defaultEventData = {
const defaultEventData = {
currentFile: file,
currentFileName: file.name,
currentFileProgress: Math.min(e.loaded / e.total, 1),
Expand Down Expand Up @@ -67,15 +67,15 @@
}

function uploadFiles (form, fileInput, name) {
var url = fileInput.getAttribute('data-url')
const url = fileInput.getAttribute('data-url')
fileInput.loaded = 0
fileInput.total = 0
var promises = Array.from(fileInput.files).map(function (file) {
const promises = Array.from(fileInput.files).map(function (file) {
form.total += file.size
fileInput.total += file.size
var s3Form = new window.FormData()
const s3Form = new window.FormData()
Array.from(fileInput.attributes).forEach(function (attr) {
var name = attr.name
let name = attr.name

if (name.startsWith('data-fields')) {
name = name.replace('data-fields-', '')
Expand All @@ -89,7 +89,7 @@
})
Promise.all(promises).then(function (results) {
results.forEach(function (result) {
var hiddenFileInput = document.createElement('input')
const hiddenFileInput = document.createElement('input')
hiddenFileInput.type = 'hidden'
hiddenFileInput.name = name
hiddenFileInput.value = parseURL(result)
Expand All @@ -104,29 +104,24 @@
})
}

function clickSubmit (e) {
var submitButton = e.currentTarget
var form = submitButton.closest('form')
var submitInput = document.createElement('input')
submitInput.type = 'hidden'
submitInput.value = submitButton.value || '1'
submitInput.name = submitButton.name
form.appendChild(submitInput)
}
function uploadS3Inputs (event) {
event.preventDefault()

const form = event.target
const submitter = event.submitter

function uploadS3Inputs (form) {
window.uploading = 0
form.loaded = 0
form.total = 0
var inputs = Array.from(form.querySelectorAll('input[type=file].s3file'))
const inputs = Array.from(form.querySelectorAll('input[type=file].s3file'))

inputs.forEach(function (input) {
var hiddenS3Input = document.createElement('input')
const hiddenS3Input = document.createElement('input')
hiddenS3Input.type = 'hidden'
hiddenS3Input.name = 's3file'
hiddenS3Input.value = input.name
form.appendChild(hiddenS3Input)
var hiddenSignatureInput = document.createElement('input')
const hiddenSignatureInput = document.createElement('input')
hiddenSignatureInput.type = 'hidden'
hiddenSignatureInput.name = input.name + '-s3f-signature'
hiddenSignatureInput.value = input.dataset.s3fSignature
Expand All @@ -136,23 +131,32 @@
window.uploading += 1
uploadFiles(form, input, input.name)
})

if (submitter) {
// override form attributes with submit button attributes
form.action = submitter.getAttribute('formaction') || form.action
form.method = submitter.getAttribute('formmethod') || form.method
form.enctype = submitter.getAttribute('formEnctype') || form.enctype
form.novalidate = submitter.getAttribute('formnovalidate') || form.novalidate
form.target = submitter.getAttribute('formtarget') || form.target
// add submit button value to form
const submitInput = document.createElement('input')
submitInput.type = 'hidden'
submitInput.value = submitter.value || '1'
submitInput.name = submitter.name
form.appendChild(submitInput)
}

waitForAllFiles(form)
}

document.addEventListener('DOMContentLoaded', function () {
var forms = Array.from(document.querySelectorAll('input[type=file].s3file')).map(function (input) {
let forms = Array.from(document.querySelectorAll('input[type=file].s3file')).map(function (input) {
return input.closest('form')
})
forms = new Set(forms)
forms.forEach(function (form) {
form.addEventListener('submit', function (e) {
e.preventDefault()
uploadS3Inputs(e.target)
})
var submitButtons = form.querySelectorAll('input[type=submit], button[type=submit]')
Array.from(submitButtons).forEach(function (submitButton) {
submitButton.addEventListener('click', clickSubmit)
})
form.addEventListener('submit', uploadS3Inputs)
})
})
})()
2 changes: 2 additions & 0 deletions tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ def test_file_insert_submit_value(
with wait_for_page_load(driver, timeout=10):
save_button.click()
assert "save" in driver.page_source
assert "formaction" not in driver.page_source

driver.get(live_server + self.create_url)
file_input = driver.find_element(By.XPATH, "//input[@name='file']")
Expand All @@ -197,6 +198,7 @@ def test_file_insert_submit_value(
save_button.click()
assert "save_continue" in driver.page_source
assert "continue_value" in driver.page_source
assert "formaction" in driver.page_source

@pytest.mark.selenium
def test_progress(self, driver, live_server, upload_file, freeze_upload_folder):
Expand Down
2 changes: 1 addition & 1 deletion tests/testapp/templates/form.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
{% csrf_token %}
{{ form }}
<input type="submit" name="save" value="Save"/>
<button type="submit" name="save_continue" value="continue_value">Save &amp; continue</button>
<button type="submit" name="save_continue" value="continue_value" formaction="?formaction=1">Save &amp; continue</button>
<div class="progress">
<div class="progress-bar" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0"
aria-valuemax="100">0%
Expand Down
2 changes: 2 additions & 0 deletions tests/testapp/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def form_valid(self, form):
"file": self.request.FILES.getlist("file"),
"other_file": self.request.FILES.getlist("other_file"),
},
"QUERY_STRING": self.request.GET,
},
status=201,
encoder=FileEncoder,
Expand All @@ -45,6 +46,7 @@ def form_valid(self, form):
"file": self.request.FILES.getlist("file"),
"other_file": self.request.FILES.getlist("other_file"),
},
"QUERY_STRING": self.request.GET,
},
status=201,
encoder=FileEncoder,
Expand Down