Clear the Field of an non-Editable AngularUI Typeahead

When working with non-editable AngularUI Typeaheads (i.e. ones that have the typeahead-editable attribute set to false), a logical thing to do would be to erase the typeahead input field’s view value if the user doesn’t select a valid typeahead option. However, there’s no built-in option to do just that, so here’s a workaround.

The main idea here is to use the ng-blur attribute to set a function that will clear the typeahead field if no valid option was selected. To do that first we need to access by name the form controller object containing the typeahead. If the typeahead is not contained in a form element, what we can do is declare one of its parent elements as a form controller using ng-form, and give names to both of them:

<div ng-form name="myForm">
<input type="text" name="myField" ng-model="myField" ng-blur="clearUnselected()" typeahead="myField in myFields" typeahead-editable="false" />
</div>

Now we can access the the typeahead’s form properties from the AngularJS controller, and reset its $viewValue property if no valid option was selected by the user. We wrap this into an AngularJS $timeout because there’s a delay between clicking on an option and the corresponding model updating. Don’t forget to inject the $timeout service into your controller!

//inside your controller
$scope.clearUnselected = function () {
$timeout(function () {
if (!$scope.myField) { //the model was not set by the typeahead
$scope.myForm.myField.$setViewValue('');
$scope.myForm.myField.$render();
}
}, 250); //a 250 ms delay should be safe enough
}

Retrofitting jQuery prop() for when using both older and newer jQuery versions

When upgrading your existing website to jQuery 1.6 or higher, you may have noticed that the attr() method stopped working like it has since time immemorial, breaking all previous code that used it. Supposedly jQuery 1.61 added some backwards compatibility fixes, but they don’t really work, at least for me. They say “just replace all attr() calls for prop() and be done”, however it’s not that simple if your code is supposed to work on different versions of jQuery, for example when developing extensions or modules for constantly updated frameworks, since prop() didn’t exist before jQuery 1.6.

Actually, there is a simple way to make your code work on both older and newer jQuery versions. All you need to do is replace all attr() calls for prop() (it takes the same arguments so don’t worry), and add the following before your code:


       if (typeof jQuery.fn.prop != 'function') {
            jQuery.fn.prop = jQuery.fn.attr;
        }
    

All this does is check if the prop() method exists, and if not, it creates it by cloning attr(). Hope this saves you some time.