Javascript, HTML, CSS e... !
0 commenti

Aggiungere funzionalità nei componenti aggiuntivi

Interagire con i Google Forms tramite Google Apps Script

Nell'articolo "I vantaggi di creare un Google Form da codice tramite Google Apps Script" sono state messe in evidenza alcune qualità derivanti da una generazione dei form gestita lato codice rispetto all'uso, se pur comodissimo, del relativo editor WYSIWYG dedicato. In questo tutorial, invece, verranno mostrate le potenzialità di Google Apps Script per l'integrazione di funzionalità aggiuntive ad un Google Form, indipendentemente dal metodo con cui è stato generato, al fine di arricchire l'interfaccia con informazioni utili ed immediate basate sulla compilazione, fino a quel momento, del form stesso da parte degli utenti che l'hanno inviato.

L'obiettivo è pertanto quello di mostrare a video, nella pagina del Form, alcuni dati prelevati dal relativo Google Spreadsheet in cui sono salvate le risposte di chi ha compilato il modulo, nel caso specifico per la raccolta di informazioni sull'interesse sportivo da parte degli utenti, ovvero quello realizzato nell'articolo menzionato poco sopra (Fig. 1):



Esempio di un Google Form

Fig. 1 - Esempio di un Google Form


Poniamo, ad esempio, che ci interessi visualizzare come informazione immediatamente disponibile il numero di utenti di sesso maschile e di sesso femminile con l'indicazione dell'intervallo di età per ciascuno dei due gruppi.
I dati su cui ci baseremo saranno quindi quelli relativi alle risposte di 'Sesso' e 'Data di nascita' che, nello Spreadsheet delle risposte al form, sono i seguenti (Fig. 2, N.B.: i dati mostrati sono puramente inventati al solo scopo illustrativo):



Esempio di uno Spreadsheet contenente le risposte ad un Google Form

Fig. 2 - Esempio di uno Spreadsheet contenente le risposte ad un Google Form


Di seguito il codice da incorporare (bound-script) all'interno del Form tramite il relativo 'Editor di script...' che può essere aperto dalla schermata di modifica del Google Form cliccando sul menu rappresentato da 3 pallini in verticale e cliccando a sua volta l'opportuno elemento nel menu che si aprirà contestualmente (Fig. 3):



Apertura dell'editor di script di un Google Form

Fig. 3 - Apertura dell'Editor di Script di un Google Form


Il codice da inserire all'interno dell'editor è il seguente:

var ui = FormApp.getUi();

function onOpen() {
  ui.createMenu('Riepilogo informazioni...')
  .addItem("Mostra info sul tipo di utenza che utilizza il form...", 'showInformation')
  .addToUi();
  var current_user = Session.getActiveUser().getEmail();
  if (current_user.length == 0) {
    showTempSideBar();    
  } else {
    showInformation();
  }
}

function showTempSideBar() {
  var result = "<div style='padding:10px;'>Se visualizzi questo messaggio significa che non hai ancora autorizzato il tuo account.<br />" +
    "Puoi abilitare il tuo account all'uso delle funzionalità aggiuntive cliccando sull'icona dei componenti aggiuntivi " +
      "(il pezzo del puzzle) per poi cliccare sulla voce di menu:<br /><strong>'Riepilogo informazioni...'</strong><br />Seguire poi le istruzioni a video." +
        "<p>A quel punto, selezionando lo stesso elemento dal menu, questa sidebar mostrerà informazioni relative al tipo di utenza attiva sul form.</div>";
  
  var html = HtmlService.createHtmlOutput(result)
  .setTitle('Abilita la funzionalità');
  
  ui.showSidebar(html);
}

function showInformation() {
  var form = FormApp.getActiveForm();
  var sh = SpreadsheetApp.openById(form.getDestinationId()).getSheetByName('Form Responses 1');
  var data = sh.getDataRange().getValues();
  var questions = form.getItems();
  var data_length = data.length;
  var gender_m = 0, gender_f = 0, age_m_min = 0, age_m_max = 0, age_f_min = 0, age_f_max = 0;
  var todayDate = new Date();
  var birthDate, age;
  for(var n in questions) {
    question_index = questions[n].getIndex() + 1;
    question_title = questions[n].getTitle();
    if (question_title == 'Sesso') {
      for(i = 1; i<data_length; i++) {
        birthDate = data[i][2];
        age = dateDifference(birthDate, todayDate);
        if (data[i][question_index] == "M") {
          gender_m = gender_m + 1;
          if (age_m_min == 0) { age_m_min = age } else { age_m_min = getMinValue(age, age_m_min) };
          if (age_m_max == 0) { age_m_max = age } else { age_m_max = getMaxValue(age, age_m_max) };
        }
        if (data[i][question_index] == "F") {
          gender_f = gender_f + 1;
          if (age_f_min == 0) { age_f_min = age } else { age_f_min = getMinValue(age, age_f_min) };
          if (age_f_max == 0) { age_f_max = age } else { age_f_max = getMaxValue(age, age_f_max) };
        }
      }
    }
  }   
  
  var result = "<div style='font-size:14px;padding:10px;'>Il form è stato compilato da:<br /><br />" +
    "- <strong>" + gender_m + "</strong> uomini di età compresa tra i <strong>" + age_m_min + "</strong> e i <strong>" + age_m_max + "</strong> anni<br />" +
      "- <strong>" + gender_f + "</strong> donne di età compresa tra i <strong>" + age_f_min + "</strong> e i <strong>" + age_f_max + "</strong> anni<br /><br />" +
      "Per aggiornare i dati cliccare sull'icona dei componenti aggiuntivi (il pezzo del puzzle) per poi cliccare sulla voce di menu:<br /><strong>'Riepilogo informazioni...'</strong><div>";
      
      var html = HtmlService.createHtmlOutput(result)
      .setTitle('Info attività utente...');

  ui.showSidebar(html);
}

function dateDifference(dateMin, dateMax) {
  dt1 = new Date(dateMin);
  dt2 = new Date(dateMax);
  return Math.floor(((Date.UTC(dt2.getFullYear(), dt2.getMonth(), dt2.getDate()) - Date.UTC(dt1.getFullYear(), dt1.getMonth(), dt1.getDate()) ) / (1000 * 60 * 60 * 24)) / 365);
}

function getMinValue(value1, value2) {
  if (value1 < value2) {
    return value1;
  }
  return value2;
}

function getMaxValue(value1, value2) {
  if (value1 > value2) {
    return value1;
  }
  return value2;
}

Come si può notare dalla funzione presente nel trigger di tipo semplice 'onOpen', all'apertura della pagina del form verrà creato un menu personalizzato (un esempio dettagliato sulla creazione dei menu personalizzati si trova nell'articolo "Menu personalizzati in SpreadsheetApp e DocumentApp con Google Apps Script") all'interno dell'interfaccia composto da un solo elemento con la finalità di mostrare, nel corpo di una colonna laterale, le informazioni sul tipo di utenza che ha, fino a quel momento, utilizzato il form.

function onOpen() {
  ui.createMenu('Riepilogo informazioni...')
  .addItem("Mostra info sul tipo di utenza che utilizza il form...", 'showInformation')
  .addToUi();
  var current_user = Session.getActiveUser().getEmail();
  if (current_user.length == 0) {
    showTempSideBar();    
  } else {
    showInformation();
  }
}

La stessa funzione controlla se l'utente è autorizzato all'uso di questo nuovo componente ed in caso negativo, tramite un'apposita funzione (nel caso specifico showTempSideBar()) mostrerà, all'interno della colonna laterale, un messaggio di richiesta di autorizzazioni per l'utente che sta utilizzando la nuova funzionalità e le relative modalità di attivazione (Fig. 4):



Richiesta di autorizzazioni all'uso del nuovo componente aggiuntivo

Fig. 4 - Richiesta di autorizzazioni all'uso del nuovo componente aggiuntivo


Una volta autorizzato l'utente seguendo i vari passaggi della procedura di autenticazione, ovvero quanto Session.getActiveUser().getEmail() sarà valorizzato (corrispondente alla mail dell'utente autorizzato), verrà mostrato nella colonna laterale il contenuto desiderato (Fig. 5):



Colonna laterale che mostra il risultato dell'elaborazione in Google Apps Script dei dati del Form presenti nel relativo Spreadsheet

Fig. 5 - Colonna laterale che mostra il risultato dell'elaborazione in Google Apps Script dei dati del Form presenti nel relativo Spreadsheet


La parte di codice dedicata all'elaborazione dei dati del Form presenti all'interno del relativo Spreadsheet di trova nella funzione showInformation() che viene ora richiamata ogni volta che la pagina del form viene aperta.
Quello che viene effettivamente svolto è il recupero del foglio di calcolo in questione ed in base agli indici delle domande del Form e le righe presenti nello Sheet, viene effettuato un ciclo per il recupero delle informazioni di sesso e data di nascita in base a due modalità (mostrate a scopo illustrativo), quella tramite i loro indici, con getIndex(), oppure tramite il titolo della domanda, con getTitle(), e viene visualizzato tramite la composizione di un contenuto HTML il messaggio deiderato previa elaborazione dei dati con le funzioni di appoggio per la somma del numero dei maschi e delle femmine e per il calcolo dell'età (recuperato per differenza di date con la funzione personalizzata dateDifference(dateMin, dateMax)) e la relativa identificazione dei valori minimi e massimi.

Per aggiornare i dati sarà sufficiente ricaricare la pagina o, meglio ancora, cliccare sull'icona dei componenti aggiuntivi (il pezzo del puzzle) per poi cliccare sulla voce di menu: 'Riepilogo informazioni...'.

E' inoltre possibile richiamare una funzione, tramite i trigger dell'editor di script, nel momento in cui un utente effettua il submit del Form. Questa funzionalità può trovare utilità, ad esempio, per farsi inviare una mail di notifica ogni volta che il Form viene inviato.
Per assegnare un trigger automatico al submit del Form è necessario selezionare, dalla barra dei menu dell'editor di Apps Script incorporato al file del Form, la voce "Modifica --> Trigger del progetto corente" e scegliere la funzione da richiamare, come mostrato nell'immagine seguente, Fig. 6:



assegnare una funzione al submit del form

Fig. 6 - Assegnare una funzione al submit del Form tramite i Trigger del progetto


Da notare, nel codice completo, la semplicità con cui è possibile far apparire la colonna laterale, ovvero tramite il metodo ui.showSidebar() ed allo stesso tempo come la manipolazione del suo contenuto HTML e CSS avviene in poche righe grazie al servizio HtmlService.

Per quanto riguarda invece il recupero delle informazioni dallo Spreadsheet, ovvero la parte di codice dove viene utilizzato il metodo getDataRange(), consiglio la lettura dell'articolo "Google Apps Script: best practice per il miglioramento delle performance" in particolare la parte dove viene raccomandato l'utilizzo delle operazioni batch.

Tags

Michele Pisani

Michele Pisani

Sviluppatore Javascript ed esperto in Digital Analytics

L'esperienza nel settore Digital Analytics unita ad anni di sviluppo in Javascript ha trovato la massima espressione in Google Apps Script che mi ha permesso, con estrema facilità e poche righe di codice, di realizzare potenti applicazioni interattive e processi automatizzati integrati con i prodotti della G Suite.

Come contattarmi
scrivi un commento

0 Commenti

Non ci sono commenti

Nessuno ha ancora commentato questo articolo, fallo tu per primo!

scrivi un commento

Scrivi un commento

Il tuo indirizzo email non sarà pubblicato.I campi contrassegnati da un * sono obbligatori
Puoi utilizzare i seguenti tag nei commenti:
[bold]testo[/bold] se vuoi evidenziare un testo con il grassetto[code]function helloworld() { }[/code] se vuoi pubblicare una porzione di codice[url]http://www.appsscript.it[/url] se devi riferirti ad un indirizzo web