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 have a input element which I am trying to name dynamically, but I had no luck so far using angular js.

neither

<input type="text" name="resource.Name" ng-model="resource.Value" ng-required="resource.IsRequired">

nor

<input type="text" name="{{resource.Name}}" ng-model="resource.Value" ng-required="resource.IsRequired">

works for me. When I try to access name attribute it always comes back as resource.Name instead of the value it contains. The main reason I am trying to name this input control is validation, if user does not enter text in the field, I would like to tell them which textbox is required. If there is any angular directive I can use for that purpose I am ready to use them as well.

Can anyone tell me how to achieve this.

My validation function is as follows:

 window.resourcesValidation = function ($scope, $rootScope, $alert) {
        var subscriptions = $scope.scopeData.Subscriptions;
        var isValidated = true;

        if ($scope.resourceDataForm && $scope.resourceDataForm.$error && $scope.resourceDataForm.$error.required) {
            var missingFields = [];
            angular.forEach($scope.resourceDataForm.$error.required, function (value, key) {
                isValidated = false;
                missingFields.push("-" + value.$name);
            });

            $alert.error("Please fill in the all required fields.\r\n" + missingFields.join("\r\n"));
        }

        if (isValidated)
            $scope.saveChanges(subscriptions);

        return isValidated;
    };
share|improve this question
    
What does $scope.resourceDataForm look like? Any chance you can make a demo in plunker or something? –  Jerrad May 25 at 14:41
    
Why are you putting resourcesValidation in a global function and not inside of a module's controller? –  Josh Beam May 25 at 14:49
    
Put a breakpoint in the resourcesValidation function and look at $scope.resourceDataForm. Is $scope.resourceDataForm.$error.required an array? Do its items have a $name property? Can you post what the entire object looks like? –  Jerrad 2 days ago
    
Yes Jerrad that's an array. first element has a $name property, which has the following value: {{subscriptionResource.Name}}, I think angularjs's ng-required validation uses name of the control before it is binded. –  erin c 2 days ago
add comment

5 Answers

up vote 1 down vote accepted

Quoting another answer on a very similar issue:

This happens because the control's name (the one with which it is registered on its parent form) is retrieved during the ngModelController's instantiation, which according to the docs takes place before the pre-linking phase* (so no interpolation yet).


In other words, validation relies on forms.$error object, which is bound to the controls that are registered with that form.
A control's ngModelController is responsible for registering a control with its parent form and it is instantiated at the pre-linking phase (when the name-expression is not interpolated yet).

This can be solved by a custom directive that manually registers the control with its parent form, but only after it's actual name is determined (after insterpolating the name-expression).


You can find the whole answer here.
Look for the UPDATE 2 section for a working solution.

(This is the link to the working demo.)

share|improve this answer
    
Thanks a lot, this seems to be my problem. I will ive it a try and let you knowç –  erin c 2 days ago
add comment

Can you show the rest of your code? (HTML, relevant controllers, etc.)

Sometimes the issue can center around asynchrony. For example, the HTML might be compiled by Angular's compiler before your $scope.resource object gets its data (perhaps, with an AJAX call).

Two-way data binding sometimes doesn't always work how you would expect. Therefore, after "putting" your data into $scope.resource with whatever function, you might need to call $scope.$apply().

share|improve this answer
    
I think my problem is in my validation function, I posted it right now. –  erin c May 25 at 14:40
add comment
<input ng-model="resource.model" name="{{resource.name}}" ng-required="{{resource.required}}"/>

seems to be working for me. Please see this plnkr .

share|improve this answer
add comment

Try this:

<input type="text" ng-attr-name="{{resource.Name}}" ng-model="resource.Value" ng-required="resource.IsRequired">

From the docs:

If an attribute with a binding is prefixed with the ngAttr prefix (denormalized as ng-attr-) then during the binding will be applied to the corresponding unprefixed attribute.

Although name="{{resource.Name}}" should work in this case as well.

Update

I found a solution here: Dynamic validation and name in a form with AngularJS

Here's a plunker that I made.

Sounds like this issue may be fixed in Angular 1.3.

share|improve this answer
    
unfortunately it did not work as well –  erin c May 25 at 14:32
    
It works. jsbin.com/vajuv/1/edit –  Jerrad May 25 at 14:33
1  
Maybe you could add some informations why you changed in the original code in this way so that future readers can understand that and fix their problem which is similar to this. –  wumm May 25 at 14:43
1  
This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. –  Artem Bilan May 25 at 14:43
1  
The original question just asked how to bind the name property. My answer provided a solution to that. They didn't add the bit about the validation function until after I answered. –  Jerrad May 25 at 14:51
show 8 more comments

If you are using Angular's form directive for validation, then you are probably encountering this issue because the form directive goes through the form's children to identify input fields when the form directive gets linked. During that stage, the name property is not properly data-bound. The solution is to use jQuery or jqLite or just JS to insert the name attribute dynamically to your input element in the compile function. The compile function of a directive is dedicated to pre-compiling DOM manipulation. (https://docs.angularjs.org/api/ng/service/$compile#comprehensive-directive-api)

share|improve this answer
    
Why am I getting downvoted? I've correctly identified the problem and proposed a solution. –  Hans 2 days ago
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.