Skip to content

Instantly share code, notes, and snippets.

@Qubadi
Last active November 7, 2024 15:31
Show Gist options
  • Save Qubadi/5793d9bd3fbc996fb35cee7e50031f33 to your computer and use it in GitHub Desktop.
Save Qubadi/5793d9bd3fbc996fb35cee7e50031f33 to your computer and use it in GitHub Desktop.
Jetformbuilder customize the Choose File and drag-and-drop of images
UPDATED: 04.11.2024
Copy the following HTML code and create a HTML snippet using your snippet plugins.
Paste the code into the plugin and save it.
Don't forget to add MIME types (image formats), for example, PNG and JPEG, in the media field where it shows 'Allow MIME types.
______________________________________________________
<style>
/* Custom styles for the file upload field */
.jet-form-builder__field-wrap.jet-form-builder-file-upload {
background: #ecf6ff !important;
border: 3px dashed #c7d4e1 !important;
padding: 20px !important;
text-align: center;
position: relative;
margin-bottom: 20px;
display: flex;
flex-direction: column;
align-items: center;
border-radius: 6px !important;
transition: border-color 0.3s ease, background-color 0.3s ease;
}
/* Styles for the image upload */
.jet-form-builder-file-upload__file img {
display: block;
width: 100%;
height: 100% !important;
padding: 0;
margin: 0;
-o-object-fit: cover;
object-fit: cover;
-o-object-position: center center;
object-position: center center;
border-radius: 6px !important;
box-shadow: 0 0 30px -8px rgba(0, 0, 0, 0.24) !important;
}
/* Styles for image content */
.jet-form-builder-file-upload__content {
min-height: auto !important;
}
/* Styles for the custom "Choose File" and "File Uploaded" buttons */
.addfile {
padding: 10px 20px;
background-color: #0037fd !important;
color: #ffffff !important;
border: none !important;
font-size: 16px;
font-weight: 600;
cursor: pointer;
border-radius: 6px;
margin-top: 10px;
}
.addfile:hover {
background-color: #000000 !important;
color: #ffffff !important;
}
/* Styles for the label that shows file upload status */
.labeladdfile {
padding: 6px 12px;
background-color: transparent;
color: #000000 !important;
font-size: 12px;
font-weight: 400;
display: block;
margin-top: 10px;
border-radius: 6px;
}
/* Class added when files are uploaded */
.files-uploaded {
background-color: #09b872 !important;
padding: 6px 12px;
color: #ffffff !important;
border-radius: 6px;
}
/* Hide the default file input visually */
.jet-form-builder-file-upload__input {
display: none;
}
/* Drag and drop hover effect */
.jet-form-builder__field-wrap.jet-form-builder-file-upload.dragover {
border-color: #0037fd !important;
background: rgba(0, 55, 253, 0.1) !important;
}
/* New styles for drag and drop text and icon */
.drag-drop-text {
font-size: 30px;
font-weight: 700;
color: #333;
margin-bottom: 10px;
display: flex;
flex-direction: column;
align-items: center;
transition: opacity 0.3s ease, height 0.3s ease;
height: auto;
}
.drag-drop-text.hidden {
opacity: 0;
height: 0;
overflow: hidden;
}
.drag-drop-text .icon {
font-size: 24px;
margin-bottom: 10px;
}
.allowed-mime-types {
font-size: 14px;
color: #666;
margin-bottom: 10px;
transition: opacity 0.3s ease, height 0.3s ease;
height: auto;
}
.allowed-mime-types.hidden {
opacity: 0;
height: 0;
overflow: hidden;
}
.allowed-mime-types .formats {
font-weight: bold;
}
.or-text {
font-size: 14px;
color: #666;
margin-bottom: 10px;
transition: opacity 0.3s ease, height 0.3s ease;
height: auto;
}
.or-text.hidden {
opacity: 0;
height: 0;
overflow: hidden;
}
/* Responsive adjustments */
@media (max-width: 767px) {
.addfile, .labeladdfile {
padding: 8px 16px;
font-size: 12px;
}
}
@media (max-width: 1024px) {
.addfile, .labeladdfile {
padding: 8px 16px;
font-size: 12px;
}
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
const { addAction } = window.JetPlugins.hooks;
addAction('jet.fb.input.makeReactive', 'set-upload-labels', function(input) {
if (!input?.nodes?.length || !input.nodes[0].classList.contains('jet-form-builder-file-upload__input')) {
return;
}
const $ = jQuery;
const upload = $(input.nodes[0]);
const fields = $(input.nodes[0].closest('.jet-form-builder-file-upload__fields'));
// Extract allowed MIME types from the input element and format them
let mimeTypes = upload.attr('accept').split(',').map(type => type.split('/')[1].trim());
if (!fields.find('.addfile').length) {
fields.prepend(`
<div class="drag-drop-text">
<i class="fas fa-file-upload icon"></i>
Drag and drop your files here
</div>
<div class="allowed-mime-types">Files supported: <span class="formats">${mimeTypes.join(', ')}</span></div>
<div class="or-text">OR</div>
`);
fields.append(`<input type="button" class="addfile" value="Choose File"/>`);
fields.append(`<div class="labeladdfile"></div>`);
}
const labelAdd = fields.find('.labeladdfile');
const buttonAdd = fields.find('.addfile');
const dragDropText = fields.find('.drag-drop-text');
const allowedMimeText = fields.find('.allowed-mime-types');
const orText = fields.find('.or-text');
upload.css('display', 'none');
buttonAdd.click(function() {
upload.trigger('click');
});
input.value.watch(function() {
const fileCount = this.current.length;
const fileText = fileCount > 0 ? `Uploaded files (${fileCount})` : '';
buttonAdd.val(fileCount > 0 ? 'File Uploaded' : 'Choose File');
labelAdd.html(fileText);
labelAdd.toggleClass('files-uploaded', fileCount > 0);
if (fileCount > 0) {
dragDropText.addClass('hidden');
allowedMimeText.addClass('hidden');
orText.addClass('hidden');
} else {
dragDropText.removeClass('hidden');
allowedMimeText.removeClass('hidden');
orText.removeClass('hidden');
}
});
const fieldWrap = fields.closest('.jet-form-builder__field-wrap.jet-form-builder-file-upload');
fieldWrap.on('dragover', function(event) {
event.preventDefault();
event.stopPropagation();
fieldWrap.addClass('dragover');
dragDropText.addClass('hidden');
allowedMimeText.addClass('hidden');
orText.addClass('hidden');
});
fieldWrap.on('dragleave', function(event) {
event.preventDefault();
event.stopPropagation();
fieldWrap.removeClass('dragover');
if (input.value.get().length === 0) {
dragDropText.removeClass('hidden');
allowedMimeText.removeClass('hidden');
orText.removeClass('hidden');
}
});
fieldWrap.on('drop', function(event) {
event.preventDefault();
event.stopPropagation();
fieldWrap.removeClass('dragover');
const files = event.originalEvent.dataTransfer.files;
// Set files to the input, trigger change event, and handle validation
upload[0].files = files;
const eventChange = new Event('change', { bubbles: true });
upload[0].dispatchEvent(eventChange);
setTimeout(() => {
const errorMessage = $('.jet-form-builder-row.field-has-error .error-message').text().trim();
if (errorMessage) {
alert(errorMessage);
window.location.reload(); // Reload the page when "Ok" is clicked
resetFileInput(); // Reset the UI if an error occurs
}
}, 100); // Slight delay to allow the backend to update the error message
});
upload.on('change', function() {
const files = upload[0].files;
if (!validateFiles(files)) {
showErrorMessage();
resetFileInput(); // Reset the UI if an error occurs
}
});
function validateFiles(files) {
const maxFileSize = 2 * 1024 * 1024;
const maxFileCount = 2;
let valid = true;
if (files.length > maxFileCount) {
valid = false;
} else {
Array.from(files).forEach(file => {
if (file.size > maxFileSize) {
valid = false;
}
});
}
return valid;
}
function showErrorMessage() {
const errorMessage = $('.jet-form-builder-row.field-has-error .error-message').text().trim();
if (errorMessage) {
alert(errorMessage);
window.location.reload(); // Reload the page when "Ok" is clicked
}
}
function resetFileInput() {
upload.val(''); // Clear the file input
labelAdd.html(''); // Clear label text
buttonAdd.val('Choose File'); // Reset button to "Choose File"
labelAdd.removeClass('files-uploaded');
dragDropText.removeClass('hidden'); // Show drag-drop text
allowedMimeText.removeClass('hidden');
orText.removeClass('hidden');
$('.jet-form-builder-file-upload__file').remove(); // Remove any displayed files
input.value.set([]); // Reset input value to empty
}
});
});
</script>
@Joe-Bloggs
Copy link

Hey @Qubadi, many thanks for this. I can't seem to get this script working for some reason.
I've got your other old script for the media upload field enhancement working perfectly fine, but in this case I just end up with an empty box and can't see any controls, button etc.

Screenshot 2024-10-23 at 9 35 47 am

Copied & pasted the script exactly the same way as the old one, default JFB form, no changes in class names or anything unusual.

Any ideas what am I doing wrong?

@Qubadi
Copy link
Author

Qubadi commented Oct 23, 2024

Hey @Qubadi, many thanks for this. I can't seem to get this script working for some reason. I've got your other old script for the media upload field enhancement working perfectly fine, but in this case I just end up with an empty box and can't see any controls, button etc.

Screenshot 2024-10-23 at 9 35 47 am Copied & pasted the script exactly the same way as the old one, default JFB form, no changes in class names or anything unusual.

Any ideas what am I doing wrong?

Hello

Goto your form, and click media field, then blocker, and scroll down to u see: Allow mime type, and type in exemple: jpeg, png etc... then save your form again, and try and see, it should works now :)
image

@Joe-Bloggs
Copy link

@Qubadi I know what's happening.

I've already had the mime types setup for the media upload field, because I was basically just upgrading the code from your older tutorial that only had the basic upload filed to this new one that has the drag and drop.

However, in my old set up for the Media Upload field, I had the mime types as 'image/jpeg' , 'image/png' and then also 'jpg' which is where the issue is.

Basically if the 'jpg' tag is present, the drag & drop breaks.

Screenshot 2024-10-23 at 9 19 27 pm

Is JPG not a valid mime type? Anyway, without it works really great.

There's one more issue though, I hope you don't mind:

If I drag and drop 3 images in the window, all 3 images will upload just fine. However when I now decide to drop-in 1 more additional image, then this 1 image will basically override the 3 previously uploaded images and these are now removed.

So rather then this image being added to the 3 existing images in the gallery, the new image replaces them.

Is there any chance you'd be able to fix that?

Many thanks again. Jo

@Qubadi
Copy link
Author

Qubadi commented Oct 24, 2024

Joe

Thanks for the feedback. There have been quite a few updates and I haven't had time to update the code, but I will now do it this weekend and test and see what I can do. Should any changes occur, I write Update with date at the top.

@Joe-Bloggs
Copy link

Thanks so much @Qubadi, I really appreciate your work. I'm finding your snippets super helpful and inspirational! You should be on Crocoblock's payroll 😉

@Qubadi
Copy link
Author

Qubadi commented Nov 4, 2024

Thanks so much @Qubadi, I really appreciate your work. I'm finding your snippets super helpful and inspirational! You should be on Crocoblock's payroll 😉

U welcome :)

To information: We have included a feature that enables the display of a pop-up message in the event that the maximum file upload limit has been reached. The system will show a popup in case you try to upload more files than the allowable file count set by the backend (limited currently to 2 files) is dragged and dropped or the 'Choose File' button is used. This makes it easier to manage the limitations, as it applies to both means of upload.

@HOTIdeia
Copy link

HOTIdeia commented Nov 7, 2024

Hello friendly people

I write from Lisbon (Portugal) and just stopped by to say that you are fantastic, your "codes" are a valuable help. I share what someone already said here, you should get help (€€€) from Crocoblock. True public knowledge sharing service. Big Hug Mário Freiria

@Qubadi
Copy link
Author

Qubadi commented Nov 7, 2024

Hello friendly people

I write from Lisbon (Portugal) and just stopped by to say that you are fantastic, your "codes" are a valuable help. I share what someone already said here, you should get help (€€€) from Crocoblock. True public knowledge sharing service. Big Hug Mário Freiria

Happy to hear that my codes are helpful. I create my codes completely for free, and I work independently. Follow us here—I’ll be sharing new codes and updating existing ones as I’m home and have time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment