1

我有一个提交按钮,其启用状态取决于其他几个小部件的状态;而且我无法在 Google Apps 脚本中提出客户端解决方案来进行验证。

例如,取三个复选框。如果(如果且仅当)至少启用了一个复选框,则应启用提交按钮。

我知道我可以通过服务器端验证来做到这一点,但应该不需要这么简单的东西。有什么建议么?谢谢。

4

2 回答 2

2

完全可以编写依赖于多个小部件状态的客户端处理程序,因为您可以将多个validateX调用链接到单个处理程序上。这里的问题是clientHandlers无法验证复选框状态。

我已经打开了一个关于这个问题的问题,你可能想给它加星标以跟踪更新和投票:

问题 2220:复选框的 UiApp 处理程序 validateValue

无论如何,有可能解决这个问题,我只是向您展示可以根据多个小部件值使用处理程序,但是当问题 2220 得到解决时,此代码会简单得多:

function doGet(e) {
  var app = UiApp.createApplication().setTitle('Checkbox Test');
  var panel = app.createVerticalPanel(),
      noChecked = app.createClientHandler(),
      button = app.createButton('Test').setEnabled(false);

  for( var i = 0; i < 3; ++i ) {
    var cb1 = app.createCheckBox('cb'+i),
        cb2 = app.createCheckBox('cb'+i).setVisible(false),
        tb = app.createTextBox().setValue('false').setVisible(false);
    cb1.addClickHandler(app.createClientHandler().forTargets(cb2).setValue(true).setVisible(true).forEventSource().setVisible(false).forTargets(tb).setText('true'));
    cb2.addClickHandler(app.createClientHandler().forTargets(cb1).setValue(false).setVisible(true).forEventSource().setVisible(false).forTargets(tb).setText('false'));
    cb1.addClickHandler(app.createClientHandler().forTargets(button).setEnabled(true));
    cb2.addClickHandler(noChecked.validateMatches(tb,'false'));
    panel.add(cb1).add(cb2).add(tb);
  }
  noChecked.forTargets(button).setEnabled(false);  

  return app.add(panel.add(button));
}
于 2012-12-19T19:25:15.610 回答
0

ClientHandlers 是故意简单的。你可以用ServerHandlers做任意代码,速度差异应该比较小。否则,是的,这是设计使然,如果您需要更复杂的客户端逻辑,则需要使用 HtmlService。

UiApp 和 HtmlService 之间的权衡与我们如何保证您不能从脚本中提供恶意代码有关。UiApp 代码使用限制性但绝对安全的简单构建器模式,而 HtmlService 使用复杂的沙箱来实现该目标,权衡不适用于旧浏览器和其他一些限制。

如果我理解正确的话,这个特定的用例在 UiApp 中是可行的。如果您想要一个可以翻转的显示/隐藏按钮的示例,这里有一个:

function doGet() {
  var app = UiApp.createApplication();
  var label = app.createLabel("I am a toggleable widget").setVisible(false);
  var show = app.createButton("show");
  var hide = app.createButton("hide").setVisible(false);
  show.addClickHandler(app.createClientHandler()
      .forTargets(label, hide).setVisible(true).forTargets(show).setVisible(false));
  hide.addClickHandler(app.createClientHandler()
      .forTargets(label, hide).setVisible(false).forTargets(show).setVisible(true));
  return app.add(show).add(hide).add(label);
}

基本上,使用 2 个按钮并翻转按钮的可见性。

复选框实际上是经过验证的 - 但验证的是它们的文本,而不是它们的值:

var app = UiApp.createApplication();
var check = app.createCheckBox();
check.setText("foo").addClickHandler(
    app.createServerHandler("clicked").validateMatches(check, "foo"));
return app.add(check);

问题跟踪器请求是合理的。

于 2012-12-19T21:44:49.660 回答