easy-file-picker
Version:
Easy File Picker is a straightforward library with no dependencies to upload/pick/read files in the browser.
124 lines (123 loc) • 4.19 kB
JavaScript
export async function getFile(options) {
const fileInput = createFileInput(false, options);
const file = new Promise((resolve, reject) => {
fileInput.onchange = (event) => {
const files = convertFileListToFileArray(event.target?.files);
resolve(files[0]);
};
fileInput.oncancel = () => {
resolve(null);
};
fileInput.onerror = (_event, _source, _line, _col, error) => {
reject(error);
};
fileInput.click();
});
return file.finally(() => fileInput.remove());
}
export async function getFiles(options) {
const fileInput = createFileInput(true, options);
const files = new Promise((resolve, reject) => {
fileInput.onchange = (event) => {
const files = convertFileListToFileArray(event.target?.files);
resolve(files);
};
fileInput.oncancel = () => {
resolve([]);
};
fileInput.onerror = (_event, _source, _line, _col, error) => {
reject(error);
};
fileInput.click();
});
return files.finally(() => fileInput.remove());
}
export async function getFileAsString(options) {
const fileInput = createFileInput(false, options);
const file = new Promise((resolve, reject) => {
fileInput.onchange = (event) => {
const files = convertFileListToFileArray(event.target?.files);
convertFileArrayToFileStringArray(files)
.then((str) => resolve(str[0]))
.catch((err) => reject(err));
};
fileInput.oncancel = () => {
resolve(null);
};
fileInput.onerror = (_event, _source, _line, _col, error) => {
reject(error);
};
fileInput.click();
});
return file.finally(() => fileInput.remove());
}
export async function getFilesAsString(options) {
const fileInput = createFileInput(false, options);
const files = new Promise((resolve, reject) => {
fileInput.onchange = (event) => {
const files = convertFileListToFileArray(event.target?.files);
convertFileArrayToFileStringArray(files)
.then((str) => resolve(str))
.catch((err) => reject(err));
};
fileInput.oncancel = () => {
resolve([]);
};
fileInput.onerror = (_event, _source, _line, _col, error) => {
reject(error);
};
fileInput.click();
});
return files.finally(() => fileInput.remove());
}
export async function uploadFilesTo(url, files, httpMethod = 'POST') {
const filesArray = Array.isArray(files) ? files : [files];
const formData = new FormData();
let i = 0;
for (const file of filesArray) {
formData.append(`File${i++}`, file, file.name);
}
return fetch(url, {
method: httpMethod,
body: formData,
});
}
function createFileInput(multpleFiles, options) {
const fileInput = document.createElement('input');
fileInput.hidden = true;
fileInput.type = 'file';
fileInput.multiple = multpleFiles;
fileInput.accept = options?.acceptedExtensions?.join(',') ?? '';
return fileInput;
}
function convertFileListToFileArray(files) {
if (files == null) {
return [];
}
const fileArray = [];
for (let i = 0; i < files.length; i++) {
fileArray.push(files[i]);
}
return fileArray;
}
async function convertFileArrayToFileStringArray(files) {
const reader = new FileReader();
const filePromises = [];
for (const file of files) {
const filePromise = new Promise((resolve) => {
reader.onload = (event) => {
resolve({
name: file.name,
size: file.size,
type: file.type,
lastModified: file.lastModified,
webkitRelativePath: file.webkitRelativePath,
content: event.target?.result,
});
};
reader.readAsText(file, 'utf-8');
});
filePromises.push(filePromise);
}
return Promise.all(filePromises);
}