Skip to content
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

Use FormData for docs/images add-multiple's edit handling #8315

Conversation

th3hamm0r
Copy link
Contributor

The ajax-request now uses multipart/form-data, similar to image-chooser-modal.js/document-chooser-modal.js, which allows to add and use FileFields in the bulk-upload-views.

This PR is a bit related to #8314, because we needed an additional FileField for our images, where the user can attach a license proof in some cases (depends on other custom fields and validation).
This works in the image chooser, but did not work in the bulk-upload-tool (add-multiple.js), because those file-inputs have not been transferred to the backend with jquery's .serialize().
So as a quickfix, we had to customize/patch get_image_multi_form(), to exclude the license proof for now, but to allow customizations in a clean way, I've created #8314.

Please check the following:

  • Do the tests still pass?1
  • Does the code comply with the style guide?
    • Run make lint from the Wagtail root.
  • For front-end changes: Did you test on all of Wagtail’s supported environments?2
    • Please list the exact browser and operating system versions you tested:
      Google Chrome 100.0.4896.75, Firefox 99.0 (both on Linux Mint/Ubuntu)
    • Please list which assistive technologies 3 you tested:
  • For new features: Has the documentation been updated accordingly?

Please describe additional details for testing this change.

Footnotes

  1. Development Testing

  2. Browser and device support

  3. Accessibility Target

@squash-labs
Copy link

squash-labs bot commented Apr 8, 2022

Manage this branch in Squash

Test this branch here: https://th3hamm0rfeatureuse-multipart-sub0n.squash.io

@th3hamm0r
Copy link
Contributor Author

In the hope for a faster review, maybe this helps:
My above changes basically replaced jquery's form.serialize() with the vanilla FormData class, very similar to the image-chooser-modal.js and the document-chooser-modal.js:

var formdata = new FormData(this);
if (!$('#id_image-chooser-upload-title', modal.body).val()) {
var li = $('#id_image-chooser-upload-title', modal.body).closest('li');
if (!li.hasClass('error')) {
li.addClass('error');
$('#id_image-chooser-upload-title', modal.body)
.closest('.field-content')
.append(
'<p class="error-message"><span>This field is required.</span></p>',
);
}
setTimeout(cancelSpinner, 500);
} else {
$.ajax({
url: this.action,
data: formdata,
processData: false,
contentType: false,
type: 'POST',
dataType: 'text',
success: modal.loadResponseText,
error: function (response, textStatus, errorThrown) {
var message =
jsonData.error_message +
'<br />' +
errorThrown +
' - ' +
response.status;
$('#tab-upload').append(
'<div class="help-block help-critical">' +
'<strong>' +
jsonData.error_label +
': </strong>' +
message +
'</div>',
);
},
});
}

var formdata = new FormData(this);
$.ajax({
url: this.action,
data: formdata,
processData: false,
contentType: false,
type: 'POST',
dataType: 'text',
success: modal.loadResponseText,
error: function (response, textStatus, errorThrown) {
var message =
jsonData.error_message +
'<br />' +
errorThrown +
' - ' +
response.status;
$('#tab-upload', modal.body).append(
'<div class="help-block help-critical">' +
'<strong>' +
jsonData.error_label +
': </strong>' +
message +
'</div>',
);
},
});

@lb-
Copy link
Member

lb- commented May 12, 2022

In principle this look good, why the change to $.ajax instead of just keeping $.post (sorry my jquery is a bit rusty - it may be obvious).

I will try to do some testing locally and get this approved.

Thanks for the explanation.

@lb- lb- self-requested a review May 12, 2022 10:36
@th3hamm0r
Copy link
Contributor Author

th3hamm0r commented May 12, 2022

In principle this look good, why the change to $.ajax instead of just keeping $.post (sorry my jquery is a bit rusty - it may be obvious).

No, there is no obvious reason. First I wanted to keep it in sync with the very similar code for the modals, and second, from my experience with jquery and the task to reduce its usage where possible, only using ajax() and none of the helpers like post, getJson,... makes it a lot easier to find and adapt (e.g. adding new options).

I will try to do some testing locally and get this approved.

Thanks for the explanation.

Nice, thanks!

@gasman
Copy link
Collaborator

gasman commented May 12, 2022

As I understand it, $.ajax is needed in order to pass the processData: false option - without that, jquery will try to interpret the FormData object as a key/value dict instead of using the multipart serialisation we want.

(Haven't tested to confirm that - I just happened to be refactoring the chooser modal JS yesterday and was wondering why it used the long-winded $.ajax route instead of modal-workflow.js's stock ajaxifyForm, and that's the conclusion I came to :-) )

@lb-
Copy link
Member

lb- commented May 12, 2022

Thanks, that makes sense.

The ajax-request now uses multipart/form-data, similar to
image-chooser-modal.js/document-chooser-modal.js, which allows to add
and use FileFields in the bulk-upload-views.
Copy link
Member

@lb- lb- left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great, put it through a bunch of scenarios and cannot see any issues.
Thanks for the explanation @th3hamm0r

Tested

  • after upload of images/docs - trigger a server side error
  • after upload of images/docs - delete the item & ensure it is not saved
  • after upload of images/docs - trigger a success save (should hide and changes be made)
  • test bad upload on drop - not part of this change but ensure it does not try to grab content that is not there (no form)

@lb- lb- force-pushed the feature/use-multipart-form-data-for-add-multiple-edit branch from b2895ef to da19967 Compare May 12, 2022 22:03
@lb-
Copy link
Member

lb- commented May 12, 2022

pushed up a rebase, with prettier formatting (added after this PR was created) + changelog.
Will check a few tests pass and merge.

@lb- lb- merged commit 885b593 into wagtail:main May 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants