Я создаю пользовательскую форму «Google Forms» с функцией загрузки файлов.
Форма использует пользовательскую страницу «Спасибо» (см. 1-ю строку: iframe).
Я нашел сценарий загрузки файлов, который нужно запустить в среде Google Script, и он будет загружать файлы на мой Google Диск.
Теперь мне нужно объединить этот скрипт загрузки с моей пользовательской формой Google. Но я точно не знаю, как этого добиться, потому что есть действия, которые необходимо объединить, и загрузка файла должна быть завершена, прежде чем переходить на страницу «Спасибо».
Я попытался объединить его, который выглядит как код ниже.
Форма:
<iframe name = "hidden_iframe" id = "hidden_iframe" style = "display:none;" onload = "if (submitted) { picUploadJs(myForm); }"></iframe>
<form id = "myForm" action = "https://docs.google.com/forms/d/e/xxx/formResponse" target = "hidden_iframe" onsubmit = "submitted=true;">
<input placeholder = "1234" name = "entry.1234" id = "user" type = "text">
<label for = "user">User:</label>
<input name = "picToLoad" type = "file" />
<div id = "status" style = "display: none">
Uploading. Please wait...
</div
<button type = "submit" name = "action">Send</button>
</form>
Скрипт загрузки:
<script>
function picUploadJs(frmData) {
document.getElementById('status').style.display = 'inline';
google.script.run
.withSuccessHandler(updateOutput)
.processForm(frmData)
};
function updateOutput() {
var outputDiv = document.getElementById('status');
outputDiv.innerHTML = "The File was UPLOADED!";
window.location='https://thankyoupage/';
}
</script>
Теперь это приводит к: Данные для ввода в форму отправляются, появляется текст статуса загрузки, но ничего не происходит: "Идет загрузка. Пожалуйста, подождите...".
Результат должен быть: Отправка входных данных формы, загрузка файла на диск и перенаправление на страницу благодарности.
Обновлено: Код Google-скрипта
function doGet(e) {
return HtmlService.createTemplateFromFile('test')
.evaluate() // evaluate MUST come before setting the Sandbox mode
.setTitle('Name To Appear in Browser Tab')
//.setSandboxMode();//Defaults to IFRAME which is now the only mode available
}
function processForm(theForm) {
var fileBlob = theForm.picToLoad;
Logger.log("fileBlob Name: " + fileBlob.getName())
Logger.log("fileBlob type: " + fileBlob.getContentType())
Logger.log('fileBlob: ' + fileBlob);
var fldrSssn = DriveApp.getFolderById('xxxx');
fldrSssn.createFile(fileBlob);
return true;
}
Я добавил код скрипта Google в свой исходный пост.
Спасибо за ответ. Прежде чем изменить ваш сценарий, я хотел бы подтвердить вашу текущую ситуацию. В вашей текущей ситуации, когда нажимается кнопка «Отправить», отправляется форма Google, запускается picUploadJs()
и файл создается на Google Диске? Пожалуйста, расскажите мне о вашей текущей ситуации, когда нажата кнопка "Отправить".
Когда нажимается «Отправить»: форма Google отправляется, picUploadJs()
запускается, но только частично: стиль элемента «статус» меняется на inline
, но функция загрузки google.script.run
, похоже, не запускается или работает неправильно.
Спасибо за ответ. Я думал, что могу понять вашу ситуацию. Поэтому я предложил модифицированный сценарий в качестве ответа. Не могли бы вы подтвердить это? Я не уверен насчет всего вашего сценария. В моей среде я мог подтвердить, что приведенный выше модифицированный скрипт работал. Но если скрипт не работал в вашей среде, приношу извинения.
document.getElementById('status').style.display = 'inline'
работает.processForm(frmData)
в Google Apps Script не работает.updateOutput()
в Javascript не работает.Если я правильно понимаю, как насчет этой модификации? Пожалуйста, подумайте об этом как об одном из нескольких ответов.
onclick
, при этом скрипт отправки в Google Form не изменен.<form id = "myForm" action = "https://docs.google.com/forms/d/e/xxx/formResponse" target = "hidden_iframe" onsubmit = "submitted=true;">
<input placeholder = "1234" name = "entry.1234" id = "user" type = "text">
<label for = "user">User:</label>
<input name = "picToLoad" type = "file" id = "sampleFile" /> <!-- Modified -->
<div id = "status" style = "display: none">
Uploading. Please wait...
</div>
<button type = "submit" name = "action" id = "sampleId" >Send</button> <!-- Modified -->
</form>
<script>
// Below script was added.
document.getElementById("sampleId").onclick = function(e) {
e.stopPropagation();
e.preventDefault();
var file = document.getElementById("sampleFile").files[0];
const f = new FileReader();
f.onload = (e) => {
const data = e.target.result.split(",");
const obj = {fileName: file.name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1]};
picUploadJs(obj);
}
f.readAsDataURL(file);
};
function picUploadJs(frmData) {
document.getElementById('status').style.display = 'inline';
google.script.run.withSuccessHandler(updateOutput).processForm(frmData)
};
function updateOutput() {
var outputDiv = document.getElementById('status');
outputDiv.innerHTML = "The File was UPLOADED!";
window.location='https://thankyoupage/';
}
</script>
function processForm(theForm) {
var fileBlob = Utilities.newBlob(Utilities.base64Decode(theForm.data), theForm.mimeType, theForm.fileName);
var fldrSssn = DriveApp.getFolderById('xxxx');
fldrSssn.createFile(fileBlob);
return true;
}
updateOutput()
на стороне Javascript.По вашему комментарию выяснилось, что When I remove the id=sampleId from the submit button, the Google Form data is submitted correctly
. Используя это, проверьте следующую модификацию.
В этой модификации убрали id = "sampleId"
и событие запускается по имени элемента.
<form id = "myForm" target = "hidden_iframe" onsubmit = "submitted=true;">
<input placeholder = "1234" name = "entry.1234" id = "user" type = "text">
<label for = "user">User:</label>
<input name = "picToLoad" type = "file" id = "sampleFile" />
<div id = "status" style = "display: none">
Uploading. Please wait...
</div>
<button type = "submit" name = "action">Send</button> <!-- Modified -->
</form>
var button = document.getElementsByName('action')[0]; // Modified
button.onclick = function(e) { // Modified
e.stopPropagation();
e.preventDefault();
var file = document.getElementById("sampleFile").files[0];
const f = new FileReader();
f.onload = (e) => {
const data = e.target.result.split(",");
const obj = {fileName: file.name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1]};
picUploadJs(obj);
}
f.readAsDataURL(file);
};
Я обновил HTML и Javascript. Пожалуйста, подтвердите. Сценарий Google Apps не изменен.
<iframe name = "hidden_iframe" id = "hidden_iframe" style = "display:none;" onload = "if (submitted) { picUploadJs(myForm); }"></iframe>
<form id = "myForm" action = "https://docs.google.com/forms/d/e/xxx/formResponse" target = "hidden_iframe" onsubmit = "submitted=true;">
<input placeholder = "1234" name = "entry.1234" id = "user" type = "text">
<label for = "user">User:</label>
<input name = "picToLoad" type = "file" id = "sampleFile" /> <!-- Modified -->
<div id = "status" style = "display: none">
Uploading. Please wait...
</div>
<button type = "submit" name = "action">Send</button>
</form>
<script>
// This function was modified.
function picUploadJs(myForm) {
var file = document.getElementById("sampleFile").files[0];
const f = new FileReader();
f.onload = (e) => {
const data = e.target.result.split(",");
const obj = {fileName: file.name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1]};
document.getElementById('status').style.display = 'inline';
google.script.run.withSuccessHandler(updateOutput).processForm(obj);
}
f.readAsDataURL(file);
}
function updateOutput() {
var outputDiv = document.getElementById('status');
outputDiv.innerHTML = "The File was UPLOADED!";
window.location='https://thankyoupage/';
}
</script>
Спасибо, что нашли время, чтобы понять все это для меня! Я изменил свой сценарий с учетом ваших изменений, но, к сожалению, теперь он не отправляет данные формы Google. Однако он загружает файл на Google Диск и перенаправляет на страницу благодарности. Когда я удаляю id=sampleId
из кнопки отправки, данные формы Google отправляются правильно (но, конечно, функция загрузки больше не работает).
Может быть, вы забыли код iframe? Потому что эта строка также использовалась в моем исходном коде: <iframe name = "hidden_iframe" id = "hidden_iframe" style = "display:none;" onload = "if (submitted) { picUploadJs(myForm); }"></iframe>
В настоящее время я пытаюсь заставить это работать так, но пока не удалось. <iframe name = "hidden_iframe" id = "hidden_iframe" style = "display:none;" onload = "if (submitted) { upload(); }"></iframe>
И поместите свой скрипт в функцию: function upload() { //your script };
Хорошо, я добавил эту строку после тега </head>
, потому что ее не было и поэтому if (submitted)
не работал: <script type = "text/javascript">var submitted=false;</script>
. Но, к сожалению, файл не загружается.
@Bldjef Спасибо за ответ. Я прошу прощения за неудобства. Из вашего ответа я изменил сценарий. Не могли бы вы подтвердить это? Если это еще не сработало, прошу прощения. Кстати, в модификации я использовал событие onclick
вместо <iframe>...</iframe>
.
Извините, но он по-прежнему не отправляет данные формы. Я думаю, что скрипт загрузки файла получает «более высокий приоритет» (или быстрее?) и пропускает функцию действия из тега <form>
.
@Bldjef Спасибо за ответ и тестирование. Я прошу прощения за неудобства. Поэтому я хотел бы подтвердить ситуацию и изменить ее. Если вы можете дать мне время, чтобы сделать, я рад.
@Bldjef Прошу прощения за неудобства. Я обновил свой ответ. Не могли бы вы подтвердить это? В этой модификации снова использовалось <iframe>...</iframe>
. Таким образом, я могу подтвердить, что оба представления могут быть выполнены. Если это не сработало, прошу прощения.
Спасибо, это работает! Ты восхитителен! Как вы думаете, можно ли выбрать несколько файлов и загрузить их? Я добавляю multiple
в поле <input>
, но я думаю, что нам также нужно прочитать весь массив, верно?
Уже понял, нашел ваш пример на Gist Github! :) У меня есть еще несколько вопросов, может быть, я могу отправить вам электронное письмо или перейти в чат?
Давайте продолжить обсуждение в чате.
@Bldjef Спасибо за ответ. Я рад, что ваша проблема была решена. О вашем новом вопросе. Я не могу понять вашу ситуацию. Я хотел бы понять ваш новый вопрос. Итак, вы можете опубликовать это как новый вопрос? В это время, пожалуйста, включите подробную информацию о вашей ситуации. Это поможет пользователям, включая меня, подумать о вашем решении. Если вы можете сотрудничать, чтобы решить вашу проблему, я рад.
Спасибо, Танайке, создан новый вопрос: stackoverflow.com/questions/55626979/…
@Bldjef Спасибо за ваш ответ. Я предложил модифицированный сценарий. Не могли бы вы подтвердить это? Кстати, вы ссылались на этот скрипт?
Могу я спросить вас о
processForm()
скрипта Google Apps?