The key to the solution of this problem is that you have to use the $compile service on the HTML returned by the formatNoMatches
function in the options object. This compilation step will wire up the ng-click directive in the markup to the scope. Unfortunately, that is a bit easier said than done.
You can see the full working example here: http://jsfiddle.net/jLD42/4/
There is no way that I know of for AngularJS to watch the select2 control to monitor the results of a search, so we must inform the controller when no results are found. This is easy to do through the formatNoMatches
function:
$scope.select2Options = {
formatNoMatches: function(term) {
console.log("Term: " + term);
var message = '<a ng-click="addTag()">Add tag:"' + term + '"</a>';
if(!$scope.$$phase) {
$scope.$apply(function() {
$scope.noResultsTag = term;
});
}
return message;
}
};
The $scope.noResultsTag
property keeps track of the last value entered by the user that returned no matches. Wrapping the update to the $scope.noResultsTag
with $scope.$apply is necessary because formatNoMatches
is called outside the context of the AngularJS digest loop.
We can watch $scope.noResultsTag
and compile the formatNoMatches
markup when changes occur:
$scope.$watch('noResultsTag', function(newVal, oldVal) {
if(newVal && newVal !== oldVal) {
$timeout(function() {
var noResultsLink = $('.select2-no-results');
console.log(noResultsLink.contents());
$compile(noResultsLink.contents())($scope);
});
}
}, true);
You may wonder what the $timeout is doing there. It is used to avoid the race condition between the select2 control updating the DOM with the formatNoMatches
markup and the watch function trying to compile that markup. Otherwise, there is a good chance that the $('.select2-no-results')
selector will not find what it is looking for and the compilation step won't have anything to compile.
Once the add tag link has been compiled, the ng-click
directive will be able to call the addTag
function on the controller. You can see this in action in the jsFiddle. Clicking the add tag link will update the Tags array with the search term you enter into the select2 control and you will be able to see it in the markup and the options list the next time you enter a new search term into the select2 control.