Skip to content

Limit the number of elements that can be selected

yanickrochon edited this page Feb 2, 2013 · 3 revisions

This example show how two multiselect widgets can affect the selection of the other one.

The concept may be modified to control how elements are available upon selection. For example, it could be modified to let only n elements selected and disable all others with var selectedCount = $("option:selected", this).length; in the multiselectChange event callback. For example :

$('#multiselect').bind('multiselectChange', function(evt, ui) {
   var selectedCount = $("option:selected", this).length;

   $(this)
      .find('option:not(:selected)').prop('disabled', selectedCount >= 2).end()
      .multiselect('refresh');
});

The following example illustrate two dependant multiselect that can limit the selection of the other based on their own selected values. Note that some modifications need to be made to support OPTION selection via an independant method; this example only support selections via user interactions using the widget.

####See a working demo here :

// this will elliminate use of unnecessary IF blokcs
var dependantSelect = {
   'multiselect_primary': 'multiselect_secondary',
   'multiselect_secondary': 'multiselect_primary',
};
$('#multiselect_primary,#multiselect_secondary').multiselect(defaultOptions)
   .bind('multiselectChange', function(evt, ui) {
      var values = $.map(ui.optionElements, function(opt) { return $(opt).attr('value'); });

      var hideSelected = true;  // true = remove, false = disable
      var dependantElement = $("#" + dependantSelect[$(this).prop("id")]);
      // iterate through all unselected options in the dependant SELECT element
      dependantElement.find("option:not(:selected)").each(function() {
         // if the current option is one of the (de)selected dependant option, process it
         if ($.inArray(this.value, values) >= 0) {
            if (hideSelected) {
               // this is a little tricky... and advanced as we dig inside the widget's private API.
               // But we need to get the corresponding option's list element in the dependant multiselect
               //
               //  1. dependantElement.data("uix-multiselect")         get the widget's internal object
               //  2.    .optionCache._elements                        get the option element's list cache
               //  3.       [$(this).data("element-index")]            get the current OPTION element's internal cache index
               //  4.    .listElement                                  get the actual list element in the widget
               //
               //  5. wrap in a specific DIV if dependent item select, or unwrap from it if not
               var listElement = dependantElement.data("uix-multiselect").optionCache._elements[$(this).data("element-index")].listElement;
               if (ui.selected) {
                  listElement.wrap($("<div></div>").addClass("restricted").hide());
               } else if (listElement.parent().is(".restricted")) {
                  listElement.unwrap();
               }
            } else {  // disable
               $(this).attr("disabled", ui.selected);
            }
         }
      }).end().multiselect("refresh");   // refresh dependant multiselect

   });