Skip to content

Instantly share code, notes, and snippets.

@heckmac
Created February 15, 2013 16:06
Show Gist options
  • Save heckmac/4961351 to your computer and use it in GitHub Desktop.
Save heckmac/4961351 to your computer and use it in GitHub Desktop.
/**
* 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) {
var items;
$http.get('data.json').success(function(response){
// Version 1
$scope.items = response;
// Version 2
items = response;
// Version 3
angular.extend($scope.version3.data, response);
});
// Requires us to write comparison code ourselves :(
$scope.version2 = {
query: function (query) {
var data = {results: []};
angular.forEach(items, function(item, key){
if (query.term.toUpperCase() === item.text.substring(0, query.term.length).toUpperCase()) {
data.results.push(item);
}
});
query.callback(data);
}
};
// Simply updating an existing reference :) (refer to $http.get() above)
$scope.version3 = {
data: []
};
// Built-in support for ajax
$scope.version4 = {
ajax: {
url: "data.json",
data: function (term, page) {
return {}; // query params go here
},
results: function (data, page) { // parse the results into the format expected by Select2.
// since we are using custom formatting functions we do not need to alter remote JSON data
return {results: data};
}
}
}
});
[
{
"id" : 1,
"text" : "First"
},
{
"id" : 2,
"text" : "Second",
"color" : "red"
},
{
"id" : 3,
"text" : "Third",
"color" : "orange"
},
{
"id" : 4,
"text" : "Fourth",
"color" : "red"
},
{
"id" : 5,
"text" : "Fifth",
"color" : "pink"
},
{
"id" : 6,
"text" : "Sixth",
"color" : "yellow"
},
{
"id" : 7,
"text" : "Seventh",
"color" : "blue"
},
{
"id" : 8,
"text" : "Eighth",
"color" : "blue"
},
{
"id" : 9,
"text" : "Ninth",
"color" : "purple"
},
{
"id" : 10,
"text" : "Tenth",
"color" : "green"
}
]
<!doctype html>
<html ng-app="plunker" >
<head>
<meta charset="utf-8">
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/base/jquery-ui.css">
<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://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.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>Select2 + AJAX Demos</h1>
<p><a href="https://gist.github.com/4279651">Fork the Original Gist</a></p>
<h3>Version 1</h3>
<p>Use a regular <code>&lt;select&gt;</code> tag and <code>ng-repeat</code></p>
<pre>Selected: {{version1model|json}}</pre>
<select ui-select2 ng-model="version1model" data-placeholder="-- Select One --" style="width:200px">
<option></option>
<option ng-repeat="item in items" value="{{item.id}}">{{item.text}}</option>
</select>
<h3>Version 2</h3>
<p>Write your own Select2 query function</p>
<pre>Selected: {{version2model|json}}</pre>
<input ui-select2="version2" ng-model="version2model" style="width:200px" />
<h3>Version 3</h3>
<p>Use the Select2 data property, and preserve the reference</p>
<pre>Selected: {{version3model|json}}</pre>
<input ui-select2="version3" ng-model="version3model" style="width:200px" />
<h3>Version 4</h3>
<p>Use the Select2 ajax property</p>
<pre>Selected: {{version4model|json}}</pre>
<input ui-select2="version4" ng-model="version4model" style="width:200px" />
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment