How to Write an Angular directive to update CSS class based on form validation


Tags: css,angularjs

Problem :

I have the following Angular/HTML which uses Bootstrap CSS classes to indicate whether a form is valid or not using Angular validation.

<form name="editor" novalidate>
    <div class="form-group" ng-class="{'has-error': editor.name.$dirty && (editor.name.$error.invalid || editor.name.$error.required)}"> 
         <input type="text" class="form-control" name="name" maxlength="150" data-ng-model="name" required />
    </div>
</form>

With more than one div.form-group obviously there is a lot of code repetition. What I would like to do is create an Angular attribute directive which will update the class of the div.form-group element if the input contained within it is invalid.

This is the markup I would like to get to:

<div class="form-group" data-form-group data-input="editor.name">
     ...
</div>

I have the following shell of a directive but I don't know how to monitor the editor.name (or input attribute) in order to update the class.

myApp.directive("formGroup", function () {
return {
    restrict: "A",
    scope: {
        input: "@"
    },
    replace: false,
    link: function (scope, elem, attrs) {

    }
    };
});

I assume I need to put the relevant code in the link function, and perhaps using $watch but other than that I am a bit in the dark



Solution :

I have ended up with the following:

myApp.directive("formGroup", function ($parse) {
  return {
    restrict: "A",
    scope: {
        input: "@"
    },
    replace: false,
    require: "^form",
    link: function (scope, elem, attrs, ctrl) {

        var expression = [ctrl.$name, scope.input, "$invalid"].join(".");

        scope.$parent.$watch(expression, function (val) {
            alert(expression + " " + val); // Pops the value.
        });
    }
  };
});

Note that although the expression in the HTML is editor.name.$error.invalid, in the link function it is editor.name.$invalid.

Using the form controller means I don't have to set the ng-model attribute on the <div>.


    CSS Howto..

    How can I use CSS to make a multi-select box but have the label appear on top instead of to the left?

    How can I override inline styles with external CSS?

    how to change stack order of of text label in JavaScript?

    Bootstrap progress bar with gradient color showing proportionally on active width

    how to use variables when setting CSS properties in Jquery?

    My jquery slideshow is not functioning properly

    how to center a div in a td cell and a link inside of it ?both vertically and horizontally?

    How to set the maximum height of CSS tables?

    How to create a div in the same size as the contained image. Both should be responsive

    How to exclude a child from the parent css property?

    How to prevent mobile device to resize and use proper css file

    How do I align columns in the center of the page? [duplicate]

    How do I add custom fonts? [duplicate]

    How to make the background image to fit into the whole page without repeating using plain css?

    How to get my navbar to fluidly contain the largest element?

    How to bind Menus and submenus apply css using Jquery?

    How to target this HTML in CSS?

    How to prevent specific css style sheet from styling a specific html tag

    How to get 'div' shaped as a flag with CSS

    Ember css dosen't work + How to create two stylsheets

    How to Surround Links with Bounding Box Using CSS

    How to override CSS :hover?

    CSS 3D containers like shown in post

    How to change header font and nav link color when slideshow image changes

    How to give option to add css classes/IDs to content to in CMS's WYSIWYG content builder/editor to non-technical client?

    How to change custom Check Box border with Dart

    How to style an asp.net menu with CSS

    How to override GWT obfuscated style for DataGrid header

    How to use fadeIn with css property change jquery

    How to horizontally stack elements using CSS?