Validate a form field with a dynamically given name in angular


I create a form dynamically in the view by iterating through an object that has the different questions to be asked to the user. One of the attributes of every question is formFieldName which is a a random string I use to give each form field a different name.

<form name="includedForm.newRequestForm" class="form-horizontal" role="form" novalidate>    

<div ng-if="message.question.attributes.structure.type == 'object'">
    <div ng-repeat="(index,objField) in message.question.attributes.structure.properties">
        <div ng-if="objField.type == 'array'" class="form-group" show-errors>
            <label for="{{objField.formFieldName}}" class="control-label col-sm-6">{{objField.title}}
                <br /><i><small>{{objField.description}}</small></i></label>
            <div class="col-sm-6">
                <select class="form-control" name="{{objField.formFieldName}}" multiple ng-model="objField.userValue" ng-required="objField.required">
                    <option ng-repeat="option in objField.items.enum" value="{{option}}">{{option}}</option>
                </select>
            </div>
        </div>

        <div ng-if="objField.type == 'boolean'" class="form-group" show-errors>
            <label for="{{objField.formFieldName}}" class="control-label col-sm-6">{{objField.title}}</label>
            <div class="col-sm-6">
                <input class="form-control" name="{{objField.formFieldName}}" ng-model="objField.userValue" type="checkbox" ng-value="option" ng-checked="message.question.attributes" />
            </div>
        </div>
    </div>
</div>

<div class="col-sm-12">
    <button ng-click="markAsDone(message)" class="btn btn-primary">Done</button>
</div>
<form>

In the controller I'm able to get the formFieldName attribute but I can't figure out how to use it to do the validation.

var MarkAsDone = function(message) {

    $scope.includedForm = {};
    var formField = message.question.attributes.formFieldName;
    if ($scope.includedForm.newRequestForm.{{formField}}.$valid){
        //submit the form
    }
}


to answer you question:

  1. first, {{}} is === $scope so you don't use that anywhere other than HTML. You use $scope in your JS and {{}} in HTML which creates a pipe (2-way binding) so that $scope.variable.property has bidirectional binding to {{variable.property }} in HTML.

    $scope.includeForm.email === {{ includeForm.email }} === ng-model="includeForm.email" === ng-bind="includeForm.email"
    

    if you set anyone of those all are set so if you set $scope it will show up in HTML and obviously as user input gets captured it is already in $scope ... all connected

  2. when attempting to get the value from HTML back into JS you would need create and set a $scope i.e so if you create $scope.dataModel.dataProperty and use that in ng-model=dataModel.dataProperty (example) you again have two way binding ... you don't need to do anything as angular is taking care of the data pipeline. So if you want to extract the value to var, which is probably a waste as the $scope is already set as soon as the user checks the box

    var formField = $scope.dataModel.dataProperty;
    // but like I said no need as $scope.dataModel.dataProperty; is your var
    
  3. In JS if you want to use a dynamic property as an object property key you would place the dynamic value in [] e.g.

    $scope.variable[dynamicProperty].method;
    // you can set a static property as a key with dot notation i.e.
    $scope.variable.staticProperty = val;
    

Hope that helps