I have created a modal dialog in my google sheet where you can see the data obtained from the sheet. This modal is only to read the data of the sheet in an orderly way and more aesthetically pleasing to the eye than with the cells of the sheet of google sheets.
The modal works fine but I have 1 question and it is the following:
There are several functions in my coge.gs to obtain the data from my google sheet. At the same time, I have to call these functions in my html file with google.script.run.withSuccessHandler
to be able to get the data in my template.
Is there any way to simplify the process of function calls in a single google.script.run.withSuccessHandler
?
This is my code html:
google.script.run.withSuccessHandler(function (value) {document.getElementById('nombreclientePE').textContent = value;} ).clientePedidoPE();
google.script.run.withSuccessHandler(function (value) {document.getElementById('numeropedidoPE').textContent = value;} ).numeroPedidoPE();
google.script.run.withSuccessHandler(function (value) {document.getElementById('fechapedidoPE').textContent = value;} ).fechaPedidoPE();
google.script.run.withSuccessHandler(function (value) {document.getElementById('estadopedidoPE').textContent = value;} ).estadoPedidoPE();
google.script.run.withSuccessHandler(function (value) {document.getElementById('logometodopagopedidoPE').src = value;} ).logoMetodoPagoPE();
google.script.run.withSuccessHandler(function (value) {document.getElementById('metodopagopedidoPE').textContent = value;} ).metodoPagoPE();
google.script.run.withSuccessHandler(function (value) {document.getElementById('gastosenviopedidoPE').textContent = value;} ).gastosEnvioPE();
google.script.run.withSuccessHandler(function (value) {document.getElementById('metodoenviopedidoPE').textContent = value;} ).metodoEnvioPE();
google.script.run.withSuccessHandler(function (value) {document.getElementById('subtotalpedidoPE').textContent = value;} ).subtotalPedidoPE();
google.script.run.withSuccessHandler(function (value) {document.getElementById('decuentocantidad%pedidoPE').textContent = value;} ).descuentoCantidadPorcentajePedidoPE();
google.script.run.withSuccessHandler(function (value) {document.getElementById('decuentocantidad€pedidoPE').textContent = value;} ).descuentoCantidadEurosPedidoPE();
google.script.run.withSuccessHandler(function (value) {document.getElementById('decuentototalpedidoPE').textContent = value;} ).descuentoTotalPedidoPE();
google.script.run.withSuccessHandler(function (value) {document.getElementById('totalpedidoPE').textContent = value;} ).totalPedidoPE();
google.script.run.withSuccessHandler(function (value) {document.getElementById('direccionpedidoPE').textContent = value;} ).direccionEnvioPE();
Link to a google sheet document with the live demo. To open the modal window, the active cell must be positioned in any cell of any customer row. Then, click on the "View order" button.
Code.gs
const o = {
'nombreclientePE': () => clientePedidoPE(),
'numeropedidoPE': () => numeroPedidoPE(),
'fechapedidoPE': () => fechaPedidoPE(),
'estadopedidoPE': () => estadoPedidoPE(),
'logometodopagopedidoPE': () => logoMetodoPagoPE(),
'metodopagopedidoPE': () => metodoPagoPE(),
'gastosenviopedidoPE': () => gastosEnvioPE(),
'metodoenviopedidoPE': () => metodoEnvioPE(),
'subtotalpedidoPE': () => subtotalPedidoPE(),
'decuentocantidad%pedidoPE': () => descuentoCantidadPorcentajePedidoPE(),
'decuentocantidad€pedidoPE': () => descuentoCantidadEurosPedidoPE(),
'decuentototalpedidoPE': () => descuentoTotalPedidoPE(),
'totalpedidoPE': () => totalPedidoPE(),
'direccionpedidoPE': () => direccionEnvioPE()
};
function PE(input) {
const output = [];
for (const id of input) {
const value = o[id]();
output.push([id, value]);
}
return output;
}
function formVerPedido2(numPedido) {
var hoja = SpreadsheetApp.getActiveSheet();
var fila = hoja.getCurrentCell().getRow();
var numPedido = hoja.getRange(fila,3,1,1).getValue();
var template = HtmlService.createTemplateFromFile('PedidosIndex');
template.input = Object.keys(o);
var pedidoContendido = template.evaluate()
.setWidth(800)
.setHeight(1300);
//var logoMetodoPago = logoMetodoPagoPE();
//htmlOutput = logoMetodoPago;
SpreadsheetApp.getUi().showModalDialog(pedidoContendido, 'Pedido #' + numPedido + '');
}
index.html
<script>const input = <?!= JSON.stringify(input) ?>;</script>
<?!= include('PedidosJavaScript'); ?> <!-- See PedidosJavaScript.html file -->
js.html
google.script.run.withSuccessHandler(onSuccess).PE(input);
function onSuccess(output) {
for (const [id, value] of output) {
document.getElementById(id).textContent = value;
}
}
If informations are coming from a form : code html
function formSubmit() {
var data = document.forms[0]
var tab = []
for (var i=0;i<data.length;i++){
if (data[i].type != "button"){
tab.push(data[i].value)
}
}
google.script.run.addData(tab);
document.forms[0].reset()
}
code gs
function addData(tab) {
mySheet.getRange(getLastDataRow(bdd) + 1,1,1,tab.length).setValues([tab])
}
What I suggest is : replace all the functions as numeroPedidoPE(), fechaPedidoPE() ... by only one (assuming that data are in the same row)
function transferPedidoData() {
var hoja = SpreadsheetApp.getActiveSheet();
var fila = hoja.getCurrentCell().getRow();
var pedidoData = hoja.getRange('B'+fila+':S'+fila).getValues();
return pedidoData;
}
then, in the html file, add this script
<script>
<?
var pedido = transferPedidoData();
?>
</script>
and finally, call for the different data in your PedidosHTML.html file as following, x as needed
<?= pedido[0][x] ?>
function direccionEnvioPE()
as is, add in html var direccionEnvio = direccionEnvioPE();
and use addresses as following <?= direccionEnvio ?>
This definitely needs to be simplified. On the client side you need something like this:
function gscriptRun(fnName) {
google.script.run
.withSuccessHandler(function (value) {
document.getElementById(fnName).textContent = value;
})
.runFunc(fnName);
}
const fnsToRun = ['clientePedidoPE', 'numeroPedidoPE'];
fnsToRun.forEach(fn => gscriptRun(fn));
We wrapping all google.script.run
calls in a function. Then we create an array of function names we want to call on the server side and call them all with Array.prototype.forEach()
.
On the server side you need to have this function:
function runFunc(fnName) {
return globalThis[fnName]();
}
It will just execute the functions by their names.
However, this doesn't look like a great approach as there are so many API calls. You probably want to re-write your code so that you can extract all data with just one call.
You could follow this type of structure if you want to grab the values from various locations in a spreadsheet. Personally I would put them right next to each other in a row and use getValues() instead of getting each value separately.
gs:
function getMyData(tA) {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");
const rgObj = {'nombreclientePE':'A1','numeropedidoPE':'A2','fechapedidoPE':'A3','estadopedidoPE':'A4','logometodopagopedidoPE':'A5','metodopagopedidoPE':'A6','gastosenviopedidoPE':'A7','metodoenviopedidoPE':'A8','subtotalpedidoPE':'A9','decuentocantidad%pedidoPE':'A10','decuentocantidad€pedidoPE':'A11','decuentototalpedidoPE':'A12','totalpedidoPE':'A13','direccionpedidoPE':'A14'}
let obj = {pA:[]}
tA.forEach(p => {
obj.pA.push(p);
obj[p] = sh.getRange(rgObj[p]).getValue();
});
return obj;
}
html:
<!DOCTYPE html>
<html>
<head>
<title>My Title</title>
</head>
<body>
<!-- You provide the body -->
<script>
window.onload = getData()
function getData() {
const tA = ['nombreclientePE','numeropedidoPE','fechapedidoPE','estadopedidoPE','logometodopagopedidoPE','metodopagopedidoPE','gastosenviopedidoPE','metodoenviopedidoPE','subtotalpedidoPE','decuentocantidad%pedidoPE','decuentocantidad€pedidoPE','decuentototalpedidoPE','totalpedidoPE','direccionpedidoPE'];
google.script.run
.withSuccessHandler((obj) => {
obj.pA.forEach(p => {
document.getElementById(e).textContent = obj[p];
})
})
.getMyData(tA)
}
</script>
</body>
</html>
I think the easiest way of doing this from what you already have is use a single google.script.run
call to a wrapper function which returns all the data and then setting the values in JavaScript.
List your elements in an array and then loop through them on Success, rather than using a google.script.run
call for each element:
const elements = [
'nombreclientePE',
'numeropedidoPE',
'fechapedidoPE',
'estadopedidoPE',
'metodopagopedidoPE',
'gastosenviopedidoPE',
'metodoenviopedidoPE',
'subtotalpedidoPE',
'decuentocantidad%pedidoPE',
'decuentocantidad€pedidoPE',
'decuentototalpedidoPE',
'totalpedidoPE',
'direccionpedidoPE',
]
const logoId = 'logometodopagopedidoPE'
function callGasFn() {
google.script.run.withSuccessHandler(setData).getAllValues()
}
function setData(data) {
elements.forEach((x, i) => document.getElementById(x).textContent = data[0][i])
document.getElementById(logoId) = data[1]
}
callGasFn()
Then in Apps Script you have your getAllValues()
function:
function getAllValues() {
return [
[
clientePedidoPE(),
numeroPedidoPE(),
fechaPedidoPE(),
estadoPedidoPE(),
metodoPagoPE(),
gastosEnvioPE(),
metodoEnvioPE(),
subtotalPedidoPE(),
descuentoCantidadPorcentajePedidoPE(),
descuentoCantidadEurosPedidoPE(),
descuentoTotalPedidoPE(),
totalPedidoPE(),
direccionEnvioPE(),
],
logoMetodoPagoPE()
]
}
I separated the logo out of the main array as it has src
set as opposed to textContent
.
In the sheet you provided, Maria del Campo
is missing from the client sheet - I don't know if this is intened but it does cause direccionEnvioPE()
to fail as her data isn't available in the sheet.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.