Search with multiple keywords with matchs in all rows

Hello!

I'm using search with multiple keywords functionality as defined in: https://www.syncfusion.com/forums/146840/advanced-search-with-multiple-keywords

Basically it uses the following code, where text is an array of keywords to be searched for across every column. If ANY of those keywords is matched in ANY column, the row will be returned.

text.forEach((key) => {
  grid.getColumns().forEach((col: any) => {
    if (flag) {
      predicate = new Predicate(col.field, 'contains', key, true, true);
      flag = false;
    } else {
      if(col.field) {
        predicate = predicate.or(col.field, 'contains', key, true, true);
      }
    }
  });
});

How can I make the row return only if ALL keywords are matched in a single row's columns?

Example search: David Lincoln

David
Jones
Joe
Lincoln
David
Lincoln


Only the third row should be returned, as it is the only one with a full match for all the keywords.

Thank you.


3 Replies 1 reply marked as answer

SK Sujith Kumar Rajkumar Syncfusion Team June 12, 2020 09:13 AM UTC

Hi Victor, 
 
Greetings from Syncfusion support. 
 
You can achieve your requirement – How can I make the row return only if ALL keywords are matched in a single row's columns by using the same approach as mentioned in this forum with some changes so that each value entered in search box separated by a comma is considered as column field based on the index. This is demonstrated in the below code snippet, 
 
var val: any; 
var refresh=false; 
var removeQuery = false; 
var valAssign = false; 
 
// Grid’s actionBegin event function 
function onActionBegin(args) {  
    if (args.requestType === "searching") { 
      // Default search operation is cancelled 
      args.cancel = true; 
      // Search string is split based on ‘,’ 
      const text = args.searchString.split(','); 
      console.log(text); 
      let flag = true; 
      let predicate: Predicate; 
      if (this.searchSettings.key !== '') { 
        // Search string is maintained in global variable 
        val = args.searchString; 
        // Filter query is generated considering each split value as each column value 
        text.forEach((key, index) => { 
          var col = this.getColumns()[index]; 
          if (flag) { 
              predicate = new Predicate(col.field, 'contains', key); 
              flag = false; 
            } else { 
              predicate = predicate.and(col.field, 'contains', key); 
            } 
        }); 
        // Query is generated and assigned to Grid query property 
        this.query = new Query().where(predicate); 
        // Search value is emptied 
        this.searchSettings.key = ''; 
        // Flag variables to differentiate operations 
        refresh = true; 
        valAssign = true; 
        removeQuery = true; 
        // Grid is refreshed 
        this.refresh(); 
      } 
    } 
    if (refresh) { 
      refresh = false; 
      this.refresh(); 
    } else if ((document.getElementById(this.element.id + '_searchbar') as HTMLInputElement).value === '' && args.requestType === "refresh" && removeQuery) { 
      // When search text box is emptied this condition will be executed 
      // Empty query is assigned to Grid query  
      this.query = new Query(); 
      removeQuery = false; 
      this.refresh(); 
  } 
} 
 
// Grid’s actionComplete event function 
function onActionComplete(args) { 
  // On Grid refresh the stored search string is assigned to search box 
  if (args.requestType === 'refresh' && valAssign) { 
      (document.getElementById(this.element.id + '_searchbar') as HTMLInputElement).value = val; 
      valAssign = false; 
    } 
} 
 
Sample based on this for your reference, 
 
 
Please get back to us if you require any further assistance. 
 
Regards, 
Sujith R 



VI Victor June 12, 2020 04:49 PM UTC

Thank you for your quick response.

The filter query proposed does not achieve the expected result.


Category Name
Product Name
BeveragesChai
BeveragesChang
BeveragesChartreuse verte

Searching for Beverages Chai will return No records to display

What we need is to show only results that match ALL the keywords in a SINGLE ROW whether it is on a single column or across multiple columns.

So in the previous example the search string "Beverages Chai"  would only return the first row.

While the search string "Beverages Cha" would return all 3 rows (Because Chai, Chang, Chartreuse all contain Cha)

The search string "Char Ve" would only return the third row.

We are trying to emulate the behavior provided by Data Tables:


Specifically:
  1. Match words out of order. For example if you search for Allan Fife it would match a row containing the words Allan and Fife, regardless of the order or position that they appear in the table.
  2. Partial word matching. As DataTables provides on-the-fly filtering with immediate feedback to the user, parts of words can be matched in the result set. For example All will match Allan.
Thank you for your help.



SK Sujith Kumar Rajkumar Syncfusion Team June 15, 2020 12:03 PM UTC

Hi Victor, 
 
Multiple column values entered in the search text box are split using comma for generating search queries in the solution we had provided. We had mentioned this in our previous update as – with some changes so that each value entered in search box separated by a comma is considered as column field based on the index.. Sorry if it was not clear enough. As mentioned the text values are split using commas and the values entered need to be in the following format – “Beverages,Chai” which will return the following result on searching, 
 
 
 
However, you can modify this format structure as per your requirement by changing how the search text is split in the below code used in the actionBegin event handler, 
 
// Grid’s actionBegin event function  
function onActionBegin(args) {   
    if (args.requestType === "searching") {  
      // Default search operation is cancelled  
      args.cancel = true; 
      // Search string is split based on ‘,’  
      // This can be modified as per your need 
      const text = args.searchString.split(',');  
      console.log(text);  
      let flag = true;  
               . 
               . 
   } 
} 
 
Let us know if you have any concerns. 
 
Regards, 
Sujith R 


Marked as answer
Loader.
Up arrow icon