3

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

2
  • salesforce.com/us/developer/docs/apexcode/Content/… gives a couple of examples. Are they not working for you? May 28, 2015 at 0:10
  • Unfortunately not. I am working on a solution that can build the searchquery string based on the checkboxes mentioned and that page does not have that type of information. I have been getting closer by adding a bunch of IF statements in the Controller
    – Jason
    May 28, 2015 at 14:08

2 Answers 2

3

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;
}
3
  • This looks very solid. I tried using it only change I made was removing the 2 extra best_practice_guides from the ArticleTypeFilter method and moving the String Literal to one line so it had no line breaks (Dev Console complained) and I am getting System.NullPointerException: Attempt to de-reference a null object referencing line 22 which in the code above would be if(ht) filters.add('ArticleType = \'How_To_Docs__kav\'');
    – Jason
    May 28, 2015 at 17:13
  • Ah that's why you were checking against true, you didn't instantiate them. I added that to the constructor but you can add back bool == true.
    – Adrian Larson
    May 28, 2015 at 17:44
  • I updated the original question to show my latest version of the controller I needed to make a few changes the OR filters would not work so needed it to be an IN and also changed the IF in method SearchArticles to have more code and an ELSE
    – Jason
    May 28, 2015 at 19:46
3

I have added a if/else statement - if the checkboxes(boolean) are all true then the SOSL has AND statements added to the end of your original SOSL to filter based on article name (just assuming you want to filter based on the article names) else the searchstring is your original SOSL.

public class ArticleSearch {

    public List<KnowledgeArticleVersion> articleList {get; private set;}
    public String searchstring { get; set; }
    public String searchquery;
    public ArticleSearch() {
        articleList = new List<KnowledgeArticleVersion>();
        searchString = String.isBlank( ApexPages.currentPage().getParameters().get('tryit') ) ? 'sample' : ApexPages.currentPage().getParameters().get('tryit'); 
        searchArticles();   
}
public PageReference searchArticles() {      

    if(boolean1 & boolean2 & boolean3 & boolean4 & boolean5 ){
        searchquery = 'FIND '+searchString+ 'RETURNING KnowledgeArticleVersion(Id, Title, Summary, LastPublishedDate, ArticleType, UrlName 
                        WHERE PublishStatus='online' AND language='en_US' AND ArticleType = 'ArticleType1' AND ArticleType = 'ArticleType2'
                        AND ArticleType = 'ArticleType3' AND ArticleType = 'ArticleType4' AND ArticleType = 'ArticleType5')';
    }else{
        searchquery = 'FIND '+searchString+ 'RETURNING KnowledgeArticleVersion(Id, 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;
    }
}
1
  • thank you for the Answer. The problem this has is the user can check just 1 or 2 or 3 or 4 or all of the checkboxes so the searchquery that is built needs to be based on which checkboxes are checked and only the first one can have an AND all others if there are more than one need to be an OR otherwise the query will never return a result since an article can only have one articletype
    – Jason
    May 28, 2015 at 14:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.