So you want a demographic field? Do it right or don't bother.
Current release: v1.0
The words we use to describe ourselves are important. Organizations should allow constituents to self-identify on key demographics in their own terms. Organizations have a conflicting need to report categorized demographic information to funders and others who need high level overviews of constituent populations. FuzzyPicklists allows organizations to retain a constituent's own identity words and pull categorized information for funder reports easily.
Obviously the pattern here applies beyond demographic fields to anywhere where free text input is more efficient than an unwieldy picklist.
At a high level, on any object, you have a free text field and a picklist field. When the free text field is updated, the app checks the org's own "dictionary" of known possible values for the text field and finds the corresponding categorized value and puts it in a corresponding picklist field. Both the free text value and the categorized value are retained on the record. Hooray!
On the object where you want one or more FuzzyPicklists, create the following for each FP:
- A text field
- A corresponding datetime text last updated field (hidden)
- A picklist field
- A corresponding datetime picklist last updated field (hidden)
For each FP,
- Create a FP record, looking up to the corresponding object and four corresponding fields.
- For each possible categorized picklist value, create a FuzzyPicklistValue, looking up to the corresponding FP.
- For each possible string match for each FPV, create a FuzzyPicklistPossibility, looking up to the corresponding FPV.
- For each object with a FP, create a new Process that fires on create or edit.
- Create a node for each FP free text field, checking if the text value has changed. If it has, execute a record update the free text datetime field with NOW(). Have each node continue evaluating, not stop.
- Create a final node with no criteria* that calls apex "Match Fuzzy Picklists" and passes the record Id in to variable "recordId". *This works because the code makes sure each picklist field needs updating before updating it, but it could slow save times on records. Best practice for performance tbd.
Set up a list view for each object or FP to surface records that didn't match on a FPP string. Categorize them manually and update the picklist. Watch for patterns and create new FPP records as needed.
Represents a single FP, with lookups to the object and four related fields.
Represents a single possible categorized value for a given FP.
Represents a single possible matching string for a given FuzzyPicklistValue.
A global invocable method that can be called via process builder. Takes a set of Ids, or in the case of PB invocation, a single Id.
The brains of the operation. Takes a set of Ids [assumed to all be of the same object], finds all Fuzzy Picklists configured for that object, and checks each record to see if it needs to have any of its FPs updated. Updates happen if picklist value is null or if the free text field has been updated since the picklist was last evaluated (based on a corresponding datetime field for each field). If no match is found in the FPPs, the picklist is left blank (or cleared out in the case of anupdated text field) and it can be manually categorized and updated.
- Allow for regex strings in FPPs.
- UI that consolidates all records of any object with any uncategorized FPs for centralized manual categorization...? Would this be helpful, or is the List View suggestion adequate?