Skip to content

Commit

Permalink
Add support for displaying spinner, implement spinner in bootstrap theme
Browse files Browse the repository at this point in the history
  • Loading branch information
slawekkolodziej authored and theanxy committed Apr 6, 2016
1 parent 3e10159 commit d1afad0
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/bootstrap/select.tpl.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<div class="ui-select-container ui-select-bootstrap dropdown" ng-class="{open: $select.open}">
<div class="ui-select-match"></div>
<i ng-show="$select.open && $select.spinnerEnabled && $select.refreshing" class="ui-select-refreshing {{$select.spinnerClass}}"></i>
<input type="text" autocomplete="off" tabindex="-1"
aria-expanded="true"
aria-label="{{ $select.baseTitle }}"
Expand Down
39 changes: 39 additions & 0 deletions src/common.css
Original file line number Diff line number Diff line change
Expand Up @@ -257,3 +257,42 @@ body > .ui-select-bootstrap.open {
.ui-select-container[theme="bootstrap"].direction-up .ui-select-dropdown {
box-shadow: 0 -4px 8px rgba(0, 0, 0, 0.25);
}


/* Spinner */
.ui-select-refreshing {
margin-top: -0.5em;
position: absolute;
right: 0.5em;
top: 50%;
}

@-webkit-keyframes ui-select-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@keyframes ui-select-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}

.ui-select-spin {
-webkit-animation: ui-select-spin 2s infinite linear;
animation: ui-select-spin 2s infinite linear;
}

.ui-select-refreshing.ng-animate {
-webkit-animation: none 0s;
}
5 changes: 4 additions & 1 deletion src/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,10 @@ var uis = angular.module('ui.select', [])
generateId: function() {
return latestId++;
},
appendToBody: false
appendToBody: false,
spinnerEnabled: false,
spinnerClass: 'glyphicons-refresh ui-select-spin',
noResults: ''
})

// See Rename minErr and make it accessible from outside https://github.com/angular/angular.js/issues/6913
Expand Down
10 changes: 9 additions & 1 deletion src/uiSelectController.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ uis.controller('uiSelectCtrl',
ctrl.focus = false;
ctrl.disabled = false;
ctrl.selected = undefined;
ctrl.refreshing = false;

ctrl.dropdownPosition = 'auto';

Expand Down Expand Up @@ -293,7 +294,14 @@ uis.controller('uiSelectCtrl',
$timeout.cancel(_refreshDelayPromise);
}
_refreshDelayPromise = $timeout(function() {
$scope.$eval(refreshAttr);
var refreshPromise = $scope.$eval(refreshAttr);

if (refreshPromise && angular.isFunction(refreshPromise.then) && !ctrl.refreshing) {
ctrl.refreshing = true;
refreshPromise.then(function() {
ctrl.refreshing = false;
});
}
}, ctrl.refreshDelay);
}
};
Expand Down
3 changes: 3 additions & 0 deletions src/uiSelectDirective.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ uis.directive('uiSelect',
$select.baseTitle = attrs.title || 'Select box';
$select.focusserTitle = $select.baseTitle + ' focus';
$select.focusserId = 'focusser-' + $select.generatedId;
$select.spinnerEnabled = angular.isDefined(tAttrs.spinnerEnabled) ? scope.$eval(tAttrs.spinnerEnabled) : uiSelectConfig.spinnerEnabled;
$select.spinnerClass = angular.isDefined(tAttrs.spinnerClass) ? tAttrs.spinnerClass : uiSelectConfig.spinnerClass;
$select.noResults = tAttrs.noResults || uiSelectConfig.noResults;

$select.closeOnSelect = function() {
if (angular.isDefined(attrs.closeOnSelect)) {
Expand Down
81 changes: 79 additions & 2 deletions test/select.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';

describe('ui-select tests', function() {
var scope, $rootScope, $compile, $timeout, $injector, uisRepeatParser;
var scope, $rootScope, $compile, $timeout, $injector, $q, uisRepeatParser;

var Key = {
Enter: 13,
Expand Down Expand Up @@ -78,13 +78,15 @@ describe('ui-select tests', function() {
});
});

beforeEach(inject(function(_$rootScope_, _$compile_, _$timeout_, _$injector_, _uisRepeatParser_) {
beforeEach(inject(function(_$rootScope_, _$compile_, _$timeout_, _$injector_, _$q_, _uisRepeatParser_) {
$rootScope = _$rootScope_;
scope = $rootScope.$new();
$compile = _$compile_;
$timeout = _$timeout_;
$injector = _$injector_;
$q = _$q_;
uisRepeatParser = _uisRepeatParser_;

scope.selection = {};

scope.getGroupLabel = function(person) {
Expand Down Expand Up @@ -1637,8 +1639,83 @@ describe('ui-select tests', function() {
expect($(el).find('.ui-select-search')).toHaveClass('ng-hide');
});

describe('spinner', function() {
var spinner, el, deferred;

function setupSelectComponent(theme, spinnerEnabled, spinnerClass) {
spinnerClass = spinnerClass ? 'spinner-class="' + spinnerClass + '"' : '';

el = compileTemplate(
'<ui-select ng-model="selection.selected" \
theme="' + theme + '" \
search-enabled="true" \
spinner-enabled="' + spinnerEnabled + '" \
' + spinnerClass + '> \
<ui-select-match></ui-select-match> \
<ui-select-choices repeat="person in people | filter: $select.search" \
refresh="fetchFromServer($select.search)" refresh-delay="0"> \
<div ng-bind-html="person.name | highlight: $select.search"></div> \
<div ng-if="person.name==\'Wladimir\'"> \
<span class="only-once">I should appear only once</span>\
</div> \
</ui-select-choices> \
</ui-select>'
);
}

function fetchFromServer(){
deferred = $q.defer();
return deferred.promise;
}

it('should not display spinner when disabled', function() {
scope.fetchFromServer = fetchFromServer;
setupSelectComponent('bootstrap', 'false', '');

openDropdown(el);

spinner = el.find('.ui-select-refreshing');
expect(spinner.length).toBe(1);
expect(spinner.hasClass('ng-hide')).toBe(true);

setSearchText(el, 'a');
expect(spinner.hasClass('ng-hide')).toBe(true);

deferred.resolve();
scope.$digest();
expect(spinner.hasClass('ng-hide')).toBe(true);
});

it('should display spinner when enabled', function() {
scope.fetchFromServer = fetchFromServer;
setupSelectComponent('bootstrap', 'true', '');

openDropdown(el);

spinner = el.find('.ui-select-refreshing');
expect(spinner.length).toBe(1);
expect(spinner.hasClass('ng-hide')).toBe(true);

setSearchText(el, 'a');
expect(spinner.hasClass('ng-hide')).toBe(false);

deferred.resolve();
scope.$digest();
expect(spinner.hasClass('ng-hide')).toBe(true);
});

it('should add spinner css classes when defined', function() {
scope.fetchFromServer = fetchFromServer;
setupSelectComponent('bootstrap', 'true', 'fa fa-spinner fa-spin');

openDropdown(el);
setSearchText(el, 'a');

spinner = el.find('.ui-select-refreshing');
expect(spinner.attr('class')).toEqual('ui-select-refreshing fa fa-spinner fa-spin');

deferred.resolve();
});
});


Expand Down

0 comments on commit d1afad0

Please sign in to comment.