Commit e97be71b authored by Nick Stenning's avatar Nick Stenning

Merge pull request #2128 from hypothesis/930-loading-icon

Show spinner in search bar during requests
parents f60d39f6 078d1f6a
module.exports = ['$parse', ($parse) -> module.exports = ['$http', '$parse', ($http, $parse) ->
uuid = 0
link: (scope, elem, attr, ctrl) -> link: (scope, elem, attr, ctrl) ->
scope.viewId = uuid++
scope.reset = (event) -> scope.reset = (event) ->
event.preventDefault() event.preventDefault()
scope.query = '' scope.query = ''
...@@ -12,6 +9,9 @@ module.exports = ['$parse', ($parse) -> ...@@ -12,6 +9,9 @@ module.exports = ['$parse', ($parse) ->
event.preventDefault() event.preventDefault()
scope.query = scope.searchtext scope.query = scope.searchtext
scope.$watch (-> $http.pendingRequests.length), (pending) ->
scope.loading = (pending > 0)
scope.$watch 'query', (query) -> scope.$watch 'query', (query) ->
return if query is undefined return if query is undefined
scope.searchtext = query scope.searchtext = query
...@@ -27,8 +27,15 @@ module.exports = ['$parse', ($parse) -> ...@@ -27,8 +27,15 @@ module.exports = ['$parse', ($parse) ->
onClear: '&' onClear: '&'
template: ''' template: '''
<form class="simple-search-form" ng-class="!searchtext && 'simple-search-inactive'" name="searchBox" ng-submit="search($event)"> <form class="simple-search-form" ng-class="!searchtext && 'simple-search-inactive'" name="searchBox" ng-submit="search($event)">
<input id="simple-search-{{viewId}}" class="simple-search-input" type="text" ng-model="searchtext" name="searchText" placeholder="Search…" /> <input class="simple-search-input" type="text" ng-model="searchtext" name="searchText"
<label for="simple-search-{{viewId}}" class="simple-search-icon h-icon-search"></label> placeholder="{{loading && 'Loading' || 'Search'}}…"
ng-disabled="loading" />
<span class="simple-search-icon" ng-hide="loading">
<i class="h-icon-search"></i>
</span>
<span class="simple-search-icon" ng-show="loading">
<i class="spinner"></i>
</span>
</form> </form>
''' '''
] ]
...@@ -3,10 +3,11 @@ ...@@ -3,10 +3,11 @@
assert = chai.assert assert = chai.assert
describe 'h:directives.simple-search', -> describe 'simple-search', ->
$compile = null $compile = null
$element = null $element = null
$scope = null $scope = null
fakeHttp = null
fakeWindow = null fakeWindow = null
isolate = null isolate = null
...@@ -16,6 +17,11 @@ describe 'h:directives.simple-search', -> ...@@ -16,6 +17,11 @@ describe 'h:directives.simple-search', ->
beforeEach module('h') beforeEach module('h')
beforeEach module ($provide) ->
fakeHttp = {pendingRequests: []}
$provide.service('$http', -> fakeHttp)
return
beforeEach inject (_$compile_, _$rootScope_) -> beforeEach inject (_$compile_, _$rootScope_) ->
$compile = _$compile_ $compile = _$compile_
$scope = _$rootScope_.$new() $scope = _$rootScope_.$new()
...@@ -64,3 +70,11 @@ describe 'h:directives.simple-search', -> ...@@ -64,3 +70,11 @@ describe 'h:directives.simple-search', ->
$form = $element.find('.simple-search-form') $form = $element.find('.simple-search-form')
assert.notInclude($form.prop('className'), 'simple-search-inactive') assert.notInclude($form.prop('className'), 'simple-search-inactive')
it 'sets the `loading` scope key when http requests are in progress', ->
fakeHttp.pendingRequests = []
isolate.$digest()
assert.isFalse(isolate.loading)
fakeHttp.pendingRequests = ['bogus']
isolate.$digest()
assert.isTrue(isolate.loading)
...@@ -13,32 +13,33 @@ ...@@ -13,32 +13,33 @@
} }
.simple-search-form * { .simple-search-form * {
box-sizing: border-box; line-height: inherit;
} }
@include icons { .simple-search-icon {
&.simple-search-icon { position: absolute;
line-height: inherit; left: 0;
position: absolute; top: 0;
left: 0;
top: 0;
}
} }
:not(:focus) ~ .simple-search-icon { :not(:focus) ~ .simple-search-icon {
color: $gray-lighter; color: $gray-lighter;
} }
.simple-search-input { input.simple-search-input {
float: left; float: left;
outline: none; outline: none;
color: $text-color; color: $text-color;
line-height: inherit;
width: 100%; width: 100%;
border: none !important; // Override base input styles. border: none;
padding: 0; padding: 0;
.simple-search-inactive &:not(:focus) { .simple-search-inactive &:not(:focus) {
border-color: #f3f3f3 !important; border-color: #f3f3f3;
}
&:disabled {
background: none;
color: $gray-light;
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment