[英]onClick event for Google Forms Submit button
This is driving me crazy, I have a simple Google Form that accepts subscriber code and their slot timings.这让我发疯了,我有一个简单的谷歌表单,它接受订阅者代码和他们的时间安排。 My purpose is to get data via Google Forms and save it to Google Sheets without having any clashes in the slots timings .我的目的是通过 Google Forms 获取数据并将其保存到 Google Sheets 中,而不会在插槽时间上发生任何冲突。
To show you an example, I am attaching an image of my form and sheet.为了向您展示一个示例,我附上了我的表单和工作表的图像。 After the first entry was done, if another slot is to be given to same subscriber, we need to ensure that the slot timings do not clash with the saved timings in google sheet that is assigned to the same subscriber.第一次输入完成后,如果要为同一订阅者分配另一个时隙,我们需要确保时隙时间不会与分配给同一订阅者的谷歌表中保存的时间冲突。 If you see the second entry, it just accepts it and for this we need a validation check which is not available.如果你看到第二个条目,它只是接受它,为此我们需要一个不可用的验证检查。 My question is, is it even possible to have an onClick validation on the submit button?我的问题是,是否可以在提交按钮上进行 onClick 验证? I have been searching for it on google like crazy but haven't got a solution.我一直在谷歌上疯狂地搜索它,但没有找到解决方案。 If this is not possible to do it in Google forms, what are my alternatives or is there any workaround available?如果在 Google 表单中无法做到这一点,我的替代方法是什么,或者是否有任何可用的解决方法?
Eagerly awaiting responses for my query.急切地等待对我的查询的答复。 Thank you.谢谢你。
Another idea you can try on your current setup is that you could use an onFormSubmit
trigger.您可以在当前设置中尝试的另一个想法是您可以使用onFormSubmit
触发器。 And once the response is submitted, it is compared to the previous rows that were added to the sheet to check if there have been any conflict with your data.提交响应后,会将其与添加到工作表中的前几行进行比较,以检查是否与您的数据有任何冲突。
Upon confirming there is, just remove the last response.确认存在后,只需删除最后一个响应。 If no conflict, then let it be and end the script there.如果没有冲突,那就让它存在并在那里结束脚本。
function checkConflict(e) {
var sheet = e.range.getSheet();
var lastRow = sheet.getLastRow();
// exclude the last submitted response
var timeSlots = sheet.getRange(2, 3, lastRow - 2, 2).getValues();
var lastResponse = e.values;
var lastStart = new Date(lastResponse[2]).getTime();
var lastEnd = new Date(lastResponse[3]).getTime();
// convert timeslots to comparable data type
timeSlots = timeSlots.map(timeSlot => [timeSlot[0].getTime(), timeSlot[1].getTime()]);
// get conflicts
var conflict = timeSlots.filter(timeSlot => (timeSlot[0] <= lastStart && timeSlot[1] >= lastStart) ||
(timeSlot[0] <= lastEnd && timeSlot[1] >= lastEnd));
// remove lastRow if conflict is 1
if(conflict.length) {
sheet.deleteRow(lastRow);
MailApp.sendEmail(lastResponse[4],
"Time Slot conflict",
"Your recent response was removed due to a conflict. Your submitted time slot is the following:\n" +
"From: " + new Date(lastStart) + "\n" +
"To: " + new Date(lastEnd));
}
else {
MailApp.sendEmail(lastResponse[4],
"Time Slot confirmed",
"Your time slot is now confirmed. Confirmed time slot is the following:\n " +
"From: " + new Date(lastStart) + "\n" +
"To: " + new Date(lastEnd));
}
}
9:01-10:00
, 8:31-9:30
) or the ending slots has 59/29 minutes (eg 9:00-9:59
, 8:30-9:29
).您可以做的是选择开始时间为 1/31 分钟(例如9:01-10:00
、 8:31-9:30
)或结束时间为 59/29 分钟(例如9:00-9:59
, 8:30-9:29
)。As @Cooper pointed out, it seems best that you create your own web app.正如@Cooper 指出的那样,您最好创建自己的网络应用程序。
After a few hours of work I've made a web app that will work for you using Google Apps Script.经过几个小时的工作,我制作了一个可以使用 Google Apps Script 为您工作的网络应用程序。 Here are the spreadsheet and script file. 这是电子表格和脚本文件。
Server Side Codes:服务器端代码:
var ss = SpreadsheetApp.getActiveSheet()
function doGet() {
return HtmlService.createTemplateFromFile('form').evaluate()
}
function submitData (data) {
ss.appendRow([new Date(),data.ssCode, new Date(data.startDateTime), new Date(data.endDateTime)])
}
function isAvailible (start, end) {
var data = ss.getDataRange().getValues()
var isAvailible = true;
var message = '';
data.forEach(row => {
if(start > row[2].valueOf() && start < row[3].valueOf() || end > row[2].valueOf() && end < row[3].valueOf()) {
isAvailible = false;
message = new Date(row[2].valueOf()) +'<br> to ' + new Date(row[3].valueOf()) + '<br> isn\'t availible.'
}
})
var response = {status: isAvailible, message: message}
return response;
}
Client Side Codes:客户端代码:
M.FormSelect.init(document.querySelectorAll('select')); var dps = document.querySelectorAll('.datepicker'); var dpsInstances = M.Datepicker.init(dps, { showClearBtn: true, autoClose: true }); dpsInstances[0].options.onSelect = function(day) { dpsInstances[1].setDate(day); endDate.value = dpsInstances[1].toString() M.updateTextFields(); } var tps = document.querySelectorAll('.timepicker'); var tpsInstances = M.Timepicker.init(tps, { twelveHour: false, showClearBtn: true, autoClose: true }); function formSubmit(data) { var startDate = new Date(data.startDate.value); var startTime = data.startTime.value.split(':'); startDate.setHours(startTime[0]); startDate.setMinutes(startTime[1]); var endDate = new Date(data.endDate.value); var endTime = data.endTime.value.split(':') endDate.setHours(endTime[0]); endDate.setMinutes(endTime[1]); if (startDate.valueOf() >= endDate.valueOf()) { M.toast({html: 'End date should be greater then start date.'}) return; } var dataToSubmit = { ssCode: data.ssCode.value, startDateTime: startDate.valueOf(), endDateTime: endDate.valueOf() } google.script.run.withSuccessHandler(function(response) { if (response.status) { google.script.run.withSuccessHandler(function() { myForm.reset() M.toast({ html: "Successful" }) }).submitData(dataToSubmit) } else { M.toast({ html: response.message }) } }).isAvailible(dataToSubmit.startDateTime, dataToSubmit.endDateTime) }
body { background: rgb(244, 235, 234) } .outer-field { border-radius: 15px; background: white; height: 150px; margin: 10px; padding: 20px; } .title { padding-left: 2%; font-weight: bold; }
<html> <head> <base target="_top"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> </head> <body> <div class="row"> <div class="col s10 offset-s1 l4 offset-l4"> <div class="outer-field" style="height: 100px"> <h4>Slot Timings</h4> </div> <form id="myForm" onsubmit="event.preventDefault(); formSubmit(this) "> <div class="outer-field"> <div class="title">Subscriber Code</div> <div class="input-field col s6 l6"> <select form="myForm" name="ssCode" required> <option value="001">001</option> <option value="002">002</option> <option value="003">003</option> </select> </div> </div> <div class="outer-field"> <div class="title">From</div> <div class="col s6 l6"> <div class="input-field"> <input type="text" id="startDate" name="startDate" class="datepicker validate" form="myForm" required> <label for="startDate">Date</label> </div> </div> <div class="col s6 l6"> <div class="input-field"> <input type="text" id="startTime" name="startTime" class="timepicker validate" form="myForm" required> <label for="startTime">Time</label> </div> </div> </div> <div class="outer-field"> <div class="title">To</div> <div class="col s6 l6"> <div class="input-field"> <input type="text" id="endDate" name="endDate" class="datepicker" form="myForm" required> <label for="endDate">Date</label> </div> </div> <div class="col s6 l6"> <div class="input-field"> <input type="text" id="endTime" name="endTime" class="timepicker" form="myForm" required> <label for="endTime">Time</label> </div> </div> </div> <button class="btn waves-effect waves-light" type="submit" name="action" style="margin-left: 3%" >Submit <i class="material-icons right">send</i> </button> </form> </div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script> </body> </html>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.