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:
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.
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.
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().
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
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 :)
Buongiorno,
io ho un foglio con molte righe e quando lo apro avrei necessità di puntare il puntatore del mouse sulla prima riga vuota del foglio. Per fare questa operazione generalmente premo Ctrl+Freccia giù, ma volendo automatizzare questa operazione si può fare con App Script? Ho letto sia questo articolo che questo: https://www.appsscript.it/tutorial/bottoni-che-eseguono-script-in-spreadsheet-con-google-apps-script/
ma essendo un'assoluta neofita non sono riuscita a creare uno script apposito.
Chiedendo su un forum mi è stata suggerita questa soluzione che tuttavia non funziona:
C'è soluzione? :) La ringrazio per qualsiasi consiglio potrà darmi.
Ciao Iolanda,
hai provato ad applicare la soluzione che ti ho indicato nel commento fatto nell'altro articolo?
https://www.appsscript.it/tutorial/bottoni-che-eseguono-script-in-spreadsheet-con-google-apps-script/?replytocom=468
Quell'approccio funziona di sicuro perché l'ho provato prima di risponderti. Ad ogni modo ti confermo che funziona correttamente anche il codice che hai riportato. Fammi sapere!
Salve Michele,
vorrei aggiungere al seguente script la possibilità di inserire contestualmente ( quando crea un nuovo numero di riferimento) nella cella I9 la data odierna :
function incrementaValoreCellaB9() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var cell = sheet.getRange(21, 22);
cell.setValue(cell.getValue() + 25);
}
Mi sa consigliare che stringa aggiungere?
Grazie mille in anticipo per l'aiuto
Ciao Benedetto,
potrebbe esserti utile la funzione Utilities, ad esempio la seguente:
Ciao Michele,
grazie mille per la sollecita risposta, non sono molto pratico ...potresti indicarmi dove aggiungerla in riferimento a quello che ti ho inviato
Ciao Benedetto,
la mia mission è rendere autonomi e consapevoli chi si approccia a questo mondo.
Do degli input nei commenti basati su un codice funzionante come visto nel video e lo faccio a in modo gratuito e per passione, il codice pronto gratuito non è utile né a me né a te né a nessuno.
Per ottenere il risultato desiderato hai bisogno di specificare il range dove vuoi scrivere, e scrivere quello che ti ho inviato prima. La logica è pressoché la stessa di quello che hai già riportato, ti basta solo prendere consapevolmente di cosa fanno le varie righe. Sono certo che ci riuscirai in bene tempo.
Nel mio canale trovi anche un corso gratuito sul JavaScript Semplificato per chi vuole iniziare a programmare, che ti fornirà i concetti basilari per ottenere il massimo risultato con il minimo sforzo :)
ok grazie ..non riesco a capire come inserirlo all'interno dello stesso script ...
sto cercano in rete ma non ho trovato nulla
no problem e buon weekend!
Ciao Michele,
non riesci proprio a darmi la stringa completa collegata alla mia ...mi faresti veramente una GRANDE cortesia.... praticamente deve aggiornare contestualmente la data all'incremento del numero di riferimento con un unico script.........
function incrementaValoreCellaB9() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var cell = sheet.getRange(21, 22);
cell.setValue(cell.getValue() + 25);
}
scusami ancora ... ma non sono riuscito a farlo!
Buona serata