【问题标题】:Omitting the fields with no value省略没有值的字段
【发布时间】:2019-10-08 19:33:47
【问题描述】:

我需要通过 Google 表格发布考试结果。如果在框中提供了 roll no,则搜索按钮显示完美获得的标记,但我需要省略没有值的字段,如主题 3、5 等,以及它们来自 html 页面的文本框

Here 是我正在使用的工作表和我正在使用的代码...

function doGet(e) {
  return HtmlService.createHtmlOutputFromFile('index')
       .setSandboxMode(HtmlService.SandboxMode.IFRAME)
       .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}

//Search for the id and return the array for that row
function search(id) {
  var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/16IH3yKJjLwM9XA0c4_BN5MVQSKh8hV7gR6_kLLfe8to/edit#gid=0");
  var sheet = ss.getSheetByName("Sheet1");
  var values = sheet
  .getDataRange()
  .getValues()
  .filter(function(row) {
    return row[0] == id;
  });

   return values[0];
}
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <style>
    .hidden {
     display:none;
     }
    </style>
  </head>
  <body>
  <input type="text" id="txtName"/>
  <button id="show">SHOW</button>
  <h1>FMATS</h1>
    Name <input type="text" id="name"/><br>
    Roll <input type="text" id="roll"/><br>
    Subject 1 <input type="text" id="sub1"/><br>
    Subject 2 <input type="text" id="sub2"/><br>
    Subject 3 <input type="text" id="sub3"/><br>
    Subject 4 <input type="text" id="sub4"/><br>
    Subject 5 <input type="text" id="sub5"/><br>
  </body>
<script>
//When click on show button it will run search function
window.onload = function(e){ 
  document.getElementById('show')
    .addEventListener('click', search);
}

//Get the value for txtName input and run search function in code.gs
function search() {
  var txtName = document.getElementById('txtName').value;
  google.script.run.withSuccessHandler(fillInfo).withFailureHandler(function (e) { console.log(e) }).search(txtName);
}

//It will run when a success response comes from search function in code.gs and updates the input with the sheet info
function fillInfo(values) {
  document.getElementById('name').value = values[1];
  document.getElementById('roll').value = values[0];
  for (var i=0;i<values.length-2;i++) {
    if (values[i+2]==null) {
      toggleElement("sub"+i);
    } else {
      document.getElementById("sub"+i).value = values[i+2];
    }
  }  
  //rest of the code here
  document.getElementById('name').value = values[1];
  document.getElementById('roll').value = values[0];
  document.getElementById('sub1').value = values[2];
  document.getElementById('sub2').value = values[3];
  document.getElementById('sub3').value = values[4];
  document.getElementById('sub4').value = values[5];
  document.getElementById('sub5').value = values[6];
}
</script>
</html>

我需要从 HTML 页面中省略主题名称和没有值的文本框。如果搜索到不在表格中的卷,则应显示“未找到任何内容”。这不是必需的,但如果主题名称来自工作表的第 1 行会很好。

我该怎么办?

【问题讨论】:

  • 在收到google.script.run的搜索请求后,我会在服务器端构建html,然后将html返回给withSuccessHandler(function(html){document.getElementById("divid").innerHTML=html})
  • 我对JS不太了解。看不懂这个:(
  • 如果您希望在 Google Apps Script 下使用,则必须学习 JavaScript 1.6。

标签: javascript html google-apps-script google-sheets


【解决方案1】:

有两种方法可以解决这个问题:

  1. 在服务器端创建您的 HTML(如 @Cooper 所说)
  2. 使用 JavaScript 操作 HTML

要在服务器端创建 HTML,您可以使用字符串并自动“写入”html。

那么你的函数将是这样的:

//It will run when a success response comes from search function in code.gs and updates the input with the sheet info
function fillInfo(response) {
  document.getElementById("divid").innerHTML=html
});

如果你绝对想在客户端操作 HTML,你会使用这样的东西:

function toggleElement(id) {
  var td = document.getElementById(id).parentElement;
  var tr = td.parentElement;
  tr.classList.toggle("hidden");
}

用法是这样的:

function fillInfo(values) {
  document.getElementById('name').value = values[1];
  document.getElementById('roll').value = values[0];
  for (var i=0;i<values.length-2;i++) {
    if (values[i+2]==null) {
      toggleElement("sub"+i);
    } else {
      document.getElementById("sub"+i).value = values[i+2];
    }
  }  
  //rest of the code here
}

然后你就会有一些 css 来做这个:

.hidden {
  display:none;
}

编辑:

这是您实施第一个解决方案的方式:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
  <input type="text" id="txtName"/>
  <button id="show">SHOW</button>
  <h1>FMATS</h1>
  <div id="dataDiv"></div>
  </body>
<script>
//When click on show button it will run search function
window.onload = function(e){ 
  document.getElementById('show')
    .addEventListener('click', search);
}

//Get the value for txtName input and run search function in code.gs
function search() {
  var txtName = document.getElementById('txtName').value;
  google.script.run.withSuccessHandler(fillInfo).withFailureHandler(function (e) { console.log(e) }).search(txtName);
}

//It will run when a success response comes from search function in code.gs and updates the input with the sheet info
function fillInfo(values) {
  console.log(values);
  document.getElementById("dataDiv").innerHTML=values
}
</script>
</html>
function doGet(e) {
  return HtmlService.createHtmlOutputFromFile('index')
       .setSandboxMode(HtmlService.SandboxMode.IFRAME)
       .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}

//Search for the id and return the array for that row
function search(id) {
  var ss = SpreadsheetApp.openByUrl("SHEETS URL");
  var sheet = ss.getSheetByName("Sheet1");
  var values = sheet
  .getDataRange()
  .getValues()
  .filter(function(row) {
    return row[0] == id;
  })[0];
  var legends = sheet.getRange(1,1,1,sheet.getMaxColumns()).getValues()[0];
  return createHTML(legends, values);
}

function createHTML(legends, values) {
  Logger.log(legends);
  var htmlResult = "";
  for (var i=0; i<values.length; i++) {
    if (values[i]!=null && values[i]!=="") {
      htmlResult += '<div class="field">' + (legends[i]+"").replace("Sub", "Subject ") + '<input type="text" id="sub1" value="'+values[i]+'"></div>';
    }
  }
  return htmlResult;
}

希望这会有所帮助!

【讨论】:

  • 这似乎是一个优雅的建议,但我不擅长 JS。我对您的第一种方法一无所知。关于 toggleElement 功能我不需要在这里使用 if 子句吗?比如如果 values[~] = Null 然后 sub~ & the SubjectName (最好是整个 ) 被隐藏?
  • 你好@ImtiazSiddique,是的。我已经更新了答案,向您展示如何在您的案例中有效地使用我提供的功能。
  • 我已尝试按照您的建议添加,但现在只显示名称和卷:(script.google.com/macros/s/…
  • 这里是脚本:script.google.com/d/…
  • 完美运行!你是一个天使老兄......非常感谢:D
【解决方案2】:

这里有一个简单示例,主要是在服务器端完成您的问题的完整解决方案。

我喜欢这样做,因为我喜欢能够使用 Utilities.formatString()。

服务器功能: 文件:aq3.gs:

function search(sObj) {
  var ss=SpreadsheetApp.getActive();
  var sh=ss.getSheetByName('Sheet1');
  var rg=sh.getDataRange();
  var vA=rg.getValues();
  var hA=vA[0];
  var dObj={dA:[]};
  for(var i=1;i<vA.length;i++) {
    if(vA[i][0]==sObj.roll) {
      var row=vA[i];
      for(var j=0;j<hA.length;j++) {
        dObj[hA[j]]=row[j];
      }
      break;
    }
  }
  var html="<style>input{margin:2px 5px 0 2px}</style>";
  for(var i=0;i<row.length;i++) {
    if(dObj[hA[i]]) {
      html+=Utilities.formatString('<br /><input id="txt-%s" type="text" value="%s" /><label for="txt-%s">%s</label>',i,dObj[hA[i]],i,hA[i]);
    }
  }
  sObj['results']=html;
  return sObj;
}

运行以下函数以使对话框运行。在搜索框中输入您希望查看的卷,然后单击搜索按钮。你只会得到有数据的盒子。

function launchExamResultsSearchDialog() {
  var userInterface=HtmlService.createHtmlOutputFromFile('aq5');
  SpreadsheetApp.getUi().showModelessDialog(userInterface, "Exam Results");
}

html: 文件:aq5.html:

<!DOCTYPE html>
<html>
  <head>
  <base target="_top">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
  <script>
    function search() {
      var text=$('#srchtext').val();
      google.script.run
      .withSuccessHandler(function(sObj) {
        document.getElementById("results").innerHTML=sObj.results;
      })
      .search({roll:text});
    }

    console.log("My Code");
  </script>
  </head>  
  <body>
    <input type="text" id="srchtext" /><input type="button" value="Search" onClick="search();" />
    <div id="results"></div>
  </body>
</html>

这是对话框的样子:

您可以不断更改搜索卷编号,对话框将用新数据替换数据。您可以通过更改标题来控制主题。

Client To Server Communication

Utilities.formatString()

【讨论】:

    猜你喜欢
    相关资源
    最近更新 更多
    热门标签