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

Riacquisire il focus con google.script.host.close()

Eseguire una funzione al click su un bottone in uno Spreadsheet e far tornare il Focus su una cella

Nell'articolo 'Bottoni che eseguono script in Spreadsheet con Google Apps Script' ho illustrato come sia possibile, in pochi passaggi, associare una funzione Apps Script ad un bottone all'interno di uno Sheet al fine di eseguire le operazioni desiderate al click su di esso.

Uno degli inconvenienti di questa funzionalità è che, dopo il click sul bottone, nonostante sia possibile posizionare automaticamente il cursore su una specifica cella dello Sheet, il focus sul foglio di calcolo viene perso pertanto coloro che hanno la necessità di scrivere direttamente da tastiera all'interno della cella selezionata si renderanno subito conto che nessun carattere viene acquisito.

Considerando che la documentazione ufficiale informa che per spostare il focus nel browser dell'utente da una finestra di dialogo o una barra laterale, nelle applicazioni della G Suite (Moving browser focus in G Suite), basta chiamare semplicemente il metodo google.script.host.editor.focus(), una prima soluzione potrebbe essere quella di avvalersi di un bottone personalizzato inserito all'interno della sidebar ed associare a quel bottone la funzione desiderata in Apps Script per poi fargli eseguire il metodo appena descritto, come nell'esempio direttamente presente nella documentazione ufficiale, editor.focus().

Tuttavia, sulla base di queste premesse, ho effettuando dei test affinché fosse possibile ottenere un comportamento simile sfruttando i bottoni personalizzati all'interno del foglio di calcolo.

Ho riscontrato che è possibile! Il risultato non è il massimo dell'eleganza ma per un uso interno di un applicativo il sistema funziona a dovere.

Il concetto gira intorno ad un uso indiretto della sidebar, considerando che il focus da essa all'editor viene passato non solo con il metodo precedentemente descritto bensì anche dopo la sua chiusura.
Per chiudere programmaticamente una sidebar esiste il metodo close(), pertanto nello specifico, l'idea è quella di invocare il metodo per aprire una sidebar vuota e chiuderla immediatamente dopo il suo caricamento tramite la chiamata di tipo HTML Service: google.script.host.close()

Il codice mostrato di seguito svolge quanto appena descritto:

Codice main.gs:

function inserisciNuovaRiga() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  sheet.insertRowBefore(2);
  showSidebar();
  var range = sheet.getRange("A2");
  sheet.setActiveRange(range);
}

function showSidebar() {
  var html = HtmlService.createHtmlOutputFromFile('sidebar');
  SpreadsheetApp.getUi().showSidebar(html);
}

Codice sidebar.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body onload="google.script.host.close();">
    
  </body>
</html>

Il requisito per il suo funzionamento, nel caso specifico, è che la funzione inserisciNuovaRiga() venga assegnata al bottone personalizzato in modo che, al click su di esso, una nuova riga venga sotto l'intestazione (con sheet.insertRowBefore(2)) per poi chiamare il metodo per aprire la sidebar che, subito dopo il suo caricamento (ovvero all'onload) esegue l'API asincrona lato client google.script.host.close() (nata appositamente per la chiusura di finestre di dialogo e barre laterali in Docs, Sheets e Forms che contengono pagine HTML Services) così da chiudersi automaticamente. In questo momento il focus tornerà al foglio di calcolo e la cella definita sarà selezionata e pronta per ricevere in input i caratteri immessi da tastiera.

Un risultato visivo del codice di cui sopra è il seguente, Fig. 1:



eseguire una funzione al click su un bottone in uno spreadsheet e far tornare il focus su un cella

Fig. 1 - Funzione eseguita al click su un bottone in uno Spreadsheet e Focus tornato su un cella


La parte poco elegante di questo approccio è che per un breve lasso di tempo, ogni volta che si clicca sul bottone per eseguire la funzione richiesta, comparirà e sparirà la sidebar.

Nota: Utilizzando .showModalDialog(html, ' ') al posto di .showSidebar(html) otterremo lo stesso risultato a livello pratico ma aggiungeremo in più un fastidioso cambiamento del colore di fondo dovuto all'aprirsi della modal fino alla sua chiusura automatica nonché la modal risulterebbe molto più invasiva rispetto alla barra laterale.

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

4 Commenti

  1. sabato 19 gennaio 2019 alle ore 15.45 Saver

    Ciao Michele, ti volevo chiedere se è possibile richiamare, come script di un bottone su foglio di calcolo, una funzione creata adhoc passando anche un parametro, oppure capire, visto che la stessa funzione viene invocata da più bottoni fifferenti, qual è il bottone che è stato cliccato. Grazie.

    Rispondi a questo commento
    • domenica 20 gennaio 2019 alle ore 22.56 Michele PisaniAutore

      Ciao Saver,
      non credo sia possibile gestire i parametri direttamente da tale funzionalità.

      Puoi eventualmente utilizzare dei workaround come ad esempio, nel caso in cui il dato da passare come parametro derivi da un input dell'utente puoi utilizzare una funzione che richiama un prompt, con Browser.inputBox, e gestire il valore che verrà inserito.
      Alternativamente, puoi inserire il valore del parametro che dovrai passare alla funzione in una cella (magari di un foglio di appoggio) e all'interazione con il bottone, invece che passarlo come parametro, andarlo a recuperare dalla cella con getRange().

      Rispondi a questo commento
  2. sabato 27 luglio 2019 alle ore 17.07 roberto codutti

    buon giorno
    premetto che sono "neofita" della programmazione di scripts google, ma di recente mi stavo interessando alle google forms per la loro facilità di gestione. Per una richiesta che mi è stata fatta da un amico vorremmo ,tramite le forms gestire una sottoiscrizione indirizzata a degli utenti (sono delle associazioni che cooperano con il Banco Alimentare), per un corso che il banco tiene in determinate giornate (5). Avrei bisogno quindi di gestire una specie di "stato" della disponibilità di posti nelle giornate in cui un ente si iscrive.
    Secondo Lei è possibile "passare" questa informazione alle forms o reagire alla conferma di inserimento se non c'è più disponibilità ?
    .. poi per aggiornarmi sulla programmazione .. sono in attesa del Suo libro.
    Cordiali saluti
    Roberto Codutti

    Rispondi a questo commento
    • domenica 28 luglio 2019 alle ore 00.24 Michele PisaniAutore

      Ciao Roberto,
      i Google Forms non supportano l'esecuzione del codice al momento della compilazione del modulo, per esigenze della tipologia descritta può essere utile creare una web app con Apps Script.

      Alternativamente, rimanendo in ambito dei Google Forms, un'idea potrebbe essere quella di attivare la raccolta delle email dell'utente che compila il form ed avvalersi del trigger onFormSubmit(). In questo modo al momento dell'invio del form puoi eseguire una funzione che verifica la disponibilità dei posti ed invia una notifica via mail all'indirizzo dell'utente.

      Spero di averti dato un valido spunto :)

      Rispondi a questo 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]https://www.appsscript.it[/url] se devi riferirti ad un indirizzo web