Search code examples
twitter-bootstrap-3angularjs-directivetoggleclass

Toggle button class using Directive in Angular


I want to toggle a buttons class depending on the state of a form in Angular. The template is based on Bootstrap.

I've setup a directive called IsDirty.

If the form has the class 'ng-valid', add the class 'btn-success' to the submit button.

Alternatively, if the form is dirty and has the class 'ng-dirty', remove the class 'btn-success' from the submit button.

So far this is what I have but it doesn't work.

var angular = require('angular');

angular.module('myApp')
    .directive('isDirty', [function() {
        return {
            restrict: 'E',
            link: function(scope, element, attrs, ctrl) {
                var submitButton = element.find('.btn-primary');

                if(element.hasClass('ng-valid')) {
                        submitButton.addClass('btn-success');
                } else {
                    submitButton.removeClass('btn-success');
                }

                scope.$apply();             
            }
        };
    }]);

My form:

<form is-dirty class="form-horizontal" role="form" name="profileForm">

    <!-- INPUT FIELDS HERE //-->

    <button type="submit" class="btn btn-primary">Save Changes</button>
    <button type="reset" class="btn btn-default">Cancel</button>
</form>

Solution

  • This should hopefully fix your problem

    .directive('ngDirty', [function() {
            return { 
                restrict: 'AE',
                link: function(scope, element, attrs, ctrl) {
                    var submitButton = element[0].querySelector('.btn-primary');
                    if(element.hasClass('ng-valid')) {
                            submitButton.classList.add("btn-danger");
                    } else {
                        submitButton.classList.remove("btn-danger");
                    }            
                }
            };
        }]);
    

    Plnkr Example

    Update:

    It's a little dirty but it seems to work and checks each input, you must bind each input to an ng-model though I have used $scope.input

    New Plnkr

    2nd Update

    I have removed the function and brought in a $timeout you will see from the example how it works.

    New update with a $timeout as function