0

我最近(在这篇文章中)建议了一个脚本,该脚本在允许提交之前检查表单的不同字段是否有答案,我使用带有验证器的客户端处理程序来完成它。

在使用该脚本时,我注意到在某些情况下,即使未满足所有验证条件,也会启用提交按钮。这取决于填写不同字段的顺序。

需要明确的是:如果您一个接一个地填写每个字段,一切都很好,如果由于某种原因您更改了此顺序(从末尾或中间开始),则恰好fileupload没有考虑验证并且提交按钮在没有选择文件的情况下启用。

(写这个我意识到它不是很清楚;-)但是看看在线测试会明白我的意思!!)

这是我使用的演示代码,如果您发现其中有什么错误可以解释这种行为,我会很高兴知道。

var submissionSSKey = '0AnqSFd3iikE3dFZ6M1JDekJIa1I5UEZIZURGN3hhM3c';
var listitems = ['Select a value','value1','value2','value3','value4','value5','value6']
var Panelstyle = {'background':'beige','padding':'40px','borderStyle':'ridge','borderWidth':'15PX','borderColor':'#eecc99'}

function doGet() {
  var app = UiApp.createApplication().setTitle('Form test').setStyleAttribute('padding','50PX');
  var panel = app.createFormPanel().setStyleAttributes(Panelstyle).setPixelSize(400, 250);
  var title = app.createHTML('<B>Form validation test</B>').setStyleAttribute('fontSize','20px').setStyleAttribute('color','brown');
  var grid = app.createGrid(9,2).setId('grid');
  var list1 = app.createListBox().setName('list1');
   for(var i in listitems){list1.addItem(listitems[i])}    
  var list2 = app.createListBox().setName('list2');
   for(var i in listitems){list2.addItem(listitems[i])}    
  var list3 = app.createListBox().setName('list3');
   for(var i in listitems){list3.addItem(listitems[i])}    
  var Textbox1 = app.createTextBox().setWidth('150px').setName('TB1');
  var Textbox2 = app.createTextBox().setWidth('150px').setName('TB2');
  var DateB = app.createDateBox().setWidth('150px').setName('dateB');
  var upLoad = app.createFileUpload().setName('uploadedFile');
  var submitButton = app.createSubmitButton('<B>Submit</B>'); 
  var warning = app.createHTML('Please fill in all fields').setStyleAttribute('background','#FFcc99').setStyleAttribute('fontSize','20px');
  //file upload
  var cliHandler2 = app.createClientHandler()
  .validateLength(Textbox1, 1, 40).validateLength(Textbox2, 1, 40).validateNotMatches(list1,'Select a value').validateNotMatches(list2,'Select a value')
  .validateNotMatches(list3,'Select a value').validateMatches(DateB, '2','g').validateNotMatches(upLoad, 'FileUpload')
  .forTargets(submitButton).setEnabled(true)
  .forTargets(warning).setHTML('Now you can submit your form').setStyleAttribute('background','#99FF99').setStyleAttribute('fontSize','12px');

  //Grid layout of items on form
  grid.setText(0, 0, 'This is a ')
      .setWidget(0, 1, title)
      .setText(1, 0, 'List Selector 1')
      .setWidget(1, 1, list1.addClickHandler(cliHandler2))
      .setText(2, 0, 'List Selector 2')
      .setWidget(2, 1, list2.addClickHandler(cliHandler2))
      .setText(3, 0, 'List Selector 3')
      .setWidget(3, 1, list3.addClickHandler(cliHandler2))
      .setText(4, 0, 'Text Box 1')
      .setWidget(4, 1, Textbox1.addClickHandler(cliHandler2))
      .setText(5, 0, 'Text Box 2')
      .setWidget(5, 1, Textbox2.addClickHandler(cliHandler2))
      .setText(6, 0, 'Date Box')
      .setWidget(6, 1, DateB)
      .setText(7, 0, 'File Upload')
      .setWidget(7, 1, upLoad.addChangeHandler(cliHandler2))
      .setWidget(8, 0, submitButton)
      .setWidget(8, 1, warning);

  var cliHandler = app.createClientHandler().forTargets(warning).setHTML('<B>PLEASE WAIT WHILE DATA IS UPLOADING<B>').setStyleAttribute('background','yellow');
  submitButton.addClickHandler(cliHandler).setEnabled(false);  
  panel.add(grid);
  app.add(panel);
  return app;
}


function doPost(e) {
  var app = UiApp.getActiveApplication();
  var ListVal1 = e.parameter.list1;  
  var ListVal2 = e.parameter.list2;  
  var ListVal3 = e.parameter.list3;  
  var textVal1 = e.parameter.TB1;
  var textVal2 = e.parameter.TB2;
  var dateVal = e.parameter.dateB;
  var sheet = SpreadsheetApp.openById(submissionSSKey).getSheetByName('Summary');
  var lastRow = sheet.getLastRow();
  var targetRange = sheet.getRange(lastRow+1, 1, 1, 6).setValues([[ListVal1,ListVal2,ListVal3,textVal1,textVal2,dateVal]]);
  var fileBlob = e.parameter.uploadedFile;
  var doc = DocsList.createFile(fileBlob);
  app.add(app.createLabel('Thank you for submitting'));
  return app
}

编辑: 这是菲尔回答后代码的修改部分。验证工作更可靠,但仍然缺乏一些恼人的用户友好性......

删除代码,编辑 2最终代码,完整的 doGet:

var submissionSSKey = '0AnqSFd3iikE3dFZ6M1JDekJIa1I5UEZIZURGN3hhM3c';
var listitems = ['Select a value','value1','value2','value3','value4','value5','value6']
var Panelstyle = {'background':'beige','padding':'40px','borderStyle':'ridge','borderWidth':'15PX','borderColor':'#eecc99'}

function doGet() {
  var app = UiApp.createApplication().setTitle('Form test').setStyleAttribute('padding','50PX');
  var panel = app.createFormPanel().setStyleAttributes(Panelstyle).setPixelSize(400, 250);
  var title = app.createHTML('<B>Form validation test</B>').setStyleAttribute('fontSize','20px').setStyleAttribute('color','brown');
  var grid = app.createGrid(10,2).setId('grid');
  var list1 = app.createListBox().setName('list1');
   for(var i in listitems){list1.addItem(listitems[i])}    
  var list2 = app.createListBox().setName('list2');
   for(var i in listitems){list2.addItem(listitems[i])}    
  var list3 = app.createListBox().setName('list3');
   for(var i in listitems){list3.addItem(listitems[i])}    
  var Textbox1 = app.createTextBox().setWidth('150px').setName('TB1');
  var Textbox2 = app.createTextBox().setWidth('150px').setName('TB2');
  var DateB = app.createDateBox().setWidth('150px').setName('dateB');
  var upLoad = app.createFileUpload().setName('uploadedFile');
  var uploadtracker = app.createTextBox().setVisible(false);
  var submitButton = app.createSubmitButton('<B>Submit</B>'); 
  var warning = app.createHTML('Please fill in all fields').setStyleAttribute('background','#FFcc99').setStyleAttribute('fontSize','20px');
  //file upload
  var cliHandler2 = app.createClientHandler()
  .validateLength(Textbox1, 1, 40).validateLength(Textbox2, 1, 40).validateNotMatches(list1,'Select a value').validateNotMatches(list2,'Select a value')
  .validateNotMatches(list3,'Select a value').validateMatches(DateB, '2','g').validateMatches(uploadtracker, 'selected')
  .forTargets(submitButton).setEnabled(true)
  .forTargets(warning).setHTML('Now you can submit your form').setStyleAttribute('background','#99FF99').setStyleAttribute('fontSize','12px');
  var cliHandler3 = app.createClientHandler().forTargets(uploadtracker).setText('selected')
  //Grid layout of items on form
  grid.setText(0, 0, 'This is a ')
      .setWidget(0, 1, title)
      .setText(1, 0, 'List Selector 1')
      .setWidget(1, 1, list1)
      .setText(2, 0, 'List Selector 2')
      .setWidget(2, 1, list2)
      .setText(3, 0, 'List Selector 3')
      .setWidget(3, 1, list3)
      .setText(4, 0, 'Text Box 1')
      .setWidget(4, 1, Textbox1)
      .setText(5, 0, 'Text Box 2')
      .setWidget(5, 1, Textbox2)
      .setText(6, 0, 'Date Box')
      .setWidget(6, 1, DateB.addValueChangeHandler(cliHandler2))
      .setText(7, 0, 'File Upload')
      .setWidget(7, 1, upLoad.addChangeHandler(cliHandler3).addChangeHandler(cliHandler2))
      .setWidget(8, 0, submitButton)
      .setWidget(8, 1, warning)
      .setWidget(9,0,uploadtracker)
      .addClickHandler(cliHandler2);

  var cliHandler = app.createClientHandler().forTargets(warning).setHTML('<B>PLEASE WAIT WHILE DATA IS UPLOADING<B>').setStyleAttribute('background','yellow');
  submitButton.addClickHandler(cliHandler).setEnabled(false);  
  panel.add(grid);
  app.add(panel);
  return app;
}
4

2 回答 2

2

粗略的解决方法

> 这并不完美

该代码添加了一个隐藏元素,用于保存 FileUpload 是否已更改。如果 FileUpload 已更改,它将 TextBox 设置为,SELECTED!但用户可以轻松地将 FileUpload更改回未选择文件,并且无法准确清除此 TextBox。

这是基于我们对 FileUpload 的了解。

  1. 当用户加载 UiApp 时,FileUpload 最初没有选择文件
  2. 当在FileUpload 上触发change事件时,所选文件已更改

所以基于这两件事,当第一次调用change时,我们知道有一个文件被选中。

> 变更摘要

创建隐藏元素

var hidden = app.createTextBox().setStyleAttribute("display","none").setValue("");

删除.validateNotMatches(upLoad, 'FileUpload')并替换为

.validateLength(hidden,1,100)

创建一个新的客户端处理程序

var cliHandler3 = app.createClientHandler().forTargets(hidden).setText("SELECTED!");

插入.addChangeHandler(cliHandler3)旧行。

upLoad.addChangeHandler(cliHandler3).addChangeHandler(cliHandler2)

替换panel.add(grid)为(“隐藏”必须添加到 FormPanel 才能工作)

var vert = app.createVerticalPanel().add(hidden).add(grid);
panel.add(vert);
于 2013-03-12T01:44:28.540 回答
1

看不到在哪里添加评论,但我想问一下 .addClickHandler(clihandler2); 到网格。这是通过在末尾添加它来完成的

grid.setText(0, 0, 'This is a ')  [rest of the code (.setText .setWidget etc) ].addClickHandler(cliHandler2);

另外,你能告诉我小部件位置 9,0 上的 uploadtracker 是什么吗?我没有看到它注意到原始代码已发布,但请参阅修改后的代码中 grid.set(text & widgets) 中的 upload 和 uploadtracker。

于 2013-03-13T19:10:20.303 回答