从不同的HTML标记中获取多个相应的值以在函数中使用 [英] Get multiple corresponding values from different HTML tags to use in a function

查看:63
本文介绍了从不同的HTML标记中获取多个相应的值以在函数中使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过按侧边栏上的按钮来调用功能。

I am trying to call a funtion by pressing the button on my sidebar.

函数应找到< input> 标记的已选中复选框,并从<$中获取相应的名称c $ c>< a> 标签

The function should find checked checkboxes of <input> tags and get corresponding names from <a> tags.

然后将名称传递给后端Google Apps脚本功能(有效)从工作表中获取一系列日历。

Then it passes names to backend Google Apps script function (which works) to get an array of calendars from sheet.

然后,它将一组名称和日历收集到一个对象{}中,并将其传递给另一个后端函数,该函数获取日历事件并将其写入工作表(这也可以工作) )。

Then it collects an array of names and calendars into one object{} and passes it to another backend function which gets calendar events and writes them to a sheet (which also works).

最终结果应该是:将日历中的事件写入工作表(从后端开始工作)。我没有从侧边栏获得事件的信息。

所以我猜想importJobs()函数存在一些错误。

So I guess there are some errors in this importJobs() function.

    //get button by id, on click run function
    document.getElementById("btn").addEventListener("click", createData)

函数:

//gets an object with 2 arrays: names and calendars
//to pass to backend function and make records to sheet
function createData() {

     //getting all checkboxes
     var allCheckboxes = document.getElementsByClassName("filled-in")
     
     //getting inputs of start and end dates
     var startdate = document.getElementById("startDate").value
     var enddate = document.getElementById("endDate").value
 
     //getting dates as date objects
     var startDate = new Date(startdate)
     var endDate = new Date(enddate)
    
     var chosenNames = []
     
     //getting all <a> tag elements
     var names = document.getElementsByTagName("a")
     
     //converting elements list into array
     var namesArr = Array.from(names)
     
     //looping all checkboxes
     for (var i = 0; i < allCheckboxes.length; i++) {
     
         //getting value of each checkbox
         var checkbox = allCheckboxes[i].value;
         
         //if checkbox is checked
         if (checkbox == true) {         
           
             //getting correspondent employee name
             var name = namesArr[i].value
             
             //and push it to an array
             chosenNames.push(name)
   
         } else {
         
         continue;             
         }
     };
 
   //object with array of chosen names
   var employees = {
   
     names: chosenNames       
   }

   //getting array of cals calling backend function
   var calendars = google.script.run.loopToGetCals(employees)
   
   //putting aray of cals into object
   employees.cals = calendars
 
    //call backend function to get calendar events
   google.script.run.getCalendarEvents(employees, startDate, endDate)
   
}; 

推荐答案

可能有些客户端代码的问题隐藏在通信界面的详细信息中。如评论中所述,某些数据类型无法在Google Apps脚本后端和 HtmlService 客户端前端之间传递。特别值得注意的是 Date 限制

Probably some of the issues with your client-side code are hidden in the details of the communication interface. As mentioned in comments, there are certain datatypes that cannot be passed between the Google Apps Script backend, and the HtmlService client-side frontend. Particularly notable are the Date restrictions.

通常,除非我传递单个值,否则通常将服务器端值序列化为JSON,然后再将其发送到客户端。这样可以确保仅传输可序列化的内容(因此,不会尝试原始的 Date 对象,也不会尝试使用本机Apps Script类对象)。

As a general rule, unless I am passing single values, I will usually serialize a server-side value to JSON before sending it to the client. This makes certain that only serializable things are being transmitted (so no raw Date objects are attempted, nor native Apps Script class objects).

此外,我发现这使得返回较大的响应更加稳定:也许 return< large 2D array> 有时会被视为未定义在客户端,而返回JSON.stringify(< same 2D array>)将作为<$ c $安全到达c> JSON.parse able参数。

Additionally, I have found that this makes returning large responses more stable: perhaps a return <large 2D array> will occasionally be seen as undefined in the client side, while return JSON.stringify(<same 2D array>) will arrive safely as a JSON.parseable parameter.

请牢记这一点,您需要修改对同步代码的使用。赋予 withSuccessHandler 的参数应该是函数变量或内联函数定义,例如

With that in mind, your use of synchronous code needs to be amended. The parameter given to withSuccessHandler should be either a function variable or an inline function definition, e.g.

...
 .withSuccessHandler(foo)
...

在命名空间的其他地方可以看到

where elsewhere in the namespace one sees

function foo(retVal, uObj) { ... }

const foo = (retVal, uObj) => { ... }; // or const foo = function (retVal, uObj) { ... };

内联语法类似于:

...
  .withSuccessHandler((retVal, uObj) => { ... })
// or
  .withSuccessHandler(function (retVal, uObj) { ... })
...

在所有这些情况下,将使用2个参数调用成功处理程序-服务器端函数的返回值( arg1 )和指定的用户对象分配给调用的 google.script.run 任务运行程序( arg2 )。

In all these cases, the success handler is invoked with 2 arguments - the return value of the server-side function (arg1), and the specified "user object" assigned to the invoked google.script.run task runner (arg2).

function getCheckedNames() {
  //getting all checkboxes
  const allCheckboxes = Array.from(document.getElementsByClassName("filled-in"));

  //getting all <a> tag elements as a native Array.
  const names = Array.from(document.getElementsByTagName("a"));

  //Reduce from all names to only those that are "checked."
  return allCheckboxes.reduce((arr, cb, i) => {
    // Store the corresponding employee name for any checked checkbox 
    if (cb.value === true)
      arr.push(names[i].value);
    return arr;
  }, []);
}
function requestCheckedCalendars() {
  const chosenNames = getCheckedNames();

  // Submit these names to the backend, to receive their calendar events.
  // Async call, so we will include this object in our call so that the
  // success handler callback can keep working with it.
  google.script.run
    .withUserObject(chosenNames)
    .withSuccessHandler(requestCalendarEvents)
    .loopToGetCals(JSON.stringify({names: chosenNames}));
}
/**
  * @param {string[]} calendars An array of Google Calendar IDs
  * @param {string[]} [chosenNames] An array of names associated with `calendars` (the "user object")
  */
function requestCalendarEvents(calendars, chosenNames) {
  // Convert from JSON-serialized data to native Object types.
  if (typeof calendars === "string")
    calendars = JSON.parse(calendars);
  if (typeof chosenNames === "string")
    chosenNames = JSON.parse(chosenNames);
  if (!chosenNames)
    chosenNames = getCheckedNames();

  const employees = {
    names: chosenNames,
    cals: calendars
  };

  //read inputs of start and end dates
  const startdate = document.getElementById("startDate").value
  const enddate = document.getElementById("endDate").value

  //getting dates as UTC milliseconds
  const startDate = new Date(startdate).getTime();
  const endDate = new Date(enddate).getTime();

  //call backend function to get calendar events
  google.script.run
    // .withSuccessHandler( <some client function> )
    .getCalendarEvents(JSON.stringify(employees), startDate, endDate);
}

其他裁判

  • .withUserObject API
  • .withSuccessHandler API
  • Arrow fns

(从理论上讲,您可以使用 Function#bind 会将一些其他参数预传递给用作成功处理程序的函数,但我尚未对此进行调查。)

(It's theoretically possible you could use Function#bind to pre-pass some additional arguments to the function used as a success handler, but I haven't investigated that.)

这篇关于从不同的HTML标记中获取多个相应的值以在函数中使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆