Как показать активность в скрипте Google Apps
Я хотел бы как-то дать пользователю статус занятости, пока мой скрипт обрабатывает. Я не могу заставить его работать. Вещи происходят только после завершения поиска. Это скрипт веб-приложения.
У меня есть определенный поиск (ограничивает поиск только в подпапках с помощью GDrive), и пока он обрабатывается, я бы хотел дать ответ. Это может занять некоторое время, поэтому я могу ускорить процесс, но, тем не менее, мне бы хотелось, чтобы тикер был занят, подсказывал, менял ярлык кнопки - что угодно. Этот скрипт находится на странице GSite в нашем домене приложений.
Я определяю запись и кнопку следующим образом:
// set text boxes for second column
grid.setWidget(1, 1, app.createTextBox().setId("search")
.setName("search").setWidth(500));
// create button and handler
grid.setWidget(1, 2, app.createButton("Search")
.addClickHandler(app.createServerHandler("findFiles").addCallbackElement(grid))
.setId('button'));
...
var msg = app.createLabel().setId('msg');
app.add(msg);
Пользовательский интерфейс выглядит так:
Я тогда обрабатываю как таковой:
//
// [ initiate the find process ]
//
function findFiles(e) {
var app = UiApp.getActiveApplication();
var msg = app.getElementById('msg');
//----> doesn't appear until search is complete?!
showMsg("...searching, please wait...");
//
// NOTE: This is hardcoded to look in folders that
// have "! Portal !" in their name ONLY
//
var folders = DriveApp.searchFolders('title contains "! Portal !"');
while (folders.hasNext()) {
var folder = folders.next();
showItems(folder, e.parameter.search);
}
if(!g_found) {
msg.setText("Sorry, nothing found. Refresh this page to try again");
} else {
msg.setText("Search is complete. Click file names to open documents.");
}
return app;
}
function showMsg(text) {
var app = UiApp.getActiveApplication();
app.getElementById('msg').setText(text);
return app;
}
//
// [ nested search ]
//
function showItems(folder, search) {
var app = UiApp.getActiveApplication();
var files = folder.searchFiles('fullText contains "' + search + '"');
while(files.hasNext()) {
g_found = true;
var file = files.next();
var link = app.createAnchor(file.getName(), file.getUrl()); // ...URL of file found
app.add(link);
var lf = app.createHTML(''); // ...add a break between URLs found
app.add(lf);
}
var subFldrs = folder.getFolders();
while (subFldrs.hasNext()) {
var fldr = subFldrs.next();
showItems(fldr, search); // ...recursive searching
}
return app;
}
Я пробовал такие вещи, как получение идентификатора кнопки, изменение ее текста и т. Д. Ничего не работает. Что мне не хватает?
2 ответа
Ок, нашел решение...
Мне нужен обработчик клиента вместо.
Итак, код для определения кнопки выглядит следующим образом...
var msg = app.createLabel().setId('msg');
...
// create button and handler
grid.setWidget(1, 2, app.createButton('Search')
.setId('button')
.addClickHandler(app.createServerHandler('findFiles').addCallbackElement(grid))
.addClickHandler(app.createClientHandler()
.forEventSource().setText('...searching...')
.forEventSource().setEnabled(false)
.forTargets(msg).setText('..processing, please wait...') ) );
...
app.add(grid);
app.add(msg);
Это работает, чтобы показать кнопку изменения и обработки сообщения немедленно!
Моя функция findFiles() теперь выглядит следующим образом...
function findFiles(e) {
var app = UiApp.getActiveApplication();
var msg = app.getElementById('msg');
//
// NOTE: This is hardcoded to look in folders that
// have "! Portal !" in their name ONLY
//
var folders = DriveApp.searchFolders('title contains "! Portal !"');
while (folders.hasNext()) {
showItems(folders.next(), e.parameter.search);
}
if(!g_found) {
msg.setText("Sorry, nothing found. Refresh this page to try again");
} else {
msg.setText("Search is complete. Click file names to open documents.");
}
// ...restore button
app.getElementById('button').setText('Search').setEnabled(true);
return app;
}
: V)
Окончательное решение
Это решение работает либо для нажатия кнопки поиска, либо для события KeyDown [Enter]. Пользователь получает индикаторы обработки в любом случае.
Я приведу весь сценарий ниже, так как он имеет несколько изменений в целом:
// Google Info Portal Search
//
// This script is embedded in a GSite page via: Insert -> Apps Script Gadget.
// It is used to search ONLY the folders starting with "! Portal "
//
//
// [ globals ]
//
var g_Fnd = 0;
//
// [ initial 'main' function for web app ]
//
function doGet() {
// create app and grid
var app = UiApp.createApplication();
var grid = app.createGrid(3,3).setId('grid');
// set label for search
grid.setWidget(0, 1, app.createLabel("Enter your search text and click the [Search] button: ")
.setStyleAttribute('fontWeight', 'bold'));
// set text boxes for second column
grid.setWidget(1, 1, app.createTextBox().setId('search')
.setName("search").setWidth(500)
.addKeyPressHandler(app.createServerHandler('checkKeyDown').addCallbackElement(grid))
.addKeyPressHandler(app.createServerHandler('showProcessing').addCallbackElement(grid)) );
// create button and handler
grid.setWidget(1, 2, app.createButton('Search')
.setId('button')
.addClickHandler(app.createServerHandler('showProcessing').addCallbackElement(grid))
.addClickHandler(app.createServerHandler('findFiles' ).addCallbackElement(grid)) );
// processing / error messages
grid.setWidget(2, 1, app.createLabel().setId('msg'));
// add widgets to application and show the app
app.add(grid);
return app;
}
//
// [ check for the Enter key ]
//
function checkKeyDown(event) {
var app = UiApp.getActiveApplication();
if(event.parameter.keyCode == 13) {
findFiles(event);
}
return app;
}
//
// [ show user processing activity ]
//
function showProcessing(event) {
var app = UiApp.getActiveApplication();
if((event.parameter.search > '') &&
((event.parameter.keyCode == 13) || (event.parameter.eventType == 'click')) ) {
app.getElementById('button').setText(' searching ').setEnabled(false);
app.getElementById('msg').setText('...processing - please wait...');
}
return app;
}
//
// [ initiate the find process ]
//
function findFiles(event) {
var app = UiApp.getActiveApplication();
var msg = app.getElementById('msg');
var srch = event.parameter.search;
// NOTE: Results are cummulative, until the page is refreshed.
g_Fnd = 0;
if(srch <= '') {
msg.setText('You haven\'t entered anything to look for? Please enter search text.');
app.getElementById('button').setText('Search').setEnabled(true);
return app;
}
//
// NOTE: The next line is hardcoded to look in Portal folders ONLY
//
var folders = DriveApp.searchFolders('title contains "! Portal "');
while (folders.hasNext()) {
showItems(folders.next(), srch);
}
if(g_Fnd) {
msg.setText('Search is complete. Click file links to open documents.');
} else {
msg.setText('Sorry, nothing found. Refresh this page to try again');
}
// ...restore button for next search
app.getElementById('button').setText('Search').setEnabled(true);
return app;
}
//
// [ nested search ]
//
function showItems(folder, search) {
var app = UiApp.getActiveApplication();
var files = folder.searchFiles('fullText contains "' + search + '"');
var file;
while(files.hasNext()) {
file = files.next();
app.add(app.createAnchor(file.getName()+'<br>', true, file.getUrl()));
g_Fnd++;
}
var subFldrs = folder.getFolders();
while (subFldrs.hasNext()) {
showItems(subFldrs.next(), search); // ...recursive searching
}
return app;
}
Этот код не очень надежен;-P (без попыток / уловки и т. Д.), Но сейчас он выполняет свою работу. Надеюсь, это полезно для других, кто ищет здесь:-)