Apex Search with Checkbox Results
January 13th, 2009
This demo is a single Apex custom controller, two Visualforce pages and a wrapper class allowing the user to search an object by keyword (via Dynamic SOQL) and return the results in a page block table with corresponding checkboxes. Selecting one or more checkboxes and clicking the ‘See Results’ button displays the list of the selected items.
This is a very common function as you typically want to search for stuff and then process some selected stuff.
You can run this demo on my developer site.
Custom Controller – CategorySearchController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | public class CategorySearchController { // the results from the search. do not init the results or a blank rows show up initially on page load public List<categoryWrapper> searchResults {get;set;} // the categories that were checked/selected. public List<categoryWrapper> selectedCategories { get { if (selectedCategories == null) selectedCategories = new List<categoryWrapper>(); return selectedCategories; } set; } // the text in the search box public string searchText { get { if (searchText == null) searchText = 'Category'; // prefill the serach box for ease of use return searchText; } set; } // constructor public CategorySearchController() {} // fired when the search button is clicked public PageReference search() { if (searchResults == null) { searchResults = new List<categoryWrapper>(); // init the list if it is null } else { searchResults.clear(); // clear out the current results if they exist } // Note: you could have achieved the same results as above by just using: // searchResults = new List<categoryWrapper>(); // dynamic soql for fun String qry = 'Select c.Name, c.Id From Cat3__c c Where c.Name LIKE \'%'+searchText+'%\' Order By c.Name'; // may need to modify for governor limits?? for(Cat3__c c : Database.query(qry)) { // create a new wrapper by passing it the category in the constructor CategoryWrapper cw = new CategoryWrapper(c); // add the wrapper to the results searchResults.add(cw); } return null; } public PageReference next() { // clear out the currently selected categories selectedCategories.clear(); // add the selected categories to a new List for (CategoryWrapper cw : searchResults) { if (cw.checked) selectedCategories.add(new CategoryWrapper(cw.cat)); } // ensure they selected at least one category or show an error message. if (selectedCategories.size() > 0) { return Page.Category_Results; } else { ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Please select at least one Category.')); return null; } } // fired when the back button is clicked public PageReference back() { return Page.Category_Search; } } |
Visualforce Search Page – Category_Search
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <apex:page controller="CategorySearchController"> <apex:form > <apex:pageBlock mode="edit" id="block"> <apex:pageBlockButtons > <apex:commandButton action="{!next}" value="See Results" disabled="{!ISNULL(searchResults)}"/> </apex:pageBlockButtons> <apex:pageMessages /> <apex:pageBlockSection > <apex:pageBlockSectionItem > <apex:outputLabel for="searchText">Search for Categories</apex:outputLabel> <apex:panelGroup > <apex:inputText id="searchText" value="{!searchText}"/> <!-- We could have rerendered just the resultsBlock below but we want the --> <!-- 'See Results' button to update also so that it is clickable. --> <apex:commandButton value="Search" action="{!search}" rerender="block" status="status"/> </apex:panelGroup> </apex:pageBlockSectionItem> </apex:pageBlockSection> <apex:actionStatus id="status" startText="Searching... please wait..."/> <apex:pageBlockSection title="Search Results" id="resultsBlock" columns="1"> <apex:pageBlockTable value="{!searchResults}" var="c" rendered="{!NOT(ISNULL(searchResults))}"> <apex:column width="25px"> <apex:inputCheckbox value="{!c.checked}"/> </apex:column> <apex:column value="{!c.cat.Name}" headerValue="Name"/> </apex:pageBlockTable> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page> |
Visualforce Results Page – Category_Results
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <apex:page controller="CategorySearchController"> <apex:form > <apex:pageBlock > <apex:pageBlockButtons > <apex:commandButton action="{!back}" value="Back"/> </apex:pageBlockButtons> <apex:pageMessages /> <apex:pageBlockSection title="You Selected" columns="1"> <apex:pageBlockTable value="{!selectedCategories}" var="c"> <apex:column value="{!c.cat.Name}"/> </apex:pageBlockTable> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page> |
Wrapper Class – CategoryWrapper
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | public class CategoryWrapper { public Boolean checked{ get; set; } public Cat3__c cat { get; set;} public CategoryWrapper(){ cat = new Cat3__c(); checked = false; } public CategoryWrapper(Cat3__c c){ cat = c; checked = false; } public static testMethod void testMe() { CategoryWrapper cw = new CategoryWrapper(); System.assertEquals(cw.checked,false); CategoryWrapper cw2 = new CategoryWrapper(new Cat3__c(name='Test1')); System.assertEquals(cw2.cat.name,'Test1'); System.assertEquals(cw2.checked,false); } } |
Categories: Apex, Code Sample, Salesforce, Visualforce












Thx for the post… but:
“String qry = ‘Select c.Name, c.Id From Cat3__c c Where c.Name LIKE \’%'+searchText+’%\’ Order By c.Name’;”
is subject to SOQL Injection. See http://wiki.developerforce.com/index.php/Apex_and_Visualforce_Security_Tips.