Add a reusable helper function for submitting creation forms

pull/7897/head
Matt Westcott 2022-05-11 17:15:43 +01:00 zatwierdzone przez LB (Ben Johnston)
rodzic d311a40e27
commit 6e9660c67b
4 zmienionych plików z 174 dodań i 194 usunięć

Wyświetl plik

@ -1,6 +1,6 @@
import $ from 'jquery';
import { initTabs } from '../../includes/tabs';
import { gettext } from '../../utils/gettext';
import { submitCreationForm } from '../../includes/chooserModal';
const ajaxifyTaskCreateTab = (modal) => {
$(
@ -13,35 +13,7 @@ const ajaxifyTaskCreateTab = (modal) => {
// eslint-disable-next-line func-names
$('form.task-create', modal.body).on('submit', function () {
const formdata = new FormData(this);
$.ajax({
url: this.action,
data: formdata,
processData: false,
contentType: false,
type: 'POST',
dataType: 'text',
success: modal.loadResponseText,
error(response, textStatus, errorThrown) {
const message =
gettext(
'Report this error to your website administrator with the following information:',
) +
'<br />' +
errorThrown +
' - ' +
response.status;
$('#tab-new', modal.body).append(
'<div class="help-block help-critical">' +
'<strong>' +
gettext('Server Error') +
': </strong>' +
message +
'</div>',
);
},
});
submitCreationForm(modal, this, { errorContainerSelector: '#tab-new' });
return false;
});

Wyświetl plik

@ -1,75 +1,21 @@
import $ from 'jquery';
import { initTabs } from '../../includes/tabs';
import { gettext } from '../../utils/gettext';
import {
submitCreationForm,
initPrefillTitleFromFilename,
} from '../../includes/chooserModal';
function ajaxifyDocumentUploadForm(modal) {
$('form.document-upload', modal.body).on('submit', function () {
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 =
gettext(
'Report this error to your website administrator with the following information:',
) +
'<br />' +
errorThrown +
' - ' +
response.status;
$('#tab-upload', modal.body).append(
'<div class="help-block help-critical">' +
'<strong>' +
gettext('Server Error') +
': </strong>' +
message +
'</div>',
);
},
});
submitCreationForm(modal, this, { errorContainerSelector: '#tab-upload' });
return false;
});
var fileWidget = $('#id_document-chooser-upload-file', modal.body);
fileWidget.on('change', function () {
var titleWidget = $('#id_document-chooser-upload-title', modal.body);
var title = titleWidget.val();
// do not override a title that already exists (from manual editing or previous upload)
if (title === '') {
// The file widget value example: `C:\fakepath\image.jpg`
var parts = fileWidget.val().split('\\');
var filename = parts[parts.length - 1];
// allow event handler to override filename (used for title) & provide maxLength as int to event
var maxTitleLength =
parseInt(titleWidget.attr('maxLength') || '0', 10) || null;
var data = { title: filename.replace(/\.[^.]+$/, '') };
// allow an event handler to customise data or call event.preventDefault to stop any title pre-filling
var form = fileWidget.closest('form').get(0);
var event = form.dispatchEvent(
new CustomEvent('wagtail:documents-upload', {
bubbles: true,
cancelable: true,
detail: {
data: data,
filename: filename,
maxTitleLength: maxTitleLength,
},
}),
);
if (!event) return; // do not set a title if event.preventDefault(); is called by handler
titleWidget.val(data.title);
}
initPrefillTitleFromFilename(modal, {
fileFieldSelector: '#id_document-chooser-upload-file',
titleFieldSelector: '#id_document-chooser-upload-title',
eventName: 'wagtail:documents-upload',
});
}

Wyświetl plik

@ -1,11 +1,13 @@
import $ from 'jquery';
import { initTabs } from '../../includes/tabs';
import { gettext } from '../../utils/gettext';
import {
submitCreationForm,
initPrefillTitleFromFilename,
SearchController,
} from '../../includes/chooserModal';
function ajaxifyImageUploadForm(modal) {
$('form.image-upload', modal.body).on('submit', function () {
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')) {
@ -18,79 +20,23 @@ function ajaxifyImageUploadForm(modal) {
}
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 =
gettext(
'Report this error to your website administrator with the following information:',
) +
'<br />' +
errorThrown +
' - ' +
response.status;
$('#tab-upload').append(
'<div class="help-block help-critical">' +
'<strong>' +
gettext('Server Error') +
': </strong>' +
message +
'</div>',
);
},
submitCreationForm(modal, this, {
errorContainerSelector: '#tab-upload',
});
}
return false;
});
var fileWidget = $('#id_image-chooser-upload-file', modal.body);
fileWidget.on('change', function () {
var titleWidget = $('#id_image-chooser-upload-title', modal.body);
var title = titleWidget.val();
// do not override a title that already exists (from manual editing or previous upload)
if (title === '') {
// The file widget value example: `C:\fakepath\image.jpg`
var parts = fileWidget.val().split('\\');
var filename = parts[parts.length - 1];
// allow event handler to override filename (used for title) & provide maxLength as int to event
var maxTitleLength =
parseInt(titleWidget.attr('maxLength') || '0', 10) || null;
var data = { title: filename.replace(/\.[^.]+$/, '') };
// allow an event handler to customise data or call event.preventDefault to stop any title pre-filling
var form = fileWidget.closest('form').get(0);
var event = form.dispatchEvent(
new CustomEvent('wagtail:images-upload', {
bubbles: true,
cancelable: true,
detail: {
data: data,
filename: filename,
maxTitleLength: maxTitleLength,
},
}),
);
if (!event) return; // do not set a title if event.preventDefault(); is called by handler
titleWidget.val(data.title);
}
initPrefillTitleFromFilename(modal, {
fileFieldSelector: '#id_image-chooser-upload-file',
titleFieldSelector: '#id_image-chooser-upload-title',
eventName: 'wagtail:images-upload',
});
}
window.IMAGE_CHOOSER_MODAL_ONLOAD_HANDLERS = {
chooser: function (modal, jsonData) {
var searchForm = $('form.image-search', modal.body);
var searchUrl = searchForm.attr('action');
function ajaxifyLinks(context) {
$('.listing a', context).on('click', function () {
modal.loadUrl(this.href);
@ -98,52 +44,27 @@ window.IMAGE_CHOOSER_MODAL_ONLOAD_HANDLERS = {
});
$('.pagination a', context).on('click', function () {
fetchResults(this.href);
searchController.fetchResults(this.href);
return false;
});
}
var request;
function fetchResults(url, requestData) {
var opts = {
url: url,
success: function (data, status) {
request = null;
$('#image-results').html(data);
ajaxifyLinks($('#image-results'));
},
error: function () {
request = null;
},
};
if (requestData) {
opts.data = requestData;
}
request = $.ajax(opts);
}
function search() {
fetchResults(searchUrl, searchForm.serialize());
return false;
}
const searchController = new SearchController({
form: $('form.image-search', modal.body),
resultsContainerSelector: '#image-results',
onLoadResults: (context) => {
ajaxifyLinks(context);
},
});
searchController.attachSearchInput('#id_q');
searchController.attachSearchFilter('#collection_chooser_collection_id');
ajaxifyLinks(modal.body);
ajaxifyImageUploadForm(modal);
$('form.image-search', modal.body).on('submit', search);
$('#id_q').on('input', function () {
if (request) {
request.abort();
}
clearTimeout($.data(this, 'timer'));
var wait = setTimeout(search, 200);
$(this).data('timer', wait);
});
$('#collection_chooser_collection_id').on('change', search);
$('a.suggested-tag').on('click', function () {
$('#id_q').val('');
fetchResults(searchUrl, {
searchController.search({
tag: $(this).text(),
collection_id: $('#collection_chooser_collection_id').val(),
});

Wyświetl plik

@ -0,0 +1,141 @@
import $ from 'jquery';
import { gettext } from '../utils/gettext';
const submitCreationForm = (modal, form, { errorContainerSelector }) => {
const formdata = new FormData(form);
$.ajax({
url: form.action,
data: formdata,
processData: false,
contentType: false,
type: 'POST',
dataType: 'text',
success: modal.loadResponseText,
error(response, textStatus, errorThrown) {
const message =
gettext(
'Report this error to your website administrator with the following information:',
) +
'<br />' +
errorThrown +
' - ' +
response.status;
$(errorContainerSelector, modal.body).append(
'<div class="help-block help-critical">' +
'<strong>' +
gettext('Server Error') +
': </strong>' +
message +
'</div>',
);
},
});
};
const initPrefillTitleFromFilename = (
modal,
{ fileFieldSelector, titleFieldSelector, eventName },
) => {
const fileWidget = $(fileFieldSelector, modal.body);
fileWidget.on('change', () => {
const titleWidget = $(titleFieldSelector, modal.body);
const title = titleWidget.val();
// do not override a title that already exists (from manual editing or previous upload)
if (title === '') {
// The file widget value example: `C:\fakepath\image.jpg`
const parts = fileWidget.val().split('\\');
const filename = parts[parts.length - 1];
// allow event handler to override filename (used for title) & provide maxLength as int to event
const maxTitleLength =
parseInt(titleWidget.attr('maxLength') || '0', 10) || null;
const data = { title: filename.replace(/\.[^.]+$/, '') };
// allow an event handler to customise data or call event.preventDefault to stop any title pre-filling
const form = fileWidget.closest('form').get(0);
const event = form.dispatchEvent(
new CustomEvent(eventName, {
bubbles: true,
cancelable: true,
detail: {
data: data,
filename: filename,
maxTitleLength: maxTitleLength,
},
}),
);
if (!event) return; // do not set a title if event.preventDefault(); is called by handler
titleWidget.val(data.title);
}
});
};
class SearchController {
constructor(opts) {
this.form = opts.form;
this.onLoadResults = opts.onLoadResults;
this.resultsContainer = $(opts.resultsContainerSelector);
this.inputDelay = opts.inputDelay || 200;
this.searchUrl = this.form.attr('action');
this.request = null;
this.form.on('submit', () => {
this.searchFromForm();
return false;
});
}
attachSearchInput(selector) {
let timer;
$(selector).on('input', () => {
if (this.request) {
this.request.abort();
}
clearTimeout(timer);
timer = setTimeout(() => {
this.searchFromForm();
}, this.inputDelay);
});
}
attachSearchFilter(selector) {
$(selector).on('change', () => {
this.searchFromForm();
});
}
fetchResults(url, queryParams) {
const requestOptions = {
url: url,
success: (resultsData) => {
this.request = null;
this.resultsContainer.html(resultsData);
if (this.onLoadResults) {
this.onLoadResults(this.resultsContainer);
}
},
error() {
this.request = null;
},
};
if (queryParams) {
requestOptions.data = queryParams;
}
this.request = $.ajax(requestOptions);
}
search(queryParams) {
this.fetchResults(this.searchUrl, queryParams);
}
searchFromForm() {
this.search(this.form.serialize());
}
}
export { submitCreationForm, initPrefillTitleFromFilename, SearchController };