Miguel Moura
Miguel Moura

Reputation: 39394

How to deactivate button while loading

I have the following Angular and HTML to display and reload a list of images:

<script type="text/javascript">

  var application = angular.module('Application', []);

  application.service('ImageService', function ($http) {
    return {
      GetList: function (page) {
        return $http.get('api/images', { params: { page: page } });
      },
    }
  });

  application.controller('ImageController', function ImageController($scope, ImageService) {

    var page = 0;
    $scope.images = [];

    var load = function () {
      ImageService.GetList(page)
        .success(function (data, status, headers, config) {
          $scope.images = $scope.images.concat(data);
        })
        .error(function (data, status, headers, config) { });
    }

    $scope.reload = function () {
      page++;
      load();
    }

    load();

  });

</script>

<div data-ng-app="Application" data-ng-controller="ImageController" class="gallery">
  <div data-ng-repeat='image in images' class="image">
    <img src="{{image.Url}}" alt="" />
  </div>
  <a href="" class="reload" data-ng-click="reload()">load more</a>      
</div>

How can I change the text of "load more" do "loading ..." and deactivate the button while is loading?

Upvotes: 0

Views: 1595

Answers (2)

Michael Kang
Michael Kang

Reputation: 52847

You could create a 'loading' directive that disables a button/link when there are pending $http requests:

Directive

  app.directive('loading', function($http) {
     return  {
         restrict: 'A',
         scope: true,
         link: function(scope, element) {
             scope.pending = $http.pendingRequests;
             scope.$watch('pending.length', function (length) {
                 if (length > 0)
                 {
                      element.attr('disabled', 'disabled');
                 }
                 else {
                      element.removeAttr('disabled');
                 }

             });

          }
       }
    });

Controller

app.controller('ctrl', function($scope, $http) {
    $scope.load = function() {
         $http({url: 'api/get', method:'GET'}).success(function(data) {
             $scope.data = data;
         });
    }
});

HTML

<div ng-controller="ctrl">
   <button ng-click="load()" loading>Click Me</button>
</div>

Upvotes: 3

Peter Ashwell
Peter Ashwell

Reputation: 4302

You could bind it to the scope:

<script type="text/javascript">

  var application = angular.module('Application', []);

  application.service('ImageService', function ($http) {
    return {
      GetList: function (page) {
        return $http.get('api/images', { params: { page: page } });
      },
    }
  });

  application.controller('ImageController', function ImageController($scope, ImageService) {

    var page = 0;
    $scope.images = [];
    $scope.loading = false;
    $scope.loadingText = function() {
        if ($scope.loading) {
            return 'loading';
        }
        return 'load more';
    }

    var load = function () {
      $scope.loading =  true;
      ImageService.GetList(page)
        .success(function (data, status, headers, config) {
          $scope.images = $scope.images.concat(data);
        })
        .error(function (data, status, headers, config) { })
        .finally(function() {$scope.loading = false});
    }

    $scope.reload = function () {
      page++;
      load();
    }

    load();

  });

</script>

<div data-ng-app="Application" data-ng-controller="ImageController" class="gallery">
  <div data-ng-repeat='image in images' class="image">
    <img src="{{image.Url}}" alt="" />
  </div>
  <a ng-disabled="{{loading}}" href="" class="reload" data-ng-click="reload()">{{loadingText()}}</a>      
</div>

Upvotes: 2

Related Questions