0

How to retrieve a complete row from a spreadsheet based on a filter on an action such as a click of a button.

I read that GAS is server-side scripting and it is complex to gain access to a spreadsheet.

Is that so. Please guide me.

I have done till this:

 $("#form-action")
    .button()
    .click(function() {

 var ss = SpreadsheetApp.openById("");
var sheet = SpreadsheetApp.getActiveSpreadsheet();
SpreadsheetApp.setActiveSheet(sheet.getSheetByName('Test'));
SpreadsheetApp.getActiveSheet().getRange("D1").setFormula('Query(A:C,"SELECT A,B,C WHERE B="' + "mydata'" + ',1)'); 
SpreadsheetApp.getActiveSheet().getRange("E:J").getValues();

});
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
tony Stark
  • 53
  • 3
  • 14

1 Answers1

1

Gaining access to the spreadsheet is not difficult at all. You have to remember that while Google Apps Script runs on Google servers, the client-side code (e.g. HTML and JavaScript code you use in your UI templates) will be sent to your browser for rendering, so you can't really mix the two and write jQuery code in GAS(.gs) files or vice versa.

To clarify, commands like

 var ss = SpreadsheetApp.openById("");

must be kept in .gs files. To use client-side HTML and JavaScript, you must create separate HTML files in your project (go to File - New - HTML file). Here's more information on serving HTML in GAS https://developers.google.com/apps-script/guides/html/

Luckily, Google provides the API that allows you to communicate between client and server sides by calling 'google.script.run.' followed by the name of the function in '.gs' file.

Example function in '.gs' file

function addRow() {

var sheet = SpreadsheetApp.getActive()
                          .getSheets()[0];

sheet.appendRow(['Calling', 'server', 'function']);

}

In your HTML template file, here's how you would call this function

<script>
    google.script.run.addRow();
</script>

Consider the example that is more relevant to your situation. In my spreadsheet, the QUERY formula changes dynamically based on the value entered by the user. The form with input field is displayed in the sidebar.

enter image description here

Project structure

enter image description here

Code for 'sidebar.html' is below. Note that using the 'name' attribute of the <input> element is mandatory. On form submit, the value of the attribute ('filterBy') will be transformed into propetry of the form object that we can reference in our server function to get user input.

    <!DOCTYPE html>
    <html>
      <head>
        <base target="_top">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>
      </head>
      <body>
        <form id="myForm">

        <input type="text" name="filterBy">

        <input type="submit" value="submit">

        </form>

        <table id="myTable"></table>

        <script>

        $('document').ready(function(){

         var form = $('#myForm');
         var table = $('#myTable');
         var runner = google.script.run;

         form.on('submit', function(event){

            event.preventDefault(); //prevents <form> redirecting to another page on submit
            table.empty(); // clear the table

            runner.withSuccessHandler(function(array){ //this callback function will be invoked after the 'retriveValues()' function below

            for (var i = 0; i < array.length; i++) {

             var item = '<tr><td>' + array[i] +'</td></tr>';
             table.append(item);


            }


            })
               .retrieveValues(this); //the function that will be called first. Here, 'this' refers to the form element


         });



        });


        </script>
      </body>
    </html>

Code in '.gs' file:

var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheets()[0];


function onOpen() {

var ui = SpreadsheetApp.getUi();
var htmlOutput = HtmlService.createTemplateFromFile('sidebar')
                          .evaluate();

ui.showSidebar(htmlOutput);

}


function retrieveValues(req) {

var res = [];  
var filterBy = req.filterBy; //getting the value of the input field. 

sheet.getRange(1, 2, 1, 1)
     .setFormula("QUERY(A1:A, \"SELECT A WHERE A > " + filterBy + "\")");


sheet.getRange(1, 2, sheet.getLastRow(), 1)
     .getValues()
     .map(function(value){

                     if (value[0] != "") res = res.concat(value[0]); // get only the values that are not empty strings. 

                  });

return res;  


}

Here's the result of entering the value and submitting the form. The server-side function returns the array of values greater than 5. The callback function that we passed as parameter to 'withSuccessHandler' then receives this array and populates the table in the sidebar.

enter image description here

Finally, I'm not sure why you are using the QUERY formula. Instead of modifying 'SELECT' statement, you could simply take the values from the target range an filter them in GAS.

Anton Dementiev
  • 5,451
  • 4
  • 20
  • 32
  • Iam so grateful for this support.. But i am getting `Script function not found: doGet`. Any guidance on this @Anton – tony Stark Aug 25 '17 at 06:41
  • Looking at the code snippet you shared, I can only guess what the end goal is. If your script file is standalone (not bound to a spreadsheet), you need to use the doGet() function to serve the UI. As in doGet () {return HtmlService.createHtmlOutputFromFile('myPage');} Please refer to GAS documentation to learn more about script types https://developers.google.com/apps-script/guides/web Being the engineer of your app, you must do your own research and figure out how things work. Asking for help is fine, but you can't have someone else debug your code line-by-line. – Anton Dementiev Aug 25 '17 at 12:43
  • @ Anton Dementiev: Can you tell me how to get the select box value also like the way we get the input text box value - **filterBy**. – tony Stark Aug 31 '17 at 13:22
  • To be honest, I don't think you appreciate the effort invested by other people into solving your problems. You haven't even marked the question as resolved, but are already asking for more answers. According to Stack Overflow rules, you must demonstrate that you put in at least some thought and effort into solving the problem yourself. This website is not about personal tutoring or having someone write free code for your projects – Anton Dementiev Aug 31 '17 at 13:53