Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

feat(input): interpolates form input name attrs for ngModel #4791

Closed
wants to merge 1 commit into from

Conversation

caitp
Copy link
Contributor

@caitp caitp commented Nov 5, 2013

@frankhuster / @niargh has brought up an issue with using the $index of a repeated element for the name attribute of a form input.

I don't know how common of a use-case it is, but it seems not especially harmful to do a one-time interpolation in post-link.

It shouldn't be a breaking change unless people are using interpolation markers in their names.

@caitp
Copy link
Contributor Author

caitp commented Nov 5, 2013

It would be cool to be able to limit parsing/interpolation to only accept types like string/number for this, and have everything else be the empty string --- But I guess that's complicated, so this is the simplest way to do it.

I don't know how valuable this is to other developers, but it seems to be useful to at least one person.

@jamie-pate
Copy link

+1

@caitp
Copy link
Contributor Author

caitp commented Nov 30, 2013

I had thought ng-attr-name might be enough for this, but testing with http://plnkr.co/edit/HQHNHCjVqEKmAC1lHvED?p=preview seems to show that it's not (priority issue, I think). (http://plnkr.co/edit/BC7GegiP5MeO65Lniw1X?p=preview works just fine with the patch)

So, updating the ng-attr-* "priority" might be one way to go, but I expect it would be much more problematic than this simple fix.

@IgorMinar
Copy link
Contributor

I'm sorry, but I wasn't able to verify your CLA signature. CLA signature is required for any code contributions to AngularJS.

Please sign our CLA and ensure that the CLA signature email address and the email address in this PR's commits match.

If you signed the CLA as a corporation, please let me know the company's name.

Thanks a bunch!

PS: If you signed the CLA in the past then most likely the email addresses don't match. Please sign the CLA again or update the email address in the commit of this PR.
PS2: If you are a Googler, please sign the CLA as well to simplify the CLA verification process.

1 similar comment
@IgorMinar
Copy link
Contributor

I'm sorry, but I wasn't able to verify your CLA signature. CLA signature is required for any code contributions to AngularJS.

Please sign our CLA and ensure that the CLA signature email address and the email address in this PR's commits match.

If you signed the CLA as a corporation, please let me know the company's name.

Thanks a bunch!

PS: If you signed the CLA in the past then most likely the email addresses don't match. Please sign the CLA again or update the email address in the commit of this PR.
PS2: If you are a Googler, please sign the CLA as well to simplify the CLA verification process.

@IgorMinar
Copy link
Contributor

CLA signature verified! Thank you!

Someone from the team will now triage your PR and it will be processed based on the determined priority (doc updates and fixes with tests are prioritized over other changes).

@caitp
Copy link
Contributor Author

caitp commented Dec 15, 2013

In the mean time, or in case this is never merged, I wrote a plnkr the other showing how you could get this functionality with separate directives, or by decorating the existing ngModel and form directives http://plnkr.co/edit/VnHHEe?p=preview (this version decorates ngModelDirective and formDirective to provide this functionality)

@caitp caitp mentioned this pull request Jan 11, 2014
2 tasks
@sjbarker sjbarker mentioned this pull request Mar 6, 2014
caitp added a commit to caitp/angular.js that referenced this pull request Sep 23, 2014
Interpolates the form controll attribute name, so that dynamic form controls (such as those rendered
in an ngRepeat) will always have their expected interpolated name.

Closes angular#4791
@caitp
Copy link
Contributor Author

caitp commented Sep 23, 2014

@tbosch / @matsko I've un-bitrotten the original patch here, I will add a followup commit which supports renaming form controls in the form itself, although honestly I don't feel like there is a real use case for that

@matsko
Copy link
Contributor

matsko commented Sep 23, 2014

Your code breaks with the ngRepeat + $index usecase.

@caitp
Copy link
Contributor Author

caitp commented Sep 23, 2014

how does it "break", you haven't explained this. There are demonstrations of it being used exactly with ngRepeat + $index --- yes, the $index doesn't change, but this is fine

@matsko
Copy link
Contributor

matsko commented Sep 23, 2014

So what happens then if the name value isn't present at the time of interpolation? You may end up getting an undefined value.

@caitp
Copy link
Contributor Author

caitp commented Sep 23, 2014

You end up getting the empty string if it's undefined at the time of interpolation. Anyways, I've added a patch which renames the form control, but honestly nobody has ever asked for this, so I don't think we actually need it until someone does. The "support all the use cases and never ship" thing just doesn't seem sensible here

@caitp
Copy link
Contributor Author

caitp commented Sep 23, 2014

Anyways, this does have some safety checks in that it requires form[oldName] to equal the control which is being renamed, which can potentially break things if there are multiple form controls whose name is the empty string.

Lets worry about that when people say it's breaking their apps, really

@caitp
Copy link
Contributor Author

caitp commented Sep 23, 2014

Okay, added another one which supports renaming forms

@caitp
Copy link
Contributor Author

caitp commented Sep 23, 2014

I still kind of feel like this is more feature than people have really asked for and it's probably better to take it one step at a time, but it's in 3 separate commits so we can think about it all separately. @tbosch can you review as well?

} else {
controller.$name = alias;
}
});
}
if (parentFormCtrl) {
formElement.on('$destroy', function() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should invoke unobserveName() here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no need to since all watchers are removed when the scope is destroyed. Internally attr.$observe uses $scope.$watch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not exactly --- the observers collection stays alive afaik. The attribute interpolation watches are removed automatically though, this is true

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's probably better to unobserve manually rather than accidentally risk keeping a reference alive

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whatever makes you guys happy :>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't add unobserve here, as we don't have it at similar places in the code neither and it confuses the reader (ask myself: "why here and not at the other places"...)

@caitp caitp force-pushed the issue-4791 branch 5 times, most recently from 58dd9ae to 1b59793 Compare September 23, 2014 18:05
caitp added a commit to caitp/angular.js that referenced this pull request Sep 23, 2014
Interpolates the form controll attribute name, so that dynamic form controls (such as those rendered
in an ngRepeat) will always have their expected interpolated name.

Closes angular#4791
@caitp
Copy link
Contributor Author

caitp commented Sep 23, 2014

I think the only thing missing is tests (and possibly functionality) for select controls

@@ -127,6 +128,23 @@ function FormController(element, attrs, $scope, $animate) {
}
};

// Private API: rename a form control
form.$$renameControl = function(control, newName) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be simplified to:

var oldName = control.$name;
if (form[oldName] === control) {
  delete form[oldName];
}
form[newName] = control;
control.$name = newName;

@tbosch
Copy link
Contributor

tbosch commented Sep 23, 2014

LGTM when my comments are resolved.
Ah, and please squash into a single commit as the commits are strongly related.

caitp added a commit to caitp/angular.js that referenced this pull request Sep 23, 2014
Interpolates the form controll attribute name, so that dynamic form controls (such as those rendered
in an ngRepeat) will always have their expected interpolated name.

Closes angular#4791

feat(input): rename form controls when name is updated

feat(form): support dynamic form validation

test(select): add tests for form control interpolation in selectDirective
@caitp
Copy link
Contributor Author

caitp commented Sep 23, 2014

some comments are addressed --- code is simplified a bit.

If it looks good to land I will fix up the commit message and get it into this release.

});


it('should interpolate input names (number)', function() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is not needed, as the change is not dependent on the input type...

caitp added a commit to caitp/angular.js that referenced this pull request Sep 23, 2014
Interpolates the form and form control attribute name, so that dynamic form controls (such as those
rendered in an ngRepeat) will always have their expected interpolated name.

The control will be present in its parent form controller with the interpolated property name, and
this name can change when the interpolated value changes.

Closes angular#4791
Interpolates the form and form control attribute name, so that dynamic form controls (such as those
rendered in an ngRepeat) will always have their expected interpolated name.

The control will be present in its parent form controller with the interpolated property name, and
this name can change when the interpolated value changes.

Closes angular#4791
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants