I am writing an AngularJS app and in this app there is a domain-management tool. When a domain is selected, I generate the domain-records in a table, letting the user edit each row. Since the fields are dynamically created, I use ng-form to enable validating each row individually, since they share the same name.
Each domain-record has a content field where an IP, CNAME, or such resides. I validate this field using a regex pattern generated from a function based on which record type is selected (A, CNAME, TXT, etc.).
The problem is that when I edit let's say, an A record, then change the record-type to CNAME, the form still appears valid since no new validation of the content-field has been performed. The only way for me to re-validate it is to start typing in the content field which then works fine.
Check images below:
I press edit on the A record and everything looks fine:
I change the record type to CNAME and the form still appears valid even though the regex changed. When I change the type I want the content (1.2.3.4) to be re-validated since it's a new regex in place:
I start typing in the content field and now the form correctly becomes invalid. I want this to happen when I change the record-type, not only when I start typing again:
#Slim version of the template to give you an idea on whats going on
<form novalidate name="recordForm" class="css-form" ng-controller="EditRecordCtrl">
<table>
<tr ng-repeat="record in domain.data.0" class="gradeA">
<td ng-init="startingTypeData = record.type" class="domains-td" ng-switch on="record.edit">
<span ng-switch-default>{{record.type}}</span>
<span ng-switch-when="true">
<select ng-change="domainRecordContentType(record.type)" ng-init="domainRecordContentType(record.type)" ng-model="record.type" ng-options="c for c in domainRecordTypes" class="span12">
</select>
</span>
</td>
<td ng-init="startingContentData = record.content" class="domains-td validation-dropdown-error-parent" ng-switch on="record.edit">
<span ng-switch-default>{{record.content}}</span>
<span ng-switch-when="true">
<ng-form name="innercContentForm">
<span class="validation-dropdown-error" ng-show="innercContentForm.content.$error.pattern">
{{ 'RECORD_EDIT_FORM_RECORD_CONTENT_PATTERN_MSG' | translate }} ( {{ record.type }} )
</span>
<input type="text" ng-model="record.content" name="content" required class="span12 edit-record-input" ng-pattern="domainRecordContentRegex.0" required />
</ng-form>
</span>
</td>
</tr>
</table>
</form>
How can I re-validate the input field when I change the drop-down menu?
Plunker example: http://plnkr.co/edit/VAR5ho Note! Small bug not showing the A record in the first row. You can still test the issue tho as I did in the images above.
Before chaning dropdown
After change first dropdown from A to CNAME all content fields are wiped
<button ng-disabled="recordForm.$invalid" ng-switch-when="true" ng-if="hideRecordType(record.type)" ng-click="recordForm.$valid && editRecord(record, domainId); record.edit=false; $parent.startingNameData=record.name; $parent.startingTypeData=record.type; $parent.startingContentData=record.content; $parent.startingTTLData=record.ttl; $parent.startingPrioData=record.prio" type="submit" class="btn btn-block btn-primary btn-icon" ><i></i>{{ 'DOMAINS_SAVE_BUTTON' | translate }}</button>
I press edit and it goes into my normal edit view
I start typing a new IP address until it becomes valid
If I make the content invalid after being valid once, like adding a dot the value gets wiped out. Why?
Current directive based on Thomas code:
domainModule.directive('revalidate', function($compile) {
return {
restrict: 'A',
link : function (scope, element, attrs) {
scope.$watch(attrs.ngModel, function (v) {
var reg = scope.$parent.domainRecordContentRegex[0];
if(!$(element).parent().parent().next().find('ng-form').find('input').val().match(reg)){
$compile($(element).parent().parent().next().find('ng-form').children('input[name="content"]').removeClass('ng-valid-pattern'))(scope);
$compile($(element).parent().parent().next().find('ng-form').children('input[name="content"]').addClass('ng-invalid-pattern'))(scope);
}
});
}
};
});
I select the actual field now and change the class to make it invalid if the regex dont match. This way the Save button also gets invalid. This works when changing in the dropdown, but it corrupts the compiled element somehow.
The simplest HTML validation feature is the required attribute. To make an input mandatory, add this attribute to the element. When this attribute is set, the element matches the :required UI pseudo-class and the form won't submit, displaying an error message on submission when the input is empty.
ng-valid is set if the form is valid. ng-invalid is set if the form is invalid. ng-pending is set if the form is pending. ng-pristine is set if the form is pristine. ng-dirty is set if the form is dirty.
ng-pristine: The ng-pristine class tells that the form has not been modified by the user. This returns true if the form has not been modified by the user. Return type: Return Boolean True if the form/input field is not modified by the user else it returns False.
To trigger validation, in ng-change of select set the value of input to its value. Change line 44 in your plunker to
<select ng-change="domainRecordContentType(record.type);innercContentForm.content.$setViewValue(innercContentForm.content.$viewValue)" ng-init="domainRecordContentType(record.type)" ng-model="record.type" ng-options="c for c in types">
Updated plunker http://plnkr.co/edit/D1AFHi
Credit: https://stackoverflow.com/a/17102401/69362
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With