У меня проблема с отображением моей HTML-формы после включения некоторых ajax-скриптов, предоставленных другими.
Я использую свой Google Sheet в качестве базы данных и использую HTML-форму для отображения информации, основанной на электронной почте пользователя сеанса. Пользователь может просматривать информацию и вносить любые изменения в форму. После отправки формы изменения будут внесены в Google Sheet.
Мне удалось заполнить HTML-форму с информацией о пользователе, код, который я использовал ниже:
GoogleScript
function doGet() {
var html = HtmlService.createTemplateFromFile('index').evaluate().setTitle('Web App').setSandboxMode(HtmlService.SandboxMode.NATIVE);
return html;
}
function getDirectory() {
var ss = SpreadsheetApp.getActiveSheet();
var directory = ObjApp.rangeToObjectsNoCamel(ss.getDataRange().getValues());
return directory;
}
function getCurrentUser() {
var userEmail = Session.getActiveUser().getEmail();
return userEmail;
}
HTML
<!DOCTYPE html>
<html>
<form id="directory-form">
<? var data = getDirectory(); ?>
<? var email = getCurrentUser(); ?>
<h1>
Update Your Experience
</h1>
<h3>
Your Email: <?= email ?>
</h3>
<? for (var i=0; i< data.length; i++) { ?>
<? if (email == data[i].emailAddress) { ?>
Name:
<input id="name" type="text" name="name" value="<?= data[i].name ?>" required>
<br>
<br>
Line of Service:
<select id="service" name="service">
<? if (data[i].service == "Mechanic") { ?> <option selected="selected" value="Mechanic">Mechanic</option> <? }else { ?> <option value="Mechanic">Mechanic</option> <? } ?>
<? if (data[i].service == "Aero") { ?> <option selected="selected" value="Aero">Aero</option> <? }else { ?> <option value="Aero">Aero</option> <? } ?>
<? if (data[i].service == "Marine") { ?> <option selected="selected" value="Marine">Marine</option> <? }else { ?> <option value="Marine">Marine</option> <? } ?>
</select>
<br>
<br>
Market:
<select id="market" name="market">
<? if (data[i].market == "Bay Area and Northwest") { ?> <option selected="selected" value="Bay Area and Northwest">Bay Area and Northwest</option> <? }else { ?> <option value="Bay Area and Northwest">Bay Area and Northwest</option> <? } ?>
<? if (data[i].market == "Central") { ?> <option selected="selected" value="Central">Central</option> <? }else { ?> <option value="Central">Central</option> <? } ?>
<? if (data[i].market == "Greater Texas") { ?> <option selected="selected" value="Greater Texas">Greater Texas</option> <? }else { ?> <option value="Greater Texas">Greater Texas</option> <? } ?>
<br>
<br>
Office:
<select id="office" name="office">
<? if (data[i].office == "Los Angeles") { ?> <option selected="selected" value="Los Angeles">Los Angeles</option> <? }else { ?> <option value="Los Angeles">Los Angeles</option> <? } ?>
<? if (data[i].office == "Louisville") { ?> <option selected="selected" value="Louisville">Louisville</option> <? }else { ?> <option value="Louisville">Louisville</option> <? } ?>
<? if (data[i].office == "McLean") { ?> <option selected="selected" value="McLean">McLean</option> <? }else { ?> <option value="McLean">McLean</option> <? } ?>
</select>
<br>
<br>
Sailor:
<? if (data[i].sailor == "Yes") { ?> <label for="sailor"><input id="sailor" type="radio" name="sailor" value="Yes" checked>Yes</label><label for="sailor"><input id="sailor" type="radio" name="sailor" value="No" >No</label>
<? }else { ?> <label for="sailor"><input id="sailor" type="radio" name="sailor" value="Yes" >Yes</label><label for="sailor"><input id="sailor" type="radio" name="sailor" value="No" checked>No</label> <? } ?>
<br>
<br>
Crew Man:
<? if (data[i].crewMan == "Yes") { ?> <label for="crewMan"><input id="crewMan" type="radio" name="crewMan" value="Yes" checked>Yes</label><label for="crewMan"><input id="crewMan" type="radio" name="crewMan" value="No">No</label>
<? }else { ?> <label for="crewMan"><input id="crewMan" type="radio" name="crewMan" value="Yes">Yes</label><label for="crewMan"><input id="crewMan" type="radio" name="crewMan" value="No" checked>No</label> <? } ?>
<br>
<br>
Instructor:
<? if (data[i].instructor == "Yes") { ?> <label for="instructor"><input id="instructor" type="radio" name="instructor" value="Yes" checked>Yes</label><label for="instructor"><input id="instructor" type="radio" name="instructor" value="No">No</label>
<? }else { ?> <label for="instructor"><input id="instructor" type="radio" name="instructor" value="Yes">Yes</label><label for="instructor"><input id="instructor" type="radio" name="instructor" value="No" checked>No</label> <? } ?>
<br>
<br>
Basic Training:
<? if (data[i].training == "Yes") { ?> <label for="training"><input id="training" type="radio" name="training" value="Yes" checked>Yes</label><label for="training"><input id="training" type="radio" name="training" value="No">No</label>
<? }else { ?> <label for="training"><input id="training" type="radio" name="training" value="Yes">Yes</label><label for="training"><input id="training" type="radio" name="training" value="No" checked>No</label> <? } ?>
<br>
<br>
Advanced Training:
<? if (data[i].advanced == "Yes") { ?> <label for="advanced"><input id="advanced" type="radio" name="advanced" value="Yes" checked>Yes</label><label for="advanced"><input id="advanced" type="radio" name="advanced" value="No">No</label>
<? }else { ?> <label for="advanced"><input id="advanced" type="radio" name="advanced" value="Yes">Yes</label><label for="advanced"><input id="advanced" type="radio" name="advanced" value="No" checked>No</label> <? } ?>
<br>
<br>
<?}else{
}
} ?>
<button type="submit" id="submit-form">Update</button>
</form>
После этого я захотел добавить функциональность для отправки данных формы обратно в Google Sheet, поэтому я использовал код, предоставленный по этой ссылке:
https://medium.com/@dmccoy/how-to-submit-an-html-form-to-google-sheets-without-google-forms-b833952cc175
Поскольку этот код использует собственную функцию doGet (), я удалил свой собственный doGet (), который рендерил HTML-страницу.
Вот код после реализации скрипта с сайта Medium:
/* function doGet() {
var html = HtmlService.createTemplateFromFile('index').evaluate().setTitle('Web App').setSandboxMode(HtmlService.SandboxMode.NATIVE);
return html;
} */
function getDirectory() {
var ss = SpreadsheetApp.getActiveSheet();
var directory = ObjApp.rangeToObjectsNoCamel(ss.getDataRange().getValues());
return directory;
}
function getCurrentUser() {
var userEmail = Session.getActiveUser().getEmail();
return userEmail;
}
// original from: http://mashe.hawksey.info/2014/07/google-sheets-as-a-database-insert-with-apps-script-using-postget-methods-with-ajax-example/
// original gist: https://gist.github.com/willpatera/ee41ae374d3c9839c2d6
function doGet(e){
return handleResponse(e);
}
// Enter sheet name where data is to be written below
var SHEET_NAME = "directory";
var SCRIPT_PROP = PropertiesService.getScriptProperties(); // new property service
function handleResponse(e) {
// shortly after my original solution Google announced the LockService[1]
// this prevents concurrent access overwritting data
// [1] http://googleappsdeveloper.blogspot.co.uk/2011/10/concurrency-and-google-apps-script.html
// we want a public lock, one that locks for all invocations
var lock = LockService.getPublicLock();
lock.waitLock(30000); // wait 30 seconds before conceding defeat.
try {
// next set where we write the data - you could write to multiple/alternate destinations
var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
var sheet = doc.getSheetByName(SHEET_NAME);
// we'll assume header is in row 1 but you can override with header_row in GET/POST data
var headRow = e.parameter.header_row || 1;
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var nextRow = sheet.getLastRow()+1; // get next row
var row = [];
// loop through the header columns
for (i in headers){
if (headers[i] == "Timestamp"){ // special case if you include a 'Timestamp' column
row.push(new Date());
} else { // else use header name to get data
row.push(e.parameter[headers[i]]);
}
}
// more efficient to set values as [][] array than individually
sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
// return json success results
return ContentService
.createTextOutput(JSON.stringify({"result":"success", "row": nextRow}))
.setMimeType(ContentService.MimeType.JSON);
} catch(e){
// if error return this
return ContentService
.createTextOutput(JSON.stringify({"result":"error", "error": e}))
.setMimeType(ContentService.MimeType.JSON);
} finally { //release lock
lock.releaseLock();
}
}
function setup() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
SCRIPT_PROP.setProperty("key", doc.getId());
}
Вот HTML с ajax:
<!DOCTYPE html>
<html>
<form id="directory-form">
<? var data = getDirectory(); ?>
<? var email = getCurrentUser(); ?>
<h1>
Update Your Experience
</h1>
<h3>
Your Email: <?= email ?>
</h3>
<? for (var i=0; i< data.length; i++) { ?>
<? if (email == data[i].emailAddress) { ?>
Name:
<input id="name" type="text" name="name" value="<?= data[i].name ?>" required>
<br>
<br>
Line of Service:
<select id="service" name="service">
<? if (data[i].service == "Mechanic") { ?> <option selected="selected" value="Mechanic">Mechanic</option> <? }else { ?> <option value="Mechanic">Mechanic</option> <? } ?>
<? if (data[i].service == "Aero") { ?> <option selected="selected" value="Aero">Aero</option> <? }else { ?> <option value="Aero">Aero</option> <? } ?>
<? if (data[i].service == "Marine") { ?> <option selected="selected" value="Marine">Marine</option> <? }else { ?> <option value="Marine">Marine</option> <? } ?>
</select>
<br>
<br>
Market:
<select id="market" name="market">
<? if (data[i].market == "Bay Area and Northwest") { ?> <option selected="selected" value="Bay Area and Northwest">Bay Area and Northwest</option> <? }else { ?> <option value="Bay Area and Northwest">Bay Area and Northwest</option> <? } ?>
<? if (data[i].market == "Central") { ?> <option selected="selected" value="Central">Central</option> <? }else { ?> <option value="Central">Central</option> <? } ?>
<? if (data[i].market == "Greater Texas") { ?> <option selected="selected" value="Greater Texas">Greater Texas</option> <? }else { ?> <option value="Greater Texas">Greater Texas</option> <? } ?>
<br>
<br>
Office:
<select id="office" name="office">
<? if (data[i].office == "Los Angeles") { ?> <option selected="selected" value="Los Angeles">Los Angeles</option> <? }else { ?> <option value="Los Angeles">Los Angeles</option> <? } ?>
<? if (data[i].office == "Louisville") { ?> <option selected="selected" value="Louisville">Louisville</option> <? }else { ?> <option value="Louisville">Louisville</option> <? } ?>
<? if (data[i].office == "McLean") { ?> <option selected="selected" value="McLean">McLean</option> <? }else { ?> <option value="McLean">McLean</option> <? } ?>
</select>
<br>
<br>
Sailor:
<? if (data[i].sailor == "Yes") { ?> <label for="sailor"><input id="sailor" type="radio" name="sailor" value="Yes" checked>Yes</label><label for="sailor"><input id="sailor" type="radio" name="sailor" value="No" >No</label>
<? }else { ?> <label for="sailor"><input id="sailor" type="radio" name="sailor" value="Yes" >Yes</label><label for="sailor"><input id="sailor" type="radio" name="sailor" value="No" checked>No</label> <? } ?>
<br>
<br>
Crew Man:
<? if (data[i].crewMan == "Yes") { ?> <label for="crewMan"><input id="crewMan" type="radio" name="crewMan" value="Yes" checked>Yes</label><label for="crewMan"><input id="crewMan" type="radio" name="crewMan" value="No">No</label>
<? }else { ?> <label for="crewMan"><input id="crewMan" type="radio" name="crewMan" value="Yes">Yes</label><label for="crewMan"><input id="crewMan" type="radio" name="crewMan" value="No" checked>No</label> <? } ?>
<br>
<br>
Instructor:
<? if (data[i].instructor == "Yes") { ?> <label for="instructor"><input id="instructor" type="radio" name="instructor" value="Yes" checked>Yes</label><label for="instructor"><input id="instructor" type="radio" name="instructor" value="No">No</label>
<? }else { ?> <label for="instructor"><input id="instructor" type="radio" name="instructor" value="Yes">Yes</label><label for="instructor"><input id="instructor" type="radio" name="instructor" value="No" checked>No</label> <? } ?>
<br>
<br>
Basic Training:
<? if (data[i].training == "Yes") { ?> <label for="training"><input id="training" type="radio" name="training" value="Yes" checked>Yes</label><label for="training"><input id="training" type="radio" name="training" value="No">No</label>
<? }else { ?> <label for="training"><input id="training" type="radio" name="training" value="Yes">Yes</label><label for="training"><input id="training" type="radio" name="training" value="No" checked>No</label> <? } ?>
<br>
<br>
Advanced Training:
<? if (data[i].advanced == "Yes") { ?> <label for="advanced"><input id="advanced" type="radio" name="advanced" value="Yes" checked>Yes</label><label for="advanced"><input id="advanced" type="radio" name="advanced" value="No">No</label>
<? }else { ?> <label for="advanced"><input id="advanced" type="radio" name="advanced" value="Yes">Yes</label><label for="advanced"><input id="advanced" type="radio" name="advanced" value="No" checked>No</label> <? } ?>
<br>
<br>
<?}else{
}
} ?>
<button type="submit" id="submit-form">Update</button>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js">
var $form = $('form#directory-form'),
url = 'https://script.google.com/macros/s/myAPPURL'
$('#submit-form').on('click', function(e) {
e.preventDefault();
var jqxhr = $.ajax({
url: url,
method: "GET",
dataType: "json",
data: $form.serializeObject()
}).success(
// do something
);
})
</html>
Когда я запускаю приложение, оно не отображает HTML-форму. Идет прямо на страницу с текстом:
{"result":"success","row":190}
Строка - это следующая пустая строка в моем Листе Google, которая заставляет меня думать, что все будет работать правильно, если будет отображаться только форма.
Приложение настроено на выполнение от имени пользователя (а не от меня), поскольку мне нужен адрес электронной почты пользователя для поиска информации в Google Sheet. Он также доступен для всех в моей организации. Там нет выбора ни для кого, даже анонимного.
Любая помощь очень ценится!