4

I have been trying to build a form input directive which will generate a form input based on the model and the model attributes . For example,

  1. if the field is name and type is text, the directive will return a input html control,
  2. if the field is a list, then it will return a select box and so on

These inputs are generated using ng-repeat in the view. The inputs are bound to the model in the scope. This is working fine. However, the form validation fails; i.e if the input controls are invalid, the main form still shows the form is valid.

I have put up a simple plunkr to illustrate the issue - http://plnkr.co/edit/R3NTJK?p=preview

NOTE : I have actually nested the form, as the input name field is also dynamically generated from the scope model.

I have been trying to a get hold on this from the past 2 days and this is really driving me nuts.

I m not sure if I m missing something.

I would really appreciate if some one could help me out with this.

0

1 Answer 1

2

Update: Use the following link function:

link: function linkFn(scope,elem,attr){
   var jqLiteWrappedElement = 
       angular.element('<input type="url" name="socialUrl" ng-model="social.url">');
   elem.replaceWith(jqLiteWrappedElement);
   $compile(jqLiteWrappedElement)(scope);
}

Plunker.

For reasons I don't understand, the replaceWith() must be executed before the call to $compile. If someone can explain why this is so, we'd appreciate it!

Update2: in the comments below, Artem mentioned that the DOM must be modified before the linking function is called, so this also works:

var myElem = angular.element('some html');
var linkFn = $compile(myElem);
element.replaceWith(myElem);
linkFn(scope);

Original answer:

Instead of the link function, just use a template in your directive:

template: '<input type="url" name="socialUrl" ng-model="social.url">'
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the input. But, I need to generate the template dynamically based on scope i.e template can be input- text/radio/checkbox, select, datepicker etc. based on the field type available in scope. In such a case, I cannot hardcode the template string and need to generate it using the link function which has access to the scope.
@Gautham, I figured out how to make it work in the link function, but I don't fully understand why. See updated answer.
@MarkRajcok, hi. Thanks for your answer. I've faced similar problem and your solution works fine. But I'm curious, did you figured out why replaceWith must be called before $compile?
@Artem, no I still don't know why.
@MarkRajcok, ok I just figured out that it's not about compile itself. It's about liking scope to compiled DOM subtree. $compile without linking before replaceWith works too. gist.github.com/armed/5369236
|

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.