2

I am trying to enable a button after page load in an AngularJS directive. I applied ng-disabled for all my buttons DURING load and I would like to keep certain buttons disabled AFTER load.

I need some direction/advice on:

  • manipulating the DOM: from ng-disabled="!newAnimal.isDisabled" to ng-disabled="newAnimal.isDisabled"

I appreciate the help. Thanks.

HTML:

    <a href="#/{{animal.id}}">
        <button class="btn btn-success" ng-disabled="!newAnimal.isDisabled" id="add-animal" loading-animals>
          Add Animal
        </button>
    </a>

FACTORY:

    var animalFactory = angular.module('app.myFactory',[])

    animalFactory.factory('newAnimal',function(){
        var newAnimal = function(){
              this.animal = ""; 
              this.totalAnimals = 0;
              this.totalAdopted = 0;
              this.isDisabled = false;
       };
      return newAnimal
   });

CONTROLLER (Modal):

.controller('InformationCtrl', function($scope, $modalInstance, $http) {
    $scope.ok = function(){
        //check if button successfully clicked
        $modalInstance.dismiss('success');

        //the code below was from a directive ('LoadingAnimals') that I was working on

        //check if all data has been loaded from backend
        var loadingPage = function(){
            return $http.pendingRequests.length > 0;
            //when all objects are loaded, manipulate DOM 
            //make ng-disabled = "!isDisabled" to "isDisabled"
            element.attr("!newAnimal.isDisabled", "newAnimal.isDisabled);
    }
        loadingPage();
    }

DIRECTIVE:

app.directive('loadingAnimals', ['$http', function($http) {
          
return {

        restrict: 'A',

        link: function (scope, element, attrs) {


            var addButton = attrs.ngDisabled;
            //console.log(element.attr('ng-disabled'));
            scope.pageLoad = function() {
                return $http.pendingRequests.length > 0;
            };

            scope.$watch(scope.pageLoad(), function (value) {
                if (value) {
                    element.attr("ng-disabled", "newAnimal.isDisabled");
                } 
                else {
                    element.removeAttr("ng-disabled");
                }
            })
        }
    }

}]);

UPDATE:

I updated my directive and it works, not the best way of achieving the results but it's one way.

(I would have preferred not to disable the button for 3 seconds but rather to listen to the $http request but since it's a workaround, I won't complain)

Thanks for all the answers. I'll update in the future if I figure out a more efficient way.


DIRECTIVE:

 .directive('loadingAnimals', function() {

       return {

          restrict: 'A',

          link: function (scope, element) {
          var disableLink = (function() {
                element.removeClass('disabled');

            });

            setTimeout(disableLink, 3000);
          }

         }

        }

      ]);

fragilewindows
  • 1,394
  • 1
  • 15
  • 26

2 Answers2

2

Not sure if I'm correct but to do something after page is completely load, you can use angular.element(document).ready() (as you can see in this answer).

So you can have a <button> structured like this:

<button type="button" class="btn btn-primary" ng-disabled="!isDisabled || !animal.totalAnimals">Add animal</button>

See the example below:

(function() {
  'use strict';

  angular
    .module('app', [])
    .controller('MainCtrl', MainCtrl);

  function MainCtrl($scope) {
    var vm = this;
    vm.animals = [
      {
        "name":"hamster",
        "totalAnimals": 20,
        "totalAdopted": 5,
      },
      {
        "name":"turtle",
        "totalAnimals": 0,
        "totalAdopted": 0,
      },
      { 
        "name":"cat",
        "totalAnimals": 9,
        "totalAdopted": 6,
      },
      { 
        "name":"dog",
        "totalAnimals": 7,
        "totalAdopted": 2,
      },
      { 
        "name":"tiger",
        "totalAnimals": 0,
        "totalAdopted": 0,
      }
    ];
    
    vm.isDisabled = true;
    
    angular.element(document).ready(function () {
      console.log('completely load!');
      vm.isDisabled = false;
    });
  }
})();
<!DOCTYPE HTML>
<html ng-app="app">

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
</head>

<body ng-controller="MainCtrl as main">
  <table class="table table-hover">
    <thead>
      <tr>
      <th>Name</th>
      <th>#of Animals Added</th>
      <th>#of Animals Adopted</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="animal in main.animals track by $index">
        <td ng-bind="animal.name"></td>
        <td ng-bind="animal.totalAnimals"></td>
        <td ng-bind="animal.totalAdopted"></td>
        <td>
          <button type="button" class="btn btn-primary" ng-disabled="!main.isDisabled || !animal.totalAnimals">Add animal</button>
        </td>
      </tr>
    </tbody>
  </table>
</body>

</html>

I hope it helps.

Community
  • 1
  • 1
developer033
  • 24,267
  • 8
  • 82
  • 108
  • I will test this out tomorrow. I see that you are using a controller instead of a directive. Is it the better/recommended way in my situation to use controllers or is this just one approach? Also, out of curiosity, what does the variable 'vm' mean? Thanks for your help. – fragilewindows Aug 08 '16 at 02:21
  • Well, I think using that `angular.element(document).ready()` can work in your case. `vm` is the reference of `this`. It's a good practice.. you can read more at [**John Papa's style guide**](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md). – developer033 Aug 08 '16 at 02:27
  • While your code is similar to what I'm trying to do, I realize I can't implement it because I have a popup modal before this table where a user has to click ok first before the data populates. I'll update my question to note that. – fragilewindows Aug 08 '16 at 17:26
1

You can also use a directive to make changes post page load

<button id="submit" ng-click="test()">Submit</button>
<disable-button></disable-button>

This is how the directive will look like

.directive('disableButton', function () {
            return {
                restrict: 'E',
                compile: function (el, attr) {
                    return {
                        pre: function (scope, el, attr) {

                        },
                        post: function (scope, el, attr) {
                            $('#submit').attr("disabled", true);
                           //add your logic here
                        }
                    }
                }
            }
        })

Refer the demo

Vinay
  • 21
  • 6