New process adding file uploads to custom forms built on the Bootstrap 5 framework - Revised September 2024
Note: this process is for any site build on the BS5 framework and prior to a September 2024 update. Any site built after September 2024 should already have the code in place to allow for file uploads to simply be added to the form without any additional code needed. This process details how to update your code to function in the same manner as post 9/2024 BS5 Sites.
- Step 1: Update the
forms.jsscript to allow for the processing of forms via ajax andmultipart/form-datacontent type that will allow for text fields AND file uploads to process with the same scripts.
forms.js Code: search for the document.querySelectorAll(".ajax-form").forEach loop of code and replace this entire code block with the one below. This is the updated function that adds event listeners to all .ajax-form class forms and does all the processing for you.
document.querySelectorAll(".ajax-form").forEach((el, index) => {
ajaxForms[index] = el.addEventListener('submit', function(event) {
event.preventDefault();
if(pristineForms) {
for(k = 0; k < pristineForms.length; k++) {
if(pristineForms[k].form === el) {
pristine = pristineForms[k];
}
}
}
if(pristine) {
if (pristine.validate() === true) {
let formContainer = el.closest('.form-container');
let successContainer = formContainer.parentNode.querySelector('.success-container');
let errorContainer = formContainer.parentNode.querySelector("div.error")
formBefore(el,formContainer,successContainer);
let formAction = el.action;
let formData = new FormData(el);
let formFields = {};
formData.forEach((value, key) => {
formFields[key] = value
});
//formData.append("_comments_input","");
fetch(formAction, {
method: "POST",
body: formData,
})
.then((response) => {
if (response.ok) {
formSuccess(el,formContainer,successContainer);
} else {
if(response.statusText) {
throw Error(`${response.status}: ${response.statusText}`);
} else if(response.status) {
throw Error(`${response.status}: Error returned from server`);
} else {
return response.json();
}
}
})
.then((errorData) => {
let errorString = "";
for (const [key, value] of Object.entries(errorData)) { errorString += `${key}: ${value}`; }
throw Error(`${ errorString }`);
})
.catch((error)=>{
errorContainer.innerHTML = error;
errorContainer.style.display = "block";
errorContainer.setAttribute('aria-hidden', 'false');
formContainer.querySelector('.loading').style.display = "none";
formContainer.querySelector('button[type=submit]').removeAttribute("disabled");
});
} else {
//scroll to the first validation error
setTimeout(function(){
banno.methods.scrollToTop(document.querySelector('.has-danger'), "form", "smooth", "start");
},100);
}
}
});
});
- Add the following hidden field to your form. This field was present on all pre-BS5 sites was removed to simplify the submission process, however what this input does is in the CMS, it looks for this formID field and then appends an additional, “honeypot” field that aids in validating the form submission to the server. If this field is missing or has a value set, then the server will fail the submission, but only when the content type is set to
multipart/form-data. Most BS5 sites have been submitting with a content type ofapplication/jsonand with that CT the server makes this “honeypot” field optional. But adding file uploads forces the content type tomultipart/form-datain order to process both text data and file uploads, hence the need for the additional hidden field.
Form input code: add this after your start <form> tag, and update the FORMIDHERE placeholder to match what is in the action of your form. You may need to put this input field in for ALL forms in your site, not just the one with the input - make sure to test another non-file-input form to make sure it still works.
<input type="hidden" name="formId" id="formId" value="FORMIDHERE"/>
For example, here is a completed code block for a contact form:
<form id="contactUsForm" data-pristine-validate action="/_/api/form/contactUs/entries" name="contactForm" class="ajax-form js-disabled">
<input type="hidden" name="formId" id="formId" value="contactUs">
...
- Then just add your file input fields as needed and everything should submit just fine!
NOTE: you will still need to have your backend database setup completed to include the new file fields in the schema. This instruction simply shows you how to update your form and scripts to make file uploads work. All the normal rules apply for form updates.