[SalesForce] How to create a Dynamic SOSL Query

I need to allow a User to narrow their article search by ArticleType when desired
My current Controller handles the search input just fine and can also accept a search via a URL parameter.

Where I am stuck is Under the search input box I want to have 5 checkboxes 1 for each of the 5 articleTypes we have. If the user checks 0,1,2,3,4 or 5 of the checkboxes I need to add the necessary AND statements to the end of my Query or not add anything if none are selected.

UPDATED

Here is my current version that so far appears to be working i need to do some more testing of course

public class ArticleSearch {

public List<KnowledgeArticleVersion> articleList {get; private set;}
public String searchstring { get; set; }
public Boolean ht { get; set; }
public Boolean kb { get; set; }
public Boolean ug { get; set; }
public Boolean bp { get; set; }
public Boolean rn { get; set; }

public ArticleSearch() {
    articleList = new List<KnowledgeArticleVersion>();
        ht = false;
        kb = false;
        ug = false;
        bp = false;
        rn = false;
}

public String ArticleTypeFilter
{
    get
    {
        List<String> filters = new List<String>();
        if(ht == true) filters.add('\'How_To_Docs__kav\'');
        if(kb == true) filters.add('\'KB_Article__kav\'');
        if(ug == true) filters.add('\'User_Guides__kav\'');
        if(bp == true) filters.add('\'Best_Practice_Guides__kav\'');
        if(rn == true) filters.add('\'Release_Notes__kav\'');
        return String.join(filters, ' , ');
    }
}
public PageReference searchArticles() {      
    IF(String.isBlank(ArticleTypeFilter)) { 
        String searchquery = 'FIND :searchString IN ALL FIELDS RETURNING KnowledgeArticleVersion(Title, Summary, LastPublishedDate, ArticleType, UrlName WHERE PublishStatus=\'online\' AND language=\'en_US\')';
        List<List<SObject>> results = search.query(searchquery);        
        articleList = ((List<KnowledgeArticleVersion>)results[0]);        
        return null; //maybe clear the list?
    }  ELSE {
    String searchquery = 'FIND :searchString IN ALL FIELDS RETURNING KnowledgeArticleVersion(Title, Summary, LastPublishedDate, ArticleType, UrlName WHERE PublishStatus=\'online\' AND language=\'en_US\' ';
    searchquery += ' AND ArticleType IN (' + ArticleTypeFilter + '))';
    system.debug(searchquery);    
    List<List<SObject>> results = search.query(searchquery);        
    articleList = ((List<KnowledgeArticleVersion>)results[0]);
    return null;
}
 } 
    }

So the checkboxes will return a Boolean value to the controller and based on their value I would build the necessary additions to the Query

Best Answer

Note that if(bool == true) is equivalent to if(bool).

UPDATE: Unless that boolean is null...

static final String QUERY_FORMAT = 'FIND :searchString IN ALL FIELDS RETURNING ' +
    'KnowledgeArticleVersion(Title, Summary, LastPublishedDate, ArticleType, UrlName ' +
    'WHERE {0} AND {1} AND {2})';

public List<KnowledgeArticleVersion> articleList {get; private set;}
public String searchstring { get; set; }
public Boolean ht { get; set; }
public Boolean kb { get; set; }
public Boolean ug { get; set; }
public Boolean bp { get; set; }
public Boolean rn { get; set; }

public ArticleSearch() {
    articleList = new List<KnowledgeArticleVersion>();
    ht = false;
    kb = false;
    ug = false;
    bp = false;
    rn = false;
}

public String ArticleTypeFilter
{
    get
    {
        List<String> filters = new List<String>();
        if(ht) filters.add('ArticleType = \'How_To_Docs__kav\'');
        if(kb) filters.add('ArticleType = \'KB_Article__kav\'');
        if(ug) filters.add('ArticleType = \'User_Guides__kav\'');
        if(bp) filters.add('ArticleType = \'Best_Practice_Guides__kav\'');
        if(rn) filters.add('ArticleType = \'Release_Notes__kav\'');
        return String.join(filters, ' OR ');
    }
}
public PageReference searchArticles() {      
    if(String.isBlank(ArticleTypeFilter)) return null; //maybe clear the list?

    String searchquery = String.format(QUERY_FORMAT, new List<String> {
        'PublishStatus=\'online\'', 'language=\'en_US\', ArticleTypeFilter
    });
    searchquery += ' AND ' + ArticleTypeFilter;
    List<List<SObject>> results = search.query(searchquery);        
    articleList = ((List<KnowledgeArticleVersion>)results[0]);
    return null;
}
Related Topic