【问题标题】:How to show busy activity in Google Apps Script如何在 Google Apps 脚本中显示忙碌活动
【发布时间】:2014-03-20 19:43:40
【问题描述】:

我想在我的脚本处理过程中以某种方式让用户处于忙碌状态。我似乎无法让它工作。事情只有在搜索完成后才会发生。这是一个网络应用脚本。

我有一个特定的搜索(仅限使用 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;
}

我已经尝试过获取按钮 ID 和更改其文本等。没有任何效果。 我错过了什么?

【问题讨论】:

    标签: google-apps-script google-drive-api google-sites


    【解决方案1】:

    好的,找到解决办法了……

    我需要一个客户端处理程序

    所以定义按钮的代码是这样的……

      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)

    【讨论】:

    • 我暂时不会将此标记为已回答,看看其他人是否有更好/其他的想法。
    • 我可能会补充一点,这并不理想。原因是,如果我想处理在文本框中按下 Enter 的情况,我就再也没有更新了。一定与服务器调用没有返回有关?!
    【解决方案2】:

    最终解决方案

    此解决方案适用于单击搜索按钮或 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(没有尝试/捕获等),但它现在可以完成这项工作。 希望它对其他在这里搜索的人有用:-)

    【讨论】:

      猜你喜欢
      • 2019-01-20
      • 2011-05-20
      • 1970-01-01
      • 2014-10-04
      • 2010-12-02
      • 1970-01-01
      • 1970-01-01
      • 2016-10-12
      • 2023-04-01
      相关资源
      最近更新 更多