I have a problem with validating inputs that are generated dynamically.
Here is the fiddle that shows the problem: http://jsfiddle.net/flsilva/8JzDb/17/
this is taken from: https://groups.google.com/forum/?fromgroups=#!topic/angular/qLeUWZVuQMI
the name is generated fine but it's not bound to the form scope. Because I can name it correctly but the form is not bound, it seems that this behavior is inconsistent.
Thoughts?
+1
@hyusetiawan @michaelahlers In the current version of AngularJS you need to use nested ng-form directives (http://docs.angularjs.org/api/ng.directive:ngForm) to validate dynamically generated input fields.
Here is a fixed jsFiddle: http://jsfiddle.net/6H8Xx/ and another example:
http://jsfiddle.net/pkozlowski_opensource/rqARD/1/
Closing for now, please feel free to reopen if you've got any further questions / issues with this one.
I really don't think this issue should be closed. The "solution" (using nested forms) seems more of a hack than a proper design pattern. Nested forms are... untidy. I'm trying to resolve the same problem with dynamic elements generated via directives, to no avail; I need my original form to be aware of its own elements.
I agree - this issue should be re-opened and only closed when a proper solution is introduced in Angular.
It would make sense to have something like a "ng-name" directive that allows setting the name from an expression.
+1
Here's a modified fixed jsFiddle that will let the parent form still submit properly (the escaping makes it pretty nasty): http://jsfiddle.net/langdonx/6H8Xx/2/
+1
Faced this problem too.
I tried to fix that, but looks like they're already moving in that direction: now attributes are interpolated before directives are linked, so ng-show
from the fiddle watches the correct value. The only thing left is to assign a name to a control not in NgModelController
but in ngModelDirective
, that's one line fix.
I also think that nested forms is going to solve this. If you have a nested form that has radio buttons in it that don't use a dynamic name attribute, you'll run into some issues with selecting the radio buttons.
+1 Users are building forms and then having other users submit data through those generated forms. We need dynamic element binding for forms. I have written entire custom validation for our forms currently, but out of the box functionality would be nice. Nesting ng-form does seems pretty messy for us since every field would have to be wrapped.
+1 encountered this issue whilst creating dynamic forms.
Is this already available in any angular build?
Also, if this is not already in a build, what's the exact solution using nested ng-form
s? As-per the documentation ng-form
names are also not interpolated.
@saurabhnanda no, there is no fix in master yet. There are several PRs opened but those need careful review. The current solution is to use the ngForm
directive as described here: http://stackoverflow.com/a/12044600/1418796
@pkozlowski-opensource -- if one uses the solution given at http://stackoverflow.com/a/12044600/1418796 how can one access the nested forms in the outer controller's scope? It wouldn't be possible, right?
The "work around" doesn't seem to work on all cases. Radio groups fail on this as the newly applied scope doesn't adhere to them. Here's an example:
+1! it would be great to see this fully supported.. current (1.1.1) nested forms doesn't seem to really work for input type, see e.g. my http://jsfiddle.net/vorburger/8CxRC/7/ for http://stackoverflow.com/questions/17841915/angularjs-ng-model-form-driven-by-ng-repeat-over-ui-model-description-data-how-t
+1 -- this would be HUGE
+1 it would be so huge
+1 Need this fixed
+1 Need this fixed, too
+1 ran into this issue just now
+1 I also ran into this issue while working on https://github.com/globaleaks/GlobaLeaks/issues/545
+1, want the issue to be fixed.
+1 Need this fixed, too
+1 would really like this fixed! (please!)
+1
:+1:
+1 It's hardly possible to create generic form components until this issue is fixed.
+1 :)
+1
:+1:
+1
It would be awesome to hear the current thinking from the team on this one.
<overly-entitled-remark>
It's somewhat ironic that Angular.js is built to enable dynamic web applications, but something as foundational as dynamic forms isn't well supported.</overly-entitled-remark>
Thanks :)
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1, have had massive problems trying to get a work around for this. Nested forms might solve the 1-many problem (albiet a messy), but I still ran into problems where the name of property is itself dynamic. i.e. innerForm.dynaminPropertyName
Had to create a hacky directive to 'correct' the name of the input on the form in the scope as they were being compiled.
+1 !!
:+1:
+1
+1
:+1:
+1
+1
+1
+1
+1
+1
+1
The following example shows the problem more clearly:
http://jsfiddle.net/Thinkscape/bbCVf/
If you need this behaviour prior to 1.3, you can easily do something like http://plnkr.co/edit/hSMzWC?p=preview (or in a more no-conflicty fashion http://plnkr.co/edit/VnHHEe?p=preview) --- There are currently pull requests open for this feature (#4791 and #5231 respectively, but actually quite a few more), feel free to vouch for those and test them out
@caitp thank you!
Here's an an example using the workaround in my context: http://jsfiddle.net/Thinkscape/23RPt/
+1 would love to see this properly resolved as a feature of AngularJs and not needing a hack.
+1 this has been painful for me too
+1
@caitp thank you!
Would you like to check the availability of 'name' attribute before 'attrs.$set('name', $interpolate(attrs.name || '')(scope));'?
In our scenario, the availability of name is important in another piece of code. $interpolate attrs.name only when it exists makes more sense here.
+1 Would love, love love to have this feature! In that case (and for others) 1.3 can't come soon enough
@Thinkscape, nice !
+1
@caitp nice use of a decorator for the form. I did the same for ngFormDirective and can now use dynamically generated sub-form names to determine which of the sub-forms is invalid (for user hints). #oweyouabeer
+1, my project is on hold because of this...
@alexbowen That's hardly an excuse - it's doable even without this feature.
Just ran into this problem - writing code exactly as in the @Thinkscape example above.
+1
+1 :+1: :+1: :+1: :+1:
ng-name plz
+1
+1
+1
+1
+1
Hang tight for another day, because the AngularDart example as a bit of a different approach to handling this and I would like to get everyone to consider the approach before we move forward on this. I'll post a link here to the HTML code tomorrow.
+1. @matsko Do you have the link?
Edit: Tried the above decorator and it worked like a charm. Thanks a lot, @Thinkscape.
Here's the decorator in coffeescript, if it pleases anyone. (This is just the part allowing interpolated form name values)
.config(['$provide', ($provide)->
$provide.decorator 'formDirective', ($delegate)->
form = $delegate[0]
controller = form.controller
form.controller = ['$scope', '$element', '$attrs', '$injector', ($scope, $element, $attrs, $injector)->
$interpolate = $injector.get('$interpolate')
$attrs.$set('name', $interpolate($attrs.name || $attrs.ngForm || '')($scope))
$injector.invoke(controller, this, {
'$scope' : $scope
'$element': $element
'$attrs' : $attrs
})
]
return $delegate
])
+1
@Thinkscape thank you for the decorator.
hey, I wrote the decorator! oh fine guys... (kidding, kidding)
Just about done with the Dart forms demo. Sorry this is taking so long.
True, @caitp is the author of the brilliant workaround and I've merely created a decorator using it :+1:
Anyways, it's about time we had an underlying fix in the core instead of workarounds... Is there a PR for that ?
As Matias said, he's been working on this in Dart for a while now, and the Dart implementation takes a slightly different approach. I guess we need to come up with a decision as to whether the greater complexity of the approach in Dart is worth it.
Yes exactly. Thanks @caitp for clarifying that.
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
Thank you @caitp and @Thinkscape for your workaround
+1
+1
I too thank @caitp and @Thinkscape for your workaround.
Hello, I 've got a solution for ng-form dynamic names :
It doesn't work with input's, only with the ng-form directive :
In angualrjs source code, replace
function FormController(element, attrs) {
by
function FormController(element, attrs, scope) {
and
form.$name = attrs.name || attrs.ngForm;
by
if(typeof scope.$eval( attrs.name ) !== 'undefined'){
form.$name = scope.$eval( attrs.name );
}
else{
form.$name = attrs.name || attrs.ngForm;
}
and
alias = attr.name || attr.ngForm;
by
if(typeof scope.$eval( attr.name ) !== 'undefined'){
var alias = scope.$eval( attr.name );
}
else{
var alias = attr.name || attr.ngForm;
}
Now in your template, you can do :
<form name="MainForm">
<div ng-form name=" dynname ">
<button type='button' ng-click='testt(dynname)'>Submit</button>
</div>
</form>
And in your controller :
$scope.dynname = 'myForm';
$scope.test = function(formName){
console.log($scope.MainForm[formName];
}
to access, and modify your form's properties.
well, not quite =) $scope.$eval()
won't take interpolation markers into account, so it would actually be name="dynname"
without the curly braces.
This isn't totally desirable, though, because you can get unexpected results with non-string properties of scope which you inadvertently use in your template.
Exactly right , Interpolation.. I didn't knew this word before ..
I was testing it while writing this post. Thank you for reminding me to edit my post above.
This understand it isn't very appropriate to edit a framework source code like this, but I spent so much time with this validator provider.
I will check if this is possible to implement the same on the input directives as well.
More later.
@caitp To force all inputs to support a dynamic name, I found out that modifying slightly the NgModelController in 1.2.9 resolves the issue for me :
in the definition of NgModelController, replacing
this.$name = $attr.name;
by
if(typeof $scope.$eval($attr.name) !== 'undefined'){
this.$name = $scope.$eval($attr.name);
}
else{
this.$name = $attr.name;
}
This solves the issue. The name attribute will be interpolated.
If we want to support as well a dynamic change of this input's name, some work needs to be done. But basically, a $watch in the ngModelDirective function would fix it : (This code is untested).
$scope.$watch('attr.name', function( newValue, oldValue){
if(typeof $scope.$eval(newValue) !== 'undefined'){
var oldName = $scope.$name;
$scope.$name = $scope.$eval(newValue);
}
else{
if(typeof newValue === 'undefined' || newValue=='' || typeof newValue=='integer'){
throw "Some probleme here mate...";
}
var oldName = $scope.$name
$scope.$name= newValue;
}
if(formCtrl){
delete(formCtrl[oldName]);
formCtrl.$addControl(modelCtrl);
}
}
}
you might think that, but it turns out you're wrong in this case! $scope.$eval($attr.name)
will never perform interpolation, at all. Not even once! It evaluates the expression, which is something the $interpolate
service also does, but $interpolate
makes sure to stringify everything, and always returns a string.
I mean, if it works for your purposes then by all means do it, but it's not an ideal solution, because of the pitfalls of $eval and the weird bugs that it can introduce when used on something that is expected to always be a string literal and not an expression.
@caitp I obviously need to go deeper in angularjs source code.
Thank you for this clear explanation.
Nested forms are not a proper solution, but a hack to get things working.
And I also want to print the validation messages at the top of the main form.
How can I do this with nested forms and all input elements having name="input"
+1 for a fix in the core.
I've had problems with @Thinkscape decorator when it was uglified so I fixed it.
Here's the solution:
$provide.decorator('ngModelDirective', ["$delegate", function($delegate) {
var ngModel = $delegate[0];
var controller = ngModel.controller;
ngModel.controller = ['$scope', '$element', '$attrs', '$injector', function(scope, element, attrs, $injector) {
var $interpolate = $injector.get('$interpolate');
attrs.$set('name', $interpolate(attrs.name || '')(scope));
$injector.invoke(controller, this, {
'$scope': scope,
'$element': element,
'$attrs': attrs
});
}];
return $delegate;
}]);
$provide.decorator('formDirective', ["$delegate", function($delegate) {
var form = $delegate[0];
var controller = form.controller;
form.controller = ['$scope', '$element', '$attrs', '$injector', function(scope, element, attrs, $injector) {
var $interpolate = $injector.get('$interpolate');
attrs.$set('name', $interpolate(attrs.name || attrs.ngForm || '')(scope));
$injector.invoke(controller, this, {
'$scope': scope,
'$element': element,
'$attrs': attrs
});
}];
return $delegate;
}]);
Thanks @Thinkscape ;)
@2fdevs no probs mate :-)
Btw: what did you change ? I don't see it ... I've incorporated the fix in all my apps and they are all compiled (minified). My original code works fine with minification... unless I'm missing something.
I've added ["$delegate"
in this lines.
$provide.decorator('ngModelDirective', ["$delegate", function($delegate) { ...
$provide.decorator('formDirective', ["$delegate", function($delegate) { ...
@Thinkscape the solution worked perfect for me but when I was testing with minified files karma tests throw me a few errors, so maybe it's only a problem with minified files and karma.
+1
Thanks, I've fixed my fiddle.
Updated workaround with demo: http://jsfiddle.net/23RPt/
Works for me, using ng-repeat:
<div ng-repeat="field in user.fields">
<input name="fields.{{$index}}">
</div>
My form now has fields.0, fields.1, etc.
+1
This is not entirely straightforward. One of the main drivers behind not allowing dynamic name
attributes on input elements in Angular 1.0 and 1.2 was that changing the name attribute of an input element doesn't work very well in IE. See http://msdn.microsoft.com/en-us/library/ms534184(v=vs.85).aspx
It seems that It may well be that for Angular applications we don't really care about the IE9 oddities but they should be clearly evaluated and documented before we can implement any such strategy.
We have a version of @caitp's code running perfectly on IE9, though that may have no bearing on whether the ultimate solution will work as well.
The nested ng-form solution is awesome cause it solves the problem in an incredibly AngularJS way. Create a new scope! You keep the name the same and have a different scope for each repeat. That's what the ng-form is doing. I don't see this as a bug, but rather the AngularJS way. Dynamic name attribute is much messier.
When dealing with forms and (sub forms via ng-form) adding additional ng-forms around inputs in an ng-repeat just to get dynamic naming thus adding another scope, seems to make the management of form validation data just that much harder. It feels like a work around. That said I am using ng-forms to implement encapsulated subforms but I choose what inputs are grouped and related within an ng-form and don't have to let a 1,000 ng-forms bloom to uniquely name input elements so I can process form validation data for each. I too have a directive that lets me do this but would rather have this in the core. That said I would understand if the AngularJS team did not want to support interpolated names within an ng-repeat due to code creep or performance issues.
+1 please
+1
+1
+1
+1
+1
+1 I'd also like to see names update so that names stay in sync when dynamically added form fields are removed eg name="myField[{{ $index }}]"
+1
+1
+1
+1
+1
How long is a fix for this 2 year old issue going to take?
@digitalgym for someone who never helped angular.js, you're pretty rude, you know?
@plentz for an issue with 135 comments and running for nearly 2 years and receiving +1's everyday, what's a reasonable response time in your opinion?
@digitalgym please see @Thinkscape's fiddle for a great workaround which fixes this problem. Just include it in your project and add a dependency to it in your app.
@digitalgym this is more like a new feature than a bug. As @fiznool said, check the fiddle with the workaround, is just copy+paste a code snippet
+1
+1
is there a way to modify the decorator so the $name value tracks a dynamic name for an ngForm? Ive got a bunch of nested ng-forms and id like to be able to discriminate which are invalid from the parent form's $error object. is there another way to do this? As is, dynamic name sticks in the attribute but $name references the pre-interpolated val
+1
@idiotslowdown if u have nested ng-forms, u can check the errors of each one using the form name
<ng-form name="myForm1">
<ng-form name="myForm2">
<div ng-class="{'has-error': myForm2['myinput1'].$invalid}">
//form element with dynamic name "myinput1"
</div>
</ng-form>
</ng-form>
console.log($scope.myForm2.$valid)
console.log($scope.myForm1.$valid)
I had no problem at all using dynamic names and nested forms (with the decorator ofc)
Here this is what I mean: http://plnkr.co/edit/icbjmZEJtzmey4TFJ9WQ?p=preview
Each failure returns $name: "{{subitem.tag}}". It would be nice to retrieve the names of invalid forms from the parent error object, while remaining agnostic to the form names themselves ahead of time
@idiotslowdown I see it now, if u inspect the var $scope.itemForm u will see {{subitem.tag}} instead of the var for each nested form. The solution in the decorator above is for dynamic input names, not for dynamic form names. If you want to do that i'm afraid you'll have to get the html with the form names pre-rendered from the backend
+1
+1
+1
+1
+1
+1, I would love to see this fixed.
It would've saved me a lot of time in my "in the deep end" Angular learning process!
+1
Had the same problem. I spent a few days researching and think found a solution.
I put a 'ng-form' inside the 'ng-repeat'. Using the name 'ng-form' and name input in directive 'ng-show', the angular can differentiate the input names, eliminating the problem of validation. =)
Hello,
I've created a directive to fix this. I hope this helps.
var ngNameDirective = ['$interpolate', function ($interpolate) {
return {
priority: 9999,
controller: ['$scope', '$attrs', function ($scope, $attrs) {
var interpolatedName = $interpolate($attrs.ngName)($scope);
if (interpolatedName) $attrs.$set('name', interpolatedName);
}]
};
}];
Using ngName directive instead of name attribute you can register form-controls (ngModels) and sub-forms (ngForms) dynamically.
+1
It's f**g ridiculous that animation got hundreds of improvement (according to changelog) and we are unable to cleanly, properly render a dynamic form in angular. I'm starting to feel that it was a very bad choice 1.5 years ago to build a large enterprise application on top of this framework...
@dropout that's a bit melodramatic. You can get this behaviour to work, it's just not "out-of-the-box". Might have to do some real work. Shock, horror, gasp!
@kirkbushell This is not a melodrama, this is the 2978934 nth fix and workaround I'm applying because it fails to prove under large scale. And it's harder to maintain these fixes and workarounds when you switch to a newer version number. You know it's enterprise development not javascript zoo...
@dropout sorry, but you must be doing it wrong. I've been running a large application for nearly 18 months, from angular js 0.6 and despite the initial cost of making it work, it hasn't failed since.
@kirkbushell I wonder how large this application is if you can maintain it yourself.
@kirkbushell @dropout seriously is there a good reason why this is being overlooked it's getting absurd the number of comments against this issue.
@dropout I never said I was the only maintainer.
@digitalgym not sure tbh, seems like a likely candidate for a fix/feature addition.
I think the subform validation should have some options where we can set all elements of a subform being pristine not to trigger an invalid form error even if some of these subform fields are required.
I am thinking to develop a very large applciation in angularjs, i love it, it is fun, fast easy and complicated at the same time.
I cant wait to @dropout and @digitalgym having some number line of code argument.
@dropout, there is a solution to this subform dynamic name fix a bit eralier in the comment. You just have to modify your app.config, and add some $provides, to override the default angular behavior concerning inputs dynamic name, so you can have
<input name="firstname_{{i}}">
into a ng-repeat.
here is the link : http://jsfiddle.net/Thinkscape/23RPt/
It's been a few months since I came up against this issue so my memory is a little hazy however here's my problem.
I have a form that has 'add another' functionality that dynamically adds new fields (3 fields) to a form, I also have an x to remove the fields. I want to access each 'subform' in a controller to perform validation actions based on the data provided by the user.
Some of the hacks in this thread have enabled me to add the new fields, but the names/indexes don't get updated upon delete so then the validation gets applied to the wrong fields, and I haven't found a way to access the inner forms individually in the controller to validate them.
Angular has a 'dynamic html' philosophy, but (unfortunately) it doesn't seem to extend to forms (yet).
nested ng-form solves that issue.
I'm pretty sure I tried that, iirc I couldn't access the nested forms in the controller (or didn't know how to). I'll have to put together a demo repo as my use case seems to be a little more advanced than the others I've seen.
If you need to access it via controller, that can get tricky. We had to do a combination of directives and shared controllers to manage the fields and forms. Depends on what your'e trying to do. If it's just validation, you should be able to use the built-in angular (or your own custom validation rules) to manage that.
@kirkbushell Excuse my ignorance, you've written "I've been running" not "maintaining"
To all the others having problems rendering complex dynamic forms against remote async validations, server generated access controlled configurations etc... my advice if you are about to start something like this roll your own thing, don't try to use angular forms and validation facilities for this because it's pretty immature and causes more problems than it solves... this whole damn thread speaks for itself
@dropout you inferred on your own that I was a lone cowboy, I've corrected you with clarification. Case closed. Even without that, your implication with your statement was rather rude, rather than just asking ;)
And must disagree with dropout, as we've been able to get it going since earlier angularjs versions. Don't spread lies @dropout simply because you've had certain difficulties. We had our earlier problems, and as I said earlier it certainly does require some custom work, but it's possible, and it'll work once setup correctly.
It would be good, however - to have this baked into the codebase.
@kirkbushell I'm not spreading lies it's my opinion. Sorry about that.
+1
+1
@Rafa-GdA Sorry for my ignorance, but how can I use your directive? I don't realize how to implement your code as a directive into my code.
Can you help me? Thanks.
@rodrigok Here's a fiddle with an example: http://jsfiddle.net/y3YJk/
And here another fiddle with the first post example using the directive: http://jsfiddle.net/8JzDb/149/
Thank you @Rafa-GdA
+1
+1
+1
This appears to be the leading workaround: http://plnkr.co/edit/hSMzWC?p=preview
Are there any pitfalls or gotchas I might need to be aware of?
+1
I'm not sure of the exact details of the gotcha.
@matsko has said that they do this differently in AngularDart for some reason, because apparently it's easier to nest child forms underneath and do dynamic validation that way. But honestly, I don't really get why that's any simpler or easier to manage than this one. I've yet to encounter the pitfall with this approach.
+1
after spending hours and hours trying to debug what i'm doing wrong, looks like it's a pretty popular pain point for the community ;). Hope to see a fix soon.
@sgandotra Soon? The issue was created two years ago.
This issue is pretty much the final straw for me. Any future apps will be on emberjs and our main big one will probably be refactored to emberjs or angulardart if it ever gets stable. Angularjs just can't be trusted, it has so many issues.
there's no reason for that kind of negativity! Anyways, workarounds are readily available and have been linked numerous times in this thread, it's not like applications are really limited here
:unamused:
+1
+1
:+1:
+1
Would be nice to have it "in the box".
+1
+1 to implement some facet of ng-name
until then, to help the community would you be willing to update the "API Reference / ng / directive components in ng / input" documentation to add a note in the "name" property description to reflect that it can not be dynamically populated and possibly leave a link to this issue?
You would be saving those of us who use dynamic form(s) and element(s) in angular a fair amount of time lost to debugging a known feature.
Thank you
I want to resolve this issue one way or another before 1.3 ships. We have workarounds which people use in production, so there is no reason we can't fix this. It's just the "how" and "when" that are problems. @dev-head I suggest you review this issue for the workarounds (I've provided some, as have others) and see if they work well for you --- they are only a few lines of code
@caitp - https://github.com/angular/angular.js/pull/4791 seems to be a pretty straight forward solution for this issue. Is there a reason not to use it?
matias has some concern with it which i haven't heard explained clearly
@caitp @shahata #4791 works, but it doesn't reapply itself incase the name changes again. So think of something like an ngRepeat ... If the $index value changes then so does the input and the errors.
I have a work in progress solution for this at the moment that somewhat works. Lots of broken tests. I can get something out by the start of next week once my schedule opens up.
so, I don't think we actually have to care about the name changing --- however, support for that should be pretty trivial with $observe().
Nobody has ever complained about needing these names to change before, basically
In other words, I think we should start with the simple fix, and then update to support changing control names if people need that in the future (I think the problem with that is really the difficulty with things like radio controls, where you have multiple controls with the same name)
/cc @tbosch / @jeffbcross what do you think about this? "support all the use cases and never ship" vs "support what people have asked for and ship"
well we didn't start with the simple fix... I hope that solves peoples issues <_<
Please try this out and let me know if there are any problems
Is the documentation wrong then at this point?
"Since you cannot dynamically generate the name attribute of input elements using interpolation, you have to wrap each set of repeated inputs in an ngForm directive and nest these in an outer form element."
Reference: https://code.angularjs.org/1.3.0-rc.4/docs/api/ng/directive/form
yes it is, care to send a PR?
I'd be happy to.
Is there anyplace that this _is_ documented? I can't seem to find any clear definition of what the final implementation supports (in terms of syntax). Is there a working example somewhere?
it's not documented anywhere, it's just the expected behaviour which is consistent with the way the framework actually works. The fact that it didn't work before was surprising to people.
The syntax is just interpolated strings, eg name="{{custom}}FormControl"
or similar. This didn't used to work the way people expected, now it does, consistent with the rest of the framework.
I guess you've found that there is some documentation that it does not support this, so it would be good to remove or rewrite it to indicate the current behaviour.
Thank you. Yes, minimally it should be removed. An example (maybe not here ... but with ng-repeat?) would be helpful.
For example, how do you reference this in something like ng-messages?
ng-messages="myForm.{{custom}}FormControl.$error"
does not work.
Interpolated paths in ngMessages is a different problem, although it could certainly receive a similar fix.
@DeborahK
maybe you van just use
ng-messages="myForm[custom + 'FormControl'].$error"
+1 on this issue. Being able to pass name arguments to directives as part of their isolate scope would make life much easier.
Currently having to hodge : http://stackoverflow.com/a/25652866 into every application that requires dynamic validation and it just feels hacky.
@scouser3008 this issue was fixed, you don't need to decorate ngModelController at all now. The name
attribute is interpolated now.
@caitp Yup, completely my fault flagging this. For IE compatibility I'm having to use v1.2 and got caught up in debugging! Apologies.
@caitp I wish I found this thread a year ago when I first had this issue. I used the ng-form hack. Unfortunately, this hack does not work when your dynamic forms that are being repeated several times have radio buttons... because even though the form validation "works", now all of your radio buttons are part of the same radio group and so you can only select 1 on the entire page of forms. But I digress...
We are stuck on 1.2.x for the moment and so my question is, did @Thinkscape 's decorators (found above) prove to be as effective as the eventual solution that is implemented in 1.3.x?
@spencerb02 you mean the decorators from my plunker? :p
So, the stuff that was merged into 1.3.x has some extra meat to it. In particular, it will remove controls from the form controller and re-add them if the interpolated value changes, and the goal is to remove them when they are destroyed, too.
The decorators just interpolate one time, so it can cause problems during ngRepeat if an $index changes, for instance.
@caitp excellent. Thank you. Forgive my naivety, but when would indexes change that wouldn't also be a redraw? Also, if I have another unique key to tie it to rather than $index, this won't be an issue, right?
@spencerb02 it's not exactly that simple, if the form is outside of ngRepeat, and the length changes, you can still have stale stuff in the form --- during a redraw, if an element is moved, it is not re-transcluded. http://plnkr.co/edit/rRYgWgdo4M9sUnGiNwqv?p=preview << so, the controller wouldn't be re-created, and it wouldn't create a new scope, just the scope values would change.
+1
+1
+1
+1
+1
+1
+1
+1
Thank you to the AngularJS devs for the changes apparently made in 1.3 because I had no trouble getting validation to work for dynamically-added form elements using ngRepeat in AngularJS 1.4.3
To summarize a slightly ambiguous discussion from earlier this year, AngularJS 1.3 now allows you to dynamically assign the name inside ngRepeat using the double curly braces.
name="formControl_{{uniqueId}}"
To reference the form element name in a more complicated path, use this pattern:
ng-messages="myForm[ 'formControl_' + uniqueId ].$error"
There is no longer a need to use subforms (embedded ngForm directives) to make validation work for dynamically added form elements - tested using AngularJS 1.4.3
+1
+1
as @jeremyml said about complicated paths, i ended up using the next path to access a dynamic field inside of an ng-form form, inside of an ng-repeat
mainForm['extraInfoForm_' + $index]['name_' + $index].$error
What a workaround!
Angular version 1.4.5
Thanks @rafa-gda for the ng-name directive! Works like a charm on 1.4.5
I'm glad to hear it @matfiz but you do not need that workaround in v1.4.5 since the form
directive interpolates the provided name
by default. If you use name
attribute instead of ng-name
in your form
it should work just fine.
@rafa-gda, thanks! But I am using it on input
fields, so I can handle more complex validations on nested, dynamically added form elements (conditions on multiple fields). The name
attribute in v1.4.5 on input
did not interpolate, I had to use your hacky ng-name
:)
@matfiz, input
fields support interpolated name
attributes since v1.3.0-beta.11 (so all stable 1.3.x and 1.4.x versions). Maybe the problem lies somewhere else.
@gkalpak, thanks for the useful remark! You were right, thanks to your information I have found an issue elsewhere
Is this fixed? I am trying to use input directives but the validations aren't working as expected =\
@jodinathan, yes this has been fixed. If you are having problems using dynamic element names, I would suggest creating a live demo of the issue and posting it to one of the appropriate support channels.
Or, if you think you found a bug/regression, please open a new issue with a detailed description (and preferrably a live demo - e.g. using CodePen, Plnkr etc).
is this issue fixed ? I am struggling same issue . Could you please work around other than nested ng-form
I am getting below error when i use {{}} symbol in ng-messages directive
Error: [$parse:syntax] Syntax Error: Token '{' is an unexpected token at column
- [<select-ist-stake name="istStakeRole{{$index}}" ng-model="team" ng-required="true"></select-ist-stake>
<span class="help-block" ng-messages="stakeHolderForm.istStakeRole$index.$errors" ng-show="stakeHolderForm.$submitted || stakeHolderForm.istStakeRole$index.$touched || stakeHolderForm.istStakeRole$index.$error" >
<span ng-messages-include="common/components/validations/validationMessages.tpl.html"></span>
</span>
]
@diwanoli, if you think this is a bug, please open a new issue providing all necessary details (ideally a runnable demo of the problem). If you are not sure if this is a bug in Angular, try asking a question on one of the support channels.
+1
+1
Most helpful comment
Thank you to the AngularJS devs for the changes apparently made in 1.3 because I had no trouble getting validation to work for dynamically-added form elements using ngRepeat in AngularJS 1.4.3
To summarize a slightly ambiguous discussion from earlier this year, AngularJS 1.3 now allows you to dynamically assign the name inside ngRepeat using the double curly braces.
To reference the form element name in a more complicated path, use this pattern:
There is no longer a need to use subforms (embedded ngForm directives) to make validation work for dynamically added form elements - tested using AngularJS 1.4.3