1

I have created a CRUD webApp based on Googlesheet. I'm getting duplicate search results when I try to search through multiple rows and columns of the html datatable in the web App. This happens when search test matches data in the multiple columns of the same row. How can I get it to display only unique results? How can alter my code to search through only first 3~4 columns?

When I try searching for Test ( Product) it lists 4 rows, but it should just return 1 row.

Attached snippet.

.gs code

function searchData(formObject){  
      var result = [];
      if(formObject.searchtext){//Execute if form passes search text
          var data = Sheets.Spreadsheets.Values.get(globalVariables().spreadsheetId, globalVariables().dataRange).values;
          for(var i=0;i<data.length;i++){
            for(var j=0;j<data[i].length;j++){
              if(data[i][j].toLowerCase().search(formObject.searchtext.toLowerCase())!=-1){
                result.push(data[i])
              }
            }
          }
      }
      return result;
    }

.js code

    function handleSearchForm(formObject) {
    google.script.run.withSuccessHandler(createTable).searchData(formObject);
    document.getElementById("search-form").reset();
  }
    <!-- SEARCH FORM-->
<form id="search-form" class="form-inline" onsubmit="handleSearchForm(this)">
  <div class="form-group mx-sm-3 mb-2">
    <label for="searchtext" class="sr-only">Search Text</label>
    <input type="search" class="form-control form-control-sm" id="searchtext" name="searchtext" placeholder="Search">
  </div>
  <button type="submit" class="btn btn-sm btn-primary mb-2">Search</button>

I have tried doing this, but it did not help.

function searchData(formObject){  
      var result = [];
      if(formObject.searchtext){//Execute if form passes search text
          var data = Sheets.Spreadsheets.Values.get(globalVariables().spreadsheetId, globalVariables().dataRange).values;
          for(var i=0;i<data.length;i++){
              const COLUMN_INDEX = 4;
              if(data[i][COLUMN_INDEX].toLowerCase().search(formObject.searchtext.toLowerCase())!=-1){
                result.push(data[i])
              }
          }
      }
      return result;
    }
Rubén
  • 34,714
  • 9
  • 70
  • 166

1 Answers1

2

From only first 3~4 columns in your question, I understood that you want to search the text from the columns "C" and "D". In this case, how about the following modified script? In this modification, your Google Apps Script is modified.

Modified script 1:

When your script is modified, it becomes as follows.

function searchData(formObject){ 
  const COLUMN_INDEXES = [2, 3]; // 2 and 3 means the columns "C" and "D".
  var result = [];
  if (formObject.searchtext) {
    var data = Sheets.Spreadsheets.Values.get(globalVariables().spreadsheetId, globalVariables().dataRange).values;
    for (var i = 0; i < data.length; i++) {
      if (COLUMN_INDEXES.some(e => data[i][e].toLowerCase().includes(formObject.searchtext.toLowerCase()))) {
        result.push(data[i]);
      }
    }
  }
  return result;
}
  • About const COLUMN_INDEX = 4; in your script, in this case, the column "E" is used. When you want to check the columns "C" and "D", please use the indexes of 2 and 3.

  • If you want to check only the column "D", please modify const COLUMN_INDEXES = [2, 3] to const COLUMN_INDEXES = [3].

Modified script 2:

In this modification, Sheets API is not used. Please set your sheet name and Spreadsheet ID.

function searchData(formObject) {
  const sheetName = "Sheet1"; // Please set the sheet name.
  const spreadsheetId = "###"; // Please set the Spreadsheet ID.

  const searchText = formObject.searchtext.toLowerCase();
  const result = SpreadsheetApp
    .openById(spreadsheetId)
    .getSheetByName(sheetName)
    .getDataRange()
    .getValues()
    .filter(r => [r[2], r[3]].some(c => c.toLowerCase().includes(searchText)));
  return result;
}
  • In this modified script, searchText is searched from the columns "C" and "D". When the value of searchText is included in the values of columns "C" and "D", the row is retrieved.

  • In this script, getDataRange is used. If you want to search the values from other range, please modify the range of above script.

  • If you want to check only the column "D", please modify [r[2], r[3]].some(c => c.toLowerCase().includes(searchText))) to [r[3]].some(c => c.toLowerCase().includes(searchText))).

Note:

References:

Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • I tried using Method 1, that doesn't seem to work. Well the search function doesn't seem to work now. after changing the code. Any thoughts? Same for second method. – user3558255 Oct 14 '21 at 06:04
  • @user3558255 Thank you for replying. I apologize for the inconvenience. Unfortunately, I cannot replicate your replying. When I tested my script using sample values, the searched values are returned as the 2-dimensional array. This is due to my poor skill. I deeply apologize for this. So in order to correctly understand your current issue, can I ask you about the detailed flow for correctly replicating your issue? By this, I would like to try to understand it. – Tanaike Oct 14 '21 at 06:08
  • @user3558255 If you can do, in order to correctly understand your situation, can you provide the sample Spreadsheet including the current script using my proposed script? By this, I would like to check your current issue. Because when I tested my script using sample values, the searched values are returned as the 2-dimensional array. This is due to my poor skill. I deeply apologize for this again. By the way, I cannot understand `This is how the global variables looks like.`. Can I ask you about the detail of it? – Tanaike Oct 14 '21 at 06:10
  • I'm trying to replicate this app: https://www.bpwebs.com/crud-operations-on-google-sheets-with-online-forms/ GS: https://script.google.com/home/projects/1VXgcXJA0joQ0YYi3_w-UwUnpgiHA2KlayxqCf7uswk_vzS74uwTI4njD/edit – user3558255 Oct 14 '21 at 06:13
  • @user3558255 Now I noticed that a sample Spreadsheet is showing in your showing URL. If you are using this Spreadsheet, the columns "C" and "D" are "Gender", "Date OF Birth". You want to search the value from these columns? I understood that you want to search the columns "C" and "D" from your question. – Tanaike Oct 14 '21 at 06:30
  • @user3558255 Or, when you want to search the values from the columns "C" and "D" in [your sample image](https://i.stack.imgur.com/2V7zC.png), in this case, at the Spreadsheet, those columns are corresponding to "A" and "B". In this case, please modify `.filter(r => [r[2], r[3]].some(c => c.toLowerCase().includes(searchText)));` to `.filter(r => [r[0], r[1]].some(c => c.toLowerCase().includes(searchText)));` in my proposed script, and test it again. – Tanaike Oct 14 '21 at 06:35