0

I received this code from another user in this forum.

Issue: As seen in the below screenshot, the search results (or data) starts to appear when you click or start typing in the search box or else only the search box loads without the data.

enter image description here

Requirement: I want to display the results (or data) as the page loads.

The code is given below

  <!doctype html>
    <html lang="en">
      <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    
        <!-- Bootstrap CSS -->
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
       
       <style>
       .nav-link {
       cursor: pointer;
       }
       </style>
    
      </head>
      <body>
        
        <div class="container">
        
        <ul class="nav nav-tabs">
      
      <li class="nav-item">
        <div class="nav-link"id="search-link">Search</div>
      </li>
    
    </ul>
    
         <div id="app"></div>    
      <!-- Content here -->
    </div>
    
        <!-- Option 1: jQuery and Bootstrap Bundle (includes Popper) -->
        <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
    
        
      <script>
      
      var data;
      
      function loadView(options){
    var id = typeof options.id === "undefined" ? "app" : options.id;
    var cb = typeof options.callback === "undefined" ? function(){} : options.callback;
    
    google.script.run.withSuccessHandler(function(html){
    document.getElementById("app").innerHTML = html;
    typeof options.params === "undefined" ? cb() : cb(options.params);
    })[options.func]();
    }
    
    function setDataForSearch(){
    google.script.run.withSuccessHandler(function(dataReturned){
    data = dataReturned.slice();
    }).getDataForSearch();
    }
    
    function search(){
    
    var searchinput = document.getElementById("searchinput").value.toString().toLowerCase().trim();
    var searchWords = searchinput.split(/\s+/);
    var searchColumns = [0,1,2,3,4,5,6,7];
    
    // and or
    
    var resultsArray = data.filter(function(r){
    
    return searchWords.every(function(word){
    return searchColumns.some(function(colIndex){
    return r[colIndex].toString().toLowerCase().indexOf(word) !== -1
    });
    
    });
    
    });
    var searchResultsBox = document.getElementById("searchResults");
    var templateBox = document.getElementById("rowTemplate");
    var template = templateBox.content;
    
    searchResultsBox.innerHTML = "";
    
    resultsArray.forEach(function(r){
    
    var tr = template.cloneNode(true);
    var hinmokuColumn = tr.querySelector(".hinmoku");
    var buhinCodeuColumn = tr.querySelector(".buhinCode");
    var buhinNameColumn = tr.querySelector(".buhinName");
    var hitsuyoColumn = tr.querySelector(".hitsuyo");
    var genkaColumn = tr.querySelector(".genka");
    var kobaiColumn = tr.querySelector(".kobai");
    var sagakuColumn = tr.querySelector(".sagaku");
    var kenshoColumn = tr.querySelector(".kensho");
    
    hinmokuColumn.textContent = r[0];
    buhinCodeuColumn.textContent = r[1];
    buhinNameColumn.textContent = r[2];
    hitsuyoColumn.textContent = r[3];
    genkaColumn.textContent = r[4];
    kobaiColumn.textContent = r[5];
    sagakuColumn.textContent = r[6];
    kenshoColumn.textContent = r[7];
    
    searchResultsBox.appendChild(tr);
    
    });
    }
    
    function loadSearchView(){
    loadView({func:"loadSearchView", callback: setDataForSearch});
    }
    
    window.addEventListener("load", loadSearchView);
    
    function inputEventHandler(e){
    if (e.target.matches("#searchinput")){
      search();
    }
    }
    document.getElementById("app").addEventListener("input",inputEventHandler);
document.getElementById("app").addEventListener("click",inputEventHandler);
        
        </script>
        
      </body>
    </html>

server-side code

function getDataForSearch(){
    
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const ws = ss.getSheetByName("TableData");
  
  return ws.getRange(2, 1, ws.getLastRow(),8).getValues();

}

I need to know what modification needs to be done in the code?

I tried document.getElementById("app").addEventListener("load",inputEventHandler); but it didn't work.

is there any other event listeners available that will load the search results (or data) (without taking any action on the site, i mean without clicking or typing in the search box)?

Thanks in advance.

Edit: loadsearchview function file code

function loadSearchView(){
 
   return loadPartialHTML_("search");
   
}

2 Answers2

0

AddEventListener when you click enter key in keyboard will help you. Link: EventListener Enter Key

Also addEventListener "change" will help you.

edit

If you want your data to load when page is loaded use one of those ways:

window.onload = function() {
        Search();
    } // way one

window.onload = Search(); //way two

<body onclick="Search()"> // way three
aldison
  • 57
  • 3
  • Hi Thank you for your response. but I want to load the data without any action taken but to appear when the page is loaded. I tried "change" it didn't work :( –  Jun 20 '21 at 14:26
  • Modify your body html tag to , and myFunction will load the data when the page will load. – aldison Jun 20 '21 at 14:28
  • It's actually a table, so I did like this "" yet it doesn't load.
    –  Jun 20 '21 at 14:32
  • Onload can only be used for , , – aldison Jun 20 '21 at 14:38
  • added the body, still remain the same. it's not loading. –  Jun 20 '21 at 14:41
  • Thank you unfortunately all three ways didn't load the search data :( –  Jun 20 '21 at 14:59
  • this works `document.getElementById("app").addEventListener("click",inputEventHandler);` in code. –  Jun 20 '21 at 15:15
0

You could use addEventListener with DOMContentLoaded to call a function when all the HTML is loaded and the DOM tree is built. For your particular situation, here's how I managed:

  1. First I need to load data into data variable and call the loadSearchView() function when the page loads:
if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", function () {
       google.script.run.withSuccessHandler(function (r) {
           data = r;
           loadSearchView();
       }).getDataForSearch();
    });
} else {
    google.script.run.withSuccessHandler(function (r) {
        data = r;
        loadSearchView();
    }).getDataForSearch();
}
  1. Then I need to load the search view, but instead of calling setDataForSearch, I implemented another function to call functions after this view is loaded. This might be useful if you want to call more than one function after the searchView loads. So basically the code would be like this:
function loadSearchView() {
   loadView({ func: "loadSearchView", callback: afterSearchViewLoads });
}

function afterSearchViewLoads(){
   loadDataWhenPageLoads();
}

function loadDataWhenPageLoads(){
  var resultArray = data;
  var searchResultsBox = document.getElementById("searchResults");
  var templateBox = document.getElementById("rowTemplate");
  var template = templateBox.content;

  searchResultsBox.innerHTML = "";

  resultsArray.forEach(function (r) {

     var tr = template.cloneNode(true);
     var hinmokuColumn = tr.querySelector(".hinmoku");
     var buhinCodeuColumn = tr.querySelector(".buhinCode");
     var buhinNameColumn = tr.querySelector(".buhinName");
     var hitsuyoColumn = tr.querySelector(".hitsuyo");
     var genkaColumn = tr.querySelector(".genka");
     var kobaiColumn = tr.querySelector(".kobai");
     var sagakuColumn = tr.querySelector(".sagaku");
     var kenshoColumn = tr.querySelector(".kensho");

     hinmokuColumn.textContent = r[0];
     buhinCodeuColumn.textContent = r[1];
     buhinNameColumn.textContent = r[2];
     hitsuyoColumn.textContent = r[3];
     genkaColumn.textContent = r[4];
     kobaiColumn.textContent = r[5];
     sagakuColumn.textContent = r[6];
     kenshoColumn.textContent = r[7];

     searchResultsBox.appendChild(tr);
  });
}

Hope this can solve your problem!

  • @luri Thank you for the time, I'm not a coder, I tried multiple times adding your code but I think I'm messing up the code not knowing where to place it properly, I'm little confused with should i replace the additional modified code or should i add it some where extra to the code? Can you please tell me where the point1 and point 2 should go in the code? Sorry for my poor coding skills :( –  Jun 21 '21 at 05:26
  • No problem. Remove `window.addEventListener("load", loadSearchView);` from your code. Part 1 should be at the bottom of your client-side script, above `` tag. Part 2 are functions declarations that can be placed near `search()` function. You basically need to implement two new functions: `afterSearchViewLoads()` and `loadDataWhenPageLoads()`. And modify the `loadSearchView()` to call `afterSearchViewLoads()` at the callback function. The rest of your original code stays the same! – Iuri Pereira Jun 21 '21 at 12:22
  • 1
    There were some scope issues. Check this version: https://docs.google.com/spreadsheets/d/1GKbfJZhsCcnDOeA_Cn-arMWEuXfOfD9Gr-I0o-2UAig/edit?usp=sharing. You can copy to your drive and see the code. I believe that now It will work! – Iuri Pereira Jun 21 '21 at 15:15
  • Thank you. It's working, Everyday i'm learning, specially from very helpful coders like you :) Thank you very much for spending your valuable time to fix this code. Thank you very very much :D –  Jun 21 '21 at 15:20