I'm doing a small project with two forms in the same spreadsheet, all the code worked well until I followed the recommendations shown in one of the answers to How to show another page in google apps script?
Once I did that, the script code of the forms used to load data in the same form ... that among other things could:
//Mostrar la fecha y hora en el form
var d = new Date();
var n = d.toLocaleString();
document.getElementById("mtempo").innerHTML = n;
//Cargar el campo fecha, con la fecha actual
document.getElementById('fecent').value = new Date().toISOString().substring(0, 10);
//Cargar un select con los datos del spreadsheet
$(function () {
google.script.run.withSuccessHandler(buildNumcon)
.getListOptions();
});
One of the solutions I found involves including from the index
<?!= include('ScriptForm1'); ?>
But this was loaded before calling the form so it did not help me, I found out that I could call the script from the button that calls the form.
<button onclick="solicitarFormulario('Form1');solicitarScript('ScriptForm1')">Formulario
1</button>
and in the index script, if it works well, call the file:
function solicitarScript(scriptForm){
google.script.run.withSuccessHandler(importarScript).include(scriptForm);
}
function importarScript(scriptForm){
$.getScript(scriptForm);
}
So far all this "good" achievement call the script but it is still loading before the form and does not seem to have any communication with the elements of this! Although it says that if it does not fill any of the data and the functions that used to work before, like cleaningFormulario () when canceling it says that it is not defined.
Someone who explains to me as a 5-year-old child what happened?
I'm using jQuery and everything that works for me. Separate the codes to try to make it work.
Main.gs:
function doGet() {
return HtmlService.createTemplateFromFile('Index')
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.NATIVE);
}
function incluir(filename) {
return HtmlService.createHtmlOutputFromFile(filename)
.getContent();
}
function getListOptions() {
var sheet = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets...')
.getSheetByName("Parametros");
var lastRow = sheet.getLastRow();
var myRange = sheet.getRange("C2:C"+4);//4 en vez de lastRow(Quitar espacios en blanco)
var conductor = myRange.getValues();
return( conductor );
}
function processFormEntregas(e){
//Guardar imagen en Drive
var name='Entregas';
var carpeta = DriveApp.getRootFolder().searchFolders("title contains '"+name+"'");
if (carpeta.hasNext()===true) {
while (carpeta.hasNext()) {
var folder = carpeta.next();
Logger.log(folder.getName()+' '+folder.getId());
}
}else{
var folder=DriveApp.getRootFolder().createFolder(name);
}
//Crea el archivo en la carpeta 'name'
var blob = e.imginp.getBlob();
var file = folder.createFile(blob);
var fileId = file.getId();
var sMtempo = new Date();
var sNroref = e.nroref;
...
var sImginp = ("https://docs.google.com/uc?export=download&id="+fileId);
var spreadSheet = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/...');
var hojaDatos = spreadSheet.getSheetByName('Entregas');
var ultimaFila = hojaDatos.getLastRow();
hojaDatos.getRange(ultimaFila+1,1).setValue(sMtempo);
...
hojaDatos.getRange(ultimaFila+1,8).setFormula('IMAGE("'+sImginp+'";1)');
SpreadsheetApp.flush();
print("Su registro ha sido guardado con exito."); //Esperando para probar
}
Index.html:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>
//De arriba no se que sirve y que no, prefiero que sobre que falte
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<?!= include('Scindex'); ?>
</head>
<body>
<div>
<p align="left" >
<button onclick="solicitarFormulario('Frecogidas')">Recogidas</button>
<button onclick="solicitarFormulario('Fentregas');solicitarScript('Scentregas')">Entregas</button>
</p>
</div>
<div id="Principal" class="smn47">
</div>
</body>
</html>
Scindex.html:
<script>
function solicitarFormulario(entrada) {
google.script.run.withSuccessHandler(cargarFormulario).incluir(entrada);
}
function cargarFormulario(entrada) {
document.getElementById('Principal').innerHTML=entrada;
}
function solicitarScript(scentrada){
google.script.run.withSuccessHandler(importarScript).incluir(scentrada);
}
function importarScript(scentrada){
$.getScript(scentrada);
}
//Esta función estaba originalmente en el form Entregas, al hacer el
//cambio como no funcionaba he probado desde aqui y lo llama pero no he
//declarado bien el formulario porque me dice que no puede realizar reset
//de undefined
function limpiarFormulario() {
var activeForm = this.form;
activeForm.reset();
activeForm.getElementById('fecent').value = new Date().toISOString().substring(0, 10);
activeForm.getElementById('output').src=" ";
activeForm.getElementById('output').alt="Vista Previa";
}
</script>
Fentregas.html:
<div >
<form id="Entregas" name="Entregas" enctype="multipart/form-data" >
<p id="mtempo" name="mtempo" align="right"></p>
<br> Referencias:
<br> <input type="text" name="nroref" id="nroref" placeholder="Referencia(s) recogida(s)" />
...
<br><br>
<input class="action" type="button" value="GUARDAR" onclick="procesaFormulario()">
<input class="create" type="button" value="CANCELAR" onclick="limpiarFormulario()">
</form>
</div>
Scentregas.html:
<script>
//Esta seccion de código estaba independiente en el formulario, se activaba
//sola cuando lo cargaba ahora no se como llamar al evento para que cargue
//luego de los elementos del formulario
var activeForm =document.forms['Entregas'];
var d = new Date();
var n = d.toLocaleString();
this.form.elements['mtempo'].innerHTML = n;
activeForm.getElementById('fecent').value = new Date().toISOString().substring(0, 10);
$(function () {
google.script.run.withSuccessHandler(buildNumcon)
.getListOptions();
});
function buildNumcon(conductor) {
var list = $('#numcon');
list.empty();
for (var i = 0; i < conductor.length; i++) {
list.append(new Option(conductor[i],conductor[i]));
}
}
var loadFile = function(event) {
var reader = new FileReader();
reader.onload = function(){
var output = activeForm.getElementById('output');
output.src = reader.result;
};
reader.readAsDataURL(event.target.files[0]);
};
//Esto ni siquiera lo he probado
function procesaFormulario(){ google.script.run.withSuccessHandler(limpiarFormulario(this)).processFormEntregas(document.forms[0]);
}
</script>
I am still seeing how I can call the elements of the form as I did before with document.getElementById does not work
The Include / include has already been corrected to the jquery libraries, I had not paid much attention to them, I had them from the beginning almost and they had not given me any problems and I still found how to declare the input to clean the form ()
function limpiarFormulario() {
var actFrm = document.forms[0];
for (i = 0; i < actFrm.elements.length; i++)
{
field_type = actFrm.elements[i].type.toLowerCase();
switch (field_type)
{
case "text":
case "password":
case "textarea":
case "hidden":
actFrm.elements[i].value = "";
break;
case "radio":
case "checkbox":
if (actFrm.elements[i].checked){
actFrm.elements[i].checked = false;
}
break;
case "select-one":
case "select-multi":
actFrm.elements[i].selectedIndex = -1;
break;
case "date":
actFrm.elements[i].value = new Date().toISOString().substring(0, 10);
default:
break;
}
}
}
I have not yet been able to solve the rest .... I need to create a function that activates after loading the form: (
I apologize first for THE DISASTER OF MY POST, I have been under a lot of stress by this code and I have given it so many laps that I had to dedicate myself to "clean it" to clarify my ideas ...
In fact I followed the recommendations made to me and added them to some own modifications:
1) change the way the buttons are used to call the forms, instead of using the onclick using:
$(document).ready(function(){
$(Bentregas).click(function(){
solicitarFormulario('Fentregas');
});
});
The problem is still THE CALL OF THE SCRIPT !!! I can not use:
<?!= include('ScriptForm1'); ?>
Why do you call the script before the form is loaded and I can not find how to create a function that runs once that form is downloaded ....
and the option of $.getScript(scriptForm);
is giving me the following error:
accounts.google.com/ServiceLogin?service=wise&passive=1209600&continue=http...BDate (). toISOString (). substring (0,% 2B10);% 2B% 257D% 2B% 26_% 3D1501010636192: one GET ... // accounts.google.com/ServiceLogin?service=wise&passive=1209600&conti...%2BDate().toISOString().substring(0,%2B10);;%2B%257D%2B%26_%3D1501010636192
userCodeAppPanel: 1 XMLHttpRequest can not load ... // accounts.google.com/ServiceLogin?service=wise&passive=1209600&conti...%2BDate().toISOString().substring(0,%2B10);;%2B%257D%2B%26_%3D1501010636192 . No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin ' link ' is therefore not allowed access. The response had HTTP status code 400.
Here the solution to this question: How to include a scrip in modular programming with GAS