Tips for incorporating a spinner during content loading within AngularJS

When the user clicks on the "Search" button, content will load and the button label will change to "Searching" with a spinner shown while the content is loading. Once the content has loaded (Promise resolved), the button label will revert back to "Search" and the button will be enabled again.

Although attempted, the below code consistently shows the spinner even after the content has loaded.

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/

Answer №1

<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>

Utilizing the ng-show or ng-hide directives is all that's required.

ng-show="expression"

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

This particular span will only be visible when the value of searchButtonText matches the string 'Searching'.

It would be beneficial to delve deeper into angular's directives as they can prove helpful in your future endeavors.

Best of luck.

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

Answer №2

Utilize the ng-show directive to toggle the visibility of the loader with ng-show="test":

JSFiddle

// Visit 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)
// Add your search functionality 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>

Answer №3

If you want to keep it simple, you can use this straightforward directive:

https://www.example.com/angular-spinner-demo

All you need to do is include the button-spinner='loading' attribute in your code:

<button class="btn btn-primary" ng-click="display()" button-spinner="loading">Fetch Data</button>

Whenever the value of your loading variable within the scope is set to true, a spinner will be displayed inside the button.

Answer №4

To make your spinner appear, simply include an ng-show directive:

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

Also, don't forget to add this functionality in your controller:

.controller("FormController", function ($scope) {
    $scope.buttonText = "Submit";
    $scope.isLoading = false;
    $scope.flag = false;
    $scope.submitForm = function() {
        $scope.flag = true;
        $scope.isLoading = true;
        $scope.buttonText = "Submitting";
        // Carry out form submission here
   }
});

Remember to reset $scope.isLoading back to false once you receive a response.

Check out the demo!

Answer №5

Utilize the ng-show directive in this manner ng-show="test" on the spinner span:

Here is a 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";
    // Perform your search functionality here
  }
});
</style> <!-- Ugly Hack due to jsFiddle issue:http://goo.gl/BUfGZ --> 
<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>

Answer №6

To toggle the class .spinning depending on the value of $scope.test, it is recommended to utilize the ng-class directive. You can view the modified code in this updated demo: http://jsfiddle.net/xc6nx235/15/

Answer №7

To implement spinner visibility control in Angular2/4, you can utilize the [hidden] attribute. Check out this Plunker example.

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

The spinning animation is defined as follows:

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

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

Your component will simply toggle the boolean value to show or hide the spinner. In this particular demonstration, the spinner spins for a duration of 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;
     }); 
   }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unable to trigger ng-click event in IE browser, while it functions properly in Chrome

<select id="from" multiple="multiple" name="list" ng-model="selectedVal"> <optgroup label= "{{geo.Geo}}" ng-repeat="geo in Geographies"> <option id="{{country.CountryKey}}" ng-repeat="country in geo.Country" ng-click="arrayPush( ...

ReactJS state refuses to update

In my FreeCodeCamp leaderboard table, I have implemented functionality where clicking on the highlighted table header calls different URLs based on sorting criteria. The application either calls https://fcctop100.herokuapp.com/api/fccusers/top/recent or ht ...

Save the raw InputMask data in Formik with Material-UI

I currently have Input Mask implemented with a customized Material UI text field inside a Formik form: <InputMask mask="999-99-9999" maskChar="X" value={values.ssn} ...

Transform nested properties of an object into a new data type

I created a versatile function that recursively converts nested property values into numbers: type CastToNumber<T> = T extends string ? number : { [K in keyof T]: CastToNumber<T[K]> }; type StringMap = { [key: string]: any }; const castOb ...

"A lengthy contenteditable div designed to mimic an input field, with the ability to horizontally scroll

When the input is too short for the entire text to be displayed, users have the option to horizontally scroll the text inside the input by dragging with the mouse. Is there a way to implement this functionality in a contenteditable field that appears as ...

Error encountered: `npm ERR! code E503`

While attempting to execute npm install on my project, which was cloned from my GitHub repository, I encountered the following error: npm ERR! code E503 npm ERR! 503 Maximum threads for service reached: fs-extra@https://registry.npmjs.org/fs-extra/-/fs-ex ...

Substitute placeholders in array with information using a loop

I have a question regarding implementing an autosort feature in JavaScript. I want my page to automatically sort data rows based on different time intervals selected by the user through checkboxes. The data updates every 3 seconds, and the autosort functio ...

Utilizing Selenium and BeautifulSoup to extract data from a website

I am currently in the process of scraping a website that dynamically loads content using JavaScript. My objective is to create a Python script that can visit a site, search for a specific word, and then send me an email if that word is present. Although I ...

What are some creative ways to design the selected tab?

In my Vue parent component, I have multiple child components. There are several elements that toggle between components by updating the current data. The issue is that I am unsure how to indicate which tab is currently active. I've tried various li ...

Searching for a streamlined approach to sending out numerous HTTP requests in a node.js environment

I'm new to the world of JS/node.js after working with .Net. I have an existing Web API host that I want to stress test with different payloads. I am aware of load testing tools available for this purpose, but my focus right now is on finding an effic ...

Troubleshooting AngularJS POST Request Error with Request Body

I am a beginner in AngularJs and I am trying to make a post request to a server with enum form. Currently, I have the following JavaScript code: function completeTaskAction2($scope, $http, Base64) { $http.defaults.headers.common['Authorization'] ...

Utilizing JavaScript variables to generate a custom pie chart on Google

Greetings! I must admit that I am a novice, especially when it comes to JavaScript. My background is mainly in PHP. Recently, I came across a fantastic pie chart created by Google https://developers.google.com/chart/interactive/docs/gallery/piechart I a ...

What was the reason for node js not functioning properly on identical paths?

When the search route is placed at the top, everything works fine. However, when it is placed at the end, the route that takes ID as a parameter keeps getting called repeatedly in Node. Why does this happen and how can it be resolved? router.get('/se ...

Submitting form by double clicking and pressing enter at the same time

When using jQuery Validate to validate forms, I encounter a problem where double-clicking the submit button results in my application making two entries with the same data. This issue also occurs when pressing enter multiple times. Despite researching dif ...

Setting model value in Angular 2 and 4 from loop index

Is it possible to assign a model value from the current loop index? I've tried, but it doesn't seem to be working. Any suggestions on how to achieve this? Check out this link for my code <p *ngFor="let person of peoples; let i = index;"& ...

Footer not being pushed down by content in mobile view on page

Hello everyone, Can you assist me with a query, please? My form works perfectly fine in desktop view, but it gets cut off on mobile view and I'm unsure of the reason why. Here is my code: .upload-pic { position: absolute; max-width: au ...

Omit certain table columns when exporting to Excel using JavaScript

I am looking to export my HTML table data into Excel sheets. After conducting a thorough research, I was able to find a solution that works for me. However, I'm facing an issue with the presence of image fields in my table data which I want to exclude ...

Example of fetching Pubnub history using AngularJS

I am not a paid PubNub user. I am utilizing the example code for an Angular JS basic chat application from PubNub, and I want to access the chat history. This specific example can be found on the PubNub website. git clone https://github.com/stephenlb/an ...

Changing the route variable in React Native's bottom bar tab functionality

I am looking to create a consistent bottom tab bar that remains the same on every screen, but I want the routes of the tabs at the bottom to change dynamically. For example, in Screen1, the tab at the bottom should route to 'Screen2'. Then, when ...

.class selector malfunctioning

I'm currently developing a card game system where players can select a card by clicking on it and then choose where to place it. However, I've encountered an issue where nothing happens when the player clicks on the target place. Here is the li ...