使用TextBox和onKeyUp以及onKeyDown进行即时搜索

时间:2012-07-24 10:18:28

标签: google-apps-script

我想制作Google Apps脚本网络应用程序,在您输入TextBox时立即搜索电子表格。

我现在正在使用的实现如下。对于每个按键事件,使用当前搜索字符串进行新搜索。我正在使用onKeyUp正在调用的函数的延迟,如果onKeyDown被调用,我试图杀死上一个函数调用,只是使用new。这有时会工作,但搜索需要不同的时间来完成,所以最后一个完成并不总是正确的。

我不知道如何在Google Apps脚本中解决此任务。这可以使用类似的东西来实现,但这些功能是不可用的:

var timer;
function up(){
  setTimeout(mySpreadsheetSearchFunction, 500);
}
function down(){
  clearTimeout (timer);
}

这是当前实现的代码无法正常工作:

function up(){
  var cache = CacheService.getPrivateCache();
  var now = parseInt(cache.get('iterate'));
  Utilities.sleep(500);
  if(parseInt(cache.get('iterate')) !== parseInt(now)){
    return;
  }else{
    search();
  }
  showInGui();
}

function down(){
  var cache = CacheService.getPrivateCache();
  cache.put('iterate', 1+parseInt(cache.get('iterate')));
}

CacheService可能是这项工作的错误工具,有什么可能更好?这是实现这样的事情的正确方法吗?

2 个答案:

答案 0 :(得分:0)

不确定是否必须使用缓存功能才能获得快速结果...我制作了一个非常好的脚本,我一直使用它的变体;-) 你可以在this test sheet

上测试一下

这是它的工作原理,脚本可能很长但只看处理程序部分(单击)

在其他版本中,我读取了函数外部的电子表格,因此数据数组成为全局变量,主要是为了限制电子表格调用的数量(有时可能达到此版本的配额限制)

// G. Variables
var sh = SpreadsheetApp.getActiveSheet();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var lastrow = ss.getLastRow();
// ...
function onOpen() {
  var menuEntries = [ {name: "Search GUI", functionName: "searchUI"},
                     ];
  ss.addMenu("Search Utilities",menuEntries);// custom menu
}
// Build a simple UI to enter search item and show results + activate result's row
function searchUI() {
  var app = UiApp.createApplication().setHeight(130).setWidth(400);
  app.setTitle("Search by name / lastname / adress");
  var panel = app.createVerticalPanel();
  var txtBox = app.createTextBox().setFocus(true);
  var label=app.createLabel(" Item to search for :")
  panel.add(label);
  txtBox.setId("item").setName("item");
  var label0=app.createLabel("Row").setWidth("40");
  var label1=app.createLabel("Name").setWidth("120");
  var label2=app.createLabel("Lastname").setWidth("120");
  var label3=app.createLabel("Street").setWidth("120");
  var hpanel = app.createHorizontalPanel();
  hpanel.add(label0).add(label1).add(label2).add(label3)
//
  var txt0=app.createTextBox().setId("lab0").setName("0").setWidth("40");
  var txt1=app.createTextBox().setId("lab1").setName("txt1").setWidth("120");
  var txt2=app.createTextBox().setId("lab2").setName("txt2").setWidth("120");
  var txt3=app.createTextBox().setId("lab3").setName("txt3").setWidth("120");
  var hpanel2 = app.createHorizontalPanel();
  hpanel2.add(txt0).add(txt1).add(txt2).add(txt3)
  var hidden = app.createHidden().setName("hidden").setId("hidden");
  var subbtn = app.createButton("next ?").setId("next").setWidth("250");
  panel.add(txtBox);
  panel.add(subbtn);
  panel.add(hidden);
  panel.add(hpanel);
  panel.add(hpanel2);
  var keyHandler = app.createServerHandler("click");
  txtBox.addKeyUpHandler(keyHandler)
  keyHandler.addCallbackElement(panel);
//
  var submitHandler = app.createServerHandler("next");
  subbtn.addClickHandler(submitHandler);
  submitHandler.addCallbackElement(panel);
//
  app.add(panel);  
  ss.show(app);
  }
//
function click(e){
   var row=ss.getActiveRange().getRowIndex();              
   var app = UiApp.getActiveApplication();
   var txtBox = app.getElementById("item");
   var subbtn = app.getElementById("next").setText("next ?")      
   var txt0=app.getElementById("lab0").setText('--');
   var txt1=app.getElementById("lab1").setText('no match').setStyleAttribute("background", "white");// default value to start with
   var txt2=app.getElementById("lab2").setText('');
   var txt3=app.getElementById("lab3").setText('');
   var item=e.parameter.item.toLowerCase(); // item to search for
   var hidden=app.getElementById("hidden")                  
   var data = sh.getRange(2,2,lastrow,3).getValues();// get the 3 columns of data
       for(nn=0;nn<data.length;++nn){ ;// iterate trough
     Logger.log(data[nn])
         if(data[nn].toString().toLowerCase().match(item.toString())==item.toString()&&item!=''){;// if a match is found in one of the 3 fields, break the loop and show results
          txt0.setText(nn+2);
          txt1.setText(data[nn][0]).setStyleAttribute("background", "cyan");
          txt2.setText(data[nn][1]);
          txt3.setText(data[nn][2]);
          sh.getRange(nn+2,2).activate();
          subbtn.setText("found '"+item+"' in row "+Number(nn+2)+", next ?");
          hidden.setValue(nn.toString())                                                                                  
          break
          }
      }
return app    ;// update UI
}
function next(e){
   var row=ss.getActiveRange().getRowIndex();              
   var app = UiApp.getActiveApplication();
   var txtBox = app.getElementById("item");
   var subbtn = app.getElementById("next").setText("no other match")      
   var hidden=app.getElementById("hidden");                  
   var start=Number(e.parameter.hidden)+1;//returns the last search index stored in the UI
   var item=e.parameter.item.toLowerCase(); // item to search for
   var txt0=app.getElementById("lab0");
   var txt1=app.getElementById("lab1").setStyleAttribute("background", "yellow");
   var txt2=app.getElementById("lab2");
   var txt3=app.getElementById("lab3");
   var data = sh.getRange(2,2,lastrow,3).getValues();// get the 3 columns of data
       for(nn=start;nn<data.length;++nn){ ;// iterate trough
         if(data[nn].toString().toLowerCase().match(item.toString())==item.toString()&&item!=''){;// if a match is found in one of the 3 fields, break the loop and show results
          txt0.setText(nn+2);
          txt1.setText(data[nn][0]).setStyleAttribute("background", "cyan");
          txt2.setText(data[nn][1]);
          txt3.setText(data[nn][2]);
          sh.getRange(nn+2,2).activate();
          subbtn.setText("found '"+item+"' in row "+Number(nn+2)+", next ?");                                                                                               
          hidden.setValue(nn.toString())                                                                                  
          break
          }
      }
return app    ;// update UI
}

答案 1 :(得分:0)

使用HtmlService,您可以在纯HTML和JavaScript中实现此功能。这使您能够加载电子表格数据一次,然后执行搜索客户端,性能应该更好。