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);
          }

         }

        }

      ]);


0

2 Answers 2

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.

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

3 Comments

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.