<!doctype html>
<html ng-app="plunker" >
<head>
  <meta charset="utf-8">
  <title>AngularJS/Angular-UI & Select2 with multiple selection</title>
  <link href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css" rel="stylesheet">
  <link href="http://ivaynberg.github.com/select2/select2-3.2/select2.css" rel="stylesheet"/>
  <link rel="stylesheet" href="style.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
  <script src="https://raw.github.com/twitter/bootstrap/master/docs/assets/js/bootstrap.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.js"></script>
  <script src="angular-ui.js"></script>
  <script src="http://ivaynberg.github.com/select2/select2-3.2/select2.js"></script>
  <script src="app.js"></script>
</head>
<body ng-controller="MainCtrl"> 
  <h1>AngularJS/Angular-UI & Select2 with multiple selection</h1>
  <pre>Selection: {{selectedItems|json}}</pre>
  <select ng-multiple="true" ui-select2 ng-model="selectedItems" data-placeholder="-- Select some items --"
          style="width:200px">
    <optgroup data-ng-repeat="a in items" label="{{a.name}}">
      <option data-ng-repeat="b in a.specialties" value="{{b.id}}">{{b.text}}</option>
    </optgroup>
  </select>
</body>
</html>
/**
 * AngularUI - The companion suite for AngularJS
 * @version v0.3.2 - 2012-12-04
 * @link http://angular-ui.github.com
 * @license MIT License, http://www.opensource.org/licenses/MIT
 */


angular.module('ui.config', []).value('ui.config', {});
angular.module('ui.filters', ['ui.config']);
angular.module('ui.directives', ['ui.config']);
angular.module('ui', ['ui.filters', 'ui.directives', 'ui.config']);

/**
 * Enhanced Select2 Dropmenus
 *
 * @AJAX Mode - When in this mode, your value will be an object (or array of objects) of the data used by Select2
 *     This change is so that you do not have to do an additional query yourself on top of Select2's own query
 * @params [options] {object} The configuration options passed to $.fn.select2(). Refer to the documentation
 */
angular.module('ui.directives').directive('uiSelect2', ['ui.config', '$http', function (uiConfig, $http) {
  var options = {};
  if (uiConfig.select2) {
    angular.extend(options, uiConfig.select2);
  }
  return {
    require: '?ngModel',
    compile: function (tElm, tAttrs) {
      var watch,
        repeatOption,
    repeatAttr,
        isSelect = tElm.is('select'),
        isMultiple = (tAttrs.multiple !== undefined);

      // Enable watching of the options dataset if in use
      if (tElm.is('select')) {
        repeatOption = tElm.find('option[ng-repeat], option[data-ng-repeat]');

        if (repeatOption.length) {
		  repeatAttr = repeatOption.attr('ng-repeat') || repeatOption.attr('data-ng-repeat');
          watch = jQuery.trim(repeatAttr.split('|')[0]).split(' ').pop();
        }
      }

      return function (scope, elm, attrs, controller) {
        // instance-specific options
        var opts = angular.extend({}, options, scope.$eval(attrs.uiSelect2));

        if (isSelect) {
          // Use <select multiple> instead
          delete opts.multiple;
          delete opts.initSelection;
        } else if (isMultiple) {
          opts.multiple = true;
        }

        if (controller) {
          // Watch the model for programmatic changes
          controller.$render = function () {
            if (isSelect) {
              elm.select2('val', controller.$modelValue);
            } else {
              if (isMultiple && !controller.$modelValue) {
                elm.select2('data', []);
              } else {
                elm.select2('data', controller.$modelValue);
              }
            }
          };


          // Watch the options dataset for changes
          if (watch) {
            scope.$watch(watch, function (newVal, oldVal, scope) {
              if (!newVal) return;
              // Delayed so that the options have time to be rendered
              setTimeout(function () {
                elm.select2('val', controller.$viewValue);
                // Refresh angular to remove the superfluous option
                elm.trigger('change');
              });
            });
          }

          if (!isSelect) {
            // Set the view and model value and update the angular template manually for the ajax/multiple select2.
            elm.bind("change", function () {
              scope.$apply(function () {
                controller.$setViewValue(elm.select2('data'));
              });
            });

            if (opts.initSelection) {
              var initSelection = opts.initSelection;
              opts.initSelection = function (element, callback) {
                initSelection(element, function (value) {
                  controller.$setViewValue(value);
                  callback(value);
                });
              };
            }
          }
        }

        attrs.$observe('disabled', function (value) {
          elm.select2(value && 'disable' || 'enable');
        });

        scope.$watch(attrs.ngMultiple, function(newVal) {
          elm.select2(opts);
        });

        // Set initial value since Angular doesn't
        elm.val(scope.$eval(attrs.ngModel));

        // Initialize the plugin late so that the injected DOM does not disrupt the template compiler
        setTimeout(function () {
          elm.select2(opts);
        });
      };
    }
  };
}]);
var app = angular.module('plunker', ['ui']);

app.controller('MainCtrl', function($scope, $http) {
  $scope.items=[
    {
      id: 23,
      name: 'foobar',
      specialties: [
        {
          "id" : 6,
          "text" : "Sixth",
          "color" : "yellow"
        },
        {
          "id" : 7,
          "text" : "Seventh",
          "color" : "blue"
        },
        {
          "id" : 8,
          "text" : "Eighth",
          "color" : "blue"
        }
      ]
    },
    {
      id: 12,
      name: 'radasfdaf',
      specialties: [
        {
          "id" : 1,
          "text" : "First"
        },
        {
          "id" : 2,
          "text" : "Second",
          "color" : "red"
        },
        {
          "id" : 3,
          "text" : "Third",
          "color" : "orange"
        }
      ]
    }
  ];
  $scope.selectedItems=[];
});