8

I would like to create form with fields created in directive. Data binding of data working correctly but validation doesn't work.

this is html:

<body ng-controller="MainCtrl">
  <h1>form</h1>
  <form name="form">
      <div ng-repeat="conf in config">
          <div field data="data" conf="conf"></div>
      </div>
  </form>
  <pre>{{data|json}}</pre>
</body>

controller and field directive:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
    $scope.data = {name: '', age: ''}
    $scope.config = [
        {field: 'name', required:true},
        {field: 'age'}
    ];
});

app.directive('field', function ($compile) {
    return {
        scope: {
            data: '=',
            conf: '='
        },
        link: function linkFn(scope, element, attrs) {
            // field container
            var row = angular.element('<div></div>');

            // label
            row.append(scope.conf.field + ': ');

            // field input
            var field = angular.element('<input type="text" />');
            field.attr('name', scope.conf.field);
            field.attr('ng-model', 'data.' + scope.conf.field);
            if (scope.conf.required) {
                field.attr('required', 'required');
            }
            row.append(field);

            // validation
            if (scope.conf.required) {
                var required = angular.element('<span>required</span>');
                required.attr('ng-show', 
                    'form.' + scope.conf.field + '.$error.required');
                row.append(required);
            }

            $compile(row)(scope);
            element.append(row);
        }
    }
});

problem is that validation for field name doesn't work and validation text required is never shown. May be form in ng-show is unknown in directive. But I don't know how to pass form into field directive. Can you help me how to fix it? Thanks.

here is live code: http://plnkr.co/edit/j0xc7iV1Sqid2VK6rMDF?p=preview

1
  • 2
    I am battling with the same issue. I found an undocumented feature in angular source: FormController has methods $addControl and $removeControl. I am thinking of tapping into these methods to dynamically add controls to the parent FormController from within the directive. Will let you know if I am successful. Commented May 27, 2013 at 21:40

3 Answers 3

5

Todo:

before:

$compile(row)(scope);
element.append(row);

after:

element.append(row);
$compile(row)(scope);

p/s in 'planker' for facilities add css:

.ng-invalid {
  border: 1px solid red;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Although highly obscure, this is actually an answer. Should be accepted ASAP
2

You'll need to use ng-form directive and push the dynamic field directly into form object.

This thread can help you out: https://github.com/angular/angular.js/issues/1404

Comments

0

Here is a plunker forked from yours to fix you're issue: http://plnkr.co/edit/qoMOPRoSnyIdMiZnbnDF?p=preview

To summarize, I added a watch that will toggle the error message instead of using the ng-show directive. Things can get hairy when you attempt to dynamically add a directive within a directive link. For a simple use case as this, it is quicker to add your own watch.

You may also look at this directive which is preconfigured to handle many use cases for validation as well as allow you to create custom validations easily https://github.com/nelsonomuto/angular-ui-form-validation

var toggleRequiredErrorMessage = function (invalid) {
    if(invalid === true) {
        addRequiredErrorMessage();
    } else {
        removeRequiredErrorMessage();
    }
};
scope.$watch( watchIfRequired, toggleRequiredErrorMessage );

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.