Angular 1.6.2
Try to iterate over elements of collection inputted by user and then check their validity and enable submit action if validation passes.
I try to use ng-form
for this purpose and have two approach but each of them has side-effect.
First approach (ng-form
at the table level):
<table class="datatable table table-stripped table-responsive" ng-form="form">
<thead>
<tr class="headers">
<th ng-repeat="header in ctrl.headers">{{header}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="linkDelay in ctrl.currentLinkDelays">
<td>{{linkDelay.label}}</td>
<td>{{linkDelay.value}}</td>
<td id="proposed-ld-input-column" width=40%>
<input id="proposed-ld-input" name="input"
class="form-control ng-invalid-min ng-invalid-max ng-invalid-required"
type="number" ng-model="ctrl.inputs[linkDelay.property]"
data-ng-required="true" min="0" max="180"/>
<div class="error" data-ng-show="form.input.$error.required">
Message required
</div>
<div class="error" data-ng-show="form.input.$error.max">
Message max
</div>
<div class="error" data-ng-show="form.input.$error.min">
Message min
</div>
</td>
</tr>
</tbody>
</table>
<button class="btn btn-primary" type="submit" ng-disabled="form.$invalid"
ng-click="ctrl.applyChanges()">
<span>Apply</span>
</button>
In this approach submit is disabled until all input are in set ranges but validation messages don't appear.
Second approach (ng-form
at the table column level):
<table class="datatable table table-stripped table-responsive">
<thead>
<tr class="headers">
<th ng-repeat="header in ctrl.headers">{{header}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="linkDelay in ctrl.currentLinkDelays">
<td>{{linkDelay.label}}</td>
<td>{{linkDelay.value}}</td>
<td id="proposed-ld-input-column" width=40% ng-form="form">
<input id="proposed-ld-input" name="input"
class="form-control ng-invalid-min ng-invalid-max ng-invalid-required"
type="number" ng-model="ctrl.inputs[linkDelay.property]"
data-ng-required="true" min="0" max="180"/>
<div class="error" data-ng-show="form.input.$error.required">
Message required
</div>
<div class="error" data-ng-show="form.input.$error.max">
Message max
</div>
<div class="error" data-ng-show="form.input.$error.min">
Message min
</div>
</td>
</tr>
</tbody>
</table>
<button class="btn btn-primary" type="submit" ng-disabled="form.$invalid"
ng-click="ctrl.applyChanges()">
<span>Apply</span>
</button>
In this approach validation messages appear but submit button is always enabled.
Could you tell me what I did wrong?
Give the inputs different names:
<table class="datatable table table-stripped table-responsive" ng-form="form">
<thead>
<tr class="headers">
<th ng-repeat="header in ctrl.headers">{{header}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="linkDelay in ctrl.currentLinkDelays">
<td>{{linkDelay.label}}</td>
<td>{{linkDelay.value}}</td>
<td id="proposed-ld-input-column{{$index}}" width=40%>
̶<̶i̶n̶p̶u̶t̶ ̶i̶d̶=̶"̶p̶r̶o̶p̶o̶s̶e̶d̶-̶l̶d̶-̶i̶n̶p̶u̶t̶"̶ ̶n̶a̶m̶e̶=̶"̶i̶n̶p̶u̶t̶"̶
<input id="proposed-ld-input{{$index}}" name="input{{$index}}"
class="form-control ng-invalid-min ng-invalid-max ng-invalid-required"
type="number" ng-model="ctrl.inputs[linkDelay.property]"
data-ng-required="true" min="0" max="180"/>
<div class="error" ng-show="form['input'+$index].$error.required">
Message required
</div>
<div class="error" ng-show="form['input'+$index].$error.max">
Message max
</div>
<div class="error" ng-show="form['input'+$index].$error.min">
Message min
</div>
</td>
</tr>
</tbody>
</table>
<button class="btn btn-primary" type="submit" ng-disabled="form.$invalid"
ng-click="ctrl.applyChanges()">
<span>Apply</span>
</button>
The ng-repeat
creates multiple inputs. They need to be assigned different names for the error messages to be correct.