【问题标题】:Google Apps Script validation issue in Google UiAppGoogle UiApp 中的 Google Apps 脚本验证问题
【发布时间】:2024-04-29 01:30:02
【问题描述】:

我一直试图弄清楚 Google 协作平台中的 Google Apps 脚本验证,但尚未使验证部分正常工作。

我需要验证两件事:

  1. “位置”文本框中至少有 5 个字符(最多 100 个)
  2. 已从下拉列表中选择日期

如果两个条件都不满足,那么它应该使两件事可见:

  1. 警告异常
  2. warnExceptionMes

就是这样。

我的其余逻辑运行良好。我才刚刚开始。

下面列出了完整的逻辑。我已将我们的域信息替换为 xxxxxxxxx。

到目前为止,它要么从不显示消息并且什么都不做,要么只是让其中一项正确就可以继续前进。它们都应该满足要求,或者应该抛出 warnExceptions。如果用户加载页面并且没有填写任何/或区域并且只是按下按钮,这也将是相同的。

如何验证位置文本框和日期框?

var templateIDToCopy = 'xxxxxxxxxx';
var folderIDtoCopyTo = 'xxxxxxxxxx';
var councilMembers = ['Unknown','Name 1','Name 2'];

function doGet(e) {
  var text= new Array();
  var app = UiApp.createApplication();
  var hpanel = app.createGrid(4, 6).setId('pannel');
  var hpanelException = app.createGrid(2,3).setId('hpanelException');
  var location = app.createTextBox().setName('location').setId("location").setWidth('200');
  var minuteTaker = app.createListBox().setName('minuteTaker').setId("minuteTaker").setWidth('200')
   for (var i = 0 ; i < councilMembers.length; i++) {
    minuteTaker.addItem(councilMembers.valueOf()[i]);
                    }
  
  var dateBox = app.createDateBox().setId('dateBox').setName('dateBox').setFireEventsForInvalid(false);
  var hour = app.createListBox(false).setId('hour').setName('hour')
//  var hour = app.createListBox(false).setId('hour').setName('hour')
  for(h=1;h<13;++h){hour.addItem(h)}
  var min = app.createListBox(false).setId('minute').setName('minute')
  .addItem('00').addItem('15').addItem('30').addItem('45'); 
  var amPm = app.createListBox(false).setId('am').setName('amPm')
  .addItem('AM').addItem('PM');  
  var dateTimeLabel = app.createLabel('',false).setId('dateTimeLabel');
  var submit = app.createButton('Create Minutes').setId('submit').setPixelSize(196, 25);
  var nextSteps = app.createAnchor('Please click here to see the minutes archive.', 'https://drive.google.com/xxxxxxxxxx/folderview?xxxxxxxxxx').setId('nextSteps').setVisible(false);
   
// Setup error message 
  var warnException =app.createImage('https://sites.google.com/xxxxxxxxxx/minutes/create-new-minutes/Opps.png').setId('warnException').setVisible(false);
  var warnExceptionMes = app.createLabel('The date and Location are required. Please try again.').setStyleAttribute('font-weight', 'normal').setStyleAttribute('font-size','14px').setVisible(false);

// handlers
  var handler1 = app.createClientHandler()
  .validateLength(location, 0, 50).validateMatches(dateBox, '2', 'g')
  .forTargets(warnException).setVisible(true)
  .forTargets(warnExceptionMes).setVisible(true);
 
  var handler2 = app.createServerHandler('handlerFunction')
  .validateLength(location, 1, 100).validateNotMatches(dateBox, '2', 'g')
  .addCallbackElement(location).addCallbackElement(dateBox).addCallbackElement(hpanel);
   
  submit.addClickHandler(handler1).addClickHandler(handler2);
   
  hpanel.setWidget(0,0,app.createLabel('Select Date'))
   .setWidget(0,1,app.createLabel('Hour'))
   .setWidget(0,2,app.createLabel('Minutes'))
   .setWidget(0,3,app.createLabel('AM/PM'))
   .setWidget(0,4,app.createLabel('Location'))
   .setWidget(0,5,app.createLabel('Minute Taker'))
   
  hpanel.setWidget(1,0,dateBox)
   .setWidget(1,1,hour)
   .setWidget(1,2,min)
   .setWidget(1,3,amPm)
   .setWidget(1,4,location)
   .setWidget(1,5,minuteTaker)
  
   hpanel.setWidget(2,5,submit)
   app.add(hpanel);//.add(warnException).add(warnExceptionMes);
  
  hpanelException.setWidget(1,1,warnException).setStyleAttribute("text-align", "right")
   .setWidget(1,2,warnExceptionMes)
  // .setWidget(1,2,nextSteps)
   app.add(hpanelException);
   return app;
     }


function handlerFunction(e) {
 var app = UiApp.getActiveApplication();
 app.getElementById('submit').setText('Building, please wait...').setEnabled(false);
   
  var location = e.parameter.location; 
  var determineName = e.parameter.minuteTaker;  
  var date = e.parameter.dateBox;
  var timeZone = date.toString().substr(25,6)+":00";  
  var dateMilli = date.getTime();  
  var hour = parseInt(e.parameter.hour);  
  var amPm = e.parameter.amPm;
  if (amPm == 'PM' && hour != 12) hour = hour + 12;  
  if (hour == 12 && amPm == 'AM') hour = 0;  
  var hourMilli = hour * 3600000;  
  var minMilli = parseInt(e.parameter.minute) * 60000;  
  var milliTotal = dateMilli + hourMilli + minMilli; 

  // create custom format
  var newDate = Utilities.formatDate(new Date(milliTotal), timeZone, 'MM/dd/yy hh:mm aaa');
  app.getElementById('dateTimeLabel').setText(newDate);

  // make a copy of the minutes template to use
  var duplicateID = DriveApp.getFileById(templateIDToCopy)
  .makeCopy('Simply Minutes v1.0 - Stage 1: Building new minutes...')
 .getId();

// get the id of the annual folder where minutes will be stored
  var getFolderID = DriveApp.getFolderById(folderIDtoCopyTo);

// copy new minutes sheet to the annual folder where minutes are stored
  var moveIT = DriveApp.getFileById(duplicateID).makeCopy('Simply Minutes v1.0 - Stage 2: Building new minutes...', getFolderID).getId();

// get the new minutes doc that was created
  var template = DocumentApp.openById(moveIT);
  var templateHeader = template.getHeader();
  var templateBody = template.getActiveSection();

// fill in the values
  templateHeader.replaceText("<date>", newDate);
  templateBody.replaceText("<date>", newDate);
  templateHeader.replaceText("<location>", location);
  templateBody.replaceText("<location>", 'N/A');
  var email = Session.getEffectiveUser().getEmail();
  var eUser = Session.getEffectiveUser().getUsername();
  var createdBy = '';
  
  if(ContactsApp.getContact(email)){     
     var fullName = ContactsApp.getContact(email).getFullName();
     createdBy = fullName;
  }
  else {
     createdBy = 'N/A';
  };
  
  var determineName = e.parameter.minuteTaker;
  templateHeader.replaceText("<minutetaker>", determineName);
  templateHeader.replaceText("<createdby>", createdBy)
  templateBody.replaceText("<minutetaker>", determineName);
  templateBody.replaceText("<createdby>", createdBy); 
  template.setName(newDate + ' TAC Minutes Recorded By ' + determineName);
  
// close out the doc
  template.saveAndClose();
  
  
  // remove the copy that was left in the root directory
 
 //  DriveApp.getFileById(duplicateID).isTrashed();
   DriveApp.getFileById(duplicateID).setTrashed(true);
  
  app = UiApp.getActiveApplication();
  app.getElementById('submit').setText('Completed!').setEnabled(false);
  app.getElementById('nextSteps').setVisible(true);
  return app;
    }
 

【问题讨论】:

    标签: javascript google-apps-script dom-events google-sites


    【解决方案1】:

    像这样尝试(见下文)我更改了一些验证并在 2 个处理程序中分开 + 添加了一个“清除”处理程序以便能够单击删除警告...test code here

    您还必须添加一些内容来清除服务器处理程序中的警告,为什么不将图像和文本警告合并到一个小部件中呢? (更容易清洁)

    代码如下:

    function doGet(e) {
      var text= new Array();
      var app = UiApp.createApplication();
      var hpanel = app.createGrid(4, 6).setId('pannel');
      var clearHandler = app.createClientHandler().forEventSource().setVisible(false)
      var hpanelException = app.createGrid(2,3).setId('hpanelException');
      var location = app.createTextBox().setName('location').setId("location").setWidth('200');
      var minuteTaker = app.createListBox().setName('minuteTaker').setId("minuteTaker").setWidth('200')
       for (var i = 0 ; i < councilMembers.length; i++) {
        minuteTaker.addItem(councilMembers.valueOf()[i]);
                        }
    
      var dateBox = app.createDateBox().setId('dateBox').setName('dateBox').setFireEventsForInvalid(false);
      var hour = app.createListBox(false).setId('hour').setName('hour')
    //  var hour = app.createListBox(false).setId('hour').setName('hour')
      for(h=1;h<13;++h){hour.addItem(h)}
      var min = app.createListBox(false).setId('minute').setName('minute')
      .addItem('00').addItem('15').addItem('30').addItem('45'); 
      var amPm = app.createListBox(false).setId('am').setName('amPm')
      .addItem('AM').addItem('PM');  
      var dateTimeLabel = app.createLabel('',false).setId('dateTimeLabel');
      var submit = app.createButton('Create Minutes').setId('submit').setPixelSize(196, 25);
      var nextSteps = app.createAnchor('Please click here to see the minutes archive.', 'https://drive.google.com/xxxxxxxxxx/folderview?xxxxxxxxxx').setId('nextSteps').setVisible(false);
    
    // Setup error message 
      var warnException =app.createImage('https://sites.google.com/xxxxxxxxxx/minutes/create-new-minutes/Opps.png').setId('warnException').setVisible(false).addClickHandler(clearHandler);
      var warnExceptionMes = app.createLabel('The date and Location are required. Please try again.').setStyleAttribute('font-weight', 'normal').setStyleAttribute('font-size','14px').setVisible(false).addClickHandler(clearHandler);
    
    // handlers
      var handler0 = app.createClientHandler()
      .validateLength(location, 0, 5)
      .forTargets(warnException).setVisible(true)
      .forTargets(warnExceptionMes).setVisible(true);
      var handler1 = app.createClientHandler()
      .validateNotMatches(dateBox, '2', 'g')
      .forTargets(warnException).setVisible(true)
      .forTargets(warnExceptionMes).setVisible(true);
    
      var handler2 = app.createServerHandler('handlerFunction')
      .validateLength(location, 6, 100).validateMatches(dateBox, '2', 'g')
      .addCallbackElement(location).addCallbackElement(dateBox).addCallbackElement(hpanel);
    
      submit.addClickHandler(handler0).addClickHandler(handler1).addClickHandler(handler2);
    
      hpanel.setWidget(0,0,app.createLabel('Select Date'))
       .setWidget(0,1,app.createLabel('Hour'))
       .setWidget(0,2,app.createLabel('Minutes'))
       .setWidget(0,3,app.createLabel('AM/PM'))
       .setWidget(0,4,app.createLabel('Location'))
       .setWidget(0,5,app.createLabel('Minute Taker'))
    
      hpanel.setWidget(1,0,dateBox)
       .setWidget(1,1,hour)
       .setWidget(1,2,min)
       .setWidget(1,3,amPm)
       .setWidget(1,4,location)
       .setWidget(1,5,minuteTaker)
    
       hpanel.setWidget(2,5,submit)
       app.add(hpanel);//.add(warnException).add(warnExceptionMes);
    
      hpanelException.setWidget(1,1,warnException).setStyleAttribute("text-align", "right")
       .setWidget(1,2,warnExceptionMes)
      // .setWidget(1,2,nextSteps)
       app.add(hpanelException);
       return app;
         }
    

    EDIT 在您的评论之后的第二个版本。 我模拟了一个需要一些时间的服务器功能,因此您可以看到所有步骤。 + 我按照建议合并了警告。 (演示代码随版本 2 更新)

    var templateIDToCopy = 'xxxxxxxxxx';
    var folderIDtoCopyTo = 'xxxxxxxxxx';
    var councilMembers = ['Unknown','Name 1','Name 2'];
    
    function doGet(e) {
      var text= new Array();
      var app = UiApp.createApplication();
      var hpanel = app.createGrid(4, 6).setId('pannel');
      var hpanelException = app.createGrid(2,3).setId('hpanelException');
      var location = app.createTextBox().setName('location').setId("location").setWidth('200');
      var minuteTaker = app.createListBox().setName('minuteTaker').setId("minuteTaker").setWidth('200')
       for (var i = 0 ; i < councilMembers.length; i++) {
        minuteTaker.addItem(councilMembers.valueOf()[i]);
                        }
    
      var dateBox = app.createDateBox().setId('dateBox').setName('dateBox').setFireEventsForInvalid(false);
      var hour = app.createListBox(false).setId('hour').setName('hour')
    //  var hour = app.createListBox(false).setId('hour').setName('hour')
      for(h=1;h<13;++h){hour.addItem(h)}
      var min = app.createListBox(false).setId('minute').setName('minute')
      .addItem('00').addItem('15').addItem('30').addItem('45'); 
      var amPm = app.createListBox(false).setId('am').setName('amPm')
      .addItem('AM').addItem('PM');  
      var dateTimeLabel = app.createLabel('',false).setId('dateTimeLabel');
      var submit = app.createButton('Create Minutes').setId('submit').setPixelSize(195, 65);
      var nextSteps = app.createAnchor('Please click here to see the minutes archive.', 'https://drive.google.com/xxxxxxxxxx/folderview?xxxxxxxxxx').setId('nextSteps').setVisible(false);
    
      var clearHandler = app.createClientHandler();
    
    // Setup error message 
      var warnException =app.createImage('https://dl.dropboxusercontent.com/u/211279/clock_e0.gif').addClickHandler(clearHandler);
      var warnExceptionMes = app.createLabel('The date and Location are required. Please try again.').setStyleAttribute('font-weight', 'normal').setStyleAttribute('font-size','14px').addClickHandler(clearHandler);
      var warnPanel = app.createHorizontalPanel().add(warnException).add(warnExceptionMes).setId('warning').setVisible(false);
    
      clearHandler.forTargets(warnPanel).setVisible(false);
    // handlers
      var handler0 = app.createClientHandler()
      .validateLength(location, 0, 5)
      .forTargets(warnPanel).setVisible(true)
    
      var handler1 = app.createClientHandler()
      .validateNotMatches(dateBox, '2', 'g')
      .forTargets(warnPanel).setVisible(true)
    
      var handler2 = app.createClientHandler()
      .validateLength(location, 6, 100).validateMatches(dateBox, '2', 'g')
      .forEventSource().setText('Server Handler is running...').setEnabled(false)
      .forTargets(warnPanel).setVisible(false);
    
      var handlerS = app.createServerHandler('handlerFunction')
      .validateLength(location, 6, 100).validateMatches(dateBox, '2', 'g')
      .addCallbackElement(location).addCallbackElement(dateBox).addCallbackElement(hpanel);
    
      submit.addClickHandler(handler0).addClickHandler(handler1).addClickHandler(handler2).addClickHandler(handlerS);
    
      hpanel.setWidget(0,0,app.createLabel('Select Date'))
       .setWidget(0,1,app.createLabel('Hour'))
       .setWidget(0,2,app.createLabel('Minutes'))
       .setWidget(0,3,app.createLabel('AM/PM'))
       .setWidget(0,4,app.createLabel('Location'))
       .setWidget(0,5,app.createLabel('Minute Taker'))
    
      hpanel.setWidget(1,0,dateBox)
       .setWidget(1,1,hour)
       .setWidget(1,2,min)
       .setWidget(1,3,amPm)
       .setWidget(1,4,location)
       .setWidget(1,5,minuteTaker)
    
      hpanel.setWidget(2,5,submit)
      app.add(hpanel);
    
      hpanelException.setWidget(1,1,warnPanel).setStyleAttribute("text-align", "right")
      app.add(hpanelException);
      return app;
    }
    
    
    function handlerFunction(e) {
      var app = UiApp.getActiveApplication();
      Utilities.sleep(1000);
      app.getElementById('submit').setText('SERVER HANDLER is DONE');
    //  app.getElementById('warning').setVisible(false);// not necassary anymore, see clientHandler2
      return app;
        }
    

    【讨论】:

    • 非常感谢谢尔盖。我真的很感激这方面的帮助。这个真的把我难住了。
    • 所以我仍然没有得到的一件事是如何让提交按钮在满足验证后执行 2 件事... 1 - 将按钮上的文本更改为“正在构建...”并禁用该按钮。我知道我可以在我的函数 handlerFunction(e) 中完成它,但我需要在此之前显示它,否则在所有代码完成之前它不会更新。
    • 也不确定如何将警告消息的图像和文本合二为一? // 设置错误信息 var warnException =app.createImage('sites.google.com/xxxxxxxxxx/minutes/create-new-minutes/…; var warnExceptionMes = app.createLabel('日期和位置为必填项。请重试。').setStyleAttribute('font-weight', 'normal' ).setStyleAttribute('font-size','14px').setVisible(false).addClickHandler(clearHandler);
    • 感谢您不接受...总是很高兴。如果您在两者之间更改问题,我回答了您的问题并提供了示例+代码......我不关注。对不起
    • 抱歉,弄错了。以为我击中了向上箭头。网站的新手。我非常感谢您的帮助。