12

I am using button spinner while loading the content, when the user clicks on the "Search" button content will load, at this time buttonLabel will be changed to "Searching" and spinner will be shown (Here button will be disabled). After loading the content (Promise resolved) buttonLabel will be reverted back to "Search" (button will be enable here).

I have tried the below code, but it is always showing the spinner.

HTML :

<button class="btn btn-xs btn btn-blue" ng-click="show()">
  <span><i class="glyphicon glyphicon-off"></i></span> {{buttonLabel}}
</button>

Script :

$scope.buttonLabel = "Search";
$scope.show = function() {
  $scope.buttonLabel = "Searching";
  $scope.test = TestService.getList( $cookieStore.get('url'),
    $rootScope.resourceName+"/students" );
    $scope.test.then( function( data ) {
      if( data.list ) {
        $scope.testData = data.list;
        $scope.buttonLabel = "Search";
      }
    }
  }

Updated Fiddle : http://jsfiddle.net/xc6nx235/18/

7 Answers 7

14
<div ng-app="formDemo" ng-controller="LocationFormCtrl">
<div>
    <button type="submit" class="btn btn-primary" ng-click="search()"> 
        <span ng-show="searchButtonText == 'Searching'"><i class="glyphicon glyphicon-refresh spinning"></i></span>
        {{ searchButtonText }}
    </button>
</div>

All you need to do is use ng-show or ng-hide directives.

ng-show="expression"

<span ng-show="searchButtonText == 'Searching'">
    <i class="glyphicon glyphicon-refresh spinning"></i>
</span>

this span will only be visible when searchButtonText will be equal to a string 'Searching'.

You should learn more about angular's directives. They'll be useful in future.

Good luck.

Demo http://jsfiddle.net/xc6nx235/16/

Sign up to request clarification or add additional context in comments.

3 Comments

@N123 You can use ng-disabled="expression" as well to disable the button.
@ Jagdeep Singh: Updated fiddle link in the question.
@JagdeepSingh Hi, after 2 seconds, button text will change, but is there any way to keep it showing Searching till we get the response back from server.?
7

Use ng-show to show (or not) the loader ng-show="test" :

JSFiddle

// http://icelab.com.au/articles/levelling-up-with-angularjs-building-a-reusable-click-to-edit-directive/

angular.module("formDemo", [])

.controller("LocationFormCtrl", function ($scope, $timeout) {
    $scope.searchButtonText = "Search";
$scope.test="false";
$scope.search = function() {
    $scope.test="true";
     $scope.searchButtonText = "Searching";
    $timeout(function(){
        $scope.test="false";
        $scope.searchButtonText = "Search";
    },1000)
    // Do your searching here
}
});
body {
    font-family:"HelveticNeue", sans-serif;
    font-size: 14px;
    padding: 20px;
}
h2 {
    color: #999;
    margin-top: 0;
}
.field {
    margin-bottom: 1em;
}
.click-to-edit {
    display: inline-block;
}
input {
    display: initial !important;
    width: auto !important;
    margin: 0 5px 0 0 !important;
}

.glyphicon.spinning {
    animation: spin 1s infinite linear;
    -webkit-animation: spin2 1s infinite linear;
}

@keyframes spin {
    from { transform: scale(1) rotate(0deg);}
    to { transform: scale(1) rotate(360deg);}
}

@-webkit-keyframes spin2 {
    from { -webkit-transform: rotate(0deg);}
    to { -webkit-transform: rotate(360deg);}
}
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/foundation/4.1.6/css/foundation.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">

<!-- Latest compiled and minified JavaScript -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script> 
<script src="https://rawgithub.com/angular-ui/angular-ui/master/build/angular-ui.js"></script>
  
<div ng-app="formDemo" ng-controller="LocationFormCtrl">
    <div>
    <button type="submit" class="btn btn-primary" ng-click="search()">
       <span ng-show="test" ><i class="glyphicon glyphicon-refresh spinning"></i></span>
        {{ searchButtonText }}
    </button>
</div>    
</div>

1 Comment

Hi, after 1 second, button text will change, but is there any way to keep it showing Searching till we get the response back from server.?
4

You can also use this simple directive:

https://rawgit.com/jvdvleuten/angular-button-spinner/master/demo.html

To use it, just add the button-spinner='loading' attribute:

<button class="btn btn-success" ng-click="show()" button-spinner="loading">Load</button>

It will append a spinner to it, inside the button, when your loading variable in the scope is true.

Comments

1

Just add an ng-show to your spinner:

<span ng-show="loading"><i class="glyphicon glyphicon-refresh spinning"></i></span>

and controller:

.controller("LocationFormCtrl", function ($scope) {
    $scope.searchButtonText = "Search";
    $scope.loading = false;
    $scope.test="false";
    $scope.search = function() {
      $scope.test="true";
      $scope.loading="true"
      $scope.searchButtonText = "Searching";
      // Do your searching here
   }
});

Then, when you get your response, set $scope.loading to false again

Demo

Comments

1

Use ng-show directive like this ng-show="test" on spinner span:

Snippet:

// http://icelab.com.au/articles/levelling-up-with-angularjs-building-a-reusable-click-to-edit-directive/

angular.module("formDemo", [])

.controller("LocationFormCtrl", function($scope) {
  $scope.searchButtonText = "Search";
  $scope.test = "false";
  $scope.search = function() {
    $scope.test = "true";
    $scope.searchButtonText = "Searching";
    // Do your searching here
  }
});
</style> <!-- Ugly Hack due to jsFiddle issue:https://github.com/jsfiddle/jsfiddle-docs-alpha/issues/132 --> 
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/foundation/4.1.6/css/foundation.min.css"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> <!-- Optional theme --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css"> <!-- Latest compiled and minified JavaScript --> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script> <!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> --> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script> <script src="https://rawgithub.com/angular-ui/angular-ui/master/build/angular-ui.js"></script> <style> body {
  font-family: "HelveticNeue", sans-serif;
  font-size: 14px;
  padding: 20px;
}
h2 {
  color: #999;
  margin-top: 0;
}
.field {
  margin-bottom: 1em;
}
.click-to-edit {
  display: inline-block;
}
input {
  display: initial !important;
  width: auto !important;
  margin: 0 5px 0 0 !important;
}
.glyphicon.spinning {
  animation: spin 1s infinite linear;
  -webkit-animation: spin2 1s infinite linear;
}
@keyframes spin {
  from {
    transform: scale(1) rotate(0deg);
  }
  to {
    transform: scale(1) rotate(360deg);
  }
}
@-webkit-keyframes spin2 {
  from {
    -webkit-transform: rotate(0deg);
  }
  to {
    -webkit-transform: rotate(360deg);
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="formDemo" ng-controller="LocationFormCtrl">
  <div>
    <button type="submit" class="btn btn-primary" ng-click="search()">
      <span ng-show="test"><i class="glyphicon glyphicon-refresh spinning"></i></span>
      {{ searchButtonText }}
    </button>
  </div>
</div>

Comments

0

You should use ng-class to add/remove the class .spinning based on $scope.test. I have updated your fiddle here: http://jsfiddle.net/xc6nx235/15/

Comments

0

For Angular2/4, you can use [hidden] to control the visibility of the spinner. Here is a Plunker.

<button class="btn btn-primary" (click)="onClickDoSomething()">
  <span [hidden]="!spin">
        <i class="glyphicon glyphicon-refresh spinning"></i>
    </span> Do something
</button>

Where spinning is defined in as:

<style>
  .spinning {
    animation: spin 1s infinite linear;
  }

  @keyframes spin {
    from {
      transform: scale(1) rotate(0deg);
    }
    to {
      transform: scale(1) rotate(360deg);
    }
  }
</style>

And your component simply sets the boolean to control the visibility of the spinner. In this example, we simply spin for 10 seconds.

import {Component} from 'angular2/core';
import {Observable} from 'rxjs/Rx';

@Component({
  selector: 'do-something',
  templateUrl: 'src/dosomething.html'
})
export class DoSomething {
   private spin: boolean = false;

   onClickDoSomething() {
     this.spin = true;
     this.sub = Observable.interval(10000).subscribe(x => {
         this.sub.unsubscribe();
         this.spin = false;
     }); 
   }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.