select2

angular, jquery, select2

by S_YOU

HTML

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.28/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css">
<script src="http://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.js"></script>
<!--[if lte IE 8]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/es5-shim/4.1.0/es5-shim.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js"></script>
    <script>
        if (!window.console) window.console = function() {}
    </script>
<![endif]-->
<div ng-controller="DemoController">
    <div>
        <select select2="{
            data: 'filteredOptions',
            select2: {
                placeholder:'Select',
                allowClear: 1
            }
        }" ng-model="selected1" ng-options="opt as opt.text for opt in (filteredOptions = (options | filter:search))">
            <option value=''>Select</option>
        </select>
        <input ng-model="search.text" placeholder="filter" />
        <div>The value selected is {{ selected1 }}.</div>
    </div>
    <div>
        <select select2="{ 
            data:'options',
            key:'id',
            create:onNewItem,
            select2:{
                tags:1,
                theme:'classic'
            }
        }" ng-model="selected2" ng-options="opt.id as opt.text for opt in options"></select>
        <div>The value selected is {{ selected2 }}.</div>
    </div>
    <div>
        <select select2="{
            data:'options',
            key:'id',
            select2:{
                theme: 'classic'
            }
        }" multiple ng-model="selected3" ng-options="opt.id as opt.text for opt in options"></select>
        <div>The value selected is {{ selected3 }}.</div>
    </div>
    <div>
        <select select2="{
            data:'options',
            trackBy: 1,
            key:'id',
 ...

SCSS

select {
    width: 200px;
}
div {
    padding: 2px;
}
    
input {
  background-color: #fff;
  border: 1px solid #aaa;
  border-radius: 4px;

  box-sizing: border-box;
  cursor: pointer;
  display: inline-block;
  height: 28px;
  user-select: none;
}

JavaScript

angular.module('demoApp', [])

    .directive("select2", function ($parse) {
    return {
        restrict: 'A',
        scope: true,
        link: function (scope, elem, attrs) {
            var opts = scope.$eval(attrs.select2) || {};
            var ngModel = $parse(attrs.ngModel);
            //console.log('options', opts);

            scope.$watchCollection(opts.data, function (data, oldVal) {
                if (!data || data == oldVal) return;

                //must use 'change.select2' or 
                //every watch triggering will add new event with 'change'
                $(elem).select2(opts.select2).on('change.select2', function (e) {
                    var optionValue = this.value;

                    //append new data, if 'onNew' callback is set
                    if (!data[optionValue] && opts.create) {
                        optionValue = opts.create(data, optionValue);
                    }

                    function findOption(data, key) {
                        if (opts.trackBy) {
                            console.log('trackBy', key, opts.key);
                            for (var i = 0; i < data.length; i++) {
                                if (opts.key) {
                                    console.log("data[i][opts.key]", data[i][opts.key]);
                                    if (data[i][opts.key] == key) { // loose compare
                                        return data[i][opts.key]
                                    }
                                } else {
                                    if (data[i] == key) { // loose compare
                                        return data[i];
                                    }
                                }
                            }
                        } else {
                            return opts.key ? data[key][opts.key] : data[key];
                        }
                    }
                    //get new values for ngModel
                    var...