I'm developing a Chrome extension and need it to prompt the user with a custom modal window asking for confirmation when they attempt to upload a file. Here's the content.js script I've been working on:
function showModal(element) {
const modal = document.createElement('div');
modal.innerHTML = `
<div style="position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);display:flex;justify-content:center;align-items:center;z-index:10000;">
<div style="background:white;padding:20px;border-radius:5px;box-shadow:0 4px 6px rgba(0,0,0,0.1);">
<p>Are you sure you want to upload the file?</p>
<button id="confirmUpload">Yes</button>
<button id="cancelUpload">No</button>
</div>
</div>
`;
document.body.appendChild(modal);
// Handling confirmUpload
document.getElementById('confirmUpload').addEventListener('click', () => {
document.body.removeChild(modal);
});
// Handling confirmUpload
document.getElementById('cancelUpload').addEventListener('click', () => {
document.body.removeChild(modal);
// Deleting the file from the element.files
const dt = new DataTransfer()
element.files = dt.files;
});
}
// React to an event when a user uploads a file to the site
document.addEventListener('change', (event) => {
event.preventDefault();
const element = event.target;
if (element instanceof HTMLInputElement && element.type === 'file') {
showModal(element);
}
}, true);
The issue
The main issue I'm encountering is that the file starts uploading immediately upon selection, before the user can respond to the modal. This behavior defeats the purpose of seeking user confirmation.
Why common solutions won't work
- Using
event.stopPropagation()isn't viable because it would necessitate custom upload logic for each site, which is impractical. - Standard alert/prompt/confirm dialogs aren't suitable either due to their lack of customization options; I intend to include features like file preview in the modal.
Given these constraints, does anyone have suggestions for a workaround or a different strategy to achieve the desired functionality? Or is it perhaps possible to achieve it with a completely different approach?
If you console.log() the event returned by the
changeeventListener, you can seecancelableis false, that is why your e.preventDefault() is not working.To get around this, you need to querySelect the specific input element before the user has triggered the
changeevent using aclickeventListener. However, this wouldn't work either, since as you said you would need to add logic for every site.Since you can't trigger a file select from inside a input element's event, you would need to hide the site's file input element, replace it with a custom button, and add logic from inside your custom button's click event to trigger the site's now invisible input element's file select using
.click().