Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm working on a project, which has similar submit forms, so I have decided to move some fields to directives.

Form example:

 <div loading class="col-sm-12" ng-controller="Controller">
        <form name="myForm" role="form" novalidate>
            <fieldset class="lines-header-border">
                <div class="col-sm-6">
                   <div class="form-group">
                       <label class="col-sm-4 control-label">Date</label>
                       <div class="col-sm-7">
                            <date-field 
                             model="myModel" 
                             date-picker-options="datePickerOptions"
                             for-name="date"
                             for-ng-class="myForm.date.$invalid"
                             is-required="true"/>

                       </div>
                     <div class="col-sm-4">
                    <input class="form-control" 
                           name="amount" 
                           ng-model="amount" 
                           ng-class="{ 'has-error' : myForm.amount.$invalid }" 
                           required/>
                </div>
                    </div>
            </fieldset>
        </form>
    </div>

Date field directive:

.directive('dateField', function() {
    return {
        restrict: 'E',
        replace: true,
        scope: {
            model: '=',

            datePickerOptions: '=',

            isRequired: '@',

            forName:'@',

            forNgClass: '&'
        },
        template: '<input ui-date="datePickerOptions" type="date" name="{{forName}}" class="form-control"  ng-model="model" ng-class="{ \'has-error\' : forNgClass()}"  ng-required="isRequired"/>'
    };
});

Validation problem on submit: Other fields gets validated on form submit button click, but this date field isn't. I think that the problem is in for-ng-class="myForm.date.$invalid".

Any suggestions?

share|improve this question
add comment

1 Answer 1

up vote 1 down vote accepted

In your case, you want to access the controller scope variable "myForm.date.$invalid" via the directive attribute "for-ng-class". Assign "@" to the directive scope variable "forNgClass" for two-way data binding. When the input field has been changed, the class will be updated accordingly.

scope:{
    .....
    forNgClass: "@"
    .....
}

I implemented a simple example:

UPDATE: Since angular can't dynamically generate the name attributes of input elements. We need to wrap the input element of dateField in an inner form (by using ngForm directive). You can refer to Angular Doc for more details about nested form in angular world.

<!DOCTYPE html>
<html>

<head>
    <style>
        .has-error{
            background:#ccc;
            border: 1px solid red;
        }
    </style>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
    <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.11/angular.min.js"></script>
    <script src="angular-ui-date.js"></script>
</head>

<body ng-app="MyApp">
    <div ng-controller="MyCtrl">
        <form name="myForm" novalidate>
            <h2>Selected date: {{dateData}}</h2>
            <date-field model="dateData" is-required="true"></date-field>
            <date-field model="dateData2" is-required="true"></date-field>
            <h3>myForm is invalid?</h3>{{myForm.$invalid}}
        </form>
    </div>
    <script>
        angular.module("MyApp",['ui.date'])
        .controller("MyCtrl",function($scope){

        })
        .directive("dateField",function(){
            return {
                restrict: "E",
                replace: "true",
                template: '<ng-form name="subForm"><input ui-date ui-date-format="yy-mm-dd" type="date" ng-class="{\'has-error\':subForm.myDate.$invalid}" name="myDate" ng-model="model" ng-required="isRequired"/></ng-form>',
                scope:{
                    model: "=",
                    isRequired: "@"
                }
            };
        });
    </script>
</body>

</html>

Here is a Online demo. You could refer to it.

share|improve this answer
    
Thanks for the reply. But as I see you added name="myDate" to the template. Is it possible to use name="forName" . So it would refer to passed field name, not to the hard coded one? –  kuldarim Jun 13 at 9:15
    
Unfortunately, Angular can't dynamically generate the name attribute of input elements. I've updated my answer and online demo. Maybe you can try to use nested form to solve your issue –  Chickenrice Jun 15 at 12:23
    
Thanks for the advice, I consider using your suggestion. But for now I think I will use hard-coded name for smaller code complexity. –  kuldarim Jun 16 at 5:18
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.