Как показать активность в скрипте 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 (без попыток / уловки и т. Д.), Но сейчас он выполняет свою работу. Надеюсь, это полезно для других, кто ищет здесь:-)

Другие вопросы по тегам