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

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.