Angular + Chosen
by rtcherry
HTML
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
<script src="http://code.jquery.com/jquery-1.6.4.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular-resource.min.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/chosen/0.9.8/chosen.css">
<script src="http://cdn.rawgit.com/harvesthq/chosen/v0.9.1/chosen/chosen.jquery.min.js"></script>
<div ng-controller="TestCntrl">Item: {{item}}
<br/> <a href="" ng-click="item = undefined">Reset</a>
<br/>Select:
<br/>
<select chosen="list" ng-model="item" ng-options="i for i in list"></select>
</div>
JavaScript
var testApp = angular.module('testApp', []);
testApp.controller('TestCntrl', function ($scope) {
$scope.list = ['One', 'Two', 'Three'];
$scope.item = undefined;
});
testApp.directive('chosen', ['$timeout', function ($timeout) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ngModel) {
var options = scope.$eval(attrs.chosenOptions) || {},
dataset = attrs.ngOptions.replace(/^.*\sin\s(.*)$/, '$1'),
refreshFunction = function () {
var hasNullOption = element.children('*[value = "?"], *[value = ""]').length == 1,
numSelectOptions = element.children().length,
numChosenOptions = element.next().find('.chzn-results li').length;
if (numSelectOptions > (hasNullOption ? 1 : 0)) {
if (numSelectOptions - (hasNullOption ? 1 : 0) != scope.$eval(dataset).length) {
element.trigger("liszt:updated");
_.delay(refreshFunction, 50);
} else if (numSelectOptions != numChosenOptions) {
element.trigger("liszt:updated");
}
} else {
_.delay(refreshFunction, 50);
}
};
$timeout(function () {
element.chosen(options);
refreshFunction();
});
scope.$watch(
attrs.ngModel,
function (newValue, oldValue) {
if (_.isUndefined(oldValue) || _.isUndefined(newValue)) {
element.trigger("liszt:updated");
}
});
element.bind('change', function () {
scope.$apply();
});
}
};
}]);
angular.element(document).ready(function () {
angular.bootstrap(document, ['testApp']);
});