The Multiselector

is a flexible selector that can allow a user to view, search and select multiple object types

View source on Github

Multiselector is an open source project developed by Soldevelo and FrontlineSMS, supported by SocialCoding4Good. It is used in FrontlineSMS and FrontlineCloud to select recipients for messages and contact fields for automations.

Used a The Contact Selector
The Contact selector showing contacts, groups and smart groups.
If you want use MultiSelector, you must run the multiselect function when your document is ready. One way to do this is:
    $(document).ready(function() {
        $("div#containerMaster").multiselect(options, translations, null, contactServiceMaster, "1");
    };
                    
The parameters multiselect function are described below.

Another example: Sports teams in London
A simple lookup from a database of sports teams in London.

Pre-selected and non-editable items
A more complex initialisation with pre-selected and non-editable items.
You can specify items, which should be selected after creating the MultiSelector. To do this, you need to create an array of items and indicate it as the third parameter the multiselect function.
    var preloadedIDs = ["contact-6", "contact-10", "110", "+48987654321", "smartgroup-2"];
    var msPreloaded = $("div#containerPreloaded").multiselect(options, translations, preloadedIDs, contactServiceMaster, "2");
                    
You can also add items after the creation of MultiSelector.
    msPreloaded.addObject("123456", true);
    msPreloaded.addObject("777888999", false);
    msPreloaded.addObject("contact-1", true);
                    
If the second parameter is true, the item is non-editable.

MultiSelector options
You can set few options to be indicated as first parameter the multiselect function.
  • displayLimit
  • The property specifies the number of elements in each category, which will be displayed when entering text in input.
        var options = {
            "displayLimit": {
                "contacts": 4,
                "groups": 1,
                "smartgroups": 1
            },
                            
  • icons
  • You can set the icon, that appears next to the category.
            "icons": {
                "contacts": "fa fa-user",
                "groups": "fa fa-group",
                "smartgroups": "fa fa-cog",
                "phone-number": "fa fa-mobile-phone"
            },
                            
  • language
  • This property allows you to select the language of the translation (see below).
            "language": "en_US",
                            
  • minResultsHeight
  •         "minResultsHeight": 100,
                            
  • contactLoading
  • You can set size and time (in milliseconds) between loading a batch of contacts.
            "contactLoading": {
                "intervalMs": 5,
                "batchSize": 10
            },
                            
  • objectAdded
  • Function which will be called when you select new element from list (see next example).
            objectAdded: function(objectId) {
                $("#lastAddedId").text("Last added id: " + objectId);
                return objectId;
            },
                            
  • objectRemoved
  • Function which will be called when you remove element, which was selected earlier (see next example).
            objectRemoved: function(objectId) {
                $("#lastRemovedId").text("Last removed id: " + objectId);
                return objectId;
            }
        };
                            

MultiSelector translations
You can easily customize selector to your, or several languages. Just create a variable that is similar to the one below and choose the appropriate language in the options.
    var translations = {
        "en_US": {
            "common.item.limit.label": "Showing %s out of %s matches",
            "common.item.selected": "Selected",
            "common.item.show.all": "Show all contacts",
            "common.item.show.all.button": "Show all",
            "common.item.select.selected": "This item is already selected.",
            "common.group.select.disabled": "This group is disabled and you can not select it.",
            "common.item.add.number": "Add this phone number",
            "common.progressbar.label": "Loading, please wait..."
        },

        "pl": {
            "common.item.limit.label": "Pokazano %s z %s dopasowań",
            "common.item.selected": "Wybrano",
            "common.item.show.all": "Pokaż wszystkie kontakty",
            "common.item.show.all.button": "Pokaż wszystko",
            "common.item.select.selected": "Ta pozycja jest już wybrana,",
            "common.group.select.disabled": "Ta grupa jest nieaktywna, nie możesz jej wybrać.",
            "common.item.add.number": "Dodaj ten numer telefonu",
            "common.progressbar.label": "Ładowanie, proszę czekać..."
        }
    };
                        

Properties objectAdded and objectRemoved
Example of use objectAdded and objectRemoved properties. Select and remove some items.

Contact service
You can assume a contactService variable will be available in the global scope, initialised before your function. It should specify the types of objects and 'database' for example:
    var types = {
        "contacts": {
            "name":"contacts",
            "displayName" : "Contacts",
            "customCssClass": "contacts"
            },
        "groups": {
            "name":"groups",
            "displayName" : "Groups",
            "customCssClass": "groups"
            },
        "smartgroups": {
            "name":"smartgroups",
            "displayName" : "Smart Groups",
            "customCssClass": "smartgroups"
            }
    }, fullContactDatabase = {
        "contacts" : [
            {
                "name" : "Alicia",
                "id" : "contact-1",
                "metadata" : "+447943419787"
            },
            ... ... ...
            {
                "name" : "Sturridge Mwakule",
                "id" : "contact-16",
                "metadata" : "I play for Cheldam"
            }
        ],
        "groups" : [
            {
                "name" : "Support Staff",
                "id" : "group-1",
                "metadata" : "4 members",
                "memberCount" : 4
            },
            ... ... ...
            {
                "name" : "Android Owners",
                "id" : "group-3",
                "metadata" : "9 members",
                "memberCount" : 9
            }
        ],
        "smartgroups" : [
            {
                "name" : "Heores",
                "id" : "smartgroup-1",
                "metadata" : "9 members",
                "memberCount" : 9
            },
            ... ... ...
            {
                "name" : "Villains",
                "id" : "smartgroup-2",
                "metadata" : "12 members",
                "memberCount" : 12
            }
        ]
    };

                    
Each type has:
  • name - which is used in code
  • displayName - which is displayed to the user as the heading when listing entries of this grouping
  • customCssClass - which should be given as a css class for each of the members when displaying them
A object in the 'database' has:
  • name - which is displayed to the user
  • id - which is a unique identifier of this object, and will form part of the 'getSelectedObjects' response in the javascript library
  • metaData - which is user-facing information that should be displayed next to the name in the dropdown
contactService variable should contains the following methods:
  • getAll() - returns all objects
  • getTypes() - returns all types of objects
  • getObjectCount(objectType) - returns the number of items type 'objectType'
  • getFilteredMatches(selectedIds, searchString) - returns all objects that match the 'searchString', but excludes any in the 'selectedIds' list

Large number of items
MultiSelector with a 10 thousands items.