I am currently developing an application to make requests. These requests can be accompanied by two attachments. These are not mandatory, there can be none, one or two.) If there are any, they will be saved in a specific folder on the Drive. This folder is a child folder created automatically and named after the id of the request. So I created a script to import the attachments when a button is clicked since I need to get the id and url of the attachment to add it to the Sheets file. However, I have a problem when there are two attachments. Indeed, this generates two folders with the same name (the id of the request) whereas I would like them to be grouped in the same folder.
Here is the html code of the attachments :
<div id="divPhotos">
<div >
<label for="photoPres" ><b>Photo de près :</b></label><br>
<input type="file" id="photoPres">
</div>
<div >
<label for="photoLoin" ><b>Photo de loin :</b></label><br>
<input type="file" id="photoLoin">
</div>
</div>
<div >
<div >
<input type="button" id = "btnFichiers" value="IMPORTER LES PHOTOS" onclick="getFiles()">
<p id="idPhotoPres" ></p>
<p id="idPhotoLoin" ></p>
</div>
</div>
Here is the corresponding javascript :
function getFiles(){
const f = document.getElementById('photoPres');
if (f.files.length > 0){
[...f.files].forEach((file, i) => {
const fr = new FileReader();
fr.onload = (e) => {
const data = e.target.result.split(",");
const obj = {fileName: f.files[i].name, mimeType: data[0].match(/:(\w. );/)[1], data: data[1]};
google.script.run.withSuccessHandler(id => {
document.getElementById("idPhotoPres").innerHTML = id
}).saveFile(obj);
}
fr.readAsDataURL(file);
});
}
const f2 = document.getElementById('photoLoin');
if (f2.files.length > 0){
[...f2.files].forEach((file2, i) => {
const fr2 = new FileReader();
fr2.onload = (e) => {
const data = e.target.result.split(",");
const obj = {fileName: f2.files[i].name, mimeType: data[0].match(/:(\w. );/)[1], data: data[1]};
google.script.run.withSuccessHandler((id) => {
document.getElementById("idPhotoLoin").innerHTML = id;
}).saveFile(obj);
}
fr2.readAsDataURL(file2);
});
}
}
And here is the apps script code for the back-end part:
function saveFile(obj){
var pieceJointe = Utilities.newBlob(Utilities.base64Decode(obj.data), obj.mimeType, obj.fileName);
const dossierDrive = DriveApp.getFolderById('1KRwd79dc8k8EArwHU_1RnkDHd-Sdv0DJ');
const idDemande = generateId().toString();
var dossierPieceJointe;
var idDosssier = folderExists(idDemande);
if (idDosssier !== false) {
dossierPieceJointe = DriveApp.getFolderById(idDosssier);
const pieceJointeAjoutee = dossierPieceJointe.createFile(pieceJointe);
const informationsPJ = {
'url' : pieceJointeAjoutee.getUrl(),
'id' : pieceJointeAjoutee.getId()
};
return informationsPJ;
} else {
dossierPieceJointe = dossierDrive.createFolder(idDemande);
const pieceJointeAjoutee = dossierPieceJointe.createFile(pieceJointe);
const informationsPJ = {
'url' : pieceJointeAjoutee.getUrl(),
};
return informationsPJ;
}
}
function generateId(){
const classeur = SpreadsheetApp.getActiveSpreadsheet();
const webAppSheet = classeur.getSheetByName("Demandes");
var lastRow = webAppSheet.getLastRow();
var splitId = []; var id; var lastDemande = "";
if(lastRow == 1){
return (new Date().getFullYear()) "_1";
}else{
lastDemande = webAppSheet.getRange(lastRow, 1).getValue();
splitId = lastDemande.split('_');
if (splitId[0] == new Date().getFullYear()){
id = lastId 1;
feuilleBDD.getRange("I2").setValue(id);
return (new Date().getFullYear()) "_" id;
}
else {
feuilleBDD.getRange("I2").setValue(1)
return (new Date().getFullYear()) "_1";
}
}
}
function folderExists(nomDossierPJ) {
const dossierDrive = DriveApp.getFolderById('1KRwd79dc8k8EArwHU_1RnkDHd-Sdv0DJ');
var folders = dossierDrive.getFolders();
var theReturn = false,folderName = "",folder;
while (folders.hasNext()) {
folder = folders.next();
folderName = folder.getName();
if (folderName === nomDossierPJ) {
theReturn = folder.getId();
break;
};
};
return theReturn;
}
Could you please help me to fix this problem? Thanks in advance for your help.
CodePudding user response:
When I saw your showing script, I'm worried that in your script, the reason for your issue might be due to that FileReader
and google.script.run
are run with the asynchronous process. If my understanding is correct, how about the following modification?
In this modification, your Javascript is modified as follows.
Modified script:
function getResponse(file) {
return new Promise((resolve, reject) => {
const fr = new FileReader();
fr.onload = e => {
const data = e.target.result.split(",");
const obj = { fileName: file.name, mimeType: data[0].match(/:(\w. );/)[1], data: data[1] };
google.script.run.withFailureHandler(reject).withSuccessHandler(resolve).saveFile(obj);
}
if (file) {
fr.readAsDataURL(file);
} else {
reject("No file");
}
});
}
async function getFiles() {
const f1 = document.getElementById('photoPres');
const f2 = document.getElementById('photoLoin');
const files = [{ f: f1.files[0], disp: "idPhotoPres" }, { f: f2.files[0], disp: "idPhotoLoin" }];
for (let i = 0; i < files.length; i ) {
if (!files[i].f) continue;
const { url } = await getResponse(files[i].f).catch(err => console.log(err));
document.getElementById(files[i].disp).innerHTML = url;
}
}
- By this modification, the files are uploaded with the synchronous process. By this, I thought that your issue might be able to be removed.
Note:
- I'm not sure about your actual situation. If you are using Web Apps, when you modified the script, please reflect the latest script in the Web Apps. Please be careful about this.