Похоже, есть много вопросов относительно того, как это сделать, но мне не удалось реализовать ничего, что подходило бы для моего случая.
У меня есть HTML-форма в модальном диалоговом окне Google Таблиц. Эта форма используется для обновления названий вакансий с помощью textFinder
. (Эти названия должностей используются в нескольких электронных таблицах компании и иногда объединяются с другими значениями, например, чтобы связать вместе должности и отдельных лиц.)
Первое поле представляет собой раскрывающийся список для выбора имени задания для обновления. Раскрывающийся список извлекает значения из диапазона в электронной таблице Google. Второе поле представляет собой текстовое поле для ввода нового имени. После отправки формы все экземпляры исходного имени задания заменяются новым именем в нескольких электронных таблицах, включая исходное имя в диапазоне электронных таблиц, который заполняет раскрывающийся список формы.
Все это работает правильно. Я застрял в том, чтобы позволить людям вносить несколько изменений подряд, не закрывая модальное окно (или не заставляя его закрываться автоматически). Раскрывающийся список не обновляется для отображения новых значений. Чего мне действительно хотелось бы добиться, так это сообщения с подтверждением (вместо предупреждения, которое я использую), а затем обновления формы. Я не уверен, как реализовать эту функцию в моем коде. Я знаю, что это можно сделать с помощью функции withSuccesshandler
, но мне не удалось заставить ее работать. Может ли кто-нибудь помочь мне с этим?
Применимый код:
Код.js
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Manager Menu')
.addItem('Update Job Name', 'updateNameModal')
.addToUi();
SpreadsheetApp.getUi();
}
function updateNameModal() {
let spread = SpreadsheetApp.getActiveSpreadsheet();
let sheet = spread.getSheetByName("Sheet2");
let values = sheet.getDataRange().getValues().map( row => row[0] ); // get the name from each row
var html = HtmlService.createTemplateFromFile("updateNameFile");
html.dropdown = values;
SpreadsheetApp.getUi().showModalDialog(html.evaluate(),"Update a Name Globally");
}
Приведенный выше скрипт создает модальное окно и определяет диапазон раскрывающегося списка.
HTML
<!DOCTYPE html>
<html>
<head>
<base target = "_top">
<link
rel = "stylesheet"
href = "https://ssl.gstatic.com/docs/script/css/add-ons1.css"
/>
<style>
.container {
margin: 5px 5px 5px 5px;
}
.input-Dropdown {
width: 290px;
font-size: 12px;
text-align: left;
float: left;
padding: 5px 5px 5px 5px;
}
.input-Text {
width: 290px;
font-size: 12px;
text-align: left;
float: left;
padding: 5px 5px 5px 5px;
}
.custom-heading {
font-weight: bold;
}
</style>
</head>
<body>
<div class = "container">
<form id = "nameForm" onkeydown = "return event.key != 'Enter'">
<!-- Create input fields to accept values from the user -->
Select a name from the list:<br><br>
<select class = "input-Dropdown" id = "Current_Name"/>
<? for(var i=1; i<dropdown.length; i++){ ?>
<option><?= dropdown[i] ?></option>
<?}?>
</select>
<br>
<br>
<br>
Change Name To:<br><br>
<input class = "input-Text" type = "text" id = "Updated_Name"/>
<br>
<br>
<br>
<button class = "action" onclick = "submitNameUpdate();">Update</button>
<button onclick = "google.script.host.close();">Close</button>
</form>
</div>
<script>
function submitNameUpdate() {
var current_name = document.getElementById("Current_Name").value;
var updated_name = document.getElementById("Updated_Name").value;
//Asynchronous
google.script.run.withSuccessHandler(data => {
window.alert("✔️ " +current_name+ " has been changed to " +updated_name+ " across the system.").servercommand();
}).withFailureHandler(er => {
alert(er);
}).updateJobName(current_name, updated_name); // <-- updateJobName function exist on Code.gs, parameters are passed to that function
}
</script>
</body>
</html>
Код.js
function updateJobName(current_name, updated_name) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet2");
let value1 = current_name;
let value2 = updated_name;
sheet.getRange("A2:A").createTextFinder(value1).replaceAllWith(value2);
Приведенный выше скрипт запускается при нажатии кнопки «Обновить» и заменяет значения в раскрывающемся списке.
Дайте мне знать, если потребуется дополнительная информация. Спасибо.
Сделали это сейчас.
Спасибо за ответ. Ваша функция updateJobName
— это ваш настоящий сценарий?
Минуточку. Позвольте мне посмотреть, чего мне не хватает.
При нажатии кнопки submitNameUpdate
фиксирует значения. updateJobName
затем завершает процесс, заменяя значения в A2:A на Лист2. У меня есть и другие скрипты, которые тоже используют эти значения, но они являются дополнительными и совершенно не влияют на функционал.
Спасибо за ответ. Судя по вашему ответу, я предложил в качестве ответа пункты модификации. Пожалуйста, подтвердите это. Если я неправильно понял ваш ожидаемый результат, прошу прощения.
Я считаю, что ваша цель состоит в следующем.
Является ли ваша функция updateJobName
вашим текущим сценарием? В вашем показе Javascript кажется, что updateJobName
возвращает data
. Но в вашем скрипте Google Apps updateJobName
не возвращает никакого значения. Я думаю, что для этого необходимо вернуть обновленные значения.
Когда эти моменты будут отражены в вашем сценарии, как насчет следующей модификации?
Во-первых, для достижения вашего запроса The alert looks unprofessional. A modal on top of the modal?
в качестве простого метода используется jquery. Итак, добавьте следующие 3 строки.
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<link rel = "stylesheet" href = "https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/themes/smoothness/jquery-ui.css">
<script src = "https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js"></script>
И чтобы отобразить What I would really like to achieve is a confirmation message (instead of the alert that I am using)...
, добавьте следующий тег в HTML.
<div class = "dialog" style = "display: none;">What I would really like to achieve is a confirmation message (instead of the alert that I am using)...</div>
А также измените submitNameUpdate
следующим образом.
google.script.run.withSuccessHandler(data => {
window.alert("✔️ " +current_name+ " has been changed to " +updated_name+ " across the system.").servercommand();
}).withFailureHandler(er => {
alert(er);
}).updateJobName(current_name, updated_name);
$(".dialog").dialog({
modal: true,
title: "sample title",
buttons: {
Ok: function () {
google.script.run.withSuccessHandler(data => {
var select = document.getElementById("Current_Name");
select.innerHTML = "";
data.forEach(e => {
var option = document.createElement("option");
option.text = e;
option.value = e;
select.appendChild(option);
});
document.getElementById("Updated_Name").value = "";
window.alert("✔️ " + current_name + " has been changed to " + updated_name + " across the system.").servercommand();
}).withFailureHandler(er => {
alert(er);
}).updateJobName(current_name, updated_name);
$(this).dialog("close");
}
}
});
Пожалуйста, измените updateJobName
следующим образом.
function updateJobName(current_name, updated_name) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet2");
let value1 = current_name;
let value2 = updated_name;
sheet.getRange("A2:A").createTextFinder(value1).replaceAllWith(value2);
return sheet.getRange("A2:A" + sheet.getLastRow()).getValues().map(row => row[0]);
}
С учетом вышеуказанных изменений при нажатии кнопки «Обновить» раскрывающийся список обновляется новыми значениями.
Я отразил следующий ответ в приведенной выше модификации:
Таким образом, часть обновления работает, за одним исключением. Мой исходный раскрывающийся диапазон — A2:A на Листе2. После отправки формы в раскрывающихся списках отображается A1:A с листа 2.
Кроме того, я надеялся, что форма отобразит подтверждающее сообщение:
What I would really like to achieve is a confirmation message (instead of the alert that I am using)...
затем обновите форму. Предупреждение выглядит непрофессионально. Модальное окно поверх модального?
По поводу следующего ответа
Что касается добавления строк на сторону Javascript, где именно следует добавить эти строки?
Измененный весь HTML выглядит следующим образом.
<!DOCTYPE html>
<html>
<head>
<base target = "_top">
<link rel = "stylesheet" href = "https://ssl.gstatic.com/docs/script/css/add-ons1.css" />
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<link rel = "stylesheet" href = "https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/themes/smoothness/jquery-ui.css">
<script src = "https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js"></script>
<style>
.container {
margin: 5px 5px 5px 5px;
}
.input-Dropdown {
width: 290px;
font-size: 12px;
text-align: left;
float: left;
padding: 5px 5px 5px 5px;
}
.input-Text {
width: 290px;
font-size: 12px;
text-align: left;
float: left;
padding: 5px 5px 5px 5px;
}
.custom-heading {
font-weight: bold;
}
</style>
</head>
<body>
<div class = "container">
<form id = "nameForm" onkeydown = "return event.key != 'Enter'">
<!-- Create input fields to accept values from the user -->
Select a name from the list:<br><br>
<select class = "input-Dropdown" id = "Current_Name"/>
<? for(var i=1; i<dropdown.length; i++){ ?>
<option>
<?= dropdown[i] ?>
</option>
<?}?>
</select>
<br>
<br>
<br>
Change Name To:<br><br>
<input class = "input-Text" type = "text" id = "Updated_Name"/>
<br>
<br>
<br>
<button class = "action" onclick = "submitNameUpdate();">Update</button>
<button onclick = "google.script.host.close();">Close</button>
</form>
</div>
<div class = "dialog" style = "display: none;">What I would really like to achieve is a confirmation message (instead of the alert that I am using)...</div>
<script>
function submitNameUpdate() {
var current_name = document.getElementById("Current_Name").value;
var updated_name = document.getElementById("Updated_Name").value;
$(".dialog").dialog({
modal: true,
title: "sample title",
buttons: {
Ok: function () {
google.script.run.withSuccessHandler(data => {
var select = document.getElementById("Current_Name");
select.innerHTML = "";
data.forEach(e => {
var option = document.createElement("option");
option.text = e;
option.value = e;
select.appendChild(option);
});
document.getElementById("Updated_Name").value = "";
window.alert("✔️ " + current_name + " has been changed to " + updated_name + " across the system.").servercommand();
}).withFailureHandler(er => {
alert(er);
}).updateJobName(current_name, updated_name);
$(this).dialog("close");
}
}
});
}
</script>
</body>
</html>
Таким образом, часть обновления работает, за одним исключением. Мой исходный раскрывающийся диапазон — A2:A на Листе2. После отправки формы в раскрывающихся списках отображается A1:A с листа 2.
Кроме того, я надеялся, что форма отобразит подтверждающее сообщение: What I would really like to achieve is a confirmation message (instead of the alert that I am using)...
затем обновите форму. Предупреждение выглядит непрофессионально. Модальное окно поверх модального?
@Codedabbler Спасибо за ответ. По поводу ваших дополнительных двух запросов я обновил свой ответ. Пожалуйста, подтвердите это. Пожалуйста, измените сообщение с подтверждением в соответствии с вашей реальной ситуацией.
Что касается добавления строк на сторону Javascript, где именно следует добавить эти строки?
@Codedabbler Спасибо за ответ. Что касается Regarding adding lines to Javascript side, where exactly should those lines be added?
, я добавил весь измененный HTML. Пожалуйста, подтвердите это.
Да. Это работает отлично, за исключением проблемы, которая у меня была в первом комментарии. So the refresh part works with one exception. My original dropdown range is A2:A on Sheet2. After form is submitted, dropdown values display A1:A from Sheet 2.
В раскрывающемся списке теперь отображается A1:A. Раньше отображалось A2:A. (У меня есть заголовок в формате A1 на Листе2).
Так близко... ты посмотришь мой последний комментарий, когда у тебя будет возможность?
@Codedabbler Спасибо за ответ. Насчет Dropdown now displays A1:A. Previously it displayed A2:A. (I have a header in A1 on Sheet2).
я уже изменил свой ответ. Пожалуйста, подтвердите последнюю строку updateJobName
. Я уже изменился на return sheet.getRange("A2:A" + sheet.getLastRow()).getValues().map(row => row[0]);
. Пожалуйста, подтвердите это еще раз. Если вы не можете этого понять, пожалуйста, скажите мне. Тогда, пожалуйста, предоставьте весь сценарий.
Теперь все работает так, как хотелось. Спасибо за все что ты сделал для меня.
Можете ли вы предоставить весь сценарий?