T6VK
T6VK

Reputation: 65

How to filter data in Column Google Sheets with URL Parameter in Google Script?

I'm trying Google Script and I want to display data based on keyword parameters which will later refer to Column C as a data filter which will be displayed according to what is searched for in the parameter keyword.

For example in my previous project I had a parameter as pagination

?page=1&limit=10

well now I have a new problem to solve which is both search and pagination, I have column b as the reference for the search

?page=1&limit=10&search=San Andreas

How do I implement the code below?

function doGet(e) {
  var page = e.parameter.page || 1;
  var limit = e.parameter.limit || 10;
  var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/10S8Igzt1tpqUBgJHVKpny-2s6G3Y3-vFsLMvlZVqpkc/edit#gid=810612111");
  var sheet = ss.getSheetByName("list_film");
  return getUsers(sheet, page, limit); 
}

function getUsers(sheet, page, limit){
  var rows = sheet.getDataRange().getValues();
  var dataArray = rows.splice(limit * (page - 1), limit).reduce((ar, [a, b, c, d]) => ar.concat({id: a, year: b, title: c, img: d}), []);
  var jo = {};
  jo.user = dataArray;
  var result = JSON.stringify(jo);
  return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);
}

Edit:

I mean column C

Edit for solved:

I want to say thank you to @Tanaike who helped me so hard!

Here's my final code

function doGet(e) {
 var page = e.parameter.page || 1;
  var limit = e.parameter.limit || 10;
  var search = e.parameter.search || "";
  var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/10S8Igzt1tpqUBgJHVKpny-2s6G3Y3-vFsLMvlZVqpkc/edit#gid=810612111");
  var sheet = ss.getSheetByName("list_film");
  return getUsers(sheet, page, limit, search);
}

function getUsers(sheet, page, limit, search){
  var lowCase = search.toString().toLowerCase();
  var rows = sheet.getDataRange().getValues().filter(([,,c]) => c.toString().toLowerCase().includes(lowCase));
  var dataArray = rows.splice(limit * (page - 1), limit).reduce((ar, [a, b, c, d]) => ar.concat({id: a, year: b, title: c, img: d}), []);
  var jo = {};
  jo.user = dataArray;
  var result = JSON.stringify(jo);
  return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);
}

Upvotes: 2

Views: 1482

Answers (1)

Tanaike
Tanaike

Reputation: 201378

I believe your goal as follows.

  • You want to retrieve the values from the sheet "list_film" of Spreadsheet SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/10S8Igzt1tpqUBgJHVKpny-2s6G3Y3-vFsLMvlZVqpkc/edit#gid=810612111").
  • You want to retrieve the values by searching the value of search from the column "B".

Modification points:

  • From e.parameter.page, e.parameter.limit and ?page=1&limit=10&search=San Andreas in your script, I understood that you are using Web Apps.
  • In this case, it is required to use San Andreas of ?page=1&limit=10&search=San Andreas like e.parameter.search.
  • I would like to propose to modify sheet.getDataRange().getValues() in getUsers by adding filter. It's like sheet.getDataRange().getValues().filter(([,b]) => b == search)

When above points are reflected to your script, it becomes as follows.

Modified script:

  var page = e.parameter.page || 1;
  var limit = e.parameter.limit || 10;
  var search = e.parameter.search || "";
  var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/10S8Igzt1tpqUBgJHVKpny-2s6G3Y3-vFsLMvlZVqpkc/edit#gid=810612111");
  var sheet = ss.getSheetByName("list_film");
  return getUsers(sheet, page, limit, search); 
}

function getUsers(sheet, page, limit, search){
  var rows = sheet.getDataRange().getValues().filter(([,b]) => b == search);
  var dataArray = rows.splice(limit * (page - 1), limit).reduce((ar, [a, b, c, d]) => ar.concat({id: a, year: b, title: c, img: d}), []);
  var jo = {};
  jo.user = dataArray;
  var result = JSON.stringify(jo);
  return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);
}
  • In this case, when it requests to https://script.google.com/macros/s/###/exec?page=1&limit=10&search=San Andreas, San Andreas is searched from the column "B" of sheet "list_film" and the rows, which are the same with San Andreas, are returned.
    • If you want to retrieve the values including search, please use b.toString().includes(search) instead of b == search.

Note:

  • When you modified the script of Web Apps, please redeploy the Web Apps as new version. By this, the latest script is reflected to the Web Apps. Please be careful this.

  • Although I'm not sure about the values of column "B", if above script was not the result you expect, please try to modify sheet.getDataRange().getValues().filter(([,b]) => b == search) to sheet.getDataRange().getDisplayValues().filter(([,b]) => b == search) and test it again.

  • If you want to compare with other column instead of the column "B", for example, when you want to compare the value of search with the column "C", please modify filter(([,b]) => b == search) to filter(([,,c]) => c == search).

References:

Added:

Modification points:

  • From your my last code as follows, it was found that my suggested script was not correctly used.

       function doGet(e) {
       var page = e.parameter.page || 1;
        var limit = e.parameter.limit || 10;
        var search = e.parameter.search || "";
        var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/10S8Igzt1tpqUBgJHVKpny-2s6G3Y3-vFsLMvlZVqpkc/edit#gid=810612111");
        var sheet = ss.getSheetByName("list_film");
        return getUsers(sheet, page, limit, search); 
      }
    
      function getUsers(sheet, page, limit, search){
        var rows = sheet.getDataRange().getDisplayValues().filter(([,b]) => b == search);
        var rows = sheet.getDataRange().getValues().slice(1);
        var rows = sheet.getDataRange().getValues().reverse();
        var dataArray = rows.splice(limit * (page - 1), limit).reduce((ar, [a, b, c, d]) => ar.concat({id: a, year: b, title: c, img: d}), []);
        var jo = {};
        jo.user = dataArray;
        var result = JSON.stringify(jo);
        return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);
      }
    
  • At var rows = sheet.getDataRange().getValues().slice(1); and var rows = sheet.getDataRange().getValues().reverse();, the values are retrieved using sheet.getDataRange().getValues(). By this, the values are not filtered. I think that this is the reason of your current issue.

When your current script is modified, it becomes as follows.

Modified script:

function doGet(e) {
 var page = e.parameter.page || 1;
  var limit = e.parameter.limit || 10;
  var search = e.parameter.search || "";
  var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/10S8Igzt1tpqUBgJHVKpny-2s6G3Y3-vFsLMvlZVqpkc/edit#gid=810612111");
  var sheet = ss.getSheetByName("list_film");
  return getUsers(sheet, page, limit, search);
}

function getUsers(sheet, page, limit, search){
  var rows = sheet.getDataRange().getDisplayValues().filter(([,,c]) => c == search);
  var dataArray = rows.splice(limit * (page - 1), limit).reduce((ar, [a, b, c, d]) => ar.concat({id: a, year: b, title: c, img: d}), []);
  var jo = {};
  jo.user = dataArray;
  var result = JSON.stringify(jo);
  return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);
}
  • If you want to remove the 1st header row and return the reversed values, please modify the function getUsers as follows.

      function getUsers(sheet, page, limit, search){
        var rows = sheet.getDataRange().getValues().slice(1).filter(([,,c]) => c == search).reverse();
        var dataArray = rows.splice(limit * (page - 1), limit).reduce((ar, [a, b, c, d]) => ar.concat({id: a, year: b, title: c, img: d}), []);
        var jo = {};
        jo.user = dataArray;
        var result = JSON.stringify(jo);
        return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);
      }
    

Upvotes: 3

Related Questions