If you’re anything like me, while working with AngularJS you will soon want to integrate your “standard library” of jQuery and UI plugins into AngularJS directives. Recently on the job, I wrote an AngularJS directive to apply a jQuery UI effect to an element—I wanted to briefly shake a small form if an input was invalid (such as you often see in native app GUIs). The directive looked something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/** * Shakes the element using jQuery UI shake if expression is truthy. * * Usage: * <ANY shake="{expr}" [after-shake="{expr}"]>...</ANY> */ MyApp.directive('shake', function() { return function(scope, elem, attrs) { scope.$watch(attrs.shake, function(shake, wasShaking) { if(shake && !wasShaking) { // The jQuery UI shake part elem.effect('shake', function() { // Digest afterShake if it was given attrs.afterShake !== undefined && scope.$apply(function() { scope.$eval(attrs.afterShake); }); }); } }); }; }); |
Much to my surprise, during the shake effect a <select /> in the form went from having a non-empty option selected to having an empty option selected, and there was not an empty option in the select to begin with.
You may already be familiar with a select in AngularJS “mysteriously” gaining an empty option. That’s not mysterious at all as it turns out; it is reasonable behavior when the model associated with the select is not given a valid value. Here is a quick sample to demonstrate this problem and solution:
This was clearly not the problem I experienced. I had initialized the model correctly, and the empty selected option only appeared after the jQuery UI effect had finished. Admittedly, I still don’t know what jQuery UI is doing to cause this. However, without delving into the core of jQuery UI, I do at least have a solution to the problem for now; the answer lies in using ng-options instead of <option /> elements.
Here is a sample of the problem and solution side by side. Switch to the Result tab, then click the “Shake” button to see one select lose its value and the other retain its value as desired.
Cookie to the first person who can say what jQuery UI is doing to trigger the problem when using <option /> elements vs. ng-options!
5 replies on “Solving AngularJS empty select option caused by jQuery UI effect”
Thank you for another informative blog. While I can’t say what jQuery is doing, I can say that you seem to know you stuff and as I am digging deeper into AngularJS, this will come in handy.
WOW!!! Nice Post!Kind Regards
Applying ng-option and browsing in IE9, causes empty selected option (styled, but with out any text).
I am implementing jQuery like this: $(element).coreUISelect(); through the angular derective.
Any suggestions?
Can you post a jsfiddle.net sample of the problem? I have wrapped many a jQuery plugin with AngularJS so hopefully I can help when I see the problem. đŸ˜‰
This is brilliant. Thank you very much for sharing.
Best Regards
– Nikolaj