Include Script associated with a google script form

1

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

    
asked by Karen Lewis 18.07.2017 в 08:25
source

1 answer

1

Summary

The code in the question has several problems

  • Problem with function names
  • Load jQuery several times, these versions being different
  • CleanFormularities function
  • Function execution order
  • Maybe others.

    Explanation

    1. Problem with function names

    One problem that the code has is that in the file .gs the function is called incluir() but in the file Index.html this function is not called but include . The line in question is:

    <?!= include('Scindex'); ?> 
    

    2. Load jQuery several times

    Another problem is that Index.html is loading jQuery several times but using different versions and accommodations. The lines are the following:

    <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>
    

    I think it's not too serious while the properties are called the same, the one that will prevail will be the last to be loaded, however, on the one hand your application is taking more time than necessary to load and it could be that your code requires a characteristics that has been changed.

    The recommendation is that you spend some time to understand jQuery, choose a version and only use one in each application to prevent interference and facilitate the debugging of the code and in particular the performance of your application.

    3. Problem with cleanform function

    Reported as resolved by the OP in a response leaving the function as follows

    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;
        }
       }
      }
    

    4. Function execution order

    The calls to functions on the server side are performed asynchronously, that is, the call is made, and the rest of the code is continued running, without waiting for the server-side function to finish executing.

    We could say that the problem is in the following line of code

    <button onclick="solicitarFormulario('Fentregas');solicitarScript('Scentregas')">Entregas</button>
    

    and in

    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);
    }
    

    One way to solve this is to change where you call the second function. Instead of doing it in the button, do in the function loadFormular.

    The button would look like this:

    <button onclick="solicitarFormulario('Fentregas');">Entregas</button>
    

    and the other part of the code like this:

    function solicitarFormulario(entrada) {
     google.script.run.withSuccessHandler(cargarFormulario).incluir(entrada);
    }
    function cargarFormulario(entrada) {
     document.getElementById('Principal').innerHTML=entrada;
     solicitarScript('Scentregas');
    }
    function solicitarScript(scentrada){
     google.script.run.withSuccessHandler(importarScript).incluir(scentrada);
    }
    function importarScript(scentrada){
     $.getScript(scentrada);
    }
    
        
    answered by 18.07.2017 в 18:43