Как я могу отобразить возврат в трех столбцах (в скрипте Google Apps), который выглядит как массив, но (для меня) не ведет себя как один? - PullRequest
0 голосов
/ 16 февраля 2020

Как я могу отобразить это возвращение в трех столбцах в моем веб-приложении , предпочтительно с заданными заголовками?

(выяснили!)

ЭТО ВЕРОЯТНО ВАЖНО! По словам автора функции gvizQuery , которую я использую для поиска данных в ссылочном листе Google, возвращаемое значение представляет собой массив массивов .

Кроме того, теперь я запускаю V8 из Google Apps Script.

Итак, это самая простая версия кода, где я предоставляю серийный номер, который отправляется на запрос функция и возвращается вместе со ссылкой на ou и самого последнего пользователя.

document.getElementById("btnserno1").addEventListener("click",fetchCBOU);
    function fetchCBOU(){
        var sernum = document.getElementById("serial").value;
        google.script.run
        .withSuccessHandler(printCBOUU)
        .queryCBOU(sernum);
    }
        window.printCBOUU = function(CBOUU) {
        console.log(CBOUU);
        var CBOU1 = CBOUU

        document.getElementById('idCB').innerHTML = CBOU1[0];
        document.getElementById('idCBOU').innerHTML = CBOU1[1];
        document.getElementById('idCBRecent').innerHTML = CBOU1[2];
  }

В журналах Stackdriver возврат отображается следующим образом.

17 февраля 2020 г., 12:07:22 Информация [[[5CD725B5B0, / Grundskolor / Boras, utd8377@edu.kunskapsskolan.se]]]

Вот как это выглядит в консоли. Сначала идеальное совпадение.

Perfect match

В веб-приложении оно отображает три значения в одном месте, а два других оставляет как undefined . displays on web app

Если вместо этого я выполню частичное совпадение, в консоли появится больше массивов.

partial match

Но в веб-приложении я получаю все эти значения в первом элементе, а два других элемента по-прежнему undefined .

Если я манипулирую входящими данными после их поступления и пытаюсь разделить их вверх, я получаю разные результаты в зависимости от того, является ли это идеальным или частичным совпадением.

Я меняю среднюю часть кода на это.

        window.printCBOUU = function(CBOUU) {
        console.log(CBOUU);        

        //Creating the new variable, based off CBOUU, adding quotation marks.
        var str = CBOUU + '';
        console.log(str);

        //Creating the new array, based off CBOUU, and now, since it has quotation marks, it becomes an array.
        var CBOU1 = str.split(",");
        console.log(CBOU1);

        document.getElementById('idCB').innerHTML = CBOU1[0];
        document.getElementById('idCBOU').innerHTML = CBOU1[1];
        document.getElementById('idCBRecent').innerHTML = CBOU1[2];
  }

Для идеального совпадения и частичного совпадения, которое имеет только одно совпадающее устройство, все еще работает.

exact & partial single match works

Но если я выполняю частичное совпадение и получаю много совпадений, все ломается, так как он больше не работает с переменными с тремя наборами данных, а вместо этого столько раз, сколько имеется соответствующих устройств, умножается на три значения. И чтобы отобразить их, мне нужно будет продолжать добавлять значения CBOU1 [n] для каждого из них.

enter image description here

Обратите внимание, что это не так данные c! Я пытаюсь отобразить возврат из функции, где я ищу частичный серийный номер из листа Google.

Logs (я думал, что это был массив, с тремя значения для каждого объекта, но, по-видимому, это может быть массив массивов)

[20-02-14 16:28:16:153 CET] [[[5CD9264KBW, /Grundskolor/Boras, user1@my.domain], [5CD9264K64, /Grundskolor/Boras, user2@my.domain], [5CD9264K7V, /Grundskolor/Boras, user3@my.domain], [5CD9264K6M, /Grundskolor/Boras, user4@my.domain]]

Консоль после того, как я попытаюсь превратить его в пригодный для использования массив (здесь это мне кажется, что я представляю собой один массив только из одного объекта со множеством значений)

["5CD9264KBW", "/Grundskolor/Boras", "user1@my.domain", "5CD9264K64", "/Grundskolor/Boras", "user2@my.domain", "5CD9264K7V", "/Grundskolor/Boras", "user3@my.domain", "5CD9264K6M", "/Grundskolor/Boras", "user4@my.domain"]

Мой ответ @Cooper, который пытался мне помочь.

Когда я пробую ваш код, @ Cooper , вот так.

document.getElementById("btnserno1").addEventListener("click",fetchCBOU);
function fetchCBOU(){
document.getElementById("idCBS").innerHTML = "";
var sernum = document.getElementById("serial").value;
google.script.run
.withSuccessHandler(printCBOUU)
.queryCBOU(sernum);
document.getElementById("serial").value = "";
}
window.printCBOUU = function(CBOUU) {
console.log('Device info: ' + CBOUU);

// function splitItUp() { // using it as part of my code, with my return
const data = CBOUU
let a=data.slice(3,-2).trim().replace(/\], \[/g,'~~~').split('~~~');
let b=[];
a.forEach(function(r){b.push(r.split(', '));});
let html='<style>td,th{border:1px solid black;}</style><table>';
b.forEach(function(r,i){html+='<tr><td>${r[0]}</td><td>${r[1]}</td><td>${r[2]}</td></tr>';});
html+='</table>';
document.getElementById("idCBS").innerHTML = html;
}

Я получаю сообщение об ошибке, поскольку оно не может работать с данными.

Uncaught TypeError: data.slice(...).trim is not a function

Если вместо этого установить данные к тому, что похоже на мое возвращение и передает любой серийный номер.

const data='[[[5CD9264KBW, /Grundskolor/Boras, user1@my.domain], [5CD9264K64, /Grundskolor/Boras, user2@my.domain], [5CD9264K7V, /Grundskolor/Boras, user3@my.domain], [5CD9264K6M, /Grundskolor/Boras, user4@my.domain]]';

Затем он запускается (конечно, не использует мой ввод), и именно так выглядит ваша функция forEach я, @ Купер. Как видите, данные не отображаются.

image of forEach result

Страница. html раздел, где отображается результат, выглядит следующим образом .

<table class="striped">
    <tr>
        <td><h6>Serial</h6></td>
        <td><h6>Device OU</h6></td>
        <td><h6>Most Recent User</h6></td>
    </tr>
    <tr>
    <td><h6 id="idCB"></h6></td>
    <td><h6 id="idCBOU"></h6></td>
    <td><h6 id="idCBRecent"></h6></td>
    </tr>
    </table>

<table id="idCBS">
</table>

Когда я получу здесь свои результаты, я бы, конечно, хотел, чтобы заголовки совпали с результатами.

УЖЕ, Я СЕЙЧАС ПРИШЛИ МНОГО БЛИЖЕ К РЕЗУЛЬТАТУ, КОТОРОМУ Я НРАВИТСЯ!

Теперь все данные перечислены в столбцах. Отсюда я позаимствовал некоторые предложения по форматированию с формой for -l oop внутри идеи массива из другого места, чтобы отобразить данные в таблице, что, вероятно, можно сделать несколькими различными более приятными способами. Может быть, даже способ сохранить правильное выравнивание?

Это текущий js.

document.getElementById("btnserno2").addEventListener("click",fetchCBS);
    function fetchCBS(){
//This clears the results between searches. Else the html+= below will keep adding rows of data at the bottom.
        document.getElementById("idCBS").innerHTML = "";

        var sernum = document.getElementById("serial2").value;
        google.script.run
        .withSuccessHandler(printCBS)
        .queryCBS(sernum);
        document.getElementById("serial2").value = "";
    }

    window.printCBS = function(CBS) {
    console.log(CBS);
    
    var i,innerArray;
    var L = CBS[0].length;
  
    for (i=0;i<L;i++) {
    innerArray = CBS[0][i];
  
    value1 = innerArray[0]; 
    value2 = innerArray[1];
    value3 = innerArray[2];
  
    console.log(value1 + "__" + value2 + "__" + value3)

// This creates the table in the idCBS spot.
// Both <table> and <tr> bits can be removed, and result is still the same.    

    let html='<style>td,th{border:0px solid black;}</style><table>';
    html+='<tr><td>' + value1 + '</td><td>' + value2 + '</td><td>' + value3 + '</td></tr>';
    html+='</table>';
    
    document.getElementById("idCBS").innerHTML += html;
  
    }
}

//Code for the clearResults button
document.getElementById("clearResults").addEventListener("click",clrResults);
function clrResults(){
    document.getElementById("idCBS").innerHTML = "";
}

Отображается на странице. html вот так.

    <h4>Results<button class="waves-effect waves-light btn-small" id="clearResults">Clear Results</button></h4>
    
    <table class="striped">
        <tr>
            <td><h6>Serial</h6></td>
            <td><h6>Device OU</h6></td>
            <td><h6>Most Recent User</h6></td>
        </tr>
        <table id="idCBS">
        </table>
    </table>

Это означает, что у меня есть заголовки приходящей таблицы, видимые перед поиском. Но, поскольку я использую две таблицы, заголовки не реагируют и не подстраиваются под ширину приходящих столбцов, которые имеют более широкие значения. Это выглядит так:

CBL_headers_not_aligned

Если я попытаюсь поместить заголовки в html + = creation l oop в js, я, конечно, получить повторные заголовки. Если я вместо этого помещу заголовки в таблицу idCBS на странице, они будут удалены ранней командой document.getElementById ("idCBS"). Inner HTML = "".

Если я не использую и вместо выберите либо, либо, тогда данные не будут зациклены должным образом, а вместо этого добавляются в ту же строку. Возможно, я не пробовал все комбинации, но я пробовал довольно много.

Я предполагаю, что есть лучшая комбинация js + html для отображения моих данных в идеально выровненной таблице, Я просто еще не нашел решение.

И, теперь я сделал!

Немного изменил код таблицы, чтобы я мог переместить idCBS туда, где он не мешал заголовкам.

        <table>
          <thead>
          <tr>
              <th><h6>Serial</h6></th>
              <th><h6>Device OU</h6></th>
              <th><h6>Most Recent User</h6></th>
          </tr>
        </thead>
        <tbody id="idCBS">
        </tbody>
        </table>

Теперь столбцы выровнены! Итак, пока все хорошо, но если у кого-то есть предложения по улучшению, не стесняйтесь комментировать.

Мне показали, что существует альтернатива перемещению idCBS.

<table id="idCBS">
  <tr><!-- table header  -->
    <th>Serial</th>
    <th>Device OU</th>
    <th>Most Recent User</th>
  </tr>
</table>

Затем используйте:

var myTable = document.getElementById("idCBS");
myTable.insertAdjacentHTML("beforeend", html);

Но если я не переместу idCBS в могу использовать мою кнопку clearResults, так как она сотрет всю таблицу. с idCBS в tdbody, insertAdjacent HTML, конечно, там тоже отлично работает.

1 Ответ

0 голосов
/ 16 февраля 2020
function splitItUp() {
  var ss=SpreadsheetApp.getActive();
  var sh=ss.getActiveSheet();
  var data='[[[5CD9264KBW, /Grundskolor/Boras, user1@my.domain], [5CD9264K64, /Grundskolor/Boras, user2@my.domain], [5CD9264K7V, /Grundskolor/Boras, user3@my.domain], [5CD9264K6M, /Grundskolor/Boras, user4@my.domain]]';
  var a=data.slice(3,-2).trim().replace(/\], \[/g,'~~~').split('~~~');
  var b=[];
  a.forEach(function(r){b.push(r.split(', '));});
  sh.getRange(1,1,b.length,b[0].length).setValues(b);                                      
}

Я предполагаю, что вы можете взять его отсюда:

function splitItUp() {
  const data='[[[5CD9264KBW, /Grundskolor/Boras, user1@my.domain], [5CD9264K64, /Grundskolor/Boras, user2@my.domain], [5CD9264K7V, /Grundskolor/Boras, user3@my.domain], [5CD9264K6M, /Grundskolor/Boras, user4@my.domain]]';
  let a=data.slice(3,-2).trim().replace(/\], \[/g,'~~~').split('~~~');
  let b=[];
  a.forEach(function(r){b.push(r.split(', '));});
  let html='<style>td,th{border:1px solid black;}</style><table>'; 
  b.forEach(function(r,i){html+=`<tr><td>${r[0]}</td><td>${r[1]}</td><td>${r[2]}</td></tr>`;});
  html+='</table>';
  var ui=HtmlService.createHtmlOutput(html);
  SpreadsheetApp.getUi().showModelessDialog(ui, 'Split It Up')                                     
}

Я просто поместил его в диалог, так как у меня сейчас нет удобного веб-приложения.

Хорошо, возможно, это то, что вы хотите.

function splitItUp() {
  const data='[[[5CD9264KBW, /Grundskolor/Boras, user1@my.domain], [5CD9264K64, /Grundskolor/Boras, user2@my.domain], [5CD9264K7V, /Grundskolor/Boras, user3@my.domain], [5CD9264K6M, /Grundskolor/Boras, user4@my.domain]]';
  let a=data.slice(3,-2).trim().replace(/\], \[/g,'~~~').split('~~~');
  let b=[];
  a.forEach(function(r){b.push(r.split(', '));});
  let html='<style>td,th{border:1px solid black;}</style><table>'; 
  b.forEach(function(r,i){html+=`<tr><td>${r[0]}</td><td>${r[1]}</td><td>${r[2]}</td></tr>`;});
  html+='</table>';
  //var ui=HtmlService.createHtmlOutput(html);
  //SpreadsheetApp.getUi().showModelessDialog(ui, 'Split It Up')
  document.getElementByID('iddeviceInfo').innerHTML=html;
}

Хорошо, вот пример небольшого веб-приложения. Я фактически запустил его как диалоговое окно.

html :( имя файла было ah1. 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(){
    splitItUp();
  });
  function splitItUp() {
    const data='[[[5CD9264KBW, /Grundskolor/Boras, user1@my.domain], [5CD9264K64, /Grundskolor/Boras, user2@my.domain], [5CD9264K7V, /Grundskolor/Boras, user3@my.domain], [5CD9264K6M, /Grundskolor/Boras, user4@my.domain]]';
    let a=data.slice(3,-2).trim().replace(/\], \[/g,'~~~').split('~~~');
    let b=[];
    a.forEach(function(r){b.push(r.split(', '));});
    let html='<style>td,th{border:1px solid black;}</style><table>'; 
    b.forEach(function(r,i){html+=`<tr><td>${r[0]}</td><td>${r[1]}</td><td>${r[2]}</td></tr>`;});
    html+='</table>';
    document.getElementById('mydiv').innerHTML=html;
  }  
  console.log('My Code');
  </script>
  </head>
  <body>
    <div id="mydiv"></div>
  </body>
</html>

gs: (для запуска в виде диалога)

function runOne() {
  SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('ah1'), 'Data');
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...