Warning: This site describes the AngularJS (1.x) implementation of the SKY UX framework. We still support this version, but it is in maintenance mode. We no longer develop features for this version of SKY UX, and we recommend that you use the latest version instead. For more information, see developer.blackbaud.com/skyux.

Select field

The select field directive launches a modal that displays items for users to select. By default, the modal allows users to select multiple items. To limit users to a single selection, you can specify single-select mode. In multi-select mode, user selections appear below the select field. In single-selct mode, the selection appears within the field.

Select field settings

  • bb-select-field — Creates a field that launches a modal with items for users to select.
    • ng-model — The array of items that users select on the modal.
    • bb-select-field-clear — Adds a clear button to the select field in single-select mode. To add the clear functionality include this attribute with no value in the bb-select-field element.
    • bb-select-field-text — For multi-select mode, specifies the text to display in the link that opens the modal. For single-select mode, specifies the placeholder text to display in the field until users make selections.
    • bb-select-field-style(Optional.) Indicates whether to display the select field in single- or multi-select mode. By default, the select field uses multi-select mode and you do not need this property. To limit users to a single selection, include this property and set it to single.
    • bb-select-field-icon(Optional.) Indicates whether to use the search icon in single-select mode. By default, the single select icon is the fa-sort icon. To use the fa-search icon, include this property and set it to search.
    • bb-select-field-click(Optional.) Specifies a function to be called when users click the select field. This function is useful when you must fetch the initial items on the modal remotely each time the modal launches.
    • bb-select-field-picker — Defines the content to display in the select field modal.
      • bb-select-field-picker-template — Specifies a template for the content of the modal. The modal generally includes a bb-checklist directive to create a filterable checkbox list for users to select items.
      • bb-select-field-picker-header(Optional.) Specifies a header for the select field modal. (Default: Select value)
    • bb-select-field-skip-while-tabbing(Optional.) Indicates whether to skip over the select field container when a user tabs through it. (Default: false)

Demo

A selection is required in this field.

Markup

<div ng-controller="SelectFieldTestController as selectFieldCtrl">
  <form name="selectFieldCtrl.selectForm">
    <div class="row">
      <div class="col-xs-12 col-md-6 col-lg-4">
        <label for="mutliSelect" class="control-label">
          Multi-select mode
        </label>
        <bb-select-field
          ng-model="selectFieldCtrl.selectedItems"
          bb-select-field-text="Select some values"
          bb-select-field-click="selectFieldCtrl.loadInitialValues()">
          <bb-select-field-picker
          bb-select-field-picker-header="Select values"
          bb-select-field-picker-template="demo/selectfield/selectfieldpicker.html">
          </bb-select-field-picker>
        </bb-select-field>
      </div>
      <div class="col-xs-12 col-md-6 col-lg-4">
        <label for="singleSelect" class="control-label required">
          Single-select mode
        </label>
        <bb-select-field
          ng-model="selectFieldCtrl.selectedSingleItems"
          name="singleSelect"
          bb-select-field-text="Select a value"
          bb-select-field-style="single"
          bb-select-field-clear
          required>
          <bb-select-field-picker bb-select-field-picker-template="demo/selectfield/selectfieldpickersingle.html">
          </bb-select-field-picker>
        </bb-select-field>
        <ng-messages for="selectFieldCtrl.selectForm.singleSelect.$error" class="text-danger" ng-show="selectFieldCtrl.selectForm.singleSelect.$touched">
          <ng-message when="required">A selection is required in this field.</ng-message>
        </ng-messages>
      </div>
    </div>
  </form>

</div>
<script type="text/ng-template" id="demo/selectfield/selectfieldpicker.html">
  <bb-checklist
    bb-checklist-items="selectFieldCtrl.listItems"
    bb-checklist-include-search="true"
    bb-checklist-mode="list"
    bb-checklist-filter-callback="selectFieldCtrl.onSearch"
    bb-checklist-is-loading="selectFieldCtrl.loadingSearch"
    bb-checklist-focus-search>
  </bb-checklist>
</script>
<script type="text/ng-template" id="demo/selectfield/selectfieldpickersingle.html">
  <bb-checklist
    bb-checklist-items="selectFieldCtrl.listItemsSingle"
    bb-checklist-include-search="true"
    bb-checklist-categories="['Constituent', 'Giving', 'Miscellaneous']"
    bb-checklist-mode="list"
    bb-checklist-select-style="single"
    bb-checklist-filter-local
    bb-checklist-focus-search>
  </bb-checklist>
</script>

JavaScript

/*global angular */

(function () {
    'use strict';

    function SelectFieldTestController($timeout) {
        var vm = this,
            searchableItems,
            searchTimeout;

        function loadInitialValues() {
            vm.listItems = searchableItems.slice(0, 6);
        }

        function loadItems(searchText) {
            var filteredItems = [],
                i;

            if (!searchText) {
                loadInitialValues();
            } else {
                for (i = 0; i < searchableItems.length; i++) {
                    if (!searchText || searchableItems[i].title.toLowerCase().indexOf(searchText.toLowerCase()) >= 0 || searchableItems[i].description.toLowerCase().indexOf(searchText.toLowerCase()) >= 0) {
                        filteredItems.push({ title: searchableItems[i].title, description: searchableItems[i].description, category: searchableItems[i].category });
                    }
                }

                vm.listItems = filteredItems;
            }
        }

        /*  If you do not wish to retrieve all the records for the select field at once,
            you can provide a search function that can fetch items remotely */
        vm.onSearch = function (args) {
            vm.loadingSearch = true;

            if (searchTimeout) {
                $timeout.cancel(searchTimeout);
            }

            searchTimeout = $timeout(function () {
                loadItems(args.searchText);
                vm.loadingSearch = false;
            }, 2000);
        };

        vm.loadInitialValues = loadInitialValues;

        searchableItems = [
            {
                title: 'Constituent summary',
                description: 'Summary information about the constituent who gave the gift',
                category: 'Constituent'
            },
            {
                title: 'Soft credits',
                description: 'Soft credits for the gift',
                category: 'Giving'
            },
            {
                title: 'Amount',
                description: 'Amount of the gift',
                category: 'Giving'
            },
            {
                title: 'Sweatshirt',
                description: 'This column has nothing to do with the other ones',
                category: 'Miscellaneous'
            },
            {
                title: 'Item 1',
                description: 'This makes the list longer',
                category: 'Miscellaneous'
            },
            {
                title: 'Item 2',
                description: 'This makes the list longer',
                category: 'Miscellaneous'
            },
            {
                title: 'Item 1a',
                description: 'This makes the list longer',
                category: 'Miscellaneous'
            },
            {
                title: 'Item 1b',
                description: 'This makes the list longer',
                category: 'Miscellaneous'
            },
            {
                title: 'Item 1c',
                description: 'This makes the list longer',
                category: 'Miscellaneous'
            },
            {
                title: 'Item 1d',
                description: 'This makes the list longer',
                category: 'Miscellaneous'
            },
            {
                title: 'Item 1e',
                description: 'This makes the list longer',
                category: 'Miscellaneous'
            },
            {
                title: 'Item 1f',
                description: 'This makes the list longer',
                category: 'Miscellaneous'
            },
            {
                title: 'Item 1g',
                description: 'This makes the list longer',
                category: 'Miscellaneous'
            },
            {
                title: 'Item 1h',
                description: 'This makes the list longer',
                category: 'Miscellaneous'
            },
            {
                title: 'Item 1i',
                description: 'This makes the list longer',
                category: 'Miscellaneous'
            },
            {
                title: 'Item 1j',
                description: 'This makes the list longer',
                category: 'Miscellaneous'
            },
            {
                title: 'Item 1k',
                description: 'This makes the list longer',
                category: 'Miscellaneous'
            }

        ];

        loadInitialValues();

        vm.selectedItems = vm.listItems.slice(0, 2);

        vm.listItemsSingle = angular.copy(vm.listItems);
        vm.selectedSingleItems = [vm.listItemsSingle[1]];
    }

    SelectFieldTestController.$inject = ['$timeout'];

    angular.module('stache')
        .controller('SelectFieldTestController', SelectFieldTestController);
})();