#javascript #jquery #ajax
#javascript #jquery #ajax
Вопрос:
Я работаю над отправкой данных формы из динамической формы пользователя на страницу Google Sheets. Существует корпус из 140 потенциальных форм, пользователям случайным образом отображаются 20. Я не получаю никаких ошибок в консоли, но Google Sheet не заполняется. Я знаю, что сценарий sheets gs в порядке, потому что соединение работало нормально в более простых вариантах использования.
Я включил html и js-код, который у меня есть ниже. Веб-сайт отлично отображается на моем локальном компьютере. Изображения и форма также работают.
<!DOCTYPE html>
<body>
<!-- Required JS packages for this project-->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js">
</script>
<script src="jquery-3.3.1.min.js"></script>
<script src="require.js"></script>
<!--Create empty form element -->
<div id = "form_submit"></div>
<!-- JS function to fill form element with 20 hold type questions forms -->
<script>
// Establish file name to hold mapping with two lists and a dict to link elements
var files = ['1.png', '10.png', ..., '98.png', '99.png']
var numWords = ["one", "two", "three",.., "one_hundred_and_fifty"]
var numWordDict = { 1: 'one', ..., 150: 'one_hundred_and_fifty' } // Generate list of 20 random digits that will select holds to be classified
// Create array of twenty random holds
var idx = []
for (var j = 0; j < 20; j ) {
idx.push(Math.floor(Math.random() * 140) 0)
}
console.log(idx)
// Loop over array and make a form element for each hold within the div element
$(document).ready(function (list) {
for (var i = 0; i < idx.length; i ) {
// retrieve mapped index
var randHoldIdx = idx[i]
// build path to hold image
var holdPath = files[randHoldIdx]
var numb = holdPath.match(/d/g);
numb = numb.join("");
var colName = numWordDict[numb]
var form_name = 'submit-to-google-sheet' numb
const scriptURL = 'https://script.google.com/macros/s/AKfycbyhMLuTGNkaNOxeNCOx_t1ERThZT8VEYDcMmiQhj773kIrUuRA/exec'
// Form element contents will be appended into the div element with id = form_submit
$("#form_submit").append(
// html form skeleton for users to select jug,pinch, crimp, pocket or undercling from radio button
// options
"<form name = " form_name ">"
"<input type='radio' name = " colName " class=" String(colName) " value=1>Jug<br>"
"<input type='radio' name = " colName " class=" String(colName) " value=2>Pinch<br>"
"<input type='radio'name = " colName " class=" String(colName) " value=3>Crimp<br>"
"<input type='radio' name = " colName " class=" String(colName) " value=4>Pocket<br>"
"<input type='radio' name = " colName " class=" String(colName) " value=5>Undercling"
// Submit button for form, close form
"<button type='submit'>Submit!</button></form>"
// image of climbing hold in question with coordinates to position on moonboard
"<div><img src=labelled_imgs/" String(holdPath) " alt='selected hold'></div>");
var form = document.forms[form_name]
window.onload=function(){
form.addEventListener('submit', e => {
e.preventDefault()
fetch(scriptURL, { method: 'POST', body: new FormData(form) })
.then(response => console.log('Success!', response))
.catch(error => console.error('Error!', error.message))
})
}
}
});
</script>
</body>
Я подозреваю, что что-то не так с прослушивателем событий. Это может быть что-то простое, но я бы приветствовал любые предложения по альтернативным решениям этой проблемы! Это немного отличается от простой отправки пользовательского ввода из формы в таблицу Google, поскольку содержимое формы изменяется при каждом отображении страницы. Для контекста это часть пользовательской краудсорсинговой платформы. Спасибо за любую помощь!
Комментарии:
1. Перейдите в редактор сценариев Google Sheets> Просмотр> Выполнение.
2. @TheMaster, после перехода к исполнениям я вижу инициализацию doPost и setup, что мне следует искать здесь?
3. Есть ли какие-либо сбои? Когда-
fetch
либо попадал в конечную точку? Вы также сказали, что на консоли нет ошибок. Тогда это регистрировалось'Success!'
?4. Сообщений о сбоях не поступало, но на консоли также нет сообщения об успешном завершении
5. Развернут ли скрипт так, чтобы любой мог получить доступ, включая анонимный?
Ответ №1:
Проблемы:
-
Вы переписываете
window.onload
функцию каждый раз в цикле для каждой формы. Только событие отправки последней формы будет отключеноonload
и отправлено на сервер. -
Когда вы создаете случайный массив чисел, нет гарантии, что он будет уникальным. Если две формы в конечном итоге имеют одинаковое имя, будет предотвращено только событие отправки первой формы.
Решение:
-
Поскольку форма уже добавлена, непосредственно запустите функцию для каждой формы внутри цикла без записи
window.onload
var form = document.forms[form_name] form.addEventListener('submit', e => { e.preventDefault(); fetch(scriptURL, { method: 'POST'.....
-
Сделать
Idx
уникальный:idx = [...new Set(idx)]
Комментарии:
1. Это полезно! Вы заметили что-нибудь странное в моем пересмотренном запросе на выборку? Время от времени происходит сбой выборки. Я не уверен, почему.
2. @Max Попробуйте добавить кнопку отправки в конце второго тега скрипта. Для загрузки скрипта требуется время. Таким образом, кнопка отправки добавляется только после предотвращения по умолчанию.
3. хорошая идея, это сгенерировало менее загадочное сообщение об ошибке и отключило перехват ошибки. Сообщение об ошибке «Ошибка при загрузке: POST ‘ script.google.com/macros/s /… «».
4. Интересно, что сообщение терпит неудачу только в Chrome
5. Я обновлял браузер после того, как пользователь нажимал кнопку отправки, которая в некоторых случаях отключала сообщение. Теперь все работает!
Ответ №2:
Я смог решить проблему, изменив архитектуру страницы. Вместо того, чтобы использовать множество разных форм для каждой задачи классификации, я использовал одну форму, которая была отправлена как единое целое.
Я опубликовал новый код ниже. Не стесняйтесь обращаться за разъяснениями!
<!DOCTYPE html>
<body>
<!-- Required JS packages for this project-->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js">
</script>
<script src="jquery-3.3.1.min.js"></script>
<script src="require.js"></script>
<!--Create empty form element -->
<div id="form_submit1">
<form id="form_submit" , name="submit_to_sheets">
</form>
</div>
<!-- JS function to fill form element with 20 hold type questions forms -->
<script>
// Establish file name to hold mapping with two lists and a dict to link elements
var files = ['1.png', '10.png',...,'99.png']
var numWords = ["one", "two",...,"one_hundred_and_fifty"]
var numWordDict = {
1: 'one',
2: 'two',
...
150: 'one_hundred_and_fifty'
} // Generate list of 20 random digits that will select holds to be classified
// Create array of twenty random holds
var idx = []
for (var j = 0; j < 20; j ) {
idx.push(Math.floor(Math.random() * 140) 0)
}
console.log(idx)
// Loop over array and make a form element for each hold within the div element
$(document).ready(function(list) {
for (var i = 0; i < idx.length; i ) {
// retrieve mapped index
var randHoldIdx = idx[i]
// build path to hold image
var holdPath = files[randHoldIdx]
var numb = holdPath.match(/d/g);
numb = numb.join("");
var colName = numWordDict[numb]
// Form element contents will be appended into the div element with id = form_submit
$("#form_submit").append(
// html form skeleton for users to select jug,pinch, crimp, pocket or undercling from radio button
// options
"<input type='radio' name = " colName " class=" String(colName) " value=1>Jug<br>"
"<input type='radio' name = " colName " class=" String(colName) " value=2>Pinch<br>"
"<input type='radio'name = " colName " class=" String(colName) " value=3>Crimp<br>"
"<input type='radio' name = " colName " class=" String(colName) " value=4>Pocket<br>"
"<input type='radio' name = " colName " class=" String(colName) " value=5>Undercling"
// image of climbing hold in question with coordinates to position on moonboard
"<div><img src=labelled_imgs/" String(holdPath) " alt='selected hold'></div>");
}
// prepend form begining to html outside of for loop
// append end of form to html outside of for loop
});
$("#form_submit").append("<button type='submit'>Submit!</button>");
</script>
<script>
const form = document.forms["submit_to_sheets"]
const scriptURL = 'https://script.google.com/macros/s/AKfycbyhMLuTGNkaNOxeNCOx_t1ERThZT8VEYDcMmiQhj773kIrUuRA/exec'
console.log(form)
console.log("loop")
form.addEventListener('submit', e => {
e.preventDefault()
fetch(scriptURL, {
method: 'POST',
body: new FormData(form)
})
.then(response => console.log('Success!', response))
.catch(error => console.error('Error!', error.message))
})
</script>
</body>
</html>