var MyApp = angular.module('MyApp', [], function() {}); /** * 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) { elem.effect('shake', function() { attrs.afterShake !== undefined && scope.$apply(function() { scope.$eval(attrs.afterShake); }); }); } }); }; }); function MainCtrl($scope) { $scope.foo = 'baz'; }
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.0.min.js"></script> <script type="text/javascript" src="https://raw.github.com/jquery/jquery-ui/master/ui/jquery.ui.core.js"></script> <script type="text/javascript" src="https://raw.github.com/jquery/jquery-ui/master/ui/jquery.ui.effect.js"></script> <script type="text/javascript" src="https://raw.github.com/jquery/jquery-ui/master/ui/jquery.ui.effect-shake.js"></script> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script> <div ng-app="MyApp" ng-controller="MainCtrl"> <div> <p>This one uses <option /> elems; the model value is destroyed by our jQuery UI effect (try the button below).</p> <select ng-model="foo" shake="doShake" after-shake="doShake = false"> <option value="bar">bar</option> <option value="baz">baz</option> </select> </div> <div> <p>This one uses ng-options and the model value is preserved as desired.</p> <select ng-model="foo" shake="doShake" after-shake="doShake = false" ng-options="value for value in ['bar', 'baz']"></select> </div> <div> <button ng-click="doShake = true" ng-hide="doShake">Shake the selects</button> </div> </div>
div+div { margin-top: 15px; }