Utilizar GAS para crear aplicaciones web (3ª y última parte)

Català (Catalán) English (Inglés)

Con este artículo, acabo la trilogía sobre web apps con Google apps script. En el primer artículo vimos qué eran y qué podíamos desarrollar. En el segundo, vimos el proceso de creación de una web app concreta. En este tercero, veremos cómo podemos hacer una web app que tenga varias páginas html.

Como decíamos en el segundo artículo, solo la función doGet puede devolver html. De hecho, cuando se accede a la URL de la aplicación, se ejecuta la función doGet que es la que devuelve el html. Este html suele tener algún botón que llama a otra función que es la que guarda datos o provoca acciones. ¿Pero y si queremos que la aplicación tenga más de una pantalla? ¿Cómo lo hacemos con una sola función doGet?

Seguiremos con el ejemplo del segundo artículo, donde creábamos un formulario KPSI que los alumnos contestaban al inicio de una unidad y en terminarla. Supongamos que la misma aplicación nos debe servir para contestar 3 formularios KPSI correspondientes a 3 unidades diferentes. ¿Cómo lo podríamos hacer? (Se puede encontrar el script final en este enlace)

Lo lógico es que la aplicación tuviera 3 botones, uno para cada unidad. Según en el botón que el alumno haga clic, debería ver y rellenar un cuestionario KPSI u otro.

Para ello, utilizaremos el parámetro de la función doGet (e). Esta e contiene los parámetros que se pasan con la URL. Por ejemplo, si la dirección de la implementación de la función es https://script.google.com/a/macros/s/AKbgx7vR1t/exec, si llamamos a la función con la siguiente URL https://script.google. como/a/macros/s/AKbgx7vR1t/ejec?p=1 podremos recuperar el valor de p a través del parámetro y de la función doGet (e).

En la función doGet, le añadimos el código para recoger el parámetro:

function doGet(e) {
 //Recogemos los parámetros (pantalla)
 let params= e.parameter;
 let pantalla=params.p;

(...)

}

De este modo, podemos decidir qué pantalla se muestra con esta función. Añadiendo la expresión switch, ya podemos hacer que se muestre una página html u otra. Recogemos el parámetro, nos aseguramos de que el alumno está en la lista, y mostramos la pantalla html que corresponde según el parámetro enviado a través de la URL (si no envía ningún parámetro, le asignaremos la pantalla 1).

function doGet(e) {
  //Recogemos los parámetros (pantalla) 
  let params= e.parameter; 
  let pantalla=params.p; 
  if (pantalla==undefined) { pantalla=1 }; //Si la llamada a la aplicación no tiene ningún paràmetre p, le asignamos la primera pantalla 
  //Comprobamos si el usuario está en la lista de alumnos
  var spreadsheet = SpreadsheetApp.openByUrl(full_control);  
  var sheet = spreadsheet.getSheetByName(full);
  var rang = sheet.getDataRange();
  var alumnes = rang.getValues();
  var numRows = rang.getNumRows();
  let identificacio=0;
  for (let i=1;i<numRows;i++){
    if (alumnes[i][1]==usuari){
      identificacio=1;
    }
  }
  //Si el alumno no está en la llista, se indica con un mensaje emergente
  if (identificacio==0){
    return HtmlService.createHtmlOutputFromFile('html_no_autoritzado').setTitle("Aplicación KPSI")
  }else{
    switch (pantalla) { 
      case 1: 
          plantilla=HtmlService.createTemplateFromFile('KPSI'); 
          plantilla.usuari=usuari; 
          plantilla.alumnes=alumnes; 
          plantilla.apli=apli;
          return plantilla.evaluate().setTitle("Aplicación KPSI") 
          break; 
        case 2: 
          plantilla=HtmlService.createTemplateFromFile('KPSI2'); 
          plantilla.usuari=usuari; 
          plantilla.alumnes=alumnes; 
          plantilla.apli=apli;
          return plantilla.evaluate().setTitle("Aplicación KPSI") 
          break;
      case 3: 
          plantilla=HtmlService.createTemplateFromFile('KPSI3'); 
          plantilla.usuari=usuari; 
          plantilla.alumnes=alumnes; 
          plantilla.apli=apli;
          return plantilla.evaluate().setTitle("Aplicación KPSI") 
    } 
  }
}

Si creamos las páginas KPSI2.html y KPSI3.html, la misma aplicación ya carga una u otra según el parámetro de la URL.

Nos falta pero, añadir los botones en las páginas KPSI, KPSI2 y KPSI3. Lo haremos solo por la KPSI, ya que en las demás será igual. La idea es hacer que, al hacer clic, se abra la URL de la aplicación con el parámetro correspondiente. Antes de ir a la página KPSI, en el código, habrá que encontrar esta dirección de la aplicación y pasarla como parámetro.

Por lo tanto, como constante en el código, añadiremos.

//Comentar en publicar la versión. Eliminar comentar para las pruebas
const apli="https://script.google.com/a/macros/s/AKfycbzEpglhjqn8FKi6DXjJydP8CB6wFvszyFqb05czYUc/dev";

//Comentar cuando se realizan pruebas y no se publica. Eliminar comentar para publicar.
//const apli=ScriptApp.getService().getUrl();

Como se puede ver, definimos dos direcciones. Una para las pruebas, que la dirección termina en / dev y otra para las implementaciones finales, que la cogemos automáticamente con el getUrl del ScriptApp. Mientras estemos trabajando con la implementación de pruebas, comentaremos la línea de ScriptApp. Cuando ya creamos la implementación por los alumnos, comentaremos la línea de la dirección / dev.

Ahora ya sí, pasamos también esta variable apli como parámetro y vamos a la página KPSI.

Vemos como quedaría en la página KPSI. Tras la cabecera y antes de los alumnos, añadiríamos:

<ul class="nav">
 <li class="nav-item">
   <a class="nav-link active" onclick="saltar(1,<?=apli ?>)" href="javascript:;">Unitat 1</a>
 </li>
 <li class="nav-item">
   <a class="nav-link" onclick="saltar(2,<?=apli ?>)" href="javascript:;">Unitat 2</a>
 </li>
 <li class="nav-item">
  <a class="nav-link" onclick="saltar(3,<?=apli ?>)" href="javascript:;">Unitat 3</a>
 </li>
</ul>

Vemos que a la aplicación le aparecen las tres unidades para elegir (en este caso, con la unidad 1 marcada como activa).

Ya solo nos falta definir en esta página KPSI la función saltar (), que es la que construirá la dirección de la aplicación con el parámetro correspondiente.

function saltar(p, apli){
  if (document.KPSI.btn_desar.disabled==false){ //Si el botón está desactivado es porque ha realizado cambios y no ha guardado
    let resposta=window.confirm("Has hecho cambios y no has guardado. ¿Has olvidado guardar los cambios? Pulsa Aceptar para volver a la página y poder guardar o Cancelar para salir sin guardar");
    if (resposta==false) {
      window.open(apli+"?p="+p, "_top");
    }
  }else{
    window.open(apli+"?p="+p, "_top");
  }
}

Como se ve en el código, aprovechamos para revisar si se han guardado los cambios. Si se quiere cambiar de pantalla sin guardar, sale un mensaje avisando para que se guarde. En todo caso, se llama a la URL de la aplicación añadiendo el parámetro p=1 (o 2 o 3, según la Unidad que se ha elegido). De este modo, siempre se vuelve a llamar a la función doGet que es la que muestra la página html que queremos.

Reconozco que el sistema no es que sea especialmente cómodo y hay que estar un poco al tanto de no equivocarse en nada, pero no es demasiado complicado. Además, tiene un efecto colateral. Si se inserta la aplicación, no van a funcionar estos saltos. Solo puede funcionar directamente con al URL, sin insertar en ningún site.

Ahora tendríamos que crear las páginas KPSI2 y KPSI3 y modificar la función que llaman para guardar. Definiríamos las funciones guardar2 y guardar3 en el código y configuraríamos donde queremos guardar los datos de estos otros formularios: en otras pestañas de la hoja de cálculo o en otros libros de cálculos.

Espero que con la serie de los 3 artículos haya sido capaz de dar las bases para poder crear web apps, recordando siempre la limitación de 30 usuarios concurrentes.

¿Y qué ventaja tiene hacer este procedimiento en lugar de crearte una aplicación con PHP? Básicamente 2. La primera, la facilidad para  utilizar las API de Google desde GAS. La segunda, no necesitamos buscar ningún servidor donde alojar nuestra aplicación, ya queda operativa desde los servidores de Google.

Català (Catalán) English (Inglés)

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.